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 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 | 2x 6x 2x 2x 4x 1x 2x 2x 2x 1x 1x 2x 2x 2x 1x 1x 2x 2x 2x 1x 1x 2x 2x 2x 1x 1x | /**
* Notification React Query Hooks
*
* Story BAT-7 - Notifications API Consolidation
*
* React Query hooks for Notification feature:
* - useNotifications: List query with filters, pagination (cache 2min)
* - useUnreadCount: Unread count query (cache 1min)
* - useMarkAsRead: Mark notification as read mutation
* - useBatchMarkAsRead: Batch mark as read mutation
* - useDeleteNotification: Delete notification mutation
*
* EventBridge Integration: Automatically fetches notifications triggered by domain events
*/
import {
useQuery,
useMutation,
useQueryClient,
type UseQueryResult,
type UseMutationResult,
} from '@tanstack/react-query';
import { notificationApiClient } from '@/services/notificationApiClient';
import type {
NotificationsResponse,
NotificationFilters,
MarkAsReadResponse,
DeleteNotificationResponse,
} from '@/types/notification';
// ============================================================================
// Query Hooks
// ============================================================================
/**
* useNotifications - Fetch paginated list of notifications
* Cache: 2 minutes (notifications are volatile)
*
* @param filters - Username (required) and optional status/eventCode filters
* @param pagination - Page number and limit
* @param options - React Query options
*/
export const useNotifications = (
filters: NotificationFilters,
pagination: { page?: number; limit?: number } = {},
options?: { enabled?: boolean }
): UseQueryResult<NotificationsResponse, Error> => {
return useQuery({
queryKey: ['notifications', filters, pagination],
queryFn: () => notificationApiClient.getNotifications(filters, pagination),
staleTime: 2 * 60 * 1000, // 2 minutes
enabled: options?.enabled !== false && !!filters.username,
});
};
/**
* useUnreadCount - Fetch unread notification count
* Cache: 1 minute (count changes frequently)
*
* @param username - Username of the user
* @param options - React Query options
*/
export const useUnreadCount = (
username: string | undefined,
options?: { enabled?: boolean }
): UseQueryResult<number, Error> => {
return useQuery({
queryKey: ['notifications', 'unread-count', username],
queryFn: () => notificationApiClient.getUnreadCount(username!),
staleTime: 1 * 60 * 1000, // 1 minute
enabled: options?.enabled !== false && !!username,
});
};
// ============================================================================
// Mutation Hooks
// ============================================================================
/**
* useMarkAsRead - Mark a single notification as read
*
* Automatically invalidates notification queries on success
*/
export const useMarkAsRead = (): UseMutationResult<MarkAsReadResponse, Error, string, unknown> => {
const queryClient = useQueryClient();
return useMutation({
mutationFn: (notificationId: string) => notificationApiClient.markAsRead(notificationId),
onSuccess: () => {
// Invalidate all notification queries to refetch with updated data
queryClient.invalidateQueries({ queryKey: ['notifications'] });
},
});
};
/**
* useBatchMarkAsRead - Mark multiple notifications as read
*
* Automatically invalidates notification queries on success
*/
export const useBatchMarkAsRead = (): UseMutationResult<
MarkAsReadResponse,
Error,
string[],
unknown
> => {
const queryClient = useQueryClient();
return useMutation({
mutationFn: (notificationIds: string[]) =>
notificationApiClient.batchMarkAsRead(notificationIds),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['notifications'] });
},
});
};
/**
* useDeleteNotification - Delete a single notification
*
* Automatically invalidates notification queries on success
*/
export const useDeleteNotification = (): UseMutationResult<
DeleteNotificationResponse,
Error,
string,
unknown
> => {
const queryClient = useQueryClient();
return useMutation({
mutationFn: (notificationId: string) =>
notificationApiClient.deleteNotification(notificationId),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['notifications'] });
},
});
};
/**
* useBatchDeleteNotifications - Delete multiple notifications
*
* Automatically invalidates notification queries on success
*/
export const useBatchDeleteNotifications = (): UseMutationResult<
DeleteNotificationResponse,
Error,
string[],
unknown
> => {
const queryClient = useQueryClient();
return useMutation({
mutationFn: (notificationIds: string[]) => notificationApiClient.batchDelete(notificationIds),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['notifications'] });
},
});
};
|