"use client"; import { useState } from "react"; import { fetchOverview, toggleFlag, type Overview } from "@/lib/api"; const STATUS_LABEL: Record = { ok: "In Ordnung", warning: "Nahe am Limit", exceeded: "Limit überschritten", }; const STATUS_COLOR: Record = { ok: "#2e7d32", warning: "#ed6c02", exceeded: "#c62828", }; export default function Page() { const [tenantId, setTenantId] = useState(""); const [overview, setOverview] = useState(null); const [loading, setLoading] = useState(false); const [error, setError] = useState(null); const [toggleError, setToggleError] = useState(null); async function load() { if (!tenantId.trim()) return; setLoading(true); setError(null); try { const data = await fetchOverview(tenantId.trim()); setOverview(data); } catch (e: any) { setError(e.message ?? "Unbekannter Fehler"); setOverview(null); } finally { setLoading(false); } } async function onToggle(key: string, next: boolean) { setToggleError(null); try { await toggleFlag(tenantId.trim(), key, next); await load(); } catch (e: any) { setToggleError(e.message ?? "Umschalten fehlgeschlagen"); } } return (

Lizenz- und Modulverwaltung

setTenantId(e.target.value)} placeholder="Tenant-ID eingeben" aria-label="Tenant-ID eingeben" style={{ flex: 1, padding: "0.5rem", fontSize: "1rem" }} />
{error && (

Fehler: {error}

)} {overview && ( <>

Lizenzstatus

Plan: {overview.plan}{" "} {overview.expired && ( (abgelaufen) )}

Gültig bis:{" "} {new Date(overview.valid_until).toLocaleDateString("de-DE")}

Freigeschaltete Module:{" "} {overview.modules.length > 0 ? overview.modules.join(", ") : "keine"}

Feature-Flags

{toggleError && (

{toggleError}

)} {overview.flags.length === 0 &&

Keine Feature-Flags definiert.

}
    {overview.flags.map((f) => (
  • {f.key}
    {!f.licensed && f.deny_grund && (
    {f.deny_grund}
    )}
  • ))}

Nutzungsstand

{overview.usage.map((u) => { const pct = u.limit > 0 ? Math.min(100, (u.value / u.limit) * 100) : 0; return (
{u.metric} {u.value} / {u.limit > 0 ? u.limit : "unbegrenzt"} —{" "} {STATUS_LABEL[u.status]}
0 ? pct : 0}%`, background: STATUS_COLOR[u.status], height: "100%", }} />
); })}
)}
); }