feat(web): add Mission Control page layout shell
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
import { MissionControlLayout } from "@/components/mission-control/MissionControlLayout";
|
||||
|
||||
export default function MissionControlPage(): React.JSX.Element {
|
||||
return <MissionControlLayout />;
|
||||
}
|
||||
@@ -156,6 +156,26 @@ function IconTerminal(): React.JSX.Element {
|
||||
);
|
||||
}
|
||||
|
||||
function IconMissionControl(): React.JSX.Element {
|
||||
return (
|
||||
<svg
|
||||
width="16"
|
||||
height="16"
|
||||
viewBox="0 0 16 16"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth="1.5"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<circle cx="8" cy="8" r="1.5" />
|
||||
<path d="M11 5a4.25 4.25 0 0 1 0 6" />
|
||||
<path d="M5 5a4.25 4.25 0 0 0 0 6" />
|
||||
<path d="M13.5 2.5a7.75 7.75 0 0 1 0 11" />
|
||||
<path d="M2.5 2.5a7.75 7.75 0 0 0 0 11" />
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
function IconSettings(): React.JSX.Element {
|
||||
return (
|
||||
<svg
|
||||
@@ -260,6 +280,11 @@ const NAV_GROUPS: NavGroup[] = [
|
||||
label: "Terminal",
|
||||
icon: <IconTerminal />,
|
||||
},
|
||||
{
|
||||
href: "/mission-control",
|
||||
label: "Mission Control",
|
||||
icon: <IconMissionControl />,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
"use client";
|
||||
|
||||
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
||||
|
||||
export function GlobalAgentRoster(): React.JSX.Element {
|
||||
return (
|
||||
<Card className="flex h-full min-h-0 flex-col">
|
||||
<CardHeader>
|
||||
<CardTitle className="text-base">Agent Roster</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent className="flex flex-1 items-center justify-center text-sm text-muted-foreground">
|
||||
No active agents
|
||||
</CardContent>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
"use client";
|
||||
|
||||
import { GlobalAgentRoster } from "@/components/mission-control/GlobalAgentRoster";
|
||||
import { MissionControlPanel } from "@/components/mission-control/MissionControlPanel";
|
||||
|
||||
const DEFAULT_PANEL_SLOTS = ["panel-1", "panel-2", "panel-3", "panel-4"] as const;
|
||||
|
||||
export function MissionControlLayout(): React.JSX.Element {
|
||||
return (
|
||||
<section className="h-full min-h-0 overflow-hidden" aria-label="Mission Control">
|
||||
<div className="grid h-full min-h-0 gap-4 xl:grid-cols-[280px_minmax(0,1fr)]">
|
||||
<aside className="h-full min-h-0">
|
||||
<GlobalAgentRoster />
|
||||
</aside>
|
||||
<main className="h-full min-h-0 overflow-hidden">
|
||||
<MissionControlPanel panels={DEFAULT_PANEL_SLOTS} />
|
||||
</main>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
"use client";
|
||||
|
||||
import { OrchestratorPanel } from "@/components/mission-control/OrchestratorPanel";
|
||||
|
||||
interface MissionControlPanelProps {
|
||||
panels: readonly string[];
|
||||
}
|
||||
|
||||
export function MissionControlPanel({ panels }: MissionControlPanelProps): React.JSX.Element {
|
||||
return (
|
||||
<div className="grid h-full min-h-0 auto-rows-fr grid-cols-1 gap-4 overflow-y-auto pr-1 md:grid-cols-2">
|
||||
{panels.map((panelId) => (
|
||||
<OrchestratorPanel key={panelId} />
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
"use client";
|
||||
|
||||
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
||||
|
||||
export function OrchestratorPanel(): React.JSX.Element {
|
||||
return (
|
||||
<Card className="flex h-full min-h-[220px] flex-col">
|
||||
<CardHeader>
|
||||
<CardTitle className="text-base">Orchestrator Panel</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent className="flex flex-1 items-center justify-center text-sm text-muted-foreground">
|
||||
Select an agent
|
||||
</CardContent>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
10
apps/web/src/hooks/useMissionControl.ts
Normal file
10
apps/web/src/hooks/useMissionControl.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
interface UseMissionControlResult {
|
||||
sessions: [];
|
||||
loading: boolean;
|
||||
error: null;
|
||||
}
|
||||
|
||||
// Stub — will be wired in P2-002
|
||||
export function useMissionControl(): UseMissionControlResult {
|
||||
return { sessions: [], loading: false, error: null };
|
||||
}
|
||||
Reference in New Issue
Block a user