cre-sync/lib/hooks/useRealtime.ts
BusyBee3333 4e6467ffb0 Add CRESync CRM application with Setup page
- Build complete Next.js CRM for commercial real estate
- Add authentication with JWT sessions and role-based access
- Add GoHighLevel API integration for contacts, conversations, opportunities
- Add AI-powered Control Center with tool calling
- Add Setup page with onboarding checklist (/setup)
- Add sidebar navigation with Setup menu item
- Fix type errors in onboarding API, GHL services, and control center tools
- Add Prisma schema with SQLite for local development
- Add UI components with clay morphism design system

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-14 17:30:55 -05:00

65 lines
1.7 KiB
TypeScript

'use client';
import { useEffect, useCallback, useRef } from 'react';
import { RealtimeEvent, RealtimeMessage } from '@/lib/realtime/events';
type EventHandler<T = any> = (data: T) => void;
export function useRealtime() {
const eventSourceRef = useRef<EventSource | null>(null);
const handlersRef = useRef<Map<RealtimeEvent, Set<EventHandler>>>(new Map());
useEffect(() => {
// Connect to SSE endpoint
const eventSource = new EventSource('/api/v1/realtime/events');
eventSourceRef.current = eventSource;
eventSource.onmessage = (event) => {
try {
const message: RealtimeMessage = JSON.parse(event.data);
// Skip connection message
if ((message as any).type === 'connected') {
console.log('[Realtime] Connected');
return;
}
// Dispatch to handlers
const handlers = handlersRef.current.get(message.event);
if (handlers) {
handlers.forEach(handler => handler(message.data));
}
} catch (error) {
console.error('[Realtime] Parse error:', error);
}
};
eventSource.onerror = (error) => {
console.error('[Realtime] Connection error:', error);
// EventSource will auto-reconnect
};
return () => {
eventSource.close();
eventSourceRef.current = null;
};
}, []);
const subscribe = useCallback(<T = any>(
event: RealtimeEvent,
handler: EventHandler<T>
): (() => void) => {
if (!handlersRef.current.has(event)) {
handlersRef.current.set(event, new Set());
}
handlersRef.current.get(event)!.add(handler);
// Return unsubscribe function
return () => {
handlersRef.current.get(event)?.delete(handler);
};
}, []);
return { subscribe };
}