import { useState, useEffect, useCallback } from 'react'; import { useSession } from 'next-auth/react'; import { Notification, NotificationCount } from '@/lib/types/notification'; // Default empty notification count const defaultNotificationCount: NotificationCount = { total: 0, unread: 0, sources: {} }; export function useNotifications() { const { data: session, status } = useSession(); const [notifications, setNotifications] = useState([]); const [notificationCount, setNotificationCount] = useState(defaultNotificationCount); const [loading, setLoading] = useState(false); const [error, setError] = useState(null); const [pollingInterval, setPollingInterval] = useState(null); // Fetch notification count const fetchNotificationCount = useCallback(async () => { if (!session?.user) return; try { setError(null); const response = await fetch('/api/notifications/count'); if (!response.ok) { const errorData = await response.json(); console.error('Failed to fetch notification count:', errorData); setError(errorData.error || 'Failed to fetch notification count'); return; } const data = await response.json(); setNotificationCount(data); } catch (err) { console.error('Error fetching notification count:', err); setError('Failed to fetch notification count'); } }, [session?.user]); // Fetch notifications const fetchNotifications = useCallback(async (page = 1, limit = 20) => { if (!session?.user) return; setLoading(true); setError(null); try { const response = await fetch(`/api/notifications?page=${page}&limit=${limit}`); if (!response.ok) { const errorData = await response.json(); console.error('Failed to fetch notifications:', errorData); setError(errorData.error || 'Failed to fetch notifications'); return; } const data = await response.json(); setNotifications(data.notifications); } catch (err) { console.error('Error fetching notifications:', err); setError('Failed to fetch notifications'); } finally { setLoading(false); } }, [session?.user]); // Mark notification as read const markAsRead = useCallback(async (notificationId: string) => { if (!session?.user) return; try { const response = await fetch(`/api/notifications/${notificationId}/read`, { method: 'POST', headers: { 'Content-Type': 'application/json' } }); if (!response.ok) { const errorData = await response.json(); console.error('Failed to mark notification as read:', errorData); return false; } // Update local state setNotifications(prev => prev.map(notification => notification.id === notificationId ? { ...notification, isRead: true } : notification ) ); // Refresh notification count fetchNotificationCount(); return true; } catch (err) { console.error('Error marking notification as read:', err); return false; } }, [session?.user, fetchNotificationCount]); // Mark all notifications as read const markAllAsRead = useCallback(async () => { if (!session?.user) return; try { const response = await fetch('/api/notifications/read-all', { method: 'POST', headers: { 'Content-Type': 'application/json' } }); if (!response.ok) { const errorData = await response.json(); console.error('Failed to mark all notifications as read:', errorData); return false; } // Update local state setNotifications(prev => prev.map(notification => ({ ...notification, isRead: true })) ); // Refresh notification count fetchNotificationCount(); return true; } catch (err) { console.error('Error marking all notifications as read:', err); return false; } }, [session?.user, fetchNotificationCount]); // Start polling for notification count const startPolling = useCallback((interval = 30000) => { if (pollingInterval) { clearInterval(pollingInterval); } const id = setInterval(() => { fetchNotificationCount(); }, interval); setPollingInterval(id); return () => { clearInterval(id); setPollingInterval(null); }; }, [fetchNotificationCount, pollingInterval]); // Stop polling const stopPolling = useCallback(() => { if (pollingInterval) { clearInterval(pollingInterval); setPollingInterval(null); } }, [pollingInterval]); // Initialize fetching on component mount useEffect(() => { if (status === 'authenticated' && session?.user) { fetchNotificationCount(); fetchNotifications(); // Start polling const cleanup = startPolling(); return () => { cleanup(); }; } }, [status, session?.user, fetchNotificationCount, fetchNotifications, startPolling]); return { notifications, notificationCount, loading, error, fetchNotifications, fetchNotificationCount, markAsRead, markAllAsRead, startPolling, stopPolling }; }