import { useMemo, useState } from "react"; import { useQuery } from "@tanstack/react-query"; import { useAuth } from "../auth/AuthContext"; import { useI18n } from "../i18n"; import { apiGet } from "../services/api"; import { formatSystemTime } from "../utils/time"; type AuditItem = { id: string; ts: string | null; actor_username: string; action: string; method: string; path: string; status_code: number; client_ip: string; detail: Record; }; function statusClass(code: number): string { if (code >= 500) return "pt-list-status--failed"; if (code >= 400) return "pt-list-status--warning"; if (code >= 200 && code < 300) return "pt-list-status--ok"; return "pt-list-status--other"; } export function AuditPage() { const { t } = useI18n(); const { ready, isAdmin } = useAuth(); const [page, setPage] = useState(1); const [username, setUsername] = useState(""); const [action, setAction] = useState(""); const query = useQuery({ queryKey: ["auditLogs", page, username, action], queryFn: () => { const p = new URLSearchParams(); p.set("page", String(page)); p.set("page_size", "50"); if (username.trim()) p.set("username", username.trim()); if (action.trim()) p.set("action", action.trim()); return apiGet<{ total: number; page: number; page_size: number; items: AuditItem[] }>( `/v1/audit-logs?${p.toString()}`, ); }, enabled: ready, }); const items = useMemo(() => query.data?.items || [], [query.data]); const total = query.data?.total || 0; const pages = Math.max(1, Math.ceil(total / 50)); const hasFilters = Boolean(username.trim() || action.trim()); return (

{t("audit.logsTitle")}

{isAdmin ? t("auth.auditHintAdmin") : t("auth.auditHintUser")}

{isAdmin ? ( { setPage(1); setUsername(e.target.value); }} /> ) : null} { setPage(1); setAction(e.target.value); }} />
{query.isLoading ?

{t("common.refreshing")}

: null} {!items.length && !query.isLoading ? (

{t("common.empty")}

) : (
{items.map((row) => ( ))}
{t("auth.colTime")} {t("auth.colUser")} {t("auth.colAction")} {t("auth.colMethod")} {t("auth.colPath")} {t("auth.colStatus")} {t("auth.colIp")}
{row.ts ? formatSystemTime(row.ts) : t("common.empty")} {row.actor_username || t("common.empty")} {row.action} {row.method} {row.path} {row.status_code} {row.client_ip || t("common.empty")}
)}
{t("common.pagerMeta", { total: String(total), page: String(page), pages: String(pages), })}
); }