SPB Git

spb/akos

Public
1.7 KB · 25 lines tsx
1import { useSearchParams } from "react-router";2import { qs, type Debt } from "../api";3import { useFetch } from "../hooks";4import { Badge, ErrorBox, Loading } from "../components/ui";5import { DebtTable } from "../components/shared";67export default function DebtPage() {8  const [sp, setSp] = useSearchParams();9  const status = sp.get("status") ?? "open", severity = sp.get("severity") ?? "";10  const { data, error, loading, reload } = useFetch<{ debt: Debt[]; summary: { severity: string; kind: string; n: number }[] }>(`debt${qs({ status, severity })}`);11  const set = (k: string, v: string) => setSp((p) => { const n = new URLSearchParams(p); if (v) n.set(k, v); else n.delete(k); return n; });12  return (13    <div>14      <h1>Knowledge Debt</h1><p className="hint">Opaque MCP, inferred schemas, undocumented endpoints, missing snapshots, untested clients, stale contracts, unresolved licenses. Critical debt blocks verified research export.</p>15      {data && <div className="row" style={{ marginBottom: 10 }}>{data.summary.map((s) => <span key={s.severity + s.kind} className="badge"><Badge v={s.severity} /> {s.kind}: {s.n}</span>)}</div>}16      <div className="filters">17        <select aria-label="Status" value={status} onChange={(e) => set("status", e.target.value)}>{["open", "in_progress", "resolved", "accepted", "all"].map((s) => <option key={s}>{s}</option>)}</select>18        <select aria-label="Severity" value={severity} onChange={(e) => set("severity", e.target.value)}><option value="">all severities</option>{["critical", "high", "medium", "low"].map((s) => <option key={s}>{s}</option>)}</select>19      </div>20      {loading && <Loading />}<ErrorBox error={error} />21      {data && <DebtTable debt={data.debt} onChange={reload} />}22    </div>23  );24}25
Files · main
Menu

Theme