import { AlertTriangle, Ban, Clock, Gavel, Radio, Shield, User } from 'lucide-react' import Link from 'next/link' import { redirect } from 'next/navigation' import { StatsCard } from '@/components/admin/stats-card' import { Badge } from '@/components/ui/badge' import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card' import { canAccess, getAdminContext, PERMS } from '@/lib/permissions' import { prisma } from '@/lib/prisma' const CFH_STATES: Record = { 0: { label: 'Open', class: 'bg-[var(--admin-error-subtle)] text-[var(--admin-error)]' }, 1: { label: 'Picked', class: 'bg-[var(--admin-warning-subtle)] text-[var(--admin-warning)]' }, 2: { label: 'Closed', class: 'bg-muted text-muted-foreground' }, } export default async function ModerationDashboard() { const { session, permissions } = await getAdminContext() if (!canAccess(permissions, PERMS.MODERATION_VIEW, session.user.rank)) redirect('/admin') const now = Math.floor(Date.now() / 1000) const todayStart = now - (now % 86400) const [openCfh, pickedCfh, todayBans, modsOnline, recentCfh, recentModActions] = await Promise.all([ prisma.supportTickets.count({ where: { state: 0 } }), prisma.supportTickets.count({ where: { state: 1 } }), prisma.ban.count({ where: { timestamp: { gte: todayStart } } }), prisma.user.count({ where: { online: '1', rank: { gte: 4 } } }), prisma.supportTickets.findMany({ orderBy: { id: 'desc' }, take: 10, }), prisma.adminAuditLog.findMany({ where: { action: { startsWith: 'mod_' }, }, orderBy: { id: 'desc' }, take: 10, include: { user: { select: { username: true } } }, }), ]) // Fetch usernames for CFH tickets const userIds = [ ...new Set([ ...recentCfh.map((t) => t.senderId), ...recentCfh.map((t) => t.reportedId), ...recentCfh.map((t) => t.modId), ]), ].filter(Boolean) const users = userIds.length > 0 ? await prisma.user.findMany({ where: { id: { in: userIds } }, select: { id: true, username: true }, }) : [] const userMap = new Map(users.map((u) => [u.id, u.username])) return (

Moderation

In-game moderation dashboard

{/* Stats */}
} href="/admin/moderation/cfh" /> } href="/admin/bans" /> } href="/admin/moderation/team" /> } href="/admin/moderation/actions" />
{/* Recent CFH */} Recent CFH Tickets View all {recentCfh.length === 0 ? (

No CFH tickets

) : (
{recentCfh.map((ticket) => { const state = CFH_STATES[ticket.state] ?? CFH_STATES[0] return ( #{ticket.id}

{ticket.issue || 'No description'}

{userMap.get(ticket.senderId) ?? '?'} →{' '} {userMap.get(ticket.reportedId) ?? '?'}

{state.label} ) })}
)}
{/* Recent Mod Actions */} Recent Mod Actions {recentModActions.length === 0 ? (

No recent actions

) : (
{recentModActions.map((log) => (

{log.action.replace('mod_', '').replace(/_/g, ' ')}

by {log.user?.username ?? '?'} · {log.target}{' '} {log.targetId ? `#${log.targetId}` : ''}

{log.createdAt}
))}
)}
) }