97 lines
3.9 KiB
TypeScript
97 lines
3.9 KiB
TypeScript
import { useRouterState } from "@tanstack/react-router"
|
|
import {
|
|
Activity, Cpu, Gauge, LayoutGrid, type LucideIcon, RefreshCw, ScrollText, Settings,
|
|
} from "lucide-react"
|
|
import { useBoxZiele, useHomelab, useInstanz, usePartner } from "@/lib/abfragen"
|
|
import { offeneUpdates } from "@/lib/homelab"
|
|
import { useStromLage } from "@/lib/strom"
|
|
|
|
// Oben die Übersicht über alles, darunter zwei sauber getrennte Bereiche — die KI-Box (Box-Wart) und das
|
|
// Homelab (Proxmox-PC) —, jeder mit eigenen Seiten und eigener Verbindungsanzeige, unten die Einstellungen.
|
|
|
|
export type Bereich = "box" | "homelab"
|
|
export type Ort = Bereich | "uebersicht" | "system"
|
|
|
|
export const BEREICHE: { id: Bereich; name: string }[] = [
|
|
{ id: "box", name: "KI-Box" },
|
|
{ id: "homelab", name: "Homelab" },
|
|
]
|
|
|
|
export type SeitenPfad =
|
|
| "/" | "/box" | "/box/updates" | "/box/modelle" | "/box/monitoring"
|
|
| "/homelab" | "/homelab/updates" | "/homelab/monitoring" | "/homelab/protokoll" | "/einstellungen"
|
|
|
|
export interface Seite {
|
|
to: SeitenPfad
|
|
label: string
|
|
Icon: LucideIcon
|
|
ort: Ort
|
|
/** Zeigt die Zahl offener Updates des Bereichs. */
|
|
zaehlt?: boolean
|
|
}
|
|
|
|
export const SEITEN: Seite[] = [
|
|
{ to: "/", label: "Übersicht", Icon: LayoutGrid, ort: "uebersicht" },
|
|
{ to: "/box", label: "Cockpit", Icon: Gauge, ort: "box" },
|
|
{ to: "/box/updates", label: "Updates", Icon: RefreshCw, ort: "box", zaehlt: true },
|
|
{ to: "/box/modelle", label: "Modelle", Icon: Cpu, ort: "box" },
|
|
{ to: "/box/monitoring", label: "Monitoring", Icon: Activity, ort: "box" },
|
|
{ to: "/homelab", label: "Cockpit", Icon: Gauge, ort: "homelab" },
|
|
{ to: "/homelab/updates", label: "Updates", Icon: RefreshCw, ort: "homelab", zaehlt: true },
|
|
{ to: "/homelab/monitoring", label: "Monitoring", Icon: Activity, ort: "homelab" },
|
|
{ to: "/homelab/protokoll", label: "Protokoll", Icon: ScrollText, ort: "homelab" },
|
|
{ to: "/einstellungen", label: "Einstellungen", Icon: Settings, ort: "system" },
|
|
]
|
|
|
|
/** Was über dem Seitentitel steht. */
|
|
export const ORT_NAME: Record<Ort, string> = {
|
|
uebersicht: "Auf einen Blick",
|
|
box: "KI-Box",
|
|
homelab: "Homelab",
|
|
system: "Beide Instanzen",
|
|
}
|
|
|
|
export const bereichName = (b: Bereich) => BEREICHE.find((x) => x.id === b)?.name ?? b
|
|
|
|
/** Welche Seite gerade offen ist — für die Überschrift oben. */
|
|
export function useAktuelleSeite(): Seite {
|
|
const pfad = useRouterState({ select: (s) => s.location.pathname }).replace(/\/+$/, "") || "/"
|
|
return SEITEN.find((s) => s.to === pfad) ?? SEITEN[0]
|
|
}
|
|
|
|
export type Verbindung = "online" | "verbinde" | "getrennt" | "fehlt"
|
|
|
|
export interface BereichStand {
|
|
verbindung: Verbindung
|
|
/** Updates, die per Knopf bereitstehen. */
|
|
updates: number
|
|
}
|
|
|
|
/**
|
|
* Verbindung und offene Updates je Bereich. Die Instanz, die die Seite ausliefert, meldet sich über den
|
|
* Live-Strom; die andere über die Partner-Prüfung (/api/partner).
|
|
*/
|
|
export function useBereichStand(): Record<Bereich, BereichStand> {
|
|
const instanz = useInstanz()
|
|
const partner = usePartner()
|
|
const strom = useStromLage()
|
|
const hier: Bereich = instanz.data?.rolle === "homelab" ? "homelab" : "box"
|
|
const eigen: Verbindung = strom === "live" ? "online" : strom
|
|
const p = partner.data
|
|
const fremd: Verbindung = !p ? "verbinde" : !p.eingerichtet ? "fehlt" : p.erreichbar ? "online" : "getrennt"
|
|
const verbindung: Record<Bereich, Verbindung> = hier === "box"
|
|
? { box: eigen, homelab: fremd }
|
|
: { box: fremd, homelab: eigen }
|
|
|
|
const box = useBoxZiele()
|
|
const homelab = useHomelab(verbindung.homelab === "online")
|
|
const boxUpdates = (box.data?.ziele ?? []).reduce(
|
|
(n, z) => n + z.bausteine.filter((b) => b.zustand === "neu" && b.aktion).length, 0,
|
|
)
|
|
const homelabUpdates = offeneUpdates(homelab.data?.ziele ?? []).filter((u) => u.baustein.aktion).length
|
|
return {
|
|
box: { verbindung: verbindung.box, updates: boxUpdates },
|
|
homelab: { verbindung: verbindung.homelab, updates: homelabUpdates },
|
|
}
|
|
}
|