"use client"; /** * DashRightRail — 320px collapsible drawer. * * Holds the live AI verdict stream, active voice speakers, and the latest * moderation actions. Reads from existing hooks (`useVoice`, etc.) — no * new fetches; just re-presentation. */ import { ChevronRight } from "lucide-react"; import { useEffect, useState } from "react"; import { useSpeakers } from "@/hooks/use-voice"; import type { ActiveSpeaker } from "@/lib/types"; import { cn } from "@/lib/utils"; import { useWebSocket } from "@/lib/ws/context"; interface DashRightRailProps { pendingVerdicts?: { id: string; ts: number; text: string }[]; recentActions?: { id: string; ts: number; verb: string; target: string }[]; } export function DashRightRail({ pendingVerdicts = [], recentActions = [], }: DashRightRailProps) { const [collapsed, setCollapsed] = useState(false); const { subscribe } = useSpeakers(); const ws = useWebSocket(); const [speakers, _setSpeakers] = useState([]); useEffect(() => subscribe(ws), [ws, subscribe]); return ( ); } function Section({ title, children, vertical, }: { title: string; children?: React.ReactNode; vertical?: boolean; }) { return (

{title}

{children}
); } function Empty({ msg }: { msg: string }) { return ( {msg} ); } function formatTs(ts: number): string { const d = new Date(ts); const pad = (n: number) => String(n).padStart(2, "0"); return `${pad(d.getHours())}:${pad(d.getMinutes())}`; }