Files
Notizarr/apps/web/src/hooks/useNotifications.ts
T
2026-09-07 09:54:30 +00:00

65 lines
2.1 KiB
TypeScript

import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
import { apiFetch, apiPatch, apiPost } from '../lib/api'
import type { Notification } from '../types'
export interface NotificationFilter {
topic?: string
unread?: boolean
starred?: boolean
q?: string
}
function toQueryString(filter: NotificationFilter): string {
const params = new URLSearchParams()
if (filter.topic) params.set('topic', filter.topic)
if (filter.unread) params.set('unread', 'true')
if (filter.starred) params.set('starred', 'true')
if (filter.q) params.set('q', filter.q)
const qs = params.toString()
return qs ? `?${qs}` : ''
}
export function useNotifications(filter: NotificationFilter = {}) {
return useQuery({
queryKey: ['notifications', filter],
queryFn: () =>
apiFetch<{ notifications: Notification[] }>(`/api/v1/notifications${toQueryString(filter)}`).then(
(r) => r.notifications,
),
})
}
export function useNotification(id: string | undefined) {
return useQuery({
queryKey: ['notifications', 'detail', id],
queryFn: () => apiFetch<{ notification: Notification }>(`/api/v1/notifications/${id}`).then((r) => r.notification),
enabled: Boolean(id),
})
}
export function useMarkAllRead() {
const queryClient = useQueryClient()
return useMutation({
mutationFn: (topic?: string) =>
apiPost<{ status: string; count: number }>(
`/api/v1/notifications/mark-all-read${topic ? `?topic=${encodeURIComponent(topic)}` : ''}`,
),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['notifications'] })
queryClient.invalidateQueries({ queryKey: ['topics'] })
},
})
}
export function useSetNotificationState() {
const queryClient = useQueryClient()
return useMutation({
mutationFn: ({ id, changes }: { id: string; changes: { read?: boolean; starred?: boolean } }) =>
apiPatch<{ notification: Notification }>(`/api/v1/notifications/${id}`, changes),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['notifications'] })
queryClient.invalidateQueries({ queryKey: ['topics'] })
},
})
}