/**
* 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) => (