"use client"; import { createContext, useContext, useState, useEffect, useCallback, ReactNode } from "react"; import { useAuth } from "@/hooks/use-auth"; import { fetchAPI, putAPI } from "@/lib/api"; import type { NotificationItem, PageResponse } from "@/lib/types"; interface NotificationContextType { unreadCount: number; notifications: NotificationItem[]; markRead: (id: number) => Promise; markAllRead: () => Promise; refresh: () => void; } const NotificationContext = createContext({ unreadCount: 0, notifications: [], markRead: async () => {}, markAllRead: async () => {}, refresh: () => {}, }); export function NotificationProvider({ children }: { children: ReactNode }) { const { user } = useAuth(); const [unreadCount, setUnreadCount] = useState(0); const [notifications, setNotifications] = useState([]); const fetchUnreadCount = useCallback(async () => { if (!user) return; try { const res = await fetchAPI<{ count: number }>("/api/notifications/unread-count"); setUnreadCount(res.count); } catch { // ignore } }, [user]); const fetchNotifications = useCallback(async () => { if (!user) return; try { const res = await fetchAPI>("/api/notifications/", { page_size: "10" }); setNotifications(res.items || []); } catch { // ignore } }, [user]); const refresh = useCallback(() => { void fetchUnreadCount(); void fetchNotifications(); }, [fetchUnreadCount, fetchNotifications]); useEffect(() => { if (!user) return; const initialRefresh = window.setTimeout(() => { void fetchUnreadCount(); }, 0); const interval = setInterval(fetchUnreadCount, 30000); return () => { window.clearTimeout(initialRefresh); clearInterval(interval); }; }, [user, fetchUnreadCount]); const markRead = useCallback(async (id: number) => { try { await putAPI(`/api/notifications/${id}/read`); setNotifications((prev) => prev.map((n) => (n.id === id ? { ...n, is_read: true } : n)) ); setUnreadCount((c) => Math.max(0, c - 1)); } catch { // ignore } }, []); const markAllRead = useCallback(async () => { try { await putAPI("/api/notifications/read-all"); setNotifications((prev) => prev.map((n) => ({ ...n, is_read: true }))); setUnreadCount(0); } catch { // ignore } }, []); return ( {children} ); } export function useNotifications() { return useContext(NotificationContext); }