'use client'; import React, { useState } from 'react'; import { ClubCapability, ClubCapabilityDefinition, ClubRankDefinition } from './types'; interface ClubPermissionMatrixProps { ranks: ClubRankDefinition[]; capabilities: ClubCapabilityDefinition[]; permissions: Record>; selectedRankId: string | null; onTogglePermission: (rankId: string, capability: ClubCapability) => void; onResetDefaults: () => void; onSavePermissions: () => Promise; isSaving: boolean; canEdit: boolean; } export function ClubPermissionMatrix({ ranks, capabilities, permissions, selectedRankId, onTogglePermission, onResetDefaults, onSavePermissions, isSaving, canEdit, }: ClubPermissionMatrixProps) { const [saveSuccess, setSaveSuccess] = useState(false); async function handleSave() { await onSavePermissions(); setSaveSuccess(true); setTimeout(() => setSaveSuccess(false), 2500); } return (
{/* Header */}
tune

Operational Permission Matrix

Configure delegated operational privileges per squad rank. Administrative roles enforce backend limits.

{canEdit && (
)}
{/* Desktop / Tablet Matrix Table */}
{capabilities.map((cap) => ( ))} {ranks.map((rank) => { const isSelected = selectedRankId === rank.id; const rankPerms = permissions[rank.id] || {}; return ( {capabilities.map((cap) => { const isGranted = rankPerms[cap.id] ?? false; const isImmutableOwner = rank.id === 'president'; return ( ); })} ); })}
Squad Rank
{cap.label} {cap.category}
{rank.icon}
{rank.title}
Level {rank.level}
{/* Legend & Architecture Note */}
Active Toggle: Rank delegates authority to lead and coordinate squad members.
shield Software RBAC: Owner and Admin roles enforce immutable security boundaries in Firestore.
); }