mirror of
https://github.com/mroxso/zelo-news.git
synced 2026-06-04 09:31:14 +02:00
feat: add SettingsPage and integrate into AppRouter and Header
This commit is contained in:
@@ -9,6 +9,7 @@ import FollowingPage from "./pages/FollowingPage";
|
||||
import Nip05ProfilePage from "./pages/Nip05ProfilePage";
|
||||
import ArticleByDTagPage from "./pages/ArticleByDTagPage";
|
||||
import { NIP19Page } from "./pages/NIP19Page";
|
||||
import SettingsPage from "./pages/SettingsPage";
|
||||
import NotFound from "./pages/NotFound";
|
||||
import HomePage from "./pages/HomePage";
|
||||
|
||||
@@ -24,6 +25,7 @@ export function AppRouter() {
|
||||
<Route path="/search" element={<SearchResultsPage />} />
|
||||
<Route path="/bookmarks" element={<BookmarksPage />} />
|
||||
<Route path="/following" element={<FollowingPage />} />
|
||||
<Route path="/settings" element={<SettingsPage />} />
|
||||
{/* NIP-05 profile route (e.g., /p/alice@example.com) */}
|
||||
<Route path="/p/:nip05" element={<Nip05ProfilePage />} />
|
||||
{/* Article by d-tag route (e.g., /article/my-article-slug) */}
|
||||
|
||||
@@ -2,7 +2,7 @@ import { Link } from 'react-router-dom';
|
||||
import { useCurrentUser } from '@/hooks/useCurrentUser';
|
||||
import { LoginArea } from '@/components/auth/LoginArea';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { PenSquare, Bookmark, Users } from 'lucide-react';
|
||||
import { PenSquare, Bookmark, Users, Settings } from 'lucide-react';
|
||||
import { ThemeToggle } from '@/components/ThemeToggle';
|
||||
|
||||
export function Header() {
|
||||
@@ -46,12 +46,22 @@ export function Header() {
|
||||
|
||||
{/* Desktop Actions */}
|
||||
<div className="hidden sm:flex items-center gap-2">
|
||||
<Button variant="ghost" size="icon" asChild>
|
||||
<Link to="/settings" aria-label="Settings">
|
||||
<Settings className="h-4 w-4" />
|
||||
</Link>
|
||||
</Button>
|
||||
<ThemeToggle />
|
||||
<LoginArea className="max-w-60" />
|
||||
</div>
|
||||
|
||||
{/* Mobile: show LoginArea in header (bottom nav is still used for nav) */}
|
||||
<div className="sm:hidden flex items-center">
|
||||
<div className="sm:hidden flex items-center gap-1">
|
||||
<Button variant="ghost" size="icon" asChild>
|
||||
<Link to="/settings" aria-label="Settings">
|
||||
<Settings className="h-4 w-4" />
|
||||
</Link>
|
||||
</Button>
|
||||
<ThemeToggle />
|
||||
<LoginArea className='pl-2' />
|
||||
</div>
|
||||
|
||||
82
src/pages/SettingsPage.tsx
Normal file
82
src/pages/SettingsPage.tsx
Normal file
@@ -0,0 +1,82 @@
|
||||
import { Settings, Palette, Wifi } from 'lucide-react';
|
||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
|
||||
import { Label } from '@/components/ui/label';
|
||||
import { Switch } from '@/components/ui/switch';
|
||||
import { RelayListManager } from '@/components/RelayListManager';
|
||||
import { useTheme } from '@/hooks/useTheme';
|
||||
|
||||
export function SettingsPage() {
|
||||
const { theme, setTheme } = useTheme();
|
||||
|
||||
const isDarkMode = theme === 'dark';
|
||||
|
||||
const handleThemeToggle = () => {
|
||||
setTheme(isDarkMode ? 'light' : 'dark');
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="container max-w-4xl py-8 px-4">
|
||||
{/* Page Header */}
|
||||
<div className="mb-8">
|
||||
<div className="flex items-center gap-3 mb-2">
|
||||
<Settings className="h-8 w-8 text-primary" />
|
||||
<h1 className="text-3xl font-bold tracking-tight">Settings</h1>
|
||||
</div>
|
||||
<p className="text-muted-foreground">
|
||||
Manage your preferences and relay connections
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Settings Sections */}
|
||||
<div className="space-y-6">
|
||||
{/* Appearance Settings */}
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<div className="flex items-center gap-2">
|
||||
<Palette className="h-5 w-5 text-primary" />
|
||||
<CardTitle>Appearance</CardTitle>
|
||||
</div>
|
||||
<CardDescription>
|
||||
Customize how the application looks
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="space-y-0.5">
|
||||
<Label htmlFor="dark-mode" className="text-base cursor-pointer">
|
||||
Dark Mode
|
||||
</Label>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Switch between light and dark themes
|
||||
</p>
|
||||
</div>
|
||||
<Switch
|
||||
id="dark-mode"
|
||||
checked={isDarkMode}
|
||||
onCheckedChange={handleThemeToggle}
|
||||
/>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
{/* Relay Settings */}
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<div className="flex items-center gap-2">
|
||||
<Wifi className="h-5 w-5 text-primary" />
|
||||
<CardTitle>Relays</CardTitle>
|
||||
</div>
|
||||
<CardDescription>
|
||||
Manage your Nostr relay connections. Read relays are used to fetch content, while write relays receive your published events.
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<RelayListManager />
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default SettingsPage;
|
||||
Reference in New Issue
Block a user