import { useState, useEffect } from 'react'; import { useNavigate } from 'react-router-dom'; import { toast } from 'sonner'; import { Sun, Moon, Users } from 'lucide-react'; import { api } from '@/api'; import { cn } from '@/lib/utils'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { Select, SelectTrigger, SelectValue, SelectContent, SelectItem, } from '@/components/ui/select'; import { useTheme } from '@/contexts/ThemeContext'; import { useAuth } from '@/hooks/useAuth'; // ─── Card wrapper ───────────────────────────────────────────────────────────── function SectionCard({ title, children }) { return (

{title}

{children}
); } // ─── Setting Row ────────────────────────────────────────────────────────────── function SettingRow({ label, description, children }) { return (

{label}

{description && (

{description}

)}
{children}
); } // ─── Theme Card ─────────────────────────────────────────────────────────────── function ThemeCard({ value, label, icon: Icon, currentTheme, onSelect }) { const selected = currentTheme === value; return ( ); } // ─── Appearance Section ─────────────────────────────────────────────────────── function AppearanceSection() { const { theme, setTheme } = useTheme(); return (
); } function LoginModeRecoverySection() { const navigate = useNavigate(); const { singleUserMode, refresh } = useAuth(); const [restoring, setRestoring] = useState(false); if (!singleUserMode) return null; const handleRestore = async () => { setRestoring(true); try { await api.restoreMultiUserMode(); toast.success('Multi-user login restored.'); refresh(); navigate('/login', { replace: true }); } catch (err) { toast.error(err.message || 'Failed to restore multi-user mode.'); } finally { setRestoring(false); } }; return ( ); } // ─── SettingsPage ───────────────────────────────────────────────────────────── export default function SettingsPage() { const DEFAULTS = { currency: 'USD', date_format: 'MM/DD/YYYY', grace_period_days: 3, }; const [settings, setSettings] = useState(DEFAULTS); const [loading, setLoading] = useState(true); const [saving, setSaving] = useState(false); useEffect(() => { api.settings() .then((d) => setSettings({ ...DEFAULTS, ...d })) .catch(() => {}) .finally(() => setLoading(false)); }, []); // eslint-disable-line react-hooks/exhaustive-deps const set = (k, v) => setSettings((p) => ({ ...p, [k]: v })); const handleSave = async () => { setSaving(true); try { await api.saveSettings({ currency: settings.currency, date_format: settings.date_format, grace_period_days: settings.grace_period_days, }); toast.success('Settings saved.'); } catch (err) { toast.error(err.message || 'Failed to save settings.'); } finally { setSaving(false); } }; if (loading) { return (
Loading…
); } return (
{/* Page header — flat on background */}

Settings

Manage app-level display and billing preferences

{/* Appearance */} {/* Login mode recovery */} {/* General */} {/* Billing Behavior */}
set('grace_period_days', parseInt(e.target.value, 10) || 0)} className="w-20" /> days
{/* Save button — right-aligned below all cards */}
); }