story-research-zapwall/hooks/useNotifications.ts
2026-01-06 11:30:23 +01:00

97 lines
2.6 KiB
TypeScript

import { useState, useEffect, useCallback } from 'react'
import { notificationService, loadStoredNotifications, saveNotifications, markNotificationAsRead, markAllAsRead, deleteNotification } from '@/lib/notifications'
import type { Notification } from '@/types/notifications'
export function useNotifications(userPubkey: string | null): {
notifications: Notification[]
unreadCount: number
loading: boolean
markAsRead: (notificationId: string) => void
markAllAsRead: () => void
deleteNotification: (notificationId: string) => void
} {
const [notifications, setNotifications] = useState<Notification[]>([])
const [loading, setLoading] = useState(true)
// Load stored notifications on mount
useEffect(() => {
if (!userPubkey) {
setNotifications([])
setLoading(false)
return
}
const loadStored = async (): Promise<void> => {
const storedNotifications = await loadStoredNotifications(userPubkey)
setNotifications(storedNotifications)
}
void loadStored()
}, [userPubkey])
// Subscribe to new notifications
useEffect(() => {
if (!userPubkey) {
return
}
const unsubscribe = notificationService.subscribeToPayments(userPubkey, (newNotification) => {
setNotifications((prev) => {
// Check if notification already exists
if (prev.some((n) => n.id === newNotification.id)) {
return prev
}
// Add new notification at the beginning
const updated = [newNotification, ...prev]
// Keep only last 100 notifications
const trimmed = updated.slice(0, 100)
// Save to IndexedDB
void saveNotifications(userPubkey, trimmed)
return trimmed
})
})
return () => {
unsubscribe()
}
}, [userPubkey])
const unreadCount = notifications.filter((n) => !n.read).length
const markAsRead = useCallback(
(notificationId: string): void => {
if (!userPubkey) {return}
setNotifications((prev) => markNotificationAsRead(userPubkey, notificationId, prev))
},
[userPubkey]
)
const markAllAsReadHandler = useCallback((): void => {
if (!userPubkey) {return}
setNotifications((prev) => markAllAsRead(userPubkey, prev))
}, [userPubkey])
const deleteNotificationHandler = useCallback(
(notificationId: string): void => {
if (!userPubkey) {return}
setNotifications((prev) => deleteNotification(userPubkey, notificationId, prev))
},
[userPubkey]
)
return {
notifications,
unreadCount,
loading,
markAsRead,
markAllAsRead: markAllAsReadHandler,
deleteNotification: deleteNotificationHandler,
}
}