/** * HUD container - main dashboard interface */ import { useMemo } from "react"; import { Button } from "@mosaic/ui"; import { RotateCcw } from "lucide-react"; import { WidgetGrid } from "./WidgetGrid"; import { WidgetRenderer } from "./WidgetRenderer"; import { useLayout } from "@/lib/hooks/useLayout"; import type { WidgetPlacement } from "@mosaic/shared"; export interface HUDProps { className?: string; } /** * Registry of available widget components * This will be populated with actual widget components */ const WIDGET_REGISTRY = { TasksWidget: { name: "tasks", displayName: "Tasks", description: "View and manage your tasks", defaultWidth: 2, defaultHeight: 3, minWidth: 1, minHeight: 2, }, CalendarWidget: { name: "calendar", displayName: "Calendar", description: "Upcoming events and schedule", defaultWidth: 2, defaultHeight: 2, minWidth: 1, minHeight: 2, }, QuickCaptureWidget: { name: "quick-capture", displayName: "Quick Capture", description: "Capture ideas and notes", defaultWidth: 2, defaultHeight: 1, minWidth: 1, minHeight: 1, }, AgentStatusWidget: { name: "agent-status", displayName: "Agent Status", description: "View running agent sessions", defaultWidth: 2, defaultHeight: 2, minWidth: 1, minHeight: 1, }, OrchestratorEventsWidget: { name: "orchestrator-events", displayName: "Orchestrator Events", description: "Recent events and stream health for orchestration", defaultWidth: 2, defaultHeight: 2, minWidth: 1, minHeight: 1, }, } as const; type WidgetRegistryKey = keyof typeof WIDGET_REGISTRY; export function HUD({ className = "" }: HUDProps): React.JSX.Element { const { currentLayout, updateLayout, addWidget, removeWidget, switchLayout, resetLayout } = useLayout(); const isEditing = true; // For now, always in edit mode (can be toggled later) const handleLayoutChange = ( newLayout: readonly { i: string; x: number; y: number; w: number; h: number }[] ): void => { updateLayout([...newLayout] as WidgetPlacement[]); }; const handleAddWidget = (widgetType: WidgetRegistryKey): void => { const widgetConfig = WIDGET_REGISTRY[widgetType]; const widgetId = `${widgetConfig.name}-${String(Date.now())}`; // Find the next available position const maxY = currentLayout?.layout.reduce((max, w): number => Math.max(max, w.y + w.h), 0) ?? 0; const newWidget = { i: widgetId, x: 0, y: maxY, w: widgetConfig.defaultWidth, h: widgetConfig.defaultHeight, minW: widgetConfig.minWidth, minH: widgetConfig.minHeight, isDraggable: true, isResizable: true, }; addWidget(newWidget); }; const handleResetLayout = (): void => { if (confirm("Are you sure you want to reset the layout? This will remove all widgets.")) { resetLayout(); } }; const widgetComponents = useMemo(() => { if (!currentLayout?.layout) return []; return currentLayout.layout.map((widget) => ( )); }, [currentLayout?.layout, isEditing, removeWidget]); return (
{/* Toolbar */}

Dashboard

{/* Widget type selector */}
{/* Widget Grid */} {widgetComponents}
); }