Files
mission-control-v2/frontend/src/components/cockpit/Geraetesymbol.tsx
T
HitonabiandClaude Opus 5.5 d524e03c68 design v5: echte Logos der Dienste (selfh.st/icons, CC BY 4.0)
181 gängige Homelab-Dienste als SVG unter /logos (440 KB), geladen mit
frontend/scripts/logos_laden.py (User-Ja 25.09.2026). 33 davon in der hellen
Variante, weil das Standard-Logo auf dem dunklen Grund verschwände (gemessen:
jedes Logo auf den Kachelgrund gezeichnet). Das Gerätesymbol zeigt das Logo,
wo es eines gibt (Name, feste Zuordnung für NPMplus, PBS, PVE Scripts), sonst
das gezeichnete Symbol; mit Logo wird die Kachel neutral, nur der Rand trägt
den Bereich. KI-Box: Ubuntu, llama.cpp, Hermes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 15:32:00 +02:00

58 lines
2.3 KiB
TypeScript

import { cn } from "cn"
import { type Geraetebild, PUNKT, type Punktzustand } from "@/lib/geraetebild"
// Kachel in der Farbe des Bereichs; Zustände trägt nur der Punkt (grün/bernstein/rot/cyan) — nie das Bild.
// Mit echtem Logo wird die Kachel neutral (sonst färbte das Violett die Markenfarben), nur der Rand behält den Bereich.
const BEREICH = {
box: "from-box/30 to-box/[0.05] ring-box/35 text-box-text",
homelab: "from-lab/30 to-lab/[0.05] ring-lab/35 text-lab-text",
} as const
const LOGO_KACHEL = {
box: "from-white/[0.1] to-white/[0.03] ring-box/30",
homelab: "from-white/[0.1] to-white/[0.03] ring-lab/30",
} as const
const LEUCHTEN = {
box: "shadow-[0_0_28px_-6px_var(--box)]",
homelab: "shadow-[0_0_28px_-6px_var(--lab)]",
} as const
const GROESSE = {
sm: { kachel: "size-8 rounded-[10px]", icon: "size-4", logo: "size-5", punkt: "size-2.5" },
md: { kachel: "size-10 rounded-xl", icon: "size-5", logo: "size-6", punkt: "size-2.5" },
lg: { kachel: "size-12 rounded-2xl", icon: "size-6", logo: "size-7", punkt: "size-3" },
} as const
/**
* Das Bild eines Geräts oder Dienstes als kleine Kachel — das echte Logo, wo es eines gibt, sonst ein Symbol —,
* optional mit Zustandspunkt unten rechts. Rein schmückend (aria-hidden): Name und Zustand stehen daneben als Text.
*/
export function Geraetesymbol({ bild, groesse = "md", punkt, leuchtet = false, className }: {
bild: Geraetebild
groesse?: keyof typeof GROESSE
punkt?: Punktzustand | null
/** Weicher Schein in der Bereichsfarbe — für die großen Kacheln im Kopf der Bereichskarten. */
leuchtet?: boolean
className?: string
}) {
const g = GROESSE[groesse]
return (
<span
aria-hidden
className={cn(
"relative inline-flex shrink-0 items-center justify-center bg-gradient-to-br ring-1 ring-inset",
bild.logo ? LOGO_KACHEL[bild.bereich] : BEREICH[bild.bereich], g.kachel, leuchtet && LEUCHTEN[bild.bereich],
className,
)}
>
{bild.logo
? <img src={`/logos/${bild.logo}.svg`} alt="" className={cn("object-contain", g.logo)} loading="lazy" draggable={false} />
: <bild.Icon className={g.icon} strokeWidth={1.75} />}
{punkt && (
<span className={cn("absolute -right-0.5 -bottom-0.5 rounded-full ring-2 ring-[#0b0f16]", g.punkt, PUNKT[punkt])} />
)}
</span>
)
}