import { cn } from "cn" import { Geraetesymbol } from "@/components/cockpit/Geraetesymbol" import { geraetebild, type Punktzustand } from "@/lib/geraetebild" import type { DockerContainer, DockerLage } from "@/lib/typen" // Docker-Dienste unter Arcane einzeln (Ausbauplan Welle 2, Punkt 8, seit 25.09.2026): je Stack die Container mit // Zustand, Gesundheit und Update-Stand — statt nur „Arcane (Docker) · 11 Images“. const UPDATE: Record = { neu: { text: "Update verfügbar", klasse: "text-cyan-text" }, lokal: { text: "lokal gebaut", klasse: "text-text-3" }, aktuell: { text: "aktuell", klasse: "text-text-3" }, unbekannt: { text: "Update-Stand unklar", klasse: "text-bernstein" }, } function punkt(c: DockerContainer): Punktzustand { if (c.zustand === "restarting" || c.gesund === false) return "rot" if (c.zustand === "running") return "ok" return "aus" } function zustandText(c: DockerContainer): string { if (c.gesund === false) return "ungesund" if (c.zustand === "restarting") return "startet immer wieder neu" if (c.zustand === "running") return c.gesund ? "läuft, gesund" : "läuft" if (c.zustand === "exited") return "beendet" if (c.zustand === "paused") return "angehalten" return c.zustand } /** Aus „ghcr.io/getarcaneapp/manager:latest“ wird „manager“ — für das Logo. */ const imageName = (image: string | null) => (image ?? "").split("/").at(-1)?.split(":")[0] ?? "" /** „2 kritische, 5 hohe Lücken“ aus Arcanes Scan (seit 25.09.2026) — nur, wenn es kritische oder hohe gibt. */ function lueckenText(c: DockerContainer): string | null { const l = c.luecken if (!l || (!l.kritisch && !l.hoch)) return null const teile = [l.kritisch ? `${l.kritisch} kritische` : null, l.hoch ? `${l.hoch} hohe` : null].filter(Boolean) return `${teile.join(", ")} Lücken` } function Zeile({ c }: { c: DockerContainer }) { const u = UPDATE[c.update] ?? UPDATE.unbekannt const luecken = lueckenText(c) return (
  • {c.name} {c.image} {luecken && ( {luecken} )} {zustandText(c)} {u.text}
  • ) } export function DockerDienste({ lage }: { lage: DockerLage }) { if (!lage.verfuegbar || lage.stacks.length === 0) return null return (
    {lage.stacks.map((s) => { const laufen = s.container.filter((c) => c.zustand === "running").length const neu = s.container.filter((c) => c.update === "neu").length return (

    {s.name}

    {laufen} von {s.container.length} laufen{neu ? ` · ${neu} mit Update` : ""}
      {s.container.map((c) => )}
    ) })}
    ) }