import { useEffect, useState } from "react"; import { useAuth } from "@/hooks/useAuth"; import { usePublicNovuSettings } from "@/hooks/usePublicNovuSettings"; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; import { Label } from "@/components/ui/label"; import { Switch } from "@/components/ui/switch"; import { Button } from "@/components/ui/button"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; import { Separator } from "@/components/ui/separator"; import { Badge } from "@/components/ui/badge"; import { Skeleton } from "@/components/ui/skeleton"; import { handleError, handleSuccess, handleInfo, handleNonCriticalError } from "@/lib/errorHandler"; import { notificationService } from "@/lib/notificationService"; import type { NotificationPreferences, NotificationTemplate, ChannelPreferences, WorkflowPreferences, FrequencySettings } from "@/types/notifications"; import { DEFAULT_NOTIFICATION_PREFERENCES } from "@/lib/notificationValidation"; export function NotificationsTab() { const { user } = useAuth(); const { isEnabled: isNovuEnabled, isLoading: isNovuLoading } = usePublicNovuSettings(); const [loading, setLoading] = useState(true); const [saving, setSaving] = useState(false); const [templates, setTemplates] = useState([]); const [channelPreferences, setChannelPreferences] = useState( DEFAULT_NOTIFICATION_PREFERENCES.channelPreferences ); const [workflowPreferences, setWorkflowPreferences] = useState({}); const [frequencySettings, setFrequencySettings] = useState( DEFAULT_NOTIFICATION_PREFERENCES.frequencySettings ); useEffect(() => { if (user) { loadPreferences(); loadTemplates(); } }, [user]); const loadPreferences = async () => { if (!user) return; try { const preferences = await notificationService.getPreferences(user.id); if (preferences) { setChannelPreferences(preferences.channelPreferences); setWorkflowPreferences(preferences.workflowPreferences); setFrequencySettings(preferences.frequencySettings); } } catch (error: unknown) { handleError(error, { action: 'Load notification preferences', userId: user.id }); } finally { setLoading(false); } }; const loadTemplates = async () => { if (!user) return; try { const templateData = await notificationService.getTemplates(); setTemplates(templateData); // Initialize workflow preferences for new templates const initialPrefs: WorkflowPreferences = {}; templateData.forEach((template) => { if (!(template.workflow_id in workflowPreferences)) { initialPrefs[template.workflow_id] = true; } }); if (Object.keys(initialPrefs).length > 0) { setWorkflowPreferences((prev) => ({ ...prev, ...initialPrefs })); } } catch (error: unknown) { handleNonCriticalError(error, { action: 'Load notification templates', userId: user.id }); } }; const savePreferences = async () => { if (!user) return; setSaving(true); try { const preferences: NotificationPreferences = { channelPreferences, workflowPreferences, frequencySettings }; const result = await notificationService.updatePreferences(user.id, preferences); if (!result.success) { throw new Error(result.error || 'Failed to save notification preferences'); } handleSuccess( 'Notification preferences saved', 'Your notification settings have been updated successfully.' ); } catch (error: unknown) { handleError(error, { action: 'Save notification preferences', userId: user.id }); } finally { setSaving(false); } }; const updateChannelPreference = (channel: keyof ChannelPreferences, value: boolean) => { setChannelPreferences((prev) => ({ ...prev, [channel]: value })); }; const updateWorkflowPreference = (workflowId: string, value: boolean) => { setWorkflowPreferences((prev) => ({ ...prev, [workflowId]: value })); }; const requestPushPermission = async () => { if (!('Notification' in window)) { handleInfo( 'Push notifications not supported', 'Your browser does not support push notifications.' ); return; } try { const permission = await Notification.requestPermission(); if (permission === 'granted') { updateChannelPreference('push', true); handleSuccess('Push notifications enabled', 'You will now receive push notifications.'); } else { handleInfo( 'Permission denied', 'Push notifications were not enabled. You can change this in your browser settings.' ); } } catch (error: unknown) { handleError(error, { action: 'Enable push notifications', userId: user?.id }); } }; const groupedTemplates = templates.reduce((acc, template) => { if (!acc[template.category]) { acc[template.category] = []; } acc[template.category].push(template); return acc; }, {} as Record); if (loading || isNovuLoading) { return (
); } return (
{!isNovuEnabled && ( Novu Not Configured Notifications are not fully configured. Contact an administrator to enable Novu integration. )} {/* Notification Channels + Frequency Grid */}
{/* Notification Channels */} Notification Channels Choose which channels you'd like to receive notifications through

Receive notifications within the application

updateChannelPreference('in_app', checked)} />

Receive notifications via email

updateChannelPreference('email', checked)} />

Browser push notifications

{ if (checked) { requestPushPermission(); } else { updateChannelPreference('push', false); } }} />
{/* Notification Frequency */} Notification Frequency Control how often you receive notifications

Group notifications and send them in batches

Limit the number of notifications you receive per hour

{/* Workflow Preferences - Full Width */} {Object.keys(groupedTemplates).map((category) => ( {category} Notifications Manage your {category} notification preferences {groupedTemplates[category].map((template, index) => (
{index > 0 && }
{template.description && (

{template.description}

)}
updateWorkflowPreference(template.workflow_id, checked) } />
))}
))}
); }