65 lines
2.1 KiB
TypeScript
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'] })
|
|
},
|
|
})
|
|
}
|