From 1b70f40e40fc23a0a83d40c472e0822c634b2b5d Mon Sep 17 00:00:00 2001 From: Ashwin Kumar Date: Thu, 26 Mar 2026 00:06:47 +0100 Subject: [PATCH] feat: phase 4 role management ui matching figma designs --- src/routes/admin/roles/index.tsx | 347 +++++++++++------------ src/routes/admin/runtime-roles/index.tsx | 225 +++++++++++---- 2 files changed, 329 insertions(+), 243 deletions(-) diff --git a/src/routes/admin/roles/index.tsx b/src/routes/admin/roles/index.tsx index 7680d99..d254014 100644 --- a/src/routes/admin/roles/index.tsx +++ b/src/routes/admin/roles/index.tsx @@ -95,195 +95,178 @@ export default function InternalRolesListPage() { return ( -
- - {/* Page title */} -
-

Internal Role Management

-

Manage internal roles and permissions

-
- - {/* Card */} -
-
- - {/* Tabs */} -
- - Create Role + + Add Role
- - {/* Toolbar */} -
-
- - handleSearch(e.currentTarget.value)} - class="w-full pl-9 pr-3 py-2 text-[13px] border border-[#e5e7eb] rounded-lg outline-none focus:border-[#fa5014] focus:ring-1 focus:ring-[#fa5014] bg-white" - /> -
- - -
- - {/* Table */} -
- - - - - - - - - - - - - - - - - - - - - - - - - {(role) => ( - - - - - - - - - - )} - - -
Role NameDepartmentUsers AssignedPermissions CountStatusCreated DateActions
- Loading roles… -
- No internal roles found.{' '} - - Create your first role. - -
-

{role.name}

-

{role.key}

-
- {role.department_name || '—'} - - {role.users_assigned} - - - {role.permissions_count} Permissions - - - - Inactive - - } - > - - Active - - - - {formatDate(role.created_at)} - -
- - View - - | - - Edit - - | - -
-
-
- - {/* Pagination */} - 0}> -
-

- Showing {((page() - 1) * (data()?.per_page ?? 8)) + 1}– - {Math.min(page() * (data()?.per_page ?? 8), data()?.total ?? 0)} of {data()?.total ?? 0} roles -

-
- - i + 1)}> - {(p) => ( - - )} - - -
-
-
+ +
+
+ + {/* Tabs */} +
+ + {(t) => ( + + )} + +
+ + {/* Filters Row */} +
+
+
+ + + +
+ handleSearch(e.currentTarget.value)} + class="h-11 w-full rounded-xl border border-[#d9dde6] bg-[#f9fafb] pl-11 pr-4 text-[14px] text-[#050026] outline-none transition-colors focus:border-[#050026] focus:bg-white" + /> +
+
+
+ + + Showing {((page() - 1) * (data()?.per_page ?? 8)) + 1}–{Math.min(page() * (data()?.per_page ?? 8), data()?.total ?? 0)} of {data()?.total ?? 0} roles + + +
+ + {/* Table */} +
+ + + + + + + + + + + + + + + + + + + + + {(role) => ( + + + + + + + + + + )} + + +
ROLE IDROLE NAMECATEGORYASSOCIATED USERSACTIVE PERMISSIONSLAST UPDATEDACTION
Loading roles...
No internal roles found.
{role.key.toUpperCase()}{role.name}{role.department_name || '—'} +
+ {/* Placeholder for avatar group if users > 0 */} + 0} fallback={0 users}> +
U
+
+{role.users_assigned - 1}
+
+
+
+ + {role.permissions_count} Permissions + + {formatDate(role.created_at)} +
+ + + + + + + + + + + + +
+
+
+ + {/* Pagination */} + 1}> +
+ Page {page()} of {totalPages()} +
+ + +
+
+
+ +
+
diff --git a/src/routes/admin/runtime-roles/index.tsx b/src/routes/admin/runtime-roles/index.tsx index 71ad006..c619b3e 100644 --- a/src/routes/admin/runtime-roles/index.tsx +++ b/src/routes/admin/runtime-roles/index.tsx @@ -1,5 +1,5 @@ import { A, useSearchParams } from '@solidjs/router'; -import { createMemo, createResource, Show } from 'solid-js'; +import { createMemo, createResource, Show, For } from 'solid-js'; import AdminShell from '~/components/AdminShell'; const API = '/api/gateway'; @@ -72,73 +72,176 @@ async function loadExternalRoles(): Promise { export default function RuntimeRolesPage() { const [searchParams] = useSearchParams(); const [roles] = createResource(loadExternalRoles); - const selectedRoleKey = createMemo(() => (searchParams.roleKey || '').toLowerCase()); + const selectedRoleKey = createMemo(() => { + const rk = searchParams.roleKey; + return (Array.isArray(rk) ? rk[0] : rk || '').toLowerCase(); + }); return (
-
-

External Role Management

-

Configure and maintain external system roles and access privileges.

-
- -
-
-
- - - - - - - - - - - - - - - - - - - - - 0}> - {roles()!.map((role) => ( - - - - - - - - ))} - - -
IDNameIssue TypeEditDelete
Loading external roles...
Failed to load external roles. Is the backend running?
No external roles configured yet.
{role.roleKey || role.id?.slice(0, 6).toUpperCase()}{role.displayName} - - View - - - - - - -
+
+ {/* Header & Title */} +
+
+

External Role Management

-
-

Showing 1 to 5 of {(roles()?.length || 0) || 5} entries

-
- - - - - -
+
+ + + + Add Role +
+ +
+
+ + {/* Tabs */} +
+ + {(t: string) => ( + + )} + +
+ + {/* Filters Row */} +
+
+
+ + + +
+ +
+
+
+ + + Showing 1–{roles()?.length || 0} of {roles()?.length || 0} roles + + +
+ + {/* Table */} +
+ + + + + + + + + + + + + + + + + + + + + + + + {(role: ExternalRole) => ( + + + + + + + + + + )} + + +
ROLE IDROLE NAMECATEGORYENABLED MODULESSTATUSONBOARDING SCHEMAACTION
Loading external roles...
Failed to load external roles. Is the backend running?
No external roles configured yet.
{(role.roleKey || role.id?.slice(0, 6)).toUpperCase()}{role.displayName}{role.vertical || '—'} + + {role.enabledModules.length} Modules + + + Inactive}> + Active + + {role.onboardingSchemaId || '—'} +
+ + + + + + + + + + + + +
+
+
+ + {/* Pagination */} +
+ Page 1 of 1 +
+ + +
+
+ +
+