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 { toast } from "sonner"; import { notificationService } from "@/lib/notificationService"; interface ChannelPreferences { in_app: boolean; email: boolean; push: boolean; } interface WorkflowPreferences { [workflowId: string]: boolean; } interface FrequencySettings { digest: 'realtime' | 'hourly' | 'daily' | 'weekly'; max_per_hour: number; } interface NotificationTemplate { id: string; workflow_id: string; name: string; description: string; category: string; is_active: boolean; } export function NotificationsTab() { const { user } = useAuth(); const { isEnabled: isNovuEnabled, isLoading: isNovuLoading } = usePublicNovuSettings(); const [loading, setLoading] = useState(true); const [templates, setTemplates] = useState([]); const [channelPreferences, setChannelPreferences] = useState({ in_app: true, email: true, push: false, }); const [workflowPreferences, setWorkflowPreferences] = useState({}); const [frequencySettings, setFrequencySettings] = useState({ digest: 'daily', max_per_hour: 10, }); useEffect(() => { if (user) { loadPreferences(); loadTemplates(); } }, [user]); const loadPreferences = async () => { if (!user) return; try { const preferences = await notificationService.getPreferences(user.id); if (preferences) { const { sms, ...channelPrefs } = preferences.channelPreferences; setChannelPreferences(channelPrefs); setWorkflowPreferences(preferences.workflowPreferences); setFrequencySettings(preferences.frequencySettings); } } catch (error) { console.error('Error loading preferences:', error); toast.error("Failed to load notification preferences"); } finally { setLoading(false); } }; const loadTemplates = async () => { try { const templateData = await notificationService.getTemplates(); setTemplates(templateData); // Initialize workflow preferences if not set 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) { console.error('Error loading templates:', error); } }; const savePreferences = async () => { if (!user) return; setLoading(true); try { const result = await notificationService.updatePreferences(user.id, { channelPreferences: { ...channelPreferences, sms: false, // SMS not supported in UI }, workflowPreferences, frequencySettings, }); if (result.success) { toast.success("Notification preferences saved successfully"); // Also update Novu subscriber profile to sync channel preferences if (notificationService.isEnabled()) { await notificationService.updateSubscriber({ subscriberId: user.id, email: user.email, }); } } else { throw new Error(result.error || 'Failed to save preferences'); } } catch (error: any) { console.error('Error saving preferences:', error); toast.error(error.message || "Failed to save notification preferences"); } finally { setLoading(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)) { toast.error("This browser doesn't support push notifications"); return; } try { const permission = await Notification.requestPermission(); if (permission === 'granted') { updateChannelPreference('push', true); toast.success("Push notifications enabled"); } else { toast.error("Push notification permission denied"); } } catch (error) { console.error('Error requesting push permission:', error); toast.error("Failed to enable push notifications"); } }; const groupedTemplates = templates.reduce((acc, template) => { if (!acc[template.category]) { acc[template.category] = []; } acc[template.category].push(template); return acc; }, {} as Record); return (
{isNovuLoading ? ( Loading notification settings... ) : !isNovuEnabled ? ( Novu Not Configured Novu notifications are not configured. Contact an administrator to configure the Novu Application Identifier in admin settings. ) : null} 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 Control how often you receive notifications

Group notifications and send them in batches

Limit the number of notifications you receive per hour

{Object.keys(groupedTemplates).map((category) => ( {category} Notifications Manage your {category} notification preferences {groupedTemplates[category].map((template, index) => (
{index > 0 && }

{template.description}

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