// Permissions.jsx — Role × Feature access matrix function PermissionsPage() { const features = [ { id: 'dashboard', label: 'Dashboard' }, { id: 'workorders', label: 'Work Orders' }, { id: 'create', label: 'Create Work Order' }, { id: 'mobile', label: 'Mobile Job View' }, { id: 'completion', label: 'Job Completion' }, { id: 'notifications', label: 'Notifications' }, { id: 'repairs', label: 'Repair Tickets' }, { id: 'analytics', label: 'Analytics' }, { id: 'export', label: 'AutoCount Export' }, { id: 'users', label: 'User Management' }, { id: 'settings', label: 'Settings' }, { id: 'permissions', label: 'Role Permissions' }, ]; const cellStyle = (lvl) => { if (lvl === 'edit') return { background: 'rgba(34,197,94,0.12)', color: '#15803d' }; if (lvl === 'view') return { background: 'rgba(37,99,235,0.10)', color: '#1d4ed8' }; return { background: 'rgba(148,163,184,0.12)', color: '#64748b' }; }; const cellLabel = (lvl) => lvl === 'edit' ? 'Edit' : lvl === 'view' ? 'View' : '—'; return (
| Feature | {ROLES.map(r => ({r} | ))}
|---|---|
| {f.label} | {ROLES.map(r => { const lvl = can(r, f.id); return ({cellLabel(lvl)} | ); })}
permissions.json so the two never drift.