Initial commit from monorepo
This commit is contained in:
138
app/composables/useNovu.ts
Normal file
138
app/composables/useNovu.ts
Normal file
@@ -0,0 +1,138 @@
|
||||
import { Novu } from '@novu/js'
|
||||
|
||||
interface NovuNotification {
|
||||
id: string
|
||||
content: string
|
||||
read: boolean
|
||||
seen: boolean
|
||||
createdAt: string
|
||||
payload?: Record<string, unknown>
|
||||
cta?: {
|
||||
type: string
|
||||
data: {
|
||||
url?: string
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let novuInstance: Novu | null = null
|
||||
|
||||
export const useNovu = () => {
|
||||
const config = useRuntimeConfig()
|
||||
const notifications = ref<NovuNotification[]>([])
|
||||
const unreadCount = ref(0)
|
||||
const isLoading = ref(false)
|
||||
const isInitialized = ref(false)
|
||||
|
||||
const init = (subscriberId: string) => {
|
||||
if (novuInstance || !subscriberId) return
|
||||
|
||||
const appId = config.public.novuAppId
|
||||
const backendUrl = config.public.novuBackendUrl
|
||||
const socketUrl = config.public.novuSocketUrl
|
||||
|
||||
if (!appId || !backendUrl) {
|
||||
console.warn('[useNovu] Missing configuration: novuAppId or novuBackendUrl')
|
||||
return
|
||||
}
|
||||
|
||||
novuInstance = new Novu({
|
||||
subscriberId,
|
||||
applicationIdentifier: appId,
|
||||
backendUrl,
|
||||
socketUrl: socketUrl || undefined
|
||||
})
|
||||
|
||||
isInitialized.value = true
|
||||
|
||||
// Subscribe to realtime updates
|
||||
novuInstance.on('notifications.notification_received', () => {
|
||||
loadNotifications()
|
||||
})
|
||||
|
||||
// Load initial data
|
||||
loadNotifications()
|
||||
}
|
||||
|
||||
const loadNotifications = async () => {
|
||||
if (!novuInstance) return
|
||||
|
||||
isLoading.value = true
|
||||
try {
|
||||
const result = await novuInstance.notifications.list({ limit: 20 })
|
||||
const data = Array.isArray(result?.data)
|
||||
? result.data
|
||||
: (result?.data?.notifications || [])
|
||||
notifications.value = data as NovuNotification[]
|
||||
unreadCount.value = notifications.value.filter((n: NovuNotification) => !n.read).length
|
||||
} catch (error) {
|
||||
console.error('[useNovu] Failed to load notifications:', error)
|
||||
} finally {
|
||||
isLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
const markAsRead = async (notificationId: string) => {
|
||||
if (!novuInstance) return
|
||||
|
||||
try {
|
||||
await novuInstance.notifications.read({ notificationId })
|
||||
// Update locally
|
||||
const notification = notifications.value.find((n: NovuNotification) => n.id === notificationId)
|
||||
if (notification) {
|
||||
notification.read = true
|
||||
unreadCount.value = notifications.value.filter((n: NovuNotification) => !n.read).length
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('[useNovu] Failed to mark as read:', error)
|
||||
}
|
||||
}
|
||||
|
||||
const markAllAsRead = async () => {
|
||||
if (!novuInstance) return
|
||||
|
||||
try {
|
||||
await novuInstance.notifications.readAll()
|
||||
notifications.value.forEach((n: NovuNotification) => { n.read = true })
|
||||
unreadCount.value = 0
|
||||
} catch (error) {
|
||||
console.error('[useNovu] Failed to mark all as read:', error)
|
||||
}
|
||||
}
|
||||
|
||||
const markAsSeen = async (notificationId: string) => {
|
||||
if (!novuInstance) return
|
||||
|
||||
try {
|
||||
await novuInstance.notifications.archive({ notificationId })
|
||||
const notification = notifications.value.find((n: NovuNotification) => n.id === notificationId)
|
||||
if (notification) {
|
||||
notification.seen = true
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('[useNovu] Failed to mark as seen:', error)
|
||||
}
|
||||
}
|
||||
|
||||
const destroy = () => {
|
||||
if (novuInstance) {
|
||||
novuInstance = null
|
||||
isInitialized.value = false
|
||||
notifications.value = []
|
||||
unreadCount.value = 0
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
init,
|
||||
destroy,
|
||||
notifications,
|
||||
unreadCount,
|
||||
isLoading,
|
||||
isInitialized,
|
||||
markAsRead,
|
||||
markAllAsRead,
|
||||
markAsSeen,
|
||||
loadNotifications
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user