import React, { createContext, useCallback, useContext, useEffect, useMemo, useState } from 'react'; import { RestClient, type RouteBinding, type RouteDecision } from '@insignia/iios-kernel-client'; const CommunityContext = createContext(null); export function CommunityProvider({ serviceUrl, token, children, }: { serviceUrl: string; token: string; children: React.ReactNode; }): React.ReactElement { const client = useMemo(() => new RestClient({ serviceUrl, token }), [serviceUrl, token]); return {children}; } function useClient(): RestClient { const c = useContext(CommunityContext); if (!c) throw new Error('community hooks must be used within '); return c; } /** Manage route bindings (origin→destination rules). */ export function useBindings(): { bindings: RouteBinding[]; refresh: () => Promise; createBinding: (input: Partial) => Promise; } { const client = useClient(); const [bindings, setBindings] = useState([]); const refresh = useCallback(async () => { try { setBindings(await client.listBindings()); } catch { /* transient */ } }, [client]); useEffect(() => { void refresh(); }, [refresh]); const createBinding = async (input: Partial) => { const b = await client.createBinding(input); await refresh(); return b; }; return { bindings, refresh, createBinding }; } /** Preview-first: simulate an interaction against the bindings (no send). */ export function useRoutePreview(): (interactionId: string, originChannelType: string, originRef?: string) => Promise { const client = useClient(); return async (interactionId, originChannelType, originRef) => (await client.simulateRoute({ interactionId, originChannelType, originRef })).decisions; } /** Pending decisions + admin approve/deny. */ export function useRouteDecisions(opts?: { state?: string; pollMs?: number }): { decisions: RouteDecision[]; refresh: () => Promise; approve: (id: string) => Promise; deny: (id: string) => Promise; } { const client = useClient(); const [decisions, setDecisions] = useState([]); const refresh = useCallback(async () => { try { setDecisions(await client.listRouteDecisions(opts?.state)); } catch { /* transient */ } }, [client, opts?.state]); useEffect(() => { void refresh(); const t = setInterval(() => void refresh(), opts?.pollMs ?? 3000); return () => clearInterval(t); }, [refresh, opts?.pollMs]); const approve = async (id: string) => { await client.approveDecision(id); await refresh(); }; const deny = async (id: string) => { await client.denyDecision(id); await refresh(); }; return { decisions, refresh, approve, deny }; }