/** * NotificationBell Component * Header bell icon with unread badge and dropdown */ import React, { useState, useEffect, useRef } from 'react'; import { NotificationList } from './NotificationList'; interface NotificationBellProps { userId?: string; } export function NotificationBell({ userId = 'demo-user' }: NotificationBellProps) { const [isOpen, setIsOpen] = useState(false); const [unreadCount, setUnreadCount] = useState(0); const [isLoading, setIsLoading] = useState(true); const dropdownRef = useRef(null); useEffect(() => { fetchUnreadCount(); // Poll for new notifications every 30 seconds const interval = setInterval(fetchUnreadCount, 30000); return () => clearInterval(interval); }, [userId]); useEffect(() => { function handleClickOutside(event: MouseEvent) { if (dropdownRef.current && !dropdownRef.current.contains(event.target as Node)) { setIsOpen(false); } } document.addEventListener('mousedown', handleClickOutside); return () => document.removeEventListener('mousedown', handleClickOutside); }, []); async function fetchUnreadCount() { try { const response = await fetch(`/api/notifications?userId=${userId}&unreadOnly=true&limit=1`); const data = await response.json(); if (data.success) { setUnreadCount(data.data.unreadCount); } } catch (error) { console.error('Failed to fetch unread count:', error); } finally { setIsLoading(false); } } function handleNotificationRead() { setUnreadCount(prev => Math.max(0, prev - 1)); } function handleAllRead() { setUnreadCount(0); } return (
{isOpen && (

Notifications

{unreadCount > 0 && ( )}
View all notifications
)}
); }