"use client"; import { useState } from "react"; import { fetchRecords, exportURL, type AuditRecord, type AuditFilter } from "@/lib/api"; const EMPTY_FILTER: AuditFilter = { tenant: "", actor: "", action: "", from: "", to: "" }; export default function Page() { const [caller, setCaller] = useState(""); const [filter, setFilter] = useState(EMPTY_FILTER); const [records, setRecords] = useState(null); const [selected, setSelected] = useState(null); const [error, setError] = useState(null); async function onSearch() { setError(null); setSelected(null); try { const data = await fetchRecords(caller.trim(), filter); setRecords(data); } catch (e: any) { setError(e.message ?? "Unbekannter Fehler"); setRecords(null); } } function onExport(format: "csv" | "json") { const url = exportURL(caller.trim(), filter, format); // Echter Datei-Download ueber Browser-Navigation, KEIN erneutes Parsen // im Frontend (Akzeptanzkriterium 2: Export aus AUD-03 direkt ausloesbar). window.open(url, "_blank"); } return (

Audit-Log

setCaller(e.target.value)} placeholder="Admin-Token (Berechtigung)" style={{ padding: "0.5rem", gridColumn: "span 3" }} /> setFilter({ ...filter, tenant: e.target.value })} placeholder="Tenant" style={{ padding: "0.5rem" }} /> setFilter({ ...filter, actor: e.target.value })} placeholder="Akteur" style={{ padding: "0.5rem" }} /> setFilter({ ...filter, action: e.target.value })} placeholder="Aktion" style={{ padding: "0.5rem" }} />
{error && (

Fehler: {error}

)} {records && ( {records.map((r, i) => ( ))} {records.length === 0 && ( )}
Zeitpunkt Tenant Akteur Aktion
{new Date(r.occurred_at).toLocaleString("de-DE")} {r.tenant_slug} {r.actor} {r.action}
Keine Einträge gefunden.
)} {selected && (

Eintrag-Details

Zeitpunkt
{new Date(selected.occurred_at).toLocaleString("de-DE")}
Tenant
{selected.tenant_slug}
Akteur
{selected.actor}
Aktion
{selected.action}
Ziel
{selected.target}
Metadaten
                {JSON.stringify(selected.metadata, null, 2)}
              
)}
); }