// Admin: the access log for everyone, with filters and a CSV download (phase 9). import { useEffect, useState, type FormEvent } from "react"; import { admin9Api, type AccessLogFilters, type AccessLogRow } from "../../api/admin"; import { errorText, fmtDetail, fmtTime } from "../../lib/format"; import { Notice, type Msg } from "./common"; const PAGE = 200; /** A datetime-local value as an ISO time, or undefined. */ function iso(local: string): string | undefined { if (!local) return undefined; const d = new Date(local); return Number.isNaN(d.getTime()) ? undefined : d.toISOString(); } interface Form { since: string; until: string; q: string; kind: string; ok: "" | "true" | "false"; ip: string; } const EMPTY: Form = { since: "", until: "", q: "", kind: "", ok: "", ip: "" }; function toFilters(f: Form): AccessLogFilters { const out: AccessLogFilters = {}; const since = iso(f.since); const until = iso(f.until); if (since) out.since = since; if (until) out.until = until; if (f.q.trim()) out.q = f.q.trim(); if (f.kind.trim()) out.kind = f.kind.trim(); if (f.ok) out.ok = f.ok; if (f.ip.trim()) out.ip = f.ip.trim(); return out; } export function AccessLogTab() { const [form, setForm] = useState