diff --git a/web/components/apikeys/ApiKeysPanel.tsx b/web/components/apikeys/ApiKeysPanel.tsx index 7602fce..d8ee83f 100644 --- a/web/components/apikeys/ApiKeysPanel.tsx +++ b/web/components/apikeys/ApiKeysPanel.tsx @@ -14,6 +14,7 @@ import { useToast, } from "@/components/ui"; import { KeyLedger, LedgerSkeleton } from "./KeyLedger"; +import { KeyPosture } from "./KeyPosture"; import { CreateKeyDialog, EXPIRY_OPTIONS } from "./CreateKeyDialog"; const ROLES: Role[] = ["owner", "admin", "member"]; @@ -137,12 +138,7 @@ export function ApiKeysPanel() { return (
-
-

API Keys

-

- {count} key{count !== 1 ? "s" : ""} · {showAll ? "instance-wide" : "yours"} -

-
+

API Keys

)} + {count > 0 && } + keyLifetime(t, capDays, now)); + + const cells: { n: number; label: string; tone: string }[] = [ + { n: tokens.length, label: `key${tokens.length === 1 ? "" : "s"} listed`, tone: "text-text-primary" }, + { n: lifetimes.filter((l) => l.state === "soon").length, label: "expire within 7 days", tone: "text-warning" }, + { n: lifetimes.filter((l) => l.state === "eternal").length, label: "never expire", tone: "text-danger" }, + // Muted, not coloured: an unused key is a cleanup candidate, not an + // incident. + { n: tokens.filter((t) => !t.last_used_at).length, label: "unused since issue", tone: "text-text-secondary" }, + ]; + + return ( +
+ {cells.map((c) => ( +
+ {c.n} + {c.label} +
+ ))} +
+ ); +}