'use client'; import { useEffect } from 'react'; import { useQuery, useQueryClient } from '@tanstack/react-query'; import { useSocket } from '@/providers/socket-provider'; import { apiFetch } from '@/lib/api/client'; const UNREAD_KEY = ['notifications', 'unread-count'] as const; export function useNotifications() { const socket = useSocket(); const queryClient = useQueryClient(); // Single source of truth: React Query cache. Socket pushes write // directly into the cache via setQueryData so we don't fight the // query → local state → query refetch ordering that the previous // useEffect-into-setState dance had. const { data } = useQuery<{ count: number }>({ queryKey: UNREAD_KEY, queryFn: () => apiFetch('/api/v1/notifications/unread-count'), staleTime: 30_000, }); useEffect(() => { if (!socket) return; const handleNew = () => { queryClient.invalidateQueries({ queryKey: ['notifications'] }); }; const handleCount = (payload: { count: number }) => { queryClient.setQueryData(UNREAD_KEY, { count: payload.count }); }; socket.on('notification:new', handleNew); socket.on('notification:unreadCount', handleCount); return () => { socket.off('notification:new', handleNew); socket.off('notification:unreadCount', handleCount); }; }, [socket, queryClient]); return { unreadCount: data?.count ?? 0 }; }