'use client' import { useState, useTransition } from 'react' import { roleAdminText } from '@/lib/i18n/admin' import { OPT_IN_PERMISSIONS, PERMISSIONS, type Permission } from '@/lib/auth/permissions' import { saveRoleMapping } from './actions' export type RoleRowData = { discordRoleId: string label: string clearanceLevel: number grantsMembership: boolean category: string permissions: string[] isPresent: boolean } const CATEGORIES = ['MEMBERSHIP', 'RANK', 'CLEARANCE', 'UNSORTED'] as const /** * Eine Rolle. Bewusst nicht optimistisch: eine Änderung am Rollen-Mapping ist * folgenreich und wirkt sofort für alle. Stattdessen Bestätigungsdialog, * gesperrter Knopf mit wechselnder Beschriftung und eine klare Rückmeldung. * Siehe docs/09-performance-und-ux.md. */ export function RoleRow({ role, levels, }: { role: RoleRowData levels: { level: number; name: string }[] }) { const [clearanceLevel, setClearanceLevel] = useState(role.clearanceLevel) const [grantsMembership, setGrantsMembership] = useState(role.grantsMembership) const [category, setCategory] = useState(role.category) const [permissions, setPermissions] = useState(role.permissions) const [saved, setSaved] = useState(false) const [error, setError] = useState(null) const [pending, startTransition] = useTransition() const dirty = clearanceLevel !== role.clearanceLevel || grantsMembership !== role.grantsMembership || category !== role.category || permissions.slice().sort().join() !== role.permissions.slice().sort().join() function toggle(permission: Permission, on: boolean) { setPermissions((current) => on ? [...current, permission] : current.filter((p) => p !== permission), ) setSaved(false) } function submit() { if (!confirm(roleAdminText.confirm)) return setError(null) startTransition(async () => { const result = await saveRoleMapping({ discordRoleId: role.discordRoleId, clearanceLevel, grantsMembership, category, permissions, }) if (result.ok) { setSaved(true) } else { setError(result.error) } }) } return (

{role.label}

{role.discordRoleId} {!role.isPresent ? ( {roleAdminText.missingFromGuild} ) : null}
{roleAdminText.permissions}
{PERMISSIONS.map((permission) => { const optIn = OPT_IN_PERMISSIONS.includes(permission) return ( ) })}
{saved && !dirty ? ( {roleAdminText.saved} ) : null} {error ? {error} : null}
) }