xpeditis2.0/apps/frontend/src/hooks/useNotifications.ts
David abe3bfe9ae feat(ui): refonte du menu et de la page de notifications
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018BAUeCFpDkRD6tU5wGsc1C
2026-09-07 21:40:56 +02:00

78 lines
2.3 KiB
TypeScript

/**
* useNotifications
*
* Source unique des notifications : la cloche, la page et tout futur écran
* lisent le même état.
*/
'use client';
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import {
getUnreadNotificationCount,
listNotifications,
markAllNotificationsAsRead,
markNotificationAsRead,
} from '@/lib/api';
import type { NotificationResponse } from '@/types/api';
interface UseNotificationsOptions {
/** Ne remonter que les non-lues. Par défaut, tout, du plus récent au plus ancien. */
unreadOnly?: boolean;
/** Nombre maximum de notifications chargées. */
limit?: number;
/** Intervalle de rafraîchissement, en millisecondes. */
refetchInterval?: number;
}
export function useNotifications(options: UseNotificationsOptions = {}) {
const { unreadOnly = false, limit = 10, refetchInterval = 30000 } = options;
const queryClient = useQueryClient();
const list = useQuery({
queryKey: ['notifications', { unreadOnly, limit }],
queryFn: () => listNotifications(unreadOnly ? { isRead: false, limit } : { limit }),
refetchInterval,
refetchOnWindowFocus: true,
});
/**
* Le compteur vient du serveur.
*
* Il etait auparavant calcule sur la page chargee — dix elements — et ne
* pouvait donc jamais depasser dix, quel que soit le nombre reel de non-lues.
*/
const count = useQuery({
queryKey: ['notifications', 'unread-count'],
queryFn: getUnreadNotificationCount,
refetchInterval,
refetchOnWindowFocus: true,
});
const invalidate = () => queryClient.invalidateQueries({ queryKey: ['notifications'] });
const markAsReadMutation = useMutation({
mutationFn: markNotificationAsRead,
onSuccess: invalidate,
});
const markAllAsReadMutation = useMutation({
mutationFn: markAllNotificationsAsRead,
onSuccess: invalidate,
});
const notifications: NotificationResponse[] = list.data?.notifications ?? [];
return {
notifications,
total: list.data?.total ?? notifications.length,
unreadCount: count.data?.count ?? 0,
isLoading: list.isPending,
isError: list.isError,
refetch: list.refetch,
markAsRead: markAsReadMutation.mutate,
markAllAsRead: markAllAsReadMutation.mutate,
isMarkingAll: markAllAsReadMutation.isPending,
};
}