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 (
<PageContainer className="max-w-5xl space-y-4 py-6">
<div className="flex flex-wrap items-center justify-between gap-2">
<Heading>Admin audit log</Heading>
<div className="flex gap-3">
<TextLink to="/admin/abuse">Abuse queue</TextLink>
<TextLink to="/admin">Back to site admin</TextLink>