From 648b6be84918650f0463cbab51f12f3e2e0b07c0 Mon Sep 17 00:00:00 2001 From: Ashwin Kumar Date: Thu, 26 Mar 2026 00:01:15 +0100 Subject: [PATCH] feat: phase 3 identity & configuration ui matching figma designs --- src/routes/admin/department.tsx | 307 +++++++++++++------------ src/routes/admin/designation.tsx | 243 +++++++++++--------- src/routes/admin/employees.tsx | 205 ++++++++++------- src/routes/admin/users.tsx | 374 +++++++++++++++++++------------ 4 files changed, 648 insertions(+), 481 deletions(-) diff --git a/src/routes/admin/department.tsx b/src/routes/admin/department.tsx index a91af77..f3c0732 100644 --- a/src/routes/admin/department.tsx +++ b/src/routes/admin/department.tsx @@ -182,87 +182,60 @@ export default function DepartmentPage() { return (
- - {/* ── Page header ── */} -
-

Departments

-

Manage organization structure and units.

-
- - {/* ── Tab + action bar ── */} -
-
- - {(t) => ( - - )} - - - - - - - +
- - - -
- {/* ── Content ── */} -
- - {/* Create form */} -
-
-
- - setCreateName(e.currentTarget.value)} - class="w-full rounded-lg border border-gray-200 px-3 py-2 text-sm outline-none focus:border-[#0a1d37] focus:ring-1 focus:ring-[#0a1d37]" - /> -
-
- - setCreateDesc(e.currentTarget.value)} - class="w-full rounded-lg border border-gray-200 px-3 py-2 text-sm outline-none focus:border-[#0a1d37] focus:ring-1 focus:ring-[#0a1d37]" - /> + {/* Create form */} +
+

Create New Department

+ +
+
+ + setCreateName(e.currentTarget.value)} + class="h-11 w-full rounded-xl border border-[#d9dde6] bg-[#f9fafb] px-4 text-[14px] outline-none transition-colors focus:border-[#050026] focus:bg-white" + /> +
+
+ + setCreateDesc(e.currentTarget.value)} + class="h-11 w-full rounded-xl border border-[#d9dde6] bg-[#f9fafb] px-4 text-[14px] outline-none transition-colors focus:border-[#050026] focus:bg-white" + /> +
-

{createError()}

+

{createError()}

-
- -
@@ -270,66 +243,105 @@ export default function DepartmentPage() {
- {/* List view */} -
- -
{actionError()}
-
+ {/* Main Table Section */} +
+
+ + {/* Error Message */} + +
{actionError()}
+
-
+ {/* Tabs */} +
+ + {(t) => ( + + )} + +
+ + {/* Filters Row */} +
+
+
+ + + +
+ +
+
+
+
+ + {/* Table */}
- +
- - - - - - - - - + + + + + + + + + - + - + - + {(item) => ( <> - - - - - - - - - + + + + + + + + @@ -356,28 +368,28 @@ export default function DepartmentPage() { {/* Inline edit row */} - @@ -388,31 +400,32 @@ export default function DepartmentPage() {
IDNameDescriptionCreated ByCreatedLast Updated ByLast Updated AtActions
DEPARTMENT IDDEPARTMENT NAMEDESCRIPTIONCREATED BYCREATEDLAST UPDATED BYLAST UPDATED ATACTION
Loading…
Loading departments...
Failed to load. Is the backend running?
Failed to load. Is the backend running?
No departments found.
No departments found.
{item.departmentId || item.id.slice(0, 8)}{deptLabel(item)}{item.description || '—'}{item.createdBy || '—'}{fmtDate(item.createdAt || item.created_at)}{item.updatedBy || item.createdBy || '—'}{fmtDate(item.updatedAt)} -
+
{item.departmentId || item.id.slice(0, 8).toUpperCase()}{deptLabel(item)}{item.description || '—'}{item.createdBy || 'System'}{fmtDate(item.createdAt || item.created_at)}{item.updatedBy || item.createdBy || 'System'}{fmtDate(item.updatedAt)} +
@@ -337,18 +349,18 @@ export default function DepartmentPage() { title="Restore" disabled={busy() === item.id} onClick={() => handleRestore(item.id)} - class="action-btn flex items-center justify-center hover:bg-gray-50 transition-colors" + class="flex h-8 w-8 items-center justify-center rounded-lg border border-green-200 bg-green-50 text-[#00c853] hover:bg-green-100 transition-colors" > - +
-
+
+
- + setEditName(e.currentTarget.value)} - class="w-full rounded-lg border border-gray-200 px-3 py-2 text-sm outline-none focus:border-[#0a1d37] focus:ring-1 focus:ring-[#0a1d37]" /> + class="h-10 w-full rounded-lg border border-[#d9dde6] bg-[#f9fafb] px-3 text-sm outline-none focus:border-[#050026] focus:bg-white transition-colors" />
- + setEditDesc(e.currentTarget.value)} - class="w-full rounded-lg border border-gray-200 px-3 py-2 text-sm outline-none focus:border-[#0a1d37] focus:ring-1 focus:ring-[#0a1d37]" /> + class="h-10 w-full rounded-lg border border-[#d9dde6] bg-[#f9fafb] px-3 text-sm outline-none focus:border-[#050026] focus:bg-white transition-colors" /> +
+ +
{editError()}
+
+
+ +
-
- -

{editError()}

-
-
- -
-
- {/* Pagination */} - 1}> -
- Page {page()} of {totalPages()} -
- - + {/* Pagination */} + 1}> +
+ Page {page()} of {totalPages()} +
+ + +
-
- -
+
+ +
+
diff --git a/src/routes/admin/designation.tsx b/src/routes/admin/designation.tsx index 8f31d75..8c608d0 100644 --- a/src/routes/admin/designation.tsx +++ b/src/routes/admin/designation.tsx @@ -248,134 +248,145 @@ export default function DesignationPage() { return (
- - {/* ── Page header ── */} -
-

Designations

-

Manage job titles and roles within departments.

-
- - {/* ── Tab + action bar ── */} -
-
- - - - - + +
- {/* Status filter — only in list view */} - - - -
- - {/* ── Content ── */} -
- {/* Create / Edit form */} -
+
+

+ {view() === 'create' ? 'Create New Designation' : `Edit: ${editingDesignation()?.name}`} +

{/* List */} -
- -
{actionError()}
-
+
+
+ + {/* Error Message */} + +
{actionError()}
+
-
+ {/* Tabs */} +
+ + {(t) => ( + + )} + +
+ + {/* Filters Row */} +
+
+
+ + + +
+ +
+
+
+
+ + {/* Table */}
- +
- - - - - - - - - - - - - + + + + + + + + + - + - + - + {(item) => { const archived = () => isArchived(item); return ( - - - - - - - - - - - - - + + + + + + + +
IDNameDepartmentDescriptionActive UsersActive JobsStatusCreated ByCreated AtLast Updated ByLast Updated AtActions
DESIGNATION IDDESIGNATION TITLEDEPARTMENTCREATED BYCREATEDLAST UPDATED BYLAST UPDATED ATACTION
Loading…
Loading designations...
Failed to load. Is the backend running?
Failed to load. Is the backend running?
No designations found.
No designations found.
{(item.designationId || item.id).slice(0, 16)}{item.name}{deptDisplay(item)}{item.description || '—'}{item.activeUsersCount ?? 0}{item.activeJobsCount ?? 0} - - {archived() ? 'ARCHIVED' : 'ACTIVE'} - - {item.createdBy || '—'}{fmtDate(item.createdAt)}{item.updatedBy || '—'}{fmtDate(item.updatedAt)} -
-
{(item.designationId || item.id).slice(0, 16).toUpperCase()}{item.name}{deptDisplay(item)}{item.createdBy || 'System'}{fmtDate(item.createdAt)}{item.updatedBy || item.createdBy || 'System'}{fmtDate(item.updatedAt)} +
+ - -
@@ -387,24 +398,32 @@ export default function DesignationPage() {
-
- 1}> -
- Page {page()} of {totalPages()} -
- - + {/* Pagination */} + 1}> +
+ Page {page()} of {totalPages()} +
+ + +
-
- -
+
+ +
+
diff --git a/src/routes/admin/employees.tsx b/src/routes/admin/employees.tsx index d54179b..ade4a22 100644 --- a/src/routes/admin/employees.tsx +++ b/src/routes/admin/employees.tsx @@ -124,58 +124,50 @@ export default function EmployeesPage() { return (
- - {/* ── Page header ── */} -
-

Internal User Management

-

Manage internal team members and their access.

-
- - {/* ── Tab bar ── */} -
-
- - +
+ {/* Header & Title */} +
+
+

Employee Management

+
+
+ + +
-
- {/* ── Content ── */} -
- - {/* Create form */} -
- + {/* Create form */} +
+

Create New Employee

+
- + setFormName(e.currentTarget.value)} - class="w-full rounded-lg border border-gray-200 px-3 py-2 text-sm outline-none focus:border-[#0a1d37] focus:ring-1 focus:ring-[#0a1d37]" /> + class="h-11 w-full rounded-xl border border-[#d9dde6] bg-[#f9fafb] px-4 text-[14px] outline-none transition-colors focus:border-[#050026] focus:bg-white" />
- + setFormEmail(e.currentTarget.value)} - class="w-full rounded-lg border border-gray-200 px-3 py-2 text-sm outline-none focus:border-[#0a1d37] focus:ring-1 focus:ring-[#0a1d37]" /> + class="h-11 w-full rounded-xl border border-[#d9dde6] bg-[#f9fafb] px-4 text-[14px] outline-none transition-colors focus:border-[#050026] focus:bg-white" />
- + setFormPassword(e.currentTarget.value)} - class="w-full rounded-lg border border-gray-200 px-3 py-2 text-sm outline-none focus:border-[#0a1d37] focus:ring-1 focus:ring-[#0a1d37]" /> + class="h-11 w-full rounded-xl border border-[#d9dde6] bg-[#f9fafb] px-4 text-[14px] outline-none transition-colors focus:border-[#050026] focus:bg-white" />
- + +
+
+
+
+ + {/* Table */}
- +
- - - - - - + + + + + + + + + - + - + - + - + {(item) => { const active = () => isActive(item); return ( - - - - - + + + + + + + - @@ -275,7 +324,7 @@ export default function EmployeesPage() {
NameEmailRoleStatusActions
EMPLOYEE IDNAME & TITLEDEPARTMENTDESIGNATIONINTERNAL ROLEJOINING DATESTATUSACTION
Loading…
Loading employees...
Failed to load. Is the backend running?
Failed to load. Is the backend running?
No internal users found.
No employees found. Add the first one.
{employeeName(item)}{item.email}{roleName(item)} - - {active() ? 'ACTIVE' : 'INACTIVE'} +
EMP-{item.id.slice(0, 6).toUpperCase()} +
+
+ {employeeName(item).charAt(0)} +
+
+
{employeeName(item)}
+
{item.email}
+
+
+
Operations{roleName(item)}Oct 24, 2023 + + {active() ? 'Active' : 'Inactive'} -
- - - +
+
-
+
diff --git a/src/routes/admin/users.tsx b/src/routes/admin/users.tsx index 8f8919c..eab5443 100644 --- a/src/routes/admin/users.tsx +++ b/src/routes/admin/users.tsx @@ -107,169 +107,255 @@ export default function UsersPage() { return (
- {/* White page header */} -
-

External User Management

-

Manage all external platform users.

-
+
+ {/* Header & Title */} +
+
+

User Management

+
+
+ + +
+
- {/* Tabs */} -
- - -
- - {/* Content */} -
- {/* Filters */} -
- { - setSearch(e.currentTarget.value); - setCurrentPage(1); - }} - class="rounded-lg border border-gray-200 px-3 py-2 text-sm outline-none focus:border-[#0a1d37] w-64" - /> - - - - - Showing {paginated().length} of {filtered().length} users - - + {/* KPI Cards Row */} +
+
+

Total Users

+

{users()?.length || 0}

+
+
+

Active Users

+

{users()?.filter((u) => u.status === 'ACTIVE').length || 0}

+
+
+

Inactive Users

+

{users()?.filter((u) => u.status === 'INACTIVE').length || 0}

+
+
+

New Users Today

+

0

+
-
-
- - - - - - - - - - - - - - - - - - - - - - - 0}> + {/* Main Table Section */} +
+
+ + {/* Tabs */} +
+ + {(t) => { + const isActiveTab = (t === 'All Users' && !filterStatus()) || + (t === 'Active' && filterStatus() === 'ACTIVE') || + (t === 'Inactive' && filterStatus() === 'INACTIVE'); + return ( + + ); + }} + +
+ + {/* Filters Row */} +
+
+
+ + + +
+ { setSearch(e.currentTarget.value); setCurrentPage(1); }} + 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 {paginated().length} of {filtered().length} users + + +
+ + {/* Table */} +
+
User IDNameEmailRegistration RoleStatusCreatedActions
Loading...
Failed to load. Is the backend running?
No users found.
+ + + + + + + + + + + + + + + + + + + + + {(item) => ( - - - - - - + + - + - + + )} - - -
USER IDUSER DETAILSROLEJOINING DATELAST LOGINSTATUSACTION
Loading users...
Failed to load. Is the backend running?
No users found.
{shortId(item.id)}{item.name || item.full_name || '—'}{item.email}{registrationRole(item)} - +
USR-{item.id.slice(0, 6).toUpperCase()} +
+
+ {(item.name || item.full_name || 'U').charAt(0)} +
+
+
{item.name || item.full_name || '—'}
+
{item.email}
+
+
- {(item.created_at || item.createdAt) - ? new Date((item.created_at || item.createdAt)!).toLocaleDateString() - : '—'} + {registrationRole(item)} + {(item.created_at || item.createdAt) ? new Date((item.created_at || item.createdAt)!).toLocaleDateString() : '—'} -
- - - - +
+ + {item.status.charAt(0) + item.status.slice(1).toLowerCase()} + + +
+ +
+ + +
+ + {/* Pagination */} + 1}> +
+ + Page {currentPage()} of {totalPages()} + +
+
-
- - Page {currentPage()} of {totalPages()} - -
-
+
+ {/* Details View */} -
- Select a user from list to view details.

}> -
-

User Details

- +
+ +
+

User Details

+
-
-
-

Profile

-

User ID: {selectedUser()!.id}

-

Name: {selectedUser()!.name || selectedUser()!.full_name || '—'}

-

Email: {selectedUser()!.email}

-

Role: {registrationRole(selectedUser()!)}

-

Status: {selectedUser()!.status}

+
+
+

Profile Information

+
+

User ID

{selectedUser()!.id}

+

Name

{selectedUser()!.name || selectedUser()!.full_name || '—'}

+

Email

{selectedUser()!.email}

+

Role

{registrationRole(selectedUser()!)}

+
+

Status

+ + {selectedUser()!.status.charAt(0) + selectedUser()!.status.slice(1).toLowerCase()} + +
+
-
-

Account

-

Created: {(selectedUser()!.created_at || selectedUser()!.createdAt) ? new Date((selectedUser()!.created_at || selectedUser()!.createdAt)!).toLocaleString() : '—'}

-

Role ID: {selectedUser()!.roleId || '—'}

-
- Edit User - +
+

Account Metadata

+
+
+

Created

+

{(selectedUser()!.created_at || selectedUser()!.createdAt) ? new Date((selectedUser()!.created_at || selectedUser()!.createdAt)!).toLocaleString() : '—'}

+
+

Role ID

{selectedUser()!.roleId || '—'}

+
+ Edit User + +