"use client"; import { useEffect, useState } from "react"; import { listApiKeys, createApiKey, revokeApiKey, type ApiKeyRecord } from "@/lib/apiKeys"; import { Card } from "@/components/ui/Card"; import { Button } from "@/components/ui/Button"; import { Badge } from "@/components/ui/Badge"; import { EmptyState } from "@/components/ui/EmptyState"; function fmtDate(iso: string) { return new Date(iso).toLocaleDateString("en-US", { month: "short", day: "numeric", year: "numeric" }); } function CreateKeyModal({ onClose, onCreated }: { onClose: () => void; onCreated: (r: ApiKeyRecord) => void }) { const [name, setName] = useState(""); const [saving, setSaving] = useState(false); const [rawKey, setRawKey] = useState(null); const [copied, setCopied] = useState(false); async function handleSubmit(e: React.FormEvent) { e.preventDefault(); setSaving(true); try { const { record, rawKey } = await createApiKey(name); onCreated(record); setRawKey(rawKey); } finally { setSaving(false); } } function copy() { if (!rawKey) return; navigator.clipboard?.writeText(rawKey).then(() => { setCopied(true); setTimeout(() => setCopied(false), 2000); }); } if (rawKey) { return (

Key created

Copy this key now — it won't be shown again. This is a sample key from the demo module in{" "} lib/apiKeys.ts; it doesn't authenticate against anything.

{rawKey}

); } return (

New API key

setName(e.target.value)} placeholder="e.g. Ops dashboard integration" className="w-full bg-gray-800 border border-gray-700 rounded-lg px-3 py-2 text-white text-sm focus:outline-none focus:border-indigo-500" />
); } export default function ApiKeysSettingsPage() { const [keys, setKeys] = useState([]); const [loading, setLoading] = useState(true); const [showCreate, setShowCreate] = useState(false); useEffect(() => { listApiKeys().then(setKeys).finally(() => setLoading(false)); }, []); async function handleRevoke(id: string) { await revokeApiKey(id); setKeys((prev) => prev.map((k) => (k.key_id === id ? { ...k, revoked: true } : k))); } const active = keys.filter((k) => !k.revoked); return (

Preview feature

Organization API keys aren't backed by a real endpoint yet — this screen runs against an in-memory demo module (lib/apiKeys.ts) so the flow can be reviewed end to end. See that file for the exact backend routes a real integration needs.

{showCreate && ( setShowCreate(false)} onCreated={(r) => setKeys((prev) => [...prev, r])} /> )}

{loading ? "Loading…" : `${active.length} active key${active.length !== 1 ? "s" : ""}`}

{!loading && keys.length === 0 ? ( ) : ( {keys.map((k) => ( ))}
Label Key Created Last used Status
{k.name} {k.key_prefix}… {fmtDate(k.created_at)} {k.last_used_at ? fmtDate(k.last_used_at) : "Never"} {k.revoked ? Revoked : Active} {!k.revoked && ( )}
)}
); }