import React, { createContext, useCallback, useContext, useEffect, useMemo, useState } from 'react'; import { RestClient, type InboxItem, type InboxState } from '@insignia/iios-kernel-client'; const InboxContext = createContext(null); /** Provides an inbox REST client to the inbox hooks. */ export function InboxProvider({ 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(InboxContext); if (!c) throw new Error('useInbox must be used within '); return c; } /** The caller's inbox items + actions. Polls on an interval (default 3s). */ export function useInbox(opts?: { state?: InboxState; pollMs?: number }): { items: InboxItem[]; refresh: () => Promise; snooze: (id: string) => Promise; done: (id: string) => Promise; reopen: (id: string) => Promise; } { const client = useClient(); const [items, setItems] = useState([]); const refresh = useCallback(async () => { try { setItems(await client.listInboxItems(opts?.state)); } catch { /* transient — keep last items */ } }, [client, opts?.state]); useEffect(() => { void refresh(); const t = setInterval(() => void refresh(), opts?.pollMs ?? 3000); return () => clearInterval(t); }, [refresh, opts?.pollMs]); const patch = async (id: string, state: InboxState): Promise => { await client.patchInboxItem(id, { state }); await refresh(); }; return { items, refresh, snooze: (id) => patch(id, 'SNOOZED'), done: (id) => patch(id, 'DONE'), reopen: (id) => patch(id, 'OPEN'), }; }