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 (
);
}
// ─── 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 */}
);
}