import { useEffect, useState } from 'react'; import { SupportProvider, useAssignedTickets, useGoOnline, useThread, useMessages, type Ticket, } from '@insignia/iios-support-web'; const SERVICE = 'http://localhost:3200'; const APP_ID = 'portal-demo'; const AGENT_ID = 'agent1'; async function devToken(userId: string): Promise { const r = await fetch(`${SERVICE}/v1/dev/token`, { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ appId: APP_ID, userId, name: userId }), }); if (!r.ok) throw new Error(`devToken ${r.status} (service running with IIOS_DEV_TOKENS=1?)`); return ((await r.json()) as { token: string }).token; } function AgentChat({ threadId }: { threadId: string }) { const { open } = useThread(); useEffect(() => { void open(threadId); // eslint-disable-next-line react-hooks/exhaustive-deps }, [threadId]); const { messages, send } = useMessages(threadId); const [text, setText] = useState(''); return (

Thread {threadId.slice(0, 8)}

{messages.map((m) => (
{m.senderActorId.slice(0, 6)}: {m.content}
))}
setText(e.target.value)} onKeyDown={(e) => { if (e.key === 'Enter' && text.trim()) { void send(text.trim()); setText(''); } }} />
); } function AgentInner() { const goOnline = useGoOnline(); const { tickets } = useAssignedTickets(); const [threadId, setThreadId] = useState(null); useEffect(() => { void goOnline(); // join default queue + go AVAILABLE // eslint-disable-next-line react-hooks/exhaustive-deps }, []); return (
Assigned tickets ({tickets.length}) {tickets.length === 0 &&
waiting for escalations…
} {tickets.map((t: Ticket) => { const tid = t.threadLinks?.[0]?.threadId ?? null; return (
{t.subject}
{t.state}
); })}
{threadId ? :
Select a ticket.
}
); } export function App() { const [token, setToken] = useState(null); useEffect(() => { void devToken(AGENT_ID).then(setToken); }, []); if (!token) return
loading agent…
; return (

IIOS P4 — Agent Dashboard ({AGENT_ID})

); }