Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 | 1x 13x 12x 1x 1x 1x 1x 1x 1x 1x 1x 1x 19x 19x 19x 1x 1x 19x 1x 19x 1x 19x 1x 1x 1x | /**
* useNotifications Hook
* Story 1.17, Task 5b: React Query hook for notifications
*
* Fetches and caches notifications with mutations for marking as read/delete.
* Uses React Query for server state management with 1-minute stale time.
*/
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import apiClient from '@/services/api/apiClient';
interface Notification {
id: string;
type: string;
title: string;
message: string;
timestamp: string;
isRead: boolean;
actionUrl: string;
priority: string;
}
interface NotificationsResponse {
notifications: Notification[];
unreadCount: number;
totalCount: number;
hasMore: boolean;
}
interface UseNotificationsOptions {
enabled?: boolean;
staleTime?: number;
}
/**
* Fetch unread notifications
*/
const fetchNotifications = async (): Promise<NotificationsResponse> => {
const response = await apiClient.get('/notifications?status=unread&limit=10');
return response.data;
};
/**
* Mark notification(s) as read
*/
const markAsReadMutation = async (notificationIds: string[]) => {
const response = await apiClient.put('/notifications/read', {
notificationIds,
});
return response.data;
};
/**
* Mark all notifications as read
*/
const markAllAsReadMutation = async () => {
const response = await apiClient.put('/notifications/read', {
markAll: true,
});
return response.data;
};
/**
* Delete a notification
*/
const deleteNotificationMutation = async (id: string) => {
const response = await apiClient.delete(`/notifications/${id}`);
return response.data;
};
/**
* Custom hook to fetch and manage notifications
*
* @param options - Query options
* @returns React Query result with notifications data and mutation functions
*
* @example
* const { data, unreadCount, markAsRead, markAllAsRead, deleteNotification } = useNotifications();
*/
export function useNotifications(options?: UseNotificationsOptions) {
const queryClient = useQueryClient();
const query = useQuery({
queryKey: ['notifications'],
queryFn: fetchNotifications,
staleTime: options?.staleTime ?? 1000 * 60, // 1 minute default
enabled: options?.enabled ?? true,
});
// Mutation for marking single notification as read
const markAsReadMut = useMutation({
mutationFn: (notificationId: string) => markAsReadMutation([notificationId]),
onSuccess: () => {
// Invalidate and refetch notifications after marking as read
queryClient.invalidateQueries({ queryKey: ['notifications'] });
},
});
// Mutation for marking all notifications as read
const markAllAsReadMut = useMutation({
mutationFn: markAllAsReadMutation,
onSuccess: () => {
// Invalidate and refetch notifications after marking all as read
queryClient.invalidateQueries({ queryKey: ['notifications'] });
},
});
// Mutation for deleting a notification
const deleteNotificationMut = useMutation({
mutationFn: deleteNotificationMutation,
onSuccess: () => {
// Invalidate and refetch notifications after deletion
queryClient.invalidateQueries({ queryKey: ['notifications'] });
},
});
return {
...query,
unreadCount: query.data?.unreadCount ?? 0,
markAsRead: (id: string) => markAsReadMut.mutateAsync(id),
markAllAsRead: () => markAllAsReadMut.mutateAsync(),
deleteNotification: (id: string) => deleteNotificationMut.mutateAsync(id),
};
}
|