import Link from "next/link"; import { ContentHeader } from "@/components/layout/ContentHeader"; import { AblaufBadge, EinkaufBadge, VerkaufBadge } from "@/components/ui/Badges"; import { Card } from "@/components/ui/Card"; import { CopyableCode } from "@/components/ui/CopyableCode"; import { formatDatum, formatTageBis } from "@/lib/format"; import { ablaufDaten } from "@/server/queries/jahresbahn"; export const metadata = { title: "Jahresbahn" }; const MONATE = ["Jan", "Feb", "Mär", "Apr", "Mai", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dez"]; const GESAMT_TAGE = 365; export default async function JahresbahnSeite() { const jetzt = new Date(); const { gruppen, naechste90Tage, abgelaufen } = await ablaufDaten(jetzt); // Die Bahn beginnt am Ersten des laufenden Monats und zeigt zwölf Monate. const start = new Date(Date.UTC(jetzt.getUTCFullYear(), jetzt.getUTCMonth(), 1)); function position(datum: Date): number | null { const tage = Math.round((datum.getTime() - start.getTime()) / 86_400_000); if (tage < 0 || tage > GESAMT_TAGE) return null; return (tage / GESAMT_TAGE) * 100; } const heutePosition = position(jetzt) ?? 0; const monate = Array.from({ length: 12 }, (_, i) => { const datum = new Date(Date.UTC(start.getUTCFullYear(), start.getUTCMonth() + i, 1)); return `${MONATE[datum.getUTCMonth()]} ${String(datum.getUTCFullYear()).slice(2)}`; }); return ( <>
{gruppen.length === 0 ? (

Noch kein Host mit Ablaufdatum gemeldet.

) : (
{monate.map((monat) => (
{monat}
))}
{gruppen.map((gruppe) => (
{gruppe.kundeId ? ( {gruppe.name} ) : ( {gruppe.name} )}
{gruppe.eintraege.map((eintrag) => { const links = position(eintrag.ablauf); const farbe = eintrag.tage < 14 ? "var(--pl-danger)" : eintrag.tage < 30 ? "var(--pl-warning)" : "var(--pl-info)"; return (
{eintrag.hostname}
{links === null ? ( außerhalb des Zeitraums ({formatDatum(eintrag.ablauf)}) ) : ( {formatDatum(eintrag.ablauf)} )}
); })}
))}
)}

Seitwärts wischen zeigt die späteren Monate. Die rote Linie markiert heute ({formatDatum(jetzt)}). Balkenfarbe: rot unter 14 Tagen, gelb unter 30 Tagen, sonst blau. Ein Klick führt zur Laufzeit mit ihren Rechnungen.

{naechste90Tage.map((eintrag) => ( ))} {naechste90Tage.length === 0 ? ( ) : null}
Host Ablauf Kunde Key Proxmox Kundenrechnung
{eintrag.hostname} {eintrag.kunde ? ( {eintrag.kunde.name} ) : ( Nicht zugeordnet )}
In den nächsten 90 Tagen läuft nichts ab.
0 ? "danger" : "info"} > {abgelaufen.length === 0 ? (

Keine abgelaufenen Subscriptions.

) : (
    {abgelaufen.map((eintrag) => (
  • {eintrag.hostname}
    {eintrag.kunde?.name ?? "Nicht zugeordnet"} · {formatDatum(eintrag.ablauf)} ( {formatTageBis(eintrag.tage)})
  • ))}
)}
); }