phase2c: Oberflaeche heisst Homelab Orchestrator, Bereich Homelab, Anfragen gehen an die richtige Instanz

- /api/instanz: Rolle der ausliefernden Instanz, ohne Netzabfragen
- lib/instanz.ts: /api/homelab/... an die Homelab-Instanz, alles andere an die Box,
  ueber /api/partner/..., wenn die andere Instanz die Seite ausliefert
- neue Seite Homelab: Stand der zweiten Instanz (noch nicht eingerichtet / verbunden /
  antwortet nicht) und was dazukommt
- Kopfzeile, Titel und Web-Manifest mit neuem Namen; fuenfter Menuepunkt, 320 px geprueft

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Hitonabi
2026-09-24 17:59:23 +02:00
co-authored by Claude Opus 5.5
parent ee2bb9d03c
commit 22bb8c672b
41 changed files with 336 additions and 99 deletions
+86
View File
@@ -0,0 +1,86 @@
import { Chip, Zustandsfeld } from "@/components/cockpit/Chip"
import { Panel } from "@/components/cockpit/Panel"
import { useInstanz, usePartner } from "@/lib/abfragen"
import type { PartnerStatus } from "@/lib/typen"
/** Was der Homelab-Teil übernimmt (Bestandsaufnahme vom 24.09.2026; ab Phase 3 kommt die Liste live). */
const GERAETE = ["Proxmox-Host", "AdGuard", "NPMplus", "NetBird", "PVE Scripts Local", "Gitea", "PBS", "Arcane mit Docker"]
function Verbindung({ partner }: { partner: PartnerStatus }) {
if (partner.erreichbar) {
return (
<>
<p className="text-[15px] text-text-2">
{partner.instanz ?? partner.name} antwortet{partner.version ? ` (Version ${partner.version})` : ""}. Die
Übersicht der Geräte mit ihren Updates folgt als Nächstes.
</p>
<p className="ziffern text-sm text-text-3">{partner.url}</p>
</>
)
}
return (
<p role="alert" className="text-[15px] text-rot-text">
Der Homelab-Teil ({partner.url}) ist {partner.fehler ?? "nicht erreichbar"}. Hält das an, meldet der Wächter es
nach fünf Minuten auf Telegram.
</p>
)
}
function NochNichtEingerichtet() {
return (
<>
<p className="text-[15px] text-text-2">
Der Homelab-Teil läuft als eigene Instanz in einem kleinen Container auf dem Proxmox-PC. Von dort prüft er
auch die KI-Box von außen.
</p>
<p className="text-[15px] text-text-2">
Steht er, zeigt diese Seite alle Geräte mit ihren offenen Updates. Ein Update startest du dann hier mit
„Jetzt updaten“: Vorher wird gesichert, danach die Erreichbarkeit geprüft, und ist sie rot, geht es von selbst
zurück.
</p>
<div className="flex flex-col gap-2">
<h3 className="schild text-sm tracking-[0.18em] text-text-3">Dazu kommen</h3>
<ul className="flex flex-wrap gap-2">
{GERAETE.map((g) => (
<li key={g}>
<Chip>{g}</Chip>
</li>
))}
</ul>
</div>
<p className="text-sm text-text-3">Der Container wird erst nach deiner Freigabe angelegt.</p>
</>
)
}
export function HomelabSeite() {
const instanz = useInstanz()
const partner = usePartner()
if (instanz.isPending || partner.isPending) return <Zustandsfeld text="Wird gelesen …" />
if (!partner.data) {
return <Zustandsfeld fehler text={`Der Stand des Homelab-Teils lässt sich nicht lesen: ${partner.error?.message ?? "keine Daten"}`} />
}
// Liefert der Homelab-Teil die Seite selbst aus, ist die Box sein Partner (ab Phase 3).
if (instanz.data?.rolle === "homelab") {
return (
<Panel titel="Homelab" rechts={<Chip art="gruen">Diese Instanz</Chip>}>
<p className="text-[15px] text-text-2">Diese Seite kommt vom Homelab-Teil auf dem Proxmox-PC.</p>
</Panel>
)
}
const p = partner.data
const chip = !p.eingerichtet
? <Chip>Noch nicht eingerichtet</Chip>
: p.erreichbar
? <Chip art="gruen">Verbunden</Chip>
: <Chip art="rot">Antwortet nicht</Chip>
return (
<Panel titel="Homelab" rechts={chip}>
{p.eingerichtet ? <Verbindung partner={p} /> : <NochNichtEingerichtet />}
</Panel>
)
}