"use client"; import { useState, useEffect, useCallback } from "react"; import { api } from "@/lib/api"; interface Props { workspaceId: string; } interface EventEntry { id: string; event_type: string; workspace_id: string | null; payload: Record; created_at: string; } // Use semantic warm-paper tokens so colors flip with theme. Earlier // the table referenced text-yellow-400 / text-purple-400 (Tailwind // raw colors, no theme variant), which read fine in dark mode but // washed out in the warm-paper light theme. text-warm covers the // "degraded" amber tone in both modes; AGENT_CARD_UPDATED is informational // metadata, so reuse text-accent for theme-consistency. const EVENT_COLORS: Record = { WORKSPACE_ONLINE: "text-good", WORKSPACE_OFFLINE: "text-ink-mid", WORKSPACE_DEGRADED: "text-warm", WORKSPACE_PROVISIONING: "text-accent", WORKSPACE_REMOVED: "text-bad", WORKSPACE_PROVISION_FAILED: "text-bad", AGENT_CARD_UPDATED: "text-accent", }; export function EventsTab({ workspaceId }: Props) { const [events, setEvents] = useState([]); const [loading, setLoading] = useState(true); const [expanded, setExpanded] = useState(null); const [error, setError] = useState(null); const loadEvents = useCallback(async () => { setLoading(true); setError(null); try { const data = await api.get(`/events/${workspaceId}`); setEvents(data); } catch (e) { setEvents([]); setError(e instanceof Error ? e.message : "Failed to load events"); } finally { setLoading(false); } }, [workspaceId]); useEffect(() => { loadEvents(); }, [loadEvents]); // Auto-refresh every 10s useEffect(() => { const interval = setInterval(loadEvents, 10000); return () => clearInterval(interval); }, [loadEvents]); if (loading && events.length === 0) { return
Loading events...
; } return (
{events.length} events
{error && (
{error}
)} {!error && events.length === 0 ? (

No events yet

) : (
{events.map((event) => { const isOpen = expanded === event.id; const panelId = `events-payload-${event.id}`; return (
{isOpen && (
                      {JSON.stringify(event.payload, null, 2)}
                    
ID: {event.id}
)}
); })}
)}
); } function formatTime(iso: string): string { const d = new Date(iso); const now = new Date(); const diff = now.getTime() - d.getTime(); if (diff < 60_000) return `${Math.floor(diff / 1000)}s ago`; if (diff < 3_600_000) return `${Math.floor(diff / 60_000)}m ago`; if (diff < 86_400_000) return `${Math.floor(diff / 3_600_000)}h ago`; return d.toLocaleDateString(); }