import { useState } from "react" import { cn } from "cn" import { Bestaetigen } from "@/components/cockpit/Bestaetigen" import { Geraetesymbol } from "@/components/cockpit/Geraetesymbol" import { Panel } from "@/components/cockpit/Panel" import { Button } from "@/components/ui/button" import { geraetebild } from "@/lib/geraetebild" import type { NeuerStack, NeuesGeraet, NeuWahl } from "@/lib/typen" import { flugplanZeit } from "@/lib/zeit" // „Neu entdeckt“ (Ausbauplan Welle 2, Punkt 7, seit 25.09.2026): Geräte, die der Orchestrator noch nicht kennt, mit // dem, was er über sie weiß, und drei Wegen, sie zu übernehmen. Freigeben setzt das Etikett watcher — erst danach darf // er dort Snapshots anlegen und Updates einspielen; deshalb fragt die Seite vorher nach. const WEG: Record = { skript: "Updates über das Community-Script", "eigene-oberflaeche": "Updates über die eigene Oberfläche der App", pakete: "Updates über die Pakete im Gast", } function Karte({ g, gesperrt, onWahl }: { g: NeuesGeraet; gesperrt: boolean; onWahl: (w: NeuWahl) => void }) { const bild = geraetebild({ art: g.art, name: g.app?.kennung ?? g.hostname ?? g.name }) const fakten = [ g.app ? `${g.app.name}${g.app.quelle ? ` (GitHub ${g.app.quelle})` : ""}` : "App unbekannt", g.app ? WEG[g.app.weg] ?? g.app.weg : null, g.app?.adresse ? `Weboberfläche ${g.app.adresse} wird geprüft` : g.app ? "Weboberfläche nicht gefunden, keine Webprüfung" : null, ].filter(Boolean) return (
  • {g.name} {g.art === "container" ? "Container" : "VM"} {g.vmid} {g.hostname && g.hostname !== g.name ? ` · „${g.hostname}“` : ""} {g.erstmals ? ` · entdeckt ${flugplanZeit(new Date(g.erstmals * 1000).toISOString()).toLowerCase()}` : ""}
    {!g.freigegeben && !g.ausgeschlossen && ( )} {!g.ausgeschlossen && ( )}
  • ) } const FRAGE: Record = { freigeben: { titel: "Für Updates freigeben?", text: "Der Orchestrator setzt in Proxmox das Etikett „watcher“. Danach darf er dort Snapshots anlegen und Updates " + "einspielen — immer erst nach deinem Klick, mit Snapshot vorher und Rückweg bei Rot.", knopf: "Freigeben", }, beobachten: { titel: "Nur beobachten?", text: "", knopf: "Übernehmen" }, ausschliessen: { titel: "Nicht anfassen?", text: "Der Orchestrator setzt in Proxmox das Etikett „watcher-aus“ und lässt das Gerät dann auch bei „Alle " + "aktualisieren“ aus.", knopf: "Nicht anfassen", }, } /** Ein neuer Docker-Stack: nur „Übernehmen“ — Etiketten gibt es unter Arcane nicht. */ function StackKarte({ s, gesperrt, onWahl }: { s: NeuerStack; gesperrt: boolean; onWahl: (w: NeuWahl) => void }) { return (
  • Docker-Stack {s.name} unter Arcane{s.erstmals ? ` · entdeckt ${flugplanZeit(new Date(s.erstmals * 1000).toISOString()).toLowerCase()}` : ""}

    Container: {s.container.join(", ") || "–"}

  • ) } export function NeuEntdeckt({ geraete, stacks = [], gesperrt, onWahl }: { geraete: NeuesGeraet[] /** Neue Docker-Stacks unter Arcane (seit 25.09.2026). */ stacks?: NeuerStack[] gesperrt: boolean onWahl: (id: string, wahl: NeuWahl) => void }) { const [frage, setFrage] = useState<{ g: NeuesGeraet; wahl: NeuWahl } | null>(null) const anzahl = geraete.length + stacks.length if (anzahl === 0) return null return (

    {anzahl === 1 ? "Eins kennt" : `${anzahl} kennt`} der Orchestrator noch nicht. Entscheide, ob er {anzahl === 1 ? " es" : " sie"} nur beobachtet oder auch aktualisieren darf.

      {geraete.map((g) => ( (wahl === "beobachten" ? onWahl(g.id, wahl) : setFrage({ g, wahl }))} /> ))} {stacks.map((s) => onWahl(s.id, wahl)} />)}
    setFrage(null)} onJa={() => { if (frage) onWahl(frage.g.id, frage.wahl) setFrage(null) }} />
    ) }