feat(realtime): implement SSE realtime notifications; publish events from resolvers; remove polling in chat/sidebar/supplies/warehouse and wire realtime refetch

This commit is contained in:
Bivekich
2025-08-11 22:13:33 +03:00
parent 52107e793e
commit 3a56092385
14 changed files with 562 additions and 40 deletions

60
src/hooks/useRealtime.ts Normal file
View File

@ -0,0 +1,60 @@
"use client"
import { useEffect, useRef } from 'react'
import { getAuthToken } from '@/lib/apollo-client'
export type RealtimeEvent = {
type: string
payload?: any
createdAt?: string
}
type Options = {
onEvent?: (evt: RealtimeEvent) => void
orgId?: string
}
export function useRealtime({ onEvent, orgId }: Options = {}) {
const handlerRef = useRef(onEvent)
handlerRef.current = onEvent
useEffect(() => {
if (typeof window === 'undefined') return
const token = getAuthToken() || localStorage.getItem('adminAuthToken')
// Try to infer orgId from cached userData if not provided
let resolvedOrgId = orgId
if (!resolvedOrgId) {
try {
const userDataRaw = localStorage.getItem('userData')
if (userDataRaw) {
const user = JSON.parse(userDataRaw)
resolvedOrgId = user?.organization?.id
}
} catch {}
}
if (!token || !resolvedOrgId) return
const url = `/api/events?token=${encodeURIComponent(token)}&orgId=${encodeURIComponent(resolvedOrgId)}`
const es = new EventSource(url)
es.onmessage = (event) => {
try {
const data = JSON.parse(event.data)
handlerRef.current?.(data)
} catch (e) {
// ignore malformed events
}
}
es.onerror = () => {
// Let the browser auto-reconnect
}
return () => {
es.close()
}
}, [orgId])
}