// Real-backend views: API keys + Playground. // Wires against /v1/admin/api-keys and /v1/chat/completions. const { useState: useStateV, useEffect: useEffectV } = React; // ─── API keys view ─────────────────────────────────────── const ApiKeysView = () => { const t = window.t; const [keys, setKeys] = useStateV([]); const [loading, setLoading] = useStateV(false); const [error, setError] = useStateV(''); const [name, setName] = useStateV(''); const [owner, setOwner] = useStateV('platform'); const [env, setEnv] = useStateV('prod'); const [lastCreated, setLastCreated] = useStateV(null); const [creating, setCreating] = useStateV(false); const load = async () => { setLoading(true); setError(''); try { const r = await fetch('/v1/admin/api-keys'); if (!r.ok) throw new Error(`HTTP ${r.status}`); const data = await r.json(); setKeys(Array.isArray(data) ? data : (data.api_keys || data.keys || [])); } catch (e) { setError(e.message); } finally { setLoading(false); } }; useEffectV(() => { load(); }, []); const create = async () => { if (!name.trim()) return; setCreating(true); setError(''); try { const r = await fetch('/v1/admin/api-keys', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ name: name.trim(), labels: { owner, env } }), }); if (!r.ok) throw new Error(`HTTP ${r.status}: ${await r.text()}`); const data = await r.json(); setLastCreated(data); setName(''); await load(); } catch (e) { setError(e.message); } finally { setCreating(false); } }; const copy = (s) => navigator.clipboard?.writeText(s); return (
{lastCreated.api_key || lastCreated.key || lastCreated.token || JSON.stringify(lastCreated)}
{data.content}