import { For, Show, createMemo, createSignal, onMount } from 'solid-js'; import { useSearchParams } from '@solidjs/router'; import AdminShell from '~/components/AdminShell'; import type { CrudRecord } from '~/lib/admin/types'; const API = '/api/gateway'; type RoleRecord = CrudRecord & { code?: string; department?: string; usersAssigned?: number; permissionsCount?: number; status: 'ACTIVE' | 'INACTIVE'; createdDate?: string; }; const FALLBACK_ROLES: RoleRecord[] = [ { id: 'r1', name: 'System Administrator', code: 'ADM-SYS', department: 'IT', usersAssigned: 12, permissionsCount: 150, status: 'ACTIVE', createdDate: '2026-01-12' }, { id: 'r2', name: 'HR Manager', code: 'HR-MGR', department: 'HR', usersAssigned: 4, permissionsCount: 45, status: 'ACTIVE', createdDate: '2026-02-05' }, { id: 'r3', name: 'Finance Controller', code: 'FIN-CON', department: 'Finance', usersAssigned: 2, permissionsCount: 60, status: 'INACTIVE', createdDate: '2026-03-18' }, ]; const MODULES = [ 'Employee Management', 'Department Management', 'Designation Management', 'Internal Role Management', 'Verification Management', 'Approval Management', 'Users Management', 'Company Management' ]; function StatusBadge(props: { status: string }) { const active = () => props.status === 'ACTIVE'; return ( {active() ? 'Active' : 'Inactive'} ); } function FormInput(props: { label: string; required?: boolean; value: string; onInput: (v: string) => void; placeholder?: string }) { return ( {props.label}{props.required && *} props.onInput(e.currentTarget.value)} placeholder={props.placeholder} style="display:block;margin-top:6px;height:40px;width:100%;border-radius:10px;border:1px solid #E5E7EB;background:white;padding:0 14px;font-size:13px;color:#111827;outline:none;box-sizing:border-box" /> ); } export default function RoleManagementPage() { const [view, setView] = createSignal<'list' | 'form' | 'detail'>('list'); const [listTab, setListTab] = createSignal<'all' | 'create' | 'view'>('all'); const [formTab, setFormTab] = createSignal<'general' | 'permissions' | 'settings'>('general'); const [detailTab, setDetailTab] = createSignal<'permissions' | 'users' | 'logs'>('permissions'); const [search, setSearch] = createSignal(''); const [rows, setRows] = createSignal([]); const [viewingRole, setViewingRole] = createSignal(null); const [editingId, setEditingId] = createSignal(null); const [openMenuId, setOpenMenuId] = createSignal(null); const [name, setName] = createSignal(''); const [code, setCode] = createSignal(''); const [dept, setDept] = createSignal(''); const [desc, setDesc] = createSignal(''); const load = async () => { setRows(FALLBACK_ROLES); }; onMount(() => void load()); const filteredRows = createMemo(() => { const q = search().toLowerCase(); if (!q) return rows(); return rows().filter(r => r.name.toLowerCase().includes(q) || (r.code || '').toLowerCase().includes(q)); }); const resetForm = () => { setEditingId(null); setName(''); setCode(''); setDept(''); setDesc(''); setFormTab('general'); }; const openCreate = () => { resetForm(); setView('form'); }; const openEdit = (row: RoleRecord) => { setEditingId(row.id); setName(row.name); setCode(row.code || ''); setDept(row.department || ''); setView('form'); setOpenMenuId(null); }; const openDetail = (row: RoleRecord) => { setViewingRole(row); setView('detail'); setListTab('view'); setOpenMenuId(null); }; return ( Internal Role Management Define and manage organizational access levels with granular permission control {/* ── LIST VIEW ── */} {([ { key: 'all', label: 'All Roles', action: () => setListTab('all') }, { key: 'create', label: 'Create Role', action: () => { setListTab('create'); openCreate(); } }, { key: 'view', label: 'View Role', action: () => setListTab('view') }, ] as const).map((tab) => ( {tab.label} ))} setSearch(e.currentTarget.value)} placeholder="Search roles..." style="height:34px;flex:1;border-radius:8px;border:1px solid #E5E7EB;background:white;padding:0 12px;font-size:13px;color:#111827;outline:none" /> Filters Export {['Role Name', 'Role Code', 'Department', 'Users', 'Status', 'Actions'].map(h => ( {h} ))} {(row) => ( {row.name} {row.code || '—'} {row.department || '—'} {row.usersAssigned} users setOpenMenuId(openMenuId() === row.id ? null : row.id)} style="display:inline-flex;height:32px;width:32px;align-items:center;justify-content:center;border-radius:8px;color:#9CA3AF;background:none;border:none;cursor:pointer"> openDetail(row)} style="display:flex;width:100%;align-items:center;gap:10px;border-radius:8px;padding:8px 12px;font-size:13px;color:#374151;background:none;border:none;cursor:pointer;text-align:left">View Role openEdit(row)} style="display:flex;width:100%;align-items:center;gap:10px;border-radius:8px;padding:8px 12px;font-size:13px;color:#374151;background:none;border:none;cursor:pointer;text-align:left">Edit Role Delete Role )} {/* ── FORM VIEW ── */} setView('list')} style="padding-bottom:12px;font-size:14px;font-weight:500;color:#6B7280;background:none;border:none;cursor:pointer">All Roles {editingId() ? 'Edit Role' : 'Create Role'} {(['general', 'permissions', 'settings'] as const).map((tab, i) => { const labels = ['General Information', 'Module Access', 'Role Settings']; const active = () => formTab() === tab; return ( setFormTab(tab)} style={`position:relative;padding:14px 8px;font-size:13px;font-weight:500;background:none;border:none;cursor:pointer;color:${active() ? '#FF5E13' : '#6B7280'}`}> {labels[i]} ); })} Module {['View', 'Create', 'Update', 'Delete'].map(p => ( {p} ))} {(mod) => ( {mod} {[1, 2, 3, 4].map(() => ( ))} )} Allow Role to Approve Requests Users with this role can make final decisions in Approval Management. setView('list')} style="height:38px;border-radius:10px;border:1px solid #E5E7EB;background:white;padding:0 20px;font-size:13px;font-weight:600;color:#374151;cursor:pointer">Cancel {editingId() ? 'Update Role' : 'Create Role'} {/* ── DETAIL VIEW ── */} {viewingRole()!.name} Code: {viewingRole()!.code} • Dept: {viewingRole()!.department} • Assigned: {viewingRole()!.usersAssigned} users openEdit(viewingRole()!)} style="height:36px;border-radius:8px;background:#0D0D2A;padding:0 16px;font-size:13px;font-weight:600;color:white;border:none;cursor:pointer">Edit Role {(['permissions', 'users', 'logs'] as const).map((tab, i) => { const labels = ['Permissions', 'Assigned Users', 'Activity Logs']; const active = () => detailTab() === tab; return ( setDetailTab(tab)} style={`position:relative;padding:14px 12px;font-size:13px;font-weight:600;background:none;border:none;cursor:pointer;color:${active() ? '#FF5E13' : '#6B7280'}`}> {labels[i]} ); })} Module {['View', 'Create', 'Update', 'Delete'].map(p => ( {p} ))} {(mod) => ( {mod} {[1, 2, 3, 4].map(() => ( ))} )} Users assigned to this role will appear here. Permissions Updated Admin modified module access levels • 1 day ago { setView('list'); setListTab('all'); }} style="height:36px;border-radius:8px;border:1px solid #E5E7EB;background:white;padding:0 16px;font-size:13px;font-weight:600;color:#374151;cursor:pointer">Back to List ); }
Define and manage organizational access levels with granular permission control
Allow Role to Approve Requests
Users with this role can make final decisions in Approval Management.
Code: {viewingRole()!.code} • Dept: {viewingRole()!.department} • Assigned: {viewingRole()!.usersAssigned} users
Permissions Updated
Admin modified module access levels • 1 day ago