import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query' import { Bell, RotateCcw } from 'lucide-react' import { toast } from 'sonner' import { getNotificationConfigs, updateNotificationConfig, resetNotificationConfigs, type NotificationConfig, type NotificationFrequency, } from '../api/notifications' const EVENT_LABELS: Record = { 'order.submitted': 'Order submitted', 'order.completed': 'Order completed', 'render.completed': 'Render completed (activity)', 'render.failed': 'Render failed (activity)', 'excel.imported': 'Excel imported', } const ALL_EVENTS = Object.keys(EVENT_LABELS) const CHANNELS: Array<{ key: 'in_app' | 'email'; label: string; comingSoon?: boolean }> = [ { key: 'in_app', label: 'In-App' }, { key: 'email', label: 'E-Mail', comingSoon: true }, ] const FREQUENCY_OPTIONS: Array<{ value: string; label: string }> = [ { value: 'immediate', label: 'Immediate' }, { value: 'daily', label: 'Daily summary' }, { value: 'never', label: 'Disabled' }, ] function Toggle({ enabled, disabled, onChange, title, }: { enabled: boolean disabled?: boolean onChange: (v: boolean) => void title?: string }) { return ( ) } export default function NotificationSettingsPage() { const qc = useQueryClient() const { data: configs = [], isLoading } = useQuery({ queryKey: ['notification-configs'], queryFn: getNotificationConfigs, }) const updateMutation = useMutation({ mutationFn: ({ eventType, channel, enabled, frequency }: { eventType: string; channel: string; enabled: boolean; frequency?: NotificationFrequency }) => updateNotificationConfig(eventType, channel, enabled, frequency), onSuccess: () => qc.invalidateQueries({ queryKey: ['notification-configs'] }), onError: () => toast.error('Failed to update setting'), }) const resetMutation = useMutation({ mutationFn: resetNotificationConfigs, onSuccess: () => { qc.invalidateQueries({ queryKey: ['notification-configs'] }) toast.success('Settings reset to defaults') }, onError: () => toast.error('Failed to reset settings'), }) // Build lookup maps const configMap = new Map() const frequencyMap = new Map() for (const c of configs) { configMap.set(`${c.event_type}:${c.channel}`, c.enabled) frequencyMap.set(`${c.event_type}:${c.channel}`, c.frequency ?? 'immediate') } const isEnabled = (event: string, channel: string) => configMap.get(`${event}:${channel}`) ?? (channel === 'in_app') const getFrequency = (event: string, channel: string): NotificationFrequency => frequencyMap.get(`${event}:${channel}`) ?? 'immediate' return (
{/* Header */}

Notification Settings

Configure which events trigger notifications for you

{/* Matrix table */}
{CHANNELS.map(ch => ( ))} {isLoading ? ( ) : ( ALL_EVENTS.map(event => ( {CHANNELS.map(ch => ( ))} )) )}
Event {ch.label} {ch.comingSoon && ( (soon) )} Frequency
Loading...
{EVENT_LABELS[event] || event} updateMutation.mutate({ eventType: event, channel: ch.key, enabled }) } title={ch.comingSoon ? 'Email notifications — coming soon' : undefined} />

In-App notifications appear in the bell icon in the sidebar. Email notifications are currently deactivated.

) }