import { useCallback, useEffect, useState } from "react"; import { useApi } from "../hooks/useApi"; import type { ConfigEntry, ConfigResponse } from "../types"; import ConfigTable from "./ConfigTable"; import AddEditModal from "./AddEditModal"; import AdminPanel from "./AdminPanel"; interface Props { onLogout: () => void; addToast: (msg: string, type: "success" | "error") => void; } export default function Dashboard({ onLogout, addToast }: Props) { const api = useApi(); const [data, setData] = useState(null); const [search, setSearch] = useState(""); const [scopeFilter, setScopeFilter] = useState<"all" | "personal" | "shared">("all"); const [modal, setModal] = useState<{ key?: string; entry?: ConfigEntry } | null>(null); const [tab, setTab] = useState<"config" | "admin">("config"); const [loading, setLoading] = useState(true); const load = useCallback(async () => { try { const d = await api.getConfig(); setData(d); } catch (e: any) { addToast("Failed to load: " + e.message, "error"); if (e.message.includes("401") || e.message.includes("403")) onLogout(); } finally { setLoading(false); } }, []); useEffect(() => { load(); }, [load]); const entries = data ? Object.entries(data.secrets || {}) : []; const filtered = entries.filter(([key, entry]) => { if (search && !key.toLowerCase().includes(search.toLowerCase())) return false; if (scopeFilter !== "all" && entry.scope !== scopeFilter) return false; return true; }); const handleSave = async (key: string, value: string, scope: string, env: boolean, secret: boolean) => { try { await api.putKey(key, scope, { value, env, secret }); addToast(`Key "${key}" saved`, "success"); setModal(null); load(); } catch (e: any) { addToast("Failed: " + e.message, "error"); } }; const handleDelete = async (key: string, scope: string) => { if (!confirm(`Delete "${key}"?`)) return; try { await api.deleteKey(key, scope); addToast(`Key "${key}" deleted`, "success"); load(); } catch (e: any) { addToast("Failed: " + e.message, "error"); } }; const isAdmin = data?.role === "admin"; if (loading) { return (
Loading...
); } return (
{/* Header */}

Config Service

{isAdmin && (
)}
{data?.agent_id} {isAdmin && admin}
{tab === "config" ? ( <> {/* Toolbar */}
setSearch(e.target.value)} placeholder="Search keys..." className="flex-1 min-w-[200px] px-4 py-2.5 bg-[#12141a] border border-[#1e2030] rounded-lg text-white text-sm placeholder-[#334155] focus:outline-none focus:border-[#3b82f6] transition-colors" />
{/* Stats */}
{[ { label: "Total Keys", value: entries.length }, { label: "Shared", value: entries.filter(([, e]) => e.scope === "shared").length }, { label: "Secrets", value: entries.filter(([, e]) => e.secret).length }, ].map((s) => (
{s.value}
{s.label}
))}
{/* Table */}
setModal({ key, entry })} onDelete={handleDelete} addToast={addToast} />
) : ( )}
{modal && ( setModal(null)} /> )}
); }