91 lines
4.2 KiB
TypeScript
91 lines
4.2 KiB
TypeScript
import { useEffect, useState } from "react"
|
|
import { Activity, Code, Bookmark, Wrench, ArrowLeft, type LucideIcon } from "lucide-react"
|
|
import { ConnectView } from "@/views/ConnectView"
|
|
import { MemoryView } from "@/views/MemoryView"
|
|
import { SystemDrawer } from "@/components/SystemDrawer"
|
|
import { useHealth } from "@/lib/queries"
|
|
import { cn } from "@/lib/utils"
|
|
import { Mc3Start } from "./Mc3Start"
|
|
import { Mc3Maschinenraum } from "./Mc3Maschinenraum"
|
|
|
|
// MC3-Prototyp-Schale. Läuft nicht-destruktiv unter #mc3, das produktive MC2 bleibt
|
|
// unangetastet. Vier Türen; Innereien sind bewusst die bestehenden, bewährten Views.
|
|
type Door = "start" | "vibe" | "konstitution" | "maschinenraum"
|
|
|
|
const DOORS: { id: Door; label: string; icon: LucideIcon }[] = [
|
|
{ id: "start", label: "Start", icon: Activity },
|
|
{ id: "vibe", label: "Vibe-Coding", icon: Code },
|
|
{ id: "konstitution", label: "Konstitution", icon: Bookmark },
|
|
{ id: "maschinenraum", label: "Maschinenraum", icon: Wrench },
|
|
]
|
|
|
|
export function Mc3App() {
|
|
const [door, setDoor] = useState<Door>("start")
|
|
const [drawerOpen, setDrawerOpen] = useState(false)
|
|
const [drawerTab, setDrawerTab] = useState<"maintenance" | "logs">("maintenance")
|
|
const { data: health } = useHealth()
|
|
|
|
useEffect(() => {
|
|
const onOpen = (e: Event) => {
|
|
setDrawerTab(((e as CustomEvent).detail?.tab as "maintenance" | "logs") || "maintenance")
|
|
setDrawerOpen(true)
|
|
}
|
|
window.addEventListener("open-system-drawer", onOpen)
|
|
return () => window.removeEventListener("open-system-drawer", onOpen)
|
|
}, [])
|
|
|
|
const boxOk = health && health.engine_reachable && (health.brain ? health.brain.ready : true)
|
|
|
|
return (
|
|
<div className="flex h-full relative">
|
|
<div className="fixed inset-0 -z-50 pointer-events-none overflow-hidden bg-[hsl(224,30%,6%)]">
|
|
<div className="absolute inset-0 opacity-30 animate-aurora bg-gradient-to-tr from-teal-500/15 via-indigo-500/10 to-purple-500/15 blur-[130px]" />
|
|
</div>
|
|
|
|
<SystemDrawer open={drawerOpen} onClose={() => setDrawerOpen(false)} defaultTab={drawerTab} />
|
|
|
|
{/* Sidebar — 4 Türen */}
|
|
<aside className="flex w-56 shrink-0 flex-col border-r border-border/40 bg-card/45 backdrop-blur-md">
|
|
<div className="flex items-center gap-2 px-5 py-4 border-b border-border/40">
|
|
<div className="h-7 w-7 rounded-lg bg-primary shadow-md shadow-primary/20" />
|
|
<div className="leading-tight">
|
|
<div className="text-sm font-semibold tracking-wide font-space">Mission Control</div>
|
|
<div className="text-[10px] text-muted-foreground">3 · Prototyp</div>
|
|
</div>
|
|
</div>
|
|
|
|
<nav className="flex-1 space-y-1 px-3 py-4">
|
|
{DOORS.map((d) => (
|
|
<button key={d.id} onClick={() => setDoor(d.id)}
|
|
className={cn(
|
|
"flex w-full items-center gap-3 rounded-md px-3 py-2 text-sm transition-all cursor-pointer",
|
|
door === d.id ? "bg-primary/15 text-primary" : "text-muted-foreground hover:bg-accent hover:text-accent-foreground",
|
|
)}>
|
|
<d.icon className="h-4.5 w-4.5 shrink-0" /> {d.label}
|
|
</button>
|
|
))}
|
|
</nav>
|
|
|
|
<div className="px-3 py-3 border-t border-border/40 space-y-2">
|
|
<div className="flex items-center gap-2 px-2 text-xs text-muted-foreground">
|
|
<span className={cn("h-2 w-2 rounded-full", boxOk ? "bg-emerald-500 animate-pulse" : "bg-amber-500")} />
|
|
{boxOk ? "Box läuft" : "prüfen"}
|
|
</div>
|
|
<a href="#dashboard"
|
|
className="flex items-center gap-1.5 rounded-md px-2 py-1.5 text-[11px] text-muted-foreground hover:text-foreground transition-colors">
|
|
<ArrowLeft className="h-3.5 w-3.5" /> zurück zu MC2
|
|
</a>
|
|
</div>
|
|
</aside>
|
|
|
|
{/* Main */}
|
|
<main className="flex-1 min-w-0 overflow-y-auto p-6 scrollbar-thin">
|
|
{door === "start" && <Mc3Start />}
|
|
{door === "vibe" && <ConnectView />}
|
|
{door === "konstitution" && <MemoryView />}
|
|
{door === "maschinenraum" && <Mc3Maschinenraum />}
|
|
</main>
|
|
</div>
|
|
)
|
|
}
|