Compare commits
2 Commits
test/ms23-
...
feat/ms23-
| Author | SHA1 | Date | |
|---|---|---|---|
| 487aac6903 | |||
| 544e828e58 |
@@ -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 {
|
function IconSettings(): React.JSX.Element {
|
||||||
return (
|
return (
|
||||||
<svg
|
<svg
|
||||||
@@ -260,6 +280,11 @@ const NAV_GROUPS: NavGroup[] = [
|
|||||||
label: "Terminal",
|
label: "Terminal",
|
||||||
icon: <IconTerminal />,
|
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