import { useState, useEffect } from 'react'; import { Bell, Check, Trash2 } from 'lucide-react'; import { Button } from '@/components/ui/button'; import { Badge } from '@/components/ui/badge'; import { Popover, PopoverContent, PopoverTrigger, } from '@/components/ui/popover'; import { ScrollArea } from '@/components/ui/scroll-area'; import { useAuth } from '@/contexts/AuthContext'; import { supabase } from '@/lib/supabase'; import { formatDistanceToNow } from 'date-fns'; interface Notification { id: string; title: string; message: string; type: 'info' | 'success' | 'warning' | 'error' | 'system'; read: boolean; action_url?: string; created_at: string; } export default function NotificationBell() { const { user } = useAuth(); const [notifications, setNotifications] = useState([]); const [unreadCount, setUnreadCount] = useState(0); const [open, setOpen] = useState(false); useEffect(() => { if (user) { loadNotifications(); subscribeToNotifications(); } // eslint-disable-next-line react-hooks/exhaustive-deps }, [user]); const loadNotifications = async () => { if (!user) return; const { data } = await supabase .from('notifications') .select('*') .eq('user_id', user.id) .order('created_at', { ascending: false }) .limit(10); if (data) { setNotifications(data); setUnreadCount(data.filter(n => !n.read).length); } }; const subscribeToNotifications = () => { const channel = supabase .channel('notifications') .on( 'postgres_changes', { event: 'INSERT', schema: 'public', table: 'notifications', filter: `user_id=eq.${user?.id}`, }, (payload) => { setNotifications(prev => [payload.new as Notification, ...prev]); setUnreadCount(prev => prev + 1); } ) .subscribe(); return () => { supabase.removeChannel(channel); }; }; const markAsRead = async (notificationId: string) => { await supabase.functions.invoke('notifications-manager', { body: { action: 'markRead', userId: user?.id, notificationId } }); setNotifications(prev => prev.map(n => n.id === notificationId ? { ...n, read: true } : n) ); setUnreadCount(prev => Math.max(0, prev - 1)); }; const markAllAsRead = async () => { await supabase.functions.invoke('notifications-manager', { body: { action: 'markAllRead', userId: user?.id } }); setNotifications(prev => prev.map(n => ({ ...n, read: true }))); setUnreadCount(0); }; const deleteNotification = async (notificationId: string) => { await supabase.functions.invoke('notifications-manager', { body: { action: 'delete', userId: user?.id, notificationId } }); setNotifications(prev => prev.filter(n => n.id !== notificationId)); }; const getTypeColor = (type: string) => { switch (type) { case 'success': return 'text-green-600'; case 'warning': return 'text-yellow-600'; case 'error': return 'text-red-600'; case 'system': return 'text-blue-600'; default: return 'text-gray-600'; } }; return (

Notifications

{unreadCount > 0 && ( )}
{notifications.length === 0 ? (
No notifications
) : (
{notifications.map((notification) => (

{notification.title}

{notification.message}

{formatDistanceToNow(new Date(notification.created_at), { addSuffix: true })}

{!notification.read && ( )}
))}
)}
); }