40 lines
1.2 KiB
TypeScript
40 lines
1.2 KiB
TypeScript
import { EmptyState } from '@/components/ui';
|
|
import { requireAdmin } from '@/lib/server/auth';
|
|
import { db } from '@/lib/server/db';
|
|
import { formatDate } from '@/lib/utils';
|
|
import { t } from '@/lib/i18n';
|
|
|
|
export const dynamic = 'force-dynamic';
|
|
|
|
export default async function AdminAuditPage() {
|
|
await requireAdmin();
|
|
const entries = await db.auditLog.findMany({
|
|
orderBy: { createdAt: 'desc' },
|
|
take: 100,
|
|
include: { actor: true },
|
|
});
|
|
|
|
return (
|
|
<div className="space-y-6">
|
|
<h1 className="text-2xl font-bold">{t('admin.audit')}</h1>
|
|
{entries.length === 0 ? (
|
|
<EmptyState />
|
|
) : (
|
|
<ul className="divide-y rounded-xl border" style={{ borderColor: 'var(--border)' }}>
|
|
{entries.map((e) => (
|
|
<li key={e.id} className="flex items-center justify-between gap-4 px-4 py-3 text-sm">
|
|
<span>
|
|
<span className="font-medium">{e.action}</span>
|
|
{e.target ? <span className="muted"> → {e.target}</span> : null}
|
|
</span>
|
|
<span className="muted shrink-0 text-xs">
|
|
{e.actor?.email ?? 'system'} · {formatDate(e.createdAt)}
|
|
</span>
|
|
</li>
|
|
))}
|
|
</ul>
|
|
)}
|
|
</div>
|
|
);
|
|
}
|