- Improved protected route handling - Enhanced direct login access detection - Centralized navigation logic - Optimized state reset process - Fixed logout navigation behavior
72 lines
2.6 KiB
TypeScript
72 lines
2.6 KiB
TypeScript
import { useState, useCallback } from 'react'
|
|
import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/Popover'
|
|
import Button from '@/components/ui/Button'
|
|
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/Select'
|
|
import { useSettingsStore } from '@/stores/settings'
|
|
import { PaletteIcon } from 'lucide-react'
|
|
import { useTranslation } from 'react-i18next'
|
|
import { cn } from '@/lib/utils'
|
|
|
|
interface AppSettingsProps {
|
|
className?: string
|
|
}
|
|
|
|
export default function AppSettings({ className }: AppSettingsProps) {
|
|
const [opened, setOpened] = useState<boolean>(false)
|
|
const { t } = useTranslation()
|
|
|
|
const language = useSettingsStore.use.language()
|
|
const setLanguage = useSettingsStore.use.setLanguage()
|
|
|
|
const theme = useSettingsStore.use.theme()
|
|
const setTheme = useSettingsStore.use.setTheme()
|
|
|
|
const handleLanguageChange = useCallback((value: string) => {
|
|
setLanguage(value as 'en' | 'zh')
|
|
}, [setLanguage])
|
|
|
|
const handleThemeChange = useCallback((value: string) => {
|
|
setTheme(value as 'light' | 'dark' | 'system')
|
|
}, [setTheme])
|
|
|
|
return (
|
|
<Popover open={opened} onOpenChange={setOpened}>
|
|
<PopoverTrigger asChild>
|
|
<Button variant="ghost" size="icon" className={cn('h-9 w-9', className)}>
|
|
<PaletteIcon className="h-5 w-5" />
|
|
</Button>
|
|
</PopoverTrigger>
|
|
<PopoverContent side="bottom" align="end" className="w-56">
|
|
<div className="flex flex-col gap-4">
|
|
<div className="flex flex-col gap-2">
|
|
<label className="text-sm font-medium">{t('settings.language')}</label>
|
|
<Select value={language} onValueChange={handleLanguageChange}>
|
|
<SelectTrigger>
|
|
<SelectValue />
|
|
</SelectTrigger>
|
|
<SelectContent>
|
|
<SelectItem value="en">English</SelectItem>
|
|
<SelectItem value="zh">中文</SelectItem>
|
|
</SelectContent>
|
|
</Select>
|
|
</div>
|
|
|
|
<div className="flex flex-col gap-2">
|
|
<label className="text-sm font-medium">{t('settings.theme')}</label>
|
|
<Select value={theme} onValueChange={handleThemeChange}>
|
|
<SelectTrigger>
|
|
<SelectValue />
|
|
</SelectTrigger>
|
|
<SelectContent>
|
|
<SelectItem value="light">{t('settings.light')}</SelectItem>
|
|
<SelectItem value="dark">{t('settings.dark')}</SelectItem>
|
|
<SelectItem value="system">{t('settings.system')}</SelectItem>
|
|
</SelectContent>
|
|
</Select>
|
|
</div>
|
|
</div>
|
|
</PopoverContent>
|
|
</Popover>
|
|
)
|
|
}
|