import { createFileRoute, notFound } from "@tanstack/react-router"; import { z } from "zod"; import { getAdminAudit } from "~/fns/admin"; import { Badge } from "~/ui/Badge"; import { EmptyState } from "~/ui/EmptyState"; import { Heading } from "~/ui/Heading"; import { PageContainer } from "~/ui/PageContainer"; import { Panel } from "~/ui/Panel"; import { RelativeTime } from "~/ui/RelativeTime"; import { TextLink } from "~/ui/TextLink"; const PAGE_SIZE = 100; export const Route = createFileRoute("/admin/audit")({ head: () => ({ meta: [{ title: "Admin audit log ยท gitfor" }] }), validateSearch: z.object({ at: z.number().int().nonnegative().optional(), id: z.string().min(1).max(64).optional(), }), beforeLoad: ({ context }) => { if (!context.viewer?.isAdmin) throw notFound(); }, loaderDeps: ({ search }) => ({ at: search.at, id: search.id }), loader: ({ deps }) => getAdminAudit({ data: { after: deps.at !== undefined && deps.id ? { createdAt: deps.at, id: deps.id } : undefined }, }), component: AdminAuditPage, }); function AdminAuditPage() { const { entries } = Route.useLoaderData(); const last = entries.at(-1); return (
Admin audit log
Abuse queue Back to site admin
{entries.length === 0 ? ( ) : ( {entries.map((entry) => ( ))}
When Admin Action Target Reason
{entry.actor_name ? ( {entry.actor_name} ) : ( deleted )} {entry.action} {entry.target_kind}:{entry.target_id} {entry.reason}
)}
{last && entries.length >= PAGE_SIZE && ( Older entries )}
); }