veza/apps/web/src/pages/SettingsPage.tsx

159 lines
8.4 KiB
TypeScript
Raw Normal View History

import { useState, useEffect } from 'react';
import { Settings, User, Bell, Shield, Palette, Globe } from 'lucide-react';
import { Button } from '@/components/ui/button';
import { useAuthStore } from '@/features/auth/store/authStore';
import { useUIStore } from '@/stores/ui';
import { useToast } from '@/hooks/useToast';
import { ThemeSwitcher } from '@/components/theme/ThemeSwitcher';
export function SettingsPage() {
const { user } = useAuthStore();
const { theme, setTheme, language, setLanguage } = useUIStore();
const { toast } = useToast();
const [activeTab, setActiveTab] = useState('profile');
const [colorTheme, setColorTheme] = useState('cyber');
// Apply color theme to document
useEffect(() => {
document.documentElement.setAttribute('data-color-theme', colorTheme);
}, [colorTheme]);
const handleThemeChange = (newTheme: string) => {
setColorTheme(newTheme);
toast({ title: 'Theme Changed', description: `Switched to ${newTheme} theme` });
};
const tabs = [
{ id: 'profile', label: 'Profile', icon: User },
{ id: 'notifications', label: 'Notifications', icon: Bell },
{ id: 'privacy', label: 'Privacy', icon: Shield },
{ id: 'appearance', label: 'Appearance', icon: Palette },
{ id: 'language', label: 'Language', icon: Globe },
];
return (
<div className="min-h-screen p-6 space-y-6">
{/* Header */}
<div className="glass-hud rounded-2xl border-white/10 p-6 hud-corner">
<div className="flex items-center gap-3">
<div className="w-12 h-12 rounded-xl bg-kodo-cyan/20 flex items-center justify-center border border-kodo-cyan/30">
<Settings className="w-6 h-6 text-kodo-cyan" />
</div>
<div>
<h1 className="text-2xl font-display font-bold text-white">Settings</h1>
<p className="text-sm text-kodo-secondary">Manage your account preferences</p>
</div>
</div>
</div>
<div className="grid grid-cols-1 lg:grid-cols-4 gap-6">
{/* Sidebar */}
<div className="glass-hud rounded-xl border-white/10 p-4 h-fit">
<nav className="space-y-1">
{tabs.map((tab) => {
const Icon = tab.icon;
return (
<button
key={tab.id}
onClick={() => setActiveTab(tab.id)}
className={`w-full flex items-center gap-3 px-4 py-3 rounded-lg transition-all ${activeTab === tab.id
? 'bg-kodo-cyan/10 text-kodo-cyan border border-kodo-cyan/30'
: 'text-kodo-secondary hover:text-white hover:bg-white/5'
}`}
>
<Icon className="w-4 h-4" />
<span className="text-sm font-medium">{tab.label}</span>
</button>
);
})}
</nav>
</div>
{/* Content */}
<div className="lg:col-span-3 glass-hud rounded-xl border-white/10 p-6">
{activeTab === 'profile' && (
<div className="space-y-6">
<h2 className="text-xl font-bold text-white">Profile Settings</h2>
<div className="space-y-4">
<div>
<label className="block text-sm font-medium text-white mb-2">Username</label>
<input
type="text"
defaultValue={user?.username}
className="w-full px-4 py-2 bg-kodo-graphite border border-white/10 rounded-lg text-white focus:border-kodo-cyan focus:outline-none"
/>
</div>
<div>
<label className="block text-sm font-medium text-white mb-2">Email</label>
<input
type="email"
defaultValue={user?.email}
className="w-full px-4 py-2 bg-kodo-graphite border border-white/10 rounded-lg text-white focus:border-kodo-cyan focus:outline-none"
/>
</div>
<Button className="bg-kodo-cyan hover:bg-kodo-cyan/80 text-black" onClick={() => toast({ title: 'Saved!', description: 'Profile settings updated successfully' })}>
Save Changes
</Button>
</div>
</div>
)}
{activeTab === 'appearance' && (
<div className="space-y-6">
<h2 className="text-xl font-bold text-white">Appearance</h2>
<ThemeSwitcher currentTheme={colorTheme} onThemeChange={handleThemeChange} />
<div className="border-t border-white/10 pt-6 mt-6">
<label className="block text-sm font-medium text-white mb-2">Light/Dark Mode</label>
<div className="grid grid-cols-3 gap-3">
{['light', 'dark', 'system'].map((t) => (
<button
key={t}
onClick={() => setTheme(t as 'light' | 'dark' | 'system')}
className={`px-4 py-3 rounded-lg border transition-all ${theme === t
? 'bg-kodo-cyan/10 border-kodo-cyan text-kodo-cyan'
: 'border-white/10 text-kodo-secondary hover:border-white/20'
}`}
>
{t.charAt(0).toUpperCase() + t.slice(1)}
</button>
))}
</div>
</div>
</div>
)}
{activeTab === 'language' && (
<div className="space-y-6">
<h2 className="text-xl font-bold text-white">Language</h2>
<div className="space-y-4">
<div>
<label className="block text-sm font-medium text-white mb-2">Preferred Language</label>
<select
value={language}
onChange={(e) => setLanguage(e.target.value as 'en' | 'fr')}
className="w-full px-4 py-2 bg-kodo-graphite border border-white/10 rounded-lg text-white focus:border-kodo-cyan focus:outline-none"
>
<option value="en">English</option>
<option value="fr">Français</option>
</select>
</div>
</div>
</div>
)}
{(activeTab === 'notifications' || activeTab === 'privacy') && (
<div className="space-y-6">
<h2 className="text-xl font-bold text-white">
{activeTab === 'notifications' ? 'Notifications' : 'Privacy'}
</h2>
<p className="text-kodo-secondary">Settings for {activeTab} will be available soon.</p>
</div>
)}
</div>
</div>
</div>
);
}