import type { Metadata } from 'next'; import { AdminFilters, AdminTitle, JsonPre, Mono, Notice } from '@/components/admin/ui'; import { DataTable, EmptyRow, Td, Th } from '@/components/ui/data-table'; import { LiveAgo } from '@/components/ui/live'; import { Pagination, withParams } from '@/components/ui/pagination'; import { Note } from '@/components/ui/section'; import { EmptyState, Unavailable } from '@/components/ui/unavailable'; import { adminApi, load, requireAdmin } from '@/lib/admin/admin-api'; import { cn } from '@/lib/cn'; import { fmtDateTime, fmtInt } from '@/lib/format'; export const metadata: Metadata = { title: 'Audit log', robots: { index: false, follow: false } }; export const dynamic = 'force-dynamic'; const LIMIT = 50; export default async function AdminAuditPage({ searchParams }: { searchParams: Promise> }) { await requireAdmin(); const sp = await searchParams; const current: Record = {}; if (sp.action) current.action = sp.action; if (sp.offset) current.offset = sp.offset; const offset = Math.max(0, Number(current.offset) || 0); const href = (patch: Record) => withParams('/admin/audit', current, patch); const res = await load(adminApi.audit({ action: current.action, limit: LIMIT, offset })); return ( <> {!res.ok ? ( ) : res.data.items.length === 0 ? ( ) : ( <> When Actor Action Target Payload IP Id {res.data.items.length === 0 && No rows.} {res.data.items.map((r) => { const mutating = !r.action.startsWith('GET '); return ( {r.actor} {r.action} {r.target ? {r.target} : —} {r.payload ? (
{r.payload.method ? `${String(r.payload.method)} ${String(r.payload.path ?? '')}` : 'payload'}
) : ( — )} {r.ip ?? '—'} {String(r.id)} ); })}
href({ offset: o || undefined })} className="mt-4" /> )} Rows are append-only; this page itself is not logged (polling GET). ); }