Files
mission-control-v2/frontend/src/features/ideen/Wahl.tsx
T
HitonabiandClaude Opus 5 dcee0096fe
Ampel / ampel (push) Successful in 34s
refactor(ideen): v3-Umbau P5 — der Monolith bekommt einen eigenen Bereich
Sechste Etappe, erster Bereich. views/IdeenView.tsx hatte 1031 Zeilen, 26 useState
und sechs Komponenten in derselben Datei (Befund B-06) — der Haupteingang des
Systems, und niemand konnte ihn ohne Vollbild-Scrollen ueberblicken.

## Der Schnitt

Er folgt den Grenzen, die im Monolithen ohnehin schon lagen: Jede Top-Level-Funktion
wird eine Datei. Der INHALT ist unveraendert — nur die Datei ist neu, damit der Diff
pruefbar bleibt.

  features/ideen/zustaende.ts       55   Zustands-/Art-Tabellen + Sortier-Rang
  features/ideen/quote.ts           22   Nutzungs-Quote der Eingabe
  features/ideen/Wahl.tsx           27   eine Auswahlkachel
  features/ideen/ErgebnisPanel.tsx  55
  features/ideen/KonzeptPanel.tsx   73
  features/ideen/ProjektGruppe.tsx  86
  features/ideen/WeiterLeiste.tsx  113
  features/ideen/IdeenAnsicht.tsx  676   Verfasser + Liste + Zeilen-Renderer

views/IdeenView.tsx bleibt als vierzeiliger Wegweiser eine Fassung lang stehen,
damit ein uebersehener Import nicht stillschweigend bricht; der Router zeigt bereits
direkt auf features/ideen/.

## Was BEWUSST noch nicht geschnitten ist

Der Zeilen-Renderer `zeile()` (188 Zeilen) bleibt in IdeenAnsicht.tsx. Er greift auf
16 Werte des umgebenden Zustands zu (busy, openLog, openKonzept, antworten, logData,
steuer, archive, answer, …). Ihn "herauszuloesen" hiesse, eine Props-Liste mit 16
Eintraegen zu schreiben — dieselbe Verflechtung in anderer Schreibweise. Das ist eine
Frage der Zustands-Zugehoerigkeit, keine Verschiebe-Uebung, und verdient eine eigene
Runde statt eine Beifaenger-Aenderung. Steht so auch im Kopfkommentar der Datei.

## Nebenbefund beim Pruefen: die eigene Anzeige log

Gegen die noch nicht aktualisierte Box zeigte die Statusleiste "Getrennt" — obwohl
die Poller sauber lieferten und alle Zahlen stimmten. Grund: Dort gibt es /api/stream
noch nicht, der SPA-Catch-all beantwortet den Pfad mit index.html, und EventSource
scheitert daran.

Die Anzeige verwechselte damit zwei Dinge. Jetzt trennt sie sie:
  Getrennt  = die Zentrale antwortet nicht, die Zahlen sind wirklich alt
  Nachlauf  = kein Strom, aber die Zentrale antwortet — die Zahlen stimmen,
              sie kommen im Takt statt sofort
  Live      = Strom steht
Eine Anzeige, die vor korrekten Daten warnt, ist genauso falsch wie eine, die
veraltete verschweigt.

## Verifiziert

  Gegen das lokale Backend: /ideen rendert, keine Fehlerflaeche
  Gegen die ECHTE Box (altes Backend, kein /api/stream): Leiste sagt "Nachlauf",
    zeigt die echten Werte (40,7/122,7 GB Unified Memory, GPU 0 %, 37 °C,
    532 748 115 Token, 1023 € gespart) — und blendet die Betriebszeit AUS, weil das
    alte Backend sie nicht liefert, statt eine Zahl zu erfinden.
    Das neue Frontend degradiert also sauber gegen den alten Stand.

37/37 Tests gruen · ESLint 0 Fehler · Einstieg 118 606 B gzip / Budget 125 000.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-28 09:22:45 +02:00

28 lines
1.1 KiB
TypeScript

// Eine der drei Auswahlkacheln im Ideen-Verfasser (Wer baut das? / Wie startest du?).
//
// Herausgeschnitten aus views/IdeenView.tsx (1031 Zeilen) beim v3-Umbau P5, Befund B-06.
// Der Inhalt ist UNVERAENDERT — nur die Datei ist neu. So bleibt der Diff pruefbar.
import { Hammer } from "lucide-react"
import { cn } from "@/lib/utils"
export function Wahl({ k, aktiv, onWahl }: {
k: { id: string; icon: typeof Hammer; titel: string; text: string }
aktiv: boolean
onWahl: () => void
}) {
return (
<button
onClick={onWahl}
className={cn("rounded-xl border p-3 text-left transition-all cursor-pointer",
aktiv ? "border-primary/60 bg-primary/5" : "border-border/50 hover:border-border")}>
<div className="flex items-center gap-2">
<k.icon className={cn("h-4 w-4 shrink-0", aktiv ? "text-primary" : "text-muted-foreground")} />
<span className="text-xs font-semibold text-foreground">{k.titel}</span>
</div>
<p className="mt-1 text-[11px] leading-relaxed text-muted-foreground">{k.text}</p>
</button>
)
}