import { useInfiniteQuery, useMutation, useQuery, useQueryClient, } from "@tanstack/react-query"; import { notificationsApi } from "./notificationsApi"; export const NOTIFICATIONS_KEY = ["notifications"] as const; export const UNREAD_KEY = ["notifications", "unread"] as const; const PAGE_SIZE = 20; /** * Paginated (infinite) notifications for one read-state. Drives a drawer * section; call `fetchNextPage` as the user scrolls. Each page carries the * server `count` so we know when to stop. */ export function useInfiniteNotifications(isRead: boolean, enabled = true) { return useInfiniteQuery({ queryKey: [...NOTIFICATIONS_KEY, "list", { isRead }], queryFn: ({ pageParam }) => notificationsApi.list({ page: pageParam, limit: PAGE_SIZE, isRead }), initialPageParam: 1, getNextPageParam: (lastPage, allPages) => { const loaded = allPages.reduce((sum, p) => sum + p.items.length, 0); return loaded < lastPage.count ? allPages.length + 1 : undefined; }, enabled, }); } export function useUnreadCount(enabled = true) { return useQuery({ queryKey: UNREAD_KEY, queryFn: () => notificationsApi.unreadCount(), enabled, // WebSocket keeps this fresh; poll as a fallback if the socket drops. refetchInterval: 60_000, }); } export function useMarkRead() { const qc = useQueryClient(); return useMutation({ mutationFn: (id: string) => notificationsApi.markRead(id), onSuccess: () => { qc.invalidateQueries({ queryKey: NOTIFICATIONS_KEY }); qc.invalidateQueries({ queryKey: UNREAD_KEY }); }, }); } export function useMarkAllRead() { const qc = useQueryClient(); return useMutation({ mutationFn: () => notificationsApi.markAllRead(), onSuccess: () => { qc.invalidateQueries({ queryKey: NOTIFICATIONS_KEY }); qc.invalidateQueries({ queryKey: UNREAD_KEY }); }, }); }