import type { Metadata } from 'next' import { db } from '@/lib/db' import { requirePermission } from '@/lib/auth/current' import { de } from '@/lib/i18n/de' import { resolveAll, type LadderRung } from '@/lib/auth/ladders' import { RoleRow } from './RoleRow' import { ClearancePreview } from './ClearancePreview' export const metadata: Metadata = { title: de.roleAdmin.heading } export const dynamic = 'force-dynamic' /** * Reihenfolge der Abschnitte: erst die Ränge, dann die Zugehörigkeit, dann die * Zugangsrollen - so, wie die Abteilung sie selbst aufzählt. Innerhalb eines * Abschnitts entscheidet die Position der Rolle auf dem Discord-Server, oben * die höchste. Damit steht die Hierarchie an einer Stelle, die ohnehin gepflegt * wird, statt in einer zweiten Sortierung in dieser Anwendung. */ const ORDER = ['RANK', 'MEMBERSHIP', 'CLEARANCE', 'UNSORTED'] as const export default async function RoleAdminPage() { // Ohne roles.manage gibt es 404, nicht 403. await requirePermission('roles.manage') const [mappings, levels, ladders] = await Promise.all([ db.roleMapping.findMany({ orderBy: [{ sortOrder: 'desc' }, { label: 'asc' }] }), db.clearanceLevelConfig.findMany({ orderBy: { level: 'asc' } }), db.roleLadder.findMany({ select: { id: true, name: true } }), ]) // Was jede Rolle **tatsächlich** gewährt, einschliesslich ihres Ranggefüges. // Ohne das zeigte diese Seite die eigene Zeile und die Vorschau eine Stufe, // die für niemanden gilt - siehe lib/auth/ladders.ts. const aufgeloest = resolveAll(mappings as LadderRung[]) const ladderName = new Map(ladders.map((leiter) => [leiter.id, leiter.name])) return (

{de.roleAdmin.heading}

{de.roleAdmin.intro}

{mappings.length === 0 ? (

{de.roleAdmin.empty}

) : ( <> ({ label: m.label, clearanceLevel: aufgeloest.get(m.discordRoleId)?.clearanceLevel ?? m.clearanceLevel, }))} /> {ORDER.map((category) => { const rows = mappings.filter((m) => m.category === category) if (rows.length === 0) return null return (

{de.roleAdmin.categories[category]}

{rows.map((role) => ( ({ level: l.level, name: l.name }))} /> ))}
) })} )}
) }