import { useState } from 'react' import { useQuery } from '@tanstack/react-query' import { apiFetch } from '@/lib/http' import { LoadingSkeleton } from '@/components/common/LoadingSkeleton' import { cn } from '@/lib/utils' interface Escalation { id: string query: string frequency: number last_seen: string teams: string[] status: 'open' | 'in_progress' | 'resolved' gap_type: 'missing_knowledge' | 'stale_content' | 'incorrect_answer' | 'out_of_scope' } interface EscalationResponse { escalations: Escalation[] total: number } async function fetchEscalations(): Promise { const res = await apiFetch('/api/analytics/escalations?limit=50') return res.json() } const STATUS_STYLES: Record = { open: 'bg-red-100 text-red-700 dark:bg-red-900/30 dark:text-red-400', in_progress: 'bg-amber-100 text-amber-700 dark:bg-amber-900/30 dark:text-amber-400', resolved: 'bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400', } const GAP_LABELS: Record = { missing_knowledge: 'Missing knowledge', stale_content: 'Stale content', incorrect_answer: 'Incorrect answer', out_of_scope: 'Out of scope', } export function EscalationTable() { const { data, isLoading } = useQuery({ queryKey: ['analytics-escalations'], queryFn: fetchEscalations, staleTime: 120_000, }) const [statusFilter, setStatusFilter] = useState<'all' | Escalation['status']>('open') const rows = (data?.escalations ?? []).filter( (e) => statusFilter === 'all' || e.status === statusFilter, ) return (

Unresolved Escalations

Queries that couldn't be answered — sorted by frequency

{(['all', 'open', 'in_progress', 'resolved'] as const).map((s) => ( ))}
{isLoading ? ( ) : rows.length === 0 ? (

No escalations in this category

) : (
{rows.map((e) => ( ))}
Query Freq Gap type Teams Status Last seen

{e.query}

{e.frequency} {GAP_LABELS[e.gap_type]} {e.teams.slice(0, 2).join(', ')}{e.teams.length > 2 ? ` +${e.teams.length - 2}` : ''} {e.status.replace('_', ' ')} {new Date(e.last_seen).toLocaleDateString()}
)}
) }