'use client'; import { useState, useEffect } from 'react'; import { Save } from 'lucide-react'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; import { Switch } from '@/components/ui/switch'; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'; import { PageHeader } from '@/components/shared/page-header'; import { apiFetch } from '@/lib/api/client'; interface NotificationPrefs { reminder_due: boolean; reminder_overdue: boolean; eoi_signed: boolean; eoi_completed: boolean; invoice_overdue: boolean; duplicate_alert: boolean; [key: string]: boolean; } export function UserSettings() { const [notifPrefs, setNotifPrefs] = useState(null); const [displayName, setDisplayName] = useState(''); const [phone, setPhone] = useState(''); const [timezone, setTimezone] = useState(''); const [saving, setSaving] = useState(null); const [message, setMessage] = useState(null); useEffect(() => { void loadProfile(); void loadNotificationPrefs(); }, []); async function loadProfile() { const res = await apiFetch<{ data: { user?: { name: string } } }>('/api/v1/me', { method: 'GET', }); setDisplayName(res.data.user?.name ?? ''); } async function loadNotificationPrefs() { try { const res = await apiFetch<{ data: NotificationPrefs }>('/api/v1/notifications/preferences'); setNotifPrefs(res.data); } catch { // Preferences may not exist yet setNotifPrefs({ reminder_due: true, reminder_overdue: true, eoi_signed: true, eoi_completed: true, invoice_overdue: true, duplicate_alert: true, }); } } async function saveProfile() { setSaving('profile'); setMessage(null); try { await apiFetch('/api/v1/me', { method: 'PATCH', body: { displayName: displayName || undefined, phone: phone || null, preferences: { timezone: timezone || undefined }, }, }); setMessage('Profile saved'); } catch (err: unknown) { setMessage(err instanceof Error ? err.message : 'Failed to save'); } finally { setSaving(null); } } async function toggleNotifPref(key: string, value: boolean) { setSaving(key); try { await apiFetch('/api/v1/notifications/preferences', { method: 'PATCH', body: { [key]: value }, }); setNotifPrefs((prev) => (prev ? { ...prev, [key]: value } : prev)); } finally { setSaving(null); } } const NOTIF_LABELS: Record = { reminder_due: 'Reminder due', reminder_overdue: 'Reminder overdue', eoi_signed: 'EOI signed by a party', eoi_completed: 'EOI fully completed', invoice_overdue: 'Invoice overdue', duplicate_alert: 'Duplicate client detected', }; return (
Profile Update your display name and contact info
setDisplayName(e.target.value)} placeholder="Your name" />
setPhone(e.target.value)} placeholder="+1 555-0123" />
setTimezone(e.target.value)} placeholder="America/Anguilla" />
{message && {message}}
Notifications Choose which notifications you receive {notifPrefs && Object.entries(NOTIF_LABELS).map(([key, label]) => (
toggleNotifPref(key, checked)} />
))}
); }