feat(frontend) : add useNotifications composable with polling
This commit is contained in:
69
frontend/composables/useNotifications.ts
Normal file
69
frontend/composables/useNotifications.ts
Normal file
@@ -0,0 +1,69 @@
|
||||
import type { Notification } from '~/services/dto/notification'
|
||||
import { useNotificationService } from '~/services/notifications'
|
||||
|
||||
const POLL_INTERVAL = 2 * 60 * 1000 // 2 minutes
|
||||
|
||||
export function useNotifications() {
|
||||
const unreadCount = useState<number>('notification-unread-count', () => 0)
|
||||
const notifications = useState<Notification[]>('notification-list', () => [])
|
||||
const isLoading = useState<boolean>('notification-loading', () => false)
|
||||
|
||||
const service = useNotificationService()
|
||||
let pollTimer: ReturnType<typeof setInterval> | null = null
|
||||
|
||||
async function fetchUnreadCount(): Promise<void> {
|
||||
try {
|
||||
unreadCount.value = await service.getUnreadCount()
|
||||
} catch {
|
||||
// Silently ignore polling errors
|
||||
}
|
||||
}
|
||||
|
||||
async function fetchNotifications(): Promise<void> {
|
||||
isLoading.value = true
|
||||
try {
|
||||
notifications.value = await service.getAll()
|
||||
} finally {
|
||||
isLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
async function markAsRead(id: number): Promise<void> {
|
||||
await service.markAsRead(id)
|
||||
const notif = notifications.value.find(n => n.id === id)
|
||||
if (notif && !notif.isRead) {
|
||||
notif.isRead = true
|
||||
unreadCount.value = Math.max(0, unreadCount.value - 1)
|
||||
}
|
||||
}
|
||||
|
||||
async function markAllAsRead(): Promise<void> {
|
||||
await service.markAllAsRead()
|
||||
notifications.value.forEach(n => n.isRead = true)
|
||||
unreadCount.value = 0
|
||||
}
|
||||
|
||||
function startPolling(): void {
|
||||
fetchUnreadCount()
|
||||
pollTimer = setInterval(fetchUnreadCount, POLL_INTERVAL)
|
||||
}
|
||||
|
||||
function stopPolling(): void {
|
||||
if (pollTimer) {
|
||||
clearInterval(pollTimer)
|
||||
pollTimer = null
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
unreadCount,
|
||||
notifications,
|
||||
isLoading,
|
||||
fetchNotifications,
|
||||
fetchUnreadCount,
|
||||
markAsRead,
|
||||
markAllAsRead,
|
||||
startPolling,
|
||||
stopPolling,
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user