'use client' import { useState, useEffect } from 'react' import { updateAISettings } from '@/app/actions/ai-settings' import { updateUserSettings } from '@/app/actions/user-settings' import { useLanguage } from '@/lib/i18n' import { toast } from 'sonner' import { Palette, Type, LayoutGrid, Maximize } from 'lucide-react' import { applyDocumentTheme, normalizeThemeId, type ThemeId } from '@/lib/apply-document-theme' import { NOTES_LAYOUT_STORAGE_KEY, parseNotesLayoutMode, setNotesLayoutPreference, } from '@/lib/notes-view-preference' import { isClassicLayoutMode, type NotesClassicLayoutMode } from '@/components/notes-list-views' import { motion } from 'motion/react' const PRESET_COLORS = [ { name: 'Warm Earth', value: '#A47148' }, { name: 'Sage', value: '#4E594A' }, { name: 'Terracotta', value: '#B1523E' }, { name: 'Iron', value: '#4A5568' }, { name: 'Charcoal', value: '#1E293B' }, { name: 'Slate', value: '#475569' }, { name: 'Olive', value: '#7C8363' }, { name: 'Wine', value: '#722F37' }, ] interface AppearanceSettingsClientProps { initialFontSize: string initialTheme: string initialFontFamily?: string initialAccentColor?: string } export function AppearanceSettingsClient({ initialFontSize, initialTheme, initialFontFamily = 'inter', initialAccentColor = '#A47148', }: AppearanceSettingsClientProps) { const { t } = useLanguage() const [theme, setTheme] = useState(normalizeThemeId(initialTheme || 'light')) const [fontSize, setFontSize] = useState(initialFontSize || 'medium') const [fontFamily, setFontFamily] = useState(initialFontFamily) const [accentColor, setAccentColor] = useState(initialAccentColor) const [notesLayout, setNotesLayout] = useState('list') useEffect(() => { const stored = parseNotesLayoutMode(localStorage.getItem(NOTES_LAYOUT_STORAGE_KEY)) setNotesLayout(isClassicLayoutMode(stored) ? stored : 'list') }, []) useEffect(() => { document.documentElement.style.setProperty('--color-brand-accent', accentColor) }, [accentColor]) const handleAccentColorChange = async (color: string) => { setAccentColor(color) document.documentElement.style.setProperty('--color-brand-accent', color) localStorage.setItem('accent-color', color) await updateUserSettings({ accentColor: color }) } const handleThemeChange = async (value: string) => { const next = normalizeThemeId(value) setTheme(next) localStorage.setItem('theme-preference', next) applyDocumentTheme(next) await updateUserSettings({ theme: next }) toast.success(t('settings.settingsSaved')) } const handleFontSizeChange = async (value: string) => { setFontSize(value) const map: Record = { small: '14px', medium: '16px', large: '18px', 'extra-large': '20px' } document.documentElement.style.setProperty('--user-font-size', map[value] || '16px') await updateAISettings({ fontSize: value as any }) toast.success(t('settings.settingsSaved')) } const handleFontFamilyChange = async (value: string) => { const font = value === 'system' ? 'system' : value === 'playfair' ? 'playfair' : value === 'jetbrains' ? 'jetbrains' : 'inter' setFontFamily(font) localStorage.setItem('font-family', font) const root = document.documentElement root.classList.remove('font-system', 'font-playfair', 'font-jetbrains') if (font === 'system') root.classList.add('font-system') if (font === 'playfair') root.classList.add('font-playfair') if (font === 'jetbrains') root.classList.add('font-jetbrains') await updateAISettings({ fontFamily: font as 'inter' | 'playfair' | 'jetbrains' | 'system' }) toast.success(t('settings.settingsSaved')) } const handleNotesLayoutChange = (value: string) => { const layout = value === 'grid' ? 'grid' : value === 'table' ? 'table' : 'list' setNotesLayout(layout) setNotesLayoutPreference(layout) window.dispatchEvent(new CustomEvent('memento-notes-layout-change', { detail: { layout } })) toast.success(t('settings.settingsSaved')) } const SelectCard = ({ icon: Icon, title, description, value, options, onChange, optionGroups, }: { icon: React.ElementType title: string description: string value: string options?: { value: string; label: string }[] optionGroups?: { label: string; options: { value: string; label: string }[] }[] onChange: (v: string) => void }) => (

{title}

{description}

) const themeOptionGroups = [ { label: t('settings.themeBaseGroup'), options: [ { value: 'light', label: t('settings.themeLight') }, { value: 'dark', label: t('settings.themeDark') }, { value: 'auto', label: t('settings.themeSystem') }, ], }, { label: t('settings.themePalettesGroup'), options: [ { value: 'sepia', label: t('settings.themeSepia') }, { value: 'midnight', label: t('settings.themeMidnight') }, { value: 'rose', label: t('settings.themeRose') }, { value: 'green', label: t('settings.themeGreen') }, { value: 'lavender', label: t('settings.themeLavender') }, { value: 'sand', label: t('settings.themeSand') }, { value: 'ocean', label: t('settings.themeOcean') }, { value: 'sunset', label: t('settings.themeSunset') }, { value: 'blue', label: t('settings.themeBlue') }, ], }, ] return (

{t('appearance.description')}

{/* Accent Color Section */}

{t('appearance.accentColorTitle')}

{t('appearance.accentColorDescription')}

{accentColor}
{PRESET_COLORS.map((color) => ( ))}
handleAccentColorChange(e.target.value)} className="w-12 h-12 rounded-2xl cursor-pointer opacity-0 absolute inset-0 z-10" />
handleNotesLayoutChange(v === 'masonry' ? 'grid' : v === 'table' ? 'table' : 'list')} />
) }