import { createBan, liftBan } from "@/actions/admin-bans"; import { StatusCard } from "@/components/admin/dashboard"; import { prisma } from "@/lib/prisma"; export const dynamic = "force-dynamic"; function fromUnix(ts: number): string { return new Date(ts * 1000).toISOString().slice(0, 16).replace("T", " "); } export default async function AdminBans() { const now = Math.floor(Date.now() / 1000); let bans: Awaited> = []; try { bans = await prisma.ban.findMany({ where: { banExpire: { gt: now } }, orderBy: { timestamp: "desc" }, take: 100, }); } catch { bans = []; } // banExpire of 0 means permanent in the emulator schema. const permanent = bans.filter((b) => b.banExpire === 0).length; const accountBans = bans.filter((b) => b.type === "account").length; return (

Bans

Active bans only (expiry in the future) ยท newest first.

0 ? "warn" : "ok"} icon="๐Ÿ”จ" /> 0 ? "danger" : "neutral"} icon="โ›”" />

New ban

Active bans ({bans.length})

{bans.length === 0 ? (

No active bans.

) : (
{bans.map((b) => ( ))}
User ID Type Reason Expires
{b.userId} {b.type} {b.banReason || "โ€”"} {b.banExpire === 0 ? ( permanent ) : ( {fromUnix(b.banExpire)} )}
)}
); }