Frontend-Erneuerung: Mobile, Diät, Tempo, UI-Politur (10-Punkte-Paket)

- Fix: 'Interaktives Terminal' im Cockpit führte ins Leere (#terminal) → Konsole
- Mobile: Off-Canvas-Sidebar mit Hamburger unter md, Inhalt volle Breite
  (vorher: 240px starre Sidebar, 135px Rest mit Quer-Scroll auf dem Handy)
- Dead Weight raus: src/mc3/ (verworfener Prototyp), DashboardView (alte
  Zentrale) + 6 nur dort genutzte Karten, 8 ungenutzte npm-Pakete
  (three, three-vrm, react-three fiber/drei, sigma, graphology ×2, @types/three)
- Code-Splitting: alle Views außer Cockpit per React.lazy → Haupt-Bundle
  983 → 739 KB, jede View ein eigenes Chunk
- Fonts lokal (@fontsource) statt Google-CDN → UI offline identisch
- Polling harmonisiert: EINE Takt-Tabelle in queries.ts (Graphen 3s, Rest
  8-60s), keine Override-Intervalle mehr in Komponenten; Updates-Check
  (apt/git!) von 4s auf 60s
- CSS-Hack-Layer aufgelöst: !important-Klassen-Sniffing → explizite
  .mc-card/.mc-card-sm/.nav-active-Klassen (Look identisch, ungeschichtete
  Regeln statt Utility-Raten); totes .light-Theme raus; Scrollbars 1× definiert
- Aurora: animierte Fullscreen-Blur-Filter → statische radial-gradients
  (gleicher Look, keine Dauer-GPU-Last)
- Sicherheit: Sudo-Passwort/HF-Token nur noch bei mutierenden Requests,
  nicht mehr auf jedem GET-Poll
- Strg+K statt ⌘K auf Windows; dist neu gebaut

Live gegen die Box verifiziert: alle 10 Views + Mobile-Flow, 0 Konsolen-Fehler.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Hitonabi
2026-07-13 12:26:27 +02:00
parent f88f8e8bf9
commit 94444f4dcb
174 changed files with 1265 additions and 3229 deletions
+6 -6
View File
@@ -15,8 +15,8 @@ import { useExpertMode } from "@/lib/useExpertMode"
export function Cockpit() {
const qc = useQueryClient()
const { data: modelsResp, isLoading: loading, error: loadErr } = useModels(4_000)
const { data: updates } = useUpdates(4_000)
const { data: modelsResp, isLoading: loading, error: loadErr } = useModels()
const { data: updates } = useUpdates()
const { data: brain } = useHermesBrain()
const { data: sysStatus } = useSystemStatus()
const { data: groupsResp } = useGroups()
@@ -265,7 +265,7 @@ export function Cockpit() {
`}</style>
{/* ZONE A: Widescreen VRAM HUD */}
<div className="rounded-2xl border border-border/60 bg-card/45 backdrop-blur-md p-5 shadow-lg shadow-black/10 space-y-3.5">
<div className="mc-card p-5 space-y-3.5">
<div className="flex justify-between items-center">
<div className="flex items-center gap-2">
<HardDrive className="h-4.5 w-4.5 text-primary" />
@@ -329,7 +329,7 @@ export function Cockpit() {
{expert && <LaneEditor />}
{/* ZONE B.5: Slot-Belegung */}
<div className="rounded-2xl border border-border/60 bg-card/45 backdrop-blur-md p-5 shadow-lg shadow-black/10 space-y-3.5">
<div className="mc-card p-5 space-y-3.5">
<div className="text-xs font-bold uppercase tracking-wider text-muted-foreground px-1">
{expert ? "Gateway Steckplatz-Belegung (Slot-Zuweisung)" : "Wer macht was bei Lucy — zum Ändern antippen"}
</div>
@@ -515,7 +515,7 @@ export function Cockpit() {
<div
key={m.name}
className={cn(
"rounded-2xl border bg-card/45 backdrop-blur-md p-5 shadow-lg shadow-black/10 flex flex-col justify-between gap-4 transition-all duration-300 hover:border-primary/40 group relative overflow-hidden",
"mc-card p-5 flex flex-col justify-between gap-4 group relative overflow-hidden",
isRunning
? "border-primary/45 shadow-primary/5"
: m.role
@@ -725,7 +725,7 @@ export function Cockpit() {
<div
key={m.name}
className={cn(
"rounded-xl border bg-card/45 backdrop-blur-md p-3.5 shadow-lg shadow-black/5 flex flex-col sm:flex-row sm:items-center justify-between gap-3 hover:border-primary/40 transition-all",
"mc-card-sm p-3.5 flex flex-col sm:flex-row sm:items-center justify-between gap-3",
isRunning
? "border-primary/45"
: m.role
+2 -2
View File
@@ -77,7 +77,7 @@ export function Discover() {
return (
<div className="space-y-6">
{/* Modus-Umschalter: geführt (Empfohlen) vs. Stöbern & Suchen */}
<div className="flex rounded-xl border border-border/60 bg-card/45 backdrop-blur-md p-1 w-fit">
<div className="flex mc-card-sm p-1 w-fit">
{([["recommended", "Empfohlen"], ["browse", "Stöbern & Suchen"]] as const).map(([m, label]) => (
<button
key={m}
@@ -145,7 +145,7 @@ export function Discover() {
<div
key={cat.role}
className={cn(
"rounded-2xl border bg-card/45 backdrop-blur-md p-5 shadow-lg shadow-black/10 flex flex-col justify-between gap-5 transition-all duration-300 hover:border-primary/40",
"mc-card p-5 flex flex-col justify-between gap-5",
installedModel ? "border-border/60" : "border-primary/20 shadow-primary/5"
)}
>
+1 -1
View File
@@ -190,7 +190,7 @@ export function ModelBrowse() {
<div
key={r.repo}
className={cn(
"rounded-xl border bg-card/45 backdrop-blur-md transition-all",
"mc-card-sm",
isOpen ? "border-primary/40 shadow-lg shadow-primary/5" : "border-border/50 hover:border-primary/30",
)}
>
@@ -26,7 +26,7 @@ export function MaschinenraumBar({
const freePct = (freeBytes / capacity) * 100
return (
<div className="rounded-2xl border border-border/60 bg-card/45 p-5 shadow-lg shadow-black/15 backdrop-blur-md">
<div className="mc-card p-5">
<div className="mb-3 flex flex-wrap items-end justify-between gap-2">
<div className="flex items-center gap-2">
<HardDrive className="h-5 w-5 text-primary" />
@@ -24,7 +24,7 @@ const short = (name: string) => name.split("/").pop()?.replace(/\.gguf$/i, "") ?
// Eingebettet als Haupt-Tab im Modell-Manager (Überschrift + Discover liefert ModelsView).
export function ModelsWorkbench() {
const qc = useQueryClient()
const { data: modelsResp, isLoading, error } = useModels(4_000)
const { data: modelsResp, isLoading, error } = useModels()
const { data: sys } = useSystemStatus()
const { data: groupsResp } = useGroups()
const { showAlert, showConfirm, showPrompt, dialogElement } = useDialog()
@@ -139,7 +139,7 @@ export function ModelsWorkbench() {
<div className="grid gap-5 lg:grid-cols-[minmax(0,1fr)_minmax(0,1.3fr)]">
{/* Master — Liste */}
<div className="rounded-2xl border border-border/60 bg-card/45 p-4 shadow-lg shadow-black/15 backdrop-blur-md">
<div className="mc-card p-4">
<div className="mb-3 flex items-center gap-2">
<div className="relative flex-1">
<Search className="pointer-events-none absolute left-2.5 top-1/2 h-3.5 w-3.5 -translate-y-1/2 text-muted-foreground/60" />
@@ -194,7 +194,7 @@ export function ModelsWorkbench() {
</div>
{/* Detail — verwalten */}
<div className="rounded-2xl border border-border/60 bg-card/45 p-5 shadow-lg shadow-black/15 backdrop-blur-md">
<div className="mc-card p-5">
{!selected ? (
<div className="flex h-full min-h-[16rem] flex-col items-center justify-center gap-2 text-center text-muted-foreground">
<Cpu className="h-8 w-8 opacity-40" />