2026-03-26 06:20:22 +01:00
import { For , Show , createMemo , createSignal , onMount } from 'solid-js' ;
feat(admin): build complete admin panel with UI parity and search/filter
- Implement all admin management pages (employees, users, jobs, leads, orders, companies, customers, candidates, approval, invoices, reviews, support, KB, pricing, coupons, credits, discounts, tax, reports, ledger)
- Implement 9 professional vertical pages (developers, designers, tutors, video editors, photographers, makeup artists, graphic designers, social media managers, fitness trainers)
- Implement internal/external dashboard and role management with builder UI
- Fix tab styling: replace inline border-bottom styles with admin-tab CSS class across 8+ pages
- Add search/filter functionality to invoice and review pages
- Add toggle status (activate/deactivate) to employees page with PATCH /api/admin/employees/{id}
- Align UI styling with NextJS admin panel for visual parity
- Add stat cards to approval page showing counts by status
- Implement graceful empty states for all list views
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-19 13:04:10 +01:00
import AdminShell from '~/components/AdminShell' ;
2026-03-26 06:20:22 +01:00
import { createModuleRecord , deleteModuleRecord , listModuleRecords , updateModuleRecord } from '~/lib/admin/client' ;
import type { CrudRecord } from '~/lib/admin/types' ;
feat(admin): build complete admin panel with UI parity and search/filter
- Implement all admin management pages (employees, users, jobs, leads, orders, companies, customers, candidates, approval, invoices, reviews, support, KB, pricing, coupons, credits, discounts, tax, reports, ledger)
- Implement 9 professional vertical pages (developers, designers, tutors, video editors, photographers, makeup artists, graphic designers, social media managers, fitness trainers)
- Implement internal/external dashboard and role management with builder UI
- Fix tab styling: replace inline border-bottom styles with admin-tab CSS class across 8+ pages
- Add search/filter functionality to invoice and review pages
- Add toggle status (activate/deactivate) to employees page with PATCH /api/admin/employees/{id}
- Align UI styling with NextJS admin panel for visual parity
- Add stat cards to approval page showing counts by status
- Implement graceful empty states for all list views
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-19 13:04:10 +01:00
2026-03-26 06:20:22 +01:00
type DepartmentRecord = CrudRecord & {
code? : string ;
feat(admin): build complete admin panel with UI parity and search/filter
- Implement all admin management pages (employees, users, jobs, leads, orders, companies, customers, candidates, approval, invoices, reviews, support, KB, pricing, coupons, credits, discounts, tax, reports, ledger)
- Implement 9 professional vertical pages (developers, designers, tutors, video editors, photographers, makeup artists, graphic designers, social media managers, fitness trainers)
- Implement internal/external dashboard and role management with builder UI
- Fix tab styling: replace inline border-bottom styles with admin-tab CSS class across 8+ pages
- Add search/filter functionality to invoice and review pages
- Add toggle status (activate/deactivate) to employees page with PATCH /api/admin/employees/{id}
- Align UI styling with NextJS admin panel for visual parity
- Add stat cards to approval page showing counts by status
- Implement graceful empty states for all list views
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-19 13:04:10 +01:00
description? : string ;
2026-03-26 06:20:22 +01:00
totalEmployees? : number ;
createdDate? : string ;
departmentHead? : string ;
departmentEmail? : string ;
feat(admin): build complete admin panel with UI parity and search/filter
- Implement all admin management pages (employees, users, jobs, leads, orders, companies, customers, candidates, approval, invoices, reviews, support, KB, pricing, coupons, credits, discounts, tax, reports, ledger)
- Implement 9 professional vertical pages (developers, designers, tutors, video editors, photographers, makeup artists, graphic designers, social media managers, fitness trainers)
- Implement internal/external dashboard and role management with builder UI
- Fix tab styling: replace inline border-bottom styles with admin-tab CSS class across 8+ pages
- Add search/filter functionality to invoice and review pages
- Add toggle status (activate/deactivate) to employees page with PATCH /api/admin/employees/{id}
- Align UI styling with NextJS admin panel for visual parity
- Add stat cards to approval page showing counts by status
- Implement graceful empty states for all list views
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-19 13:04:10 +01:00
} ;
2026-03-26 06:20:22 +01:00
const FALLBACK_DEPARTMENTS : DepartmentRecord [ ] = [
{ id : 'd1' , name : 'Marketing' , code : 'MKT-002' , description : 'Brand management and digital marketing' , totalEmployees : 23 , status : 'ACTIVE' , updatedAt : '2026-03-01' , createdDate : '2026-03-01' } ,
{ id : 'd2' , name : 'Human Resources' , code : 'HR-003' , description : 'Employee relations and talent acquisition' , totalEmployees : 12 , status : 'ACTIVE' , updatedAt : '2026-03-01' , createdDate : '2026-03-01' } ,
{ id : 'd3' , name : 'Finance' , code : 'FIN-004' , description : 'Financial planning and accounting' , totalEmployees : 18 , status : 'ACTIVE' , updatedAt : '2026-03-01' , createdDate : '2026-03-01' } ,
{ id : 'd4' , name : 'Operations' , code : 'OPS-005' , description : 'Business operations and process management' , totalEmployees : 31 , status : 'ACTIVE' , updatedAt : '2026-03-01' , createdDate : '2026-03-01' } ,
{ id : 'd5' , name : 'Customer Success' , code : 'CS-006' , description : 'Client support and relationship management' , totalEmployees : 27 , status : 'ACTIVE' , updatedAt : '2026-03-01' , createdDate : '2026-03-01' } ,
{ id : 'd6' , name : 'Product' , code : 'PRD-007' , description : 'Product strategy and development' , totalEmployees : 19 , status : 'ACTIVE' , updatedAt : '2026-03-01' , createdDate : '2026-03-01' } ,
{ id : 'd7' , name : 'Sales' , code : 'SAL-008' , description : 'Revenue generation and client acquisition' , totalEmployees : 34 , status : 'ACTIVE' , updatedAt : '2026-03-01' , createdDate : '2026-03-01' } ,
{ id : 'd8' , name : 'Engineering' , code : 'ENG-001' , description : 'Software development and technical architecture' , totalEmployees : 45 , status : 'ACTIVE' , updatedAt : '2026-03-01' , createdDate : '2026-03-01' } ,
] ;
feat(admin): build complete admin panel with UI parity and search/filter
- Implement all admin management pages (employees, users, jobs, leads, orders, companies, customers, candidates, approval, invoices, reviews, support, KB, pricing, coupons, credits, discounts, tax, reports, ledger)
- Implement 9 professional vertical pages (developers, designers, tutors, video editors, photographers, makeup artists, graphic designers, social media managers, fitness trainers)
- Implement internal/external dashboard and role management with builder UI
- Fix tab styling: replace inline border-bottom styles with admin-tab CSS class across 8+ pages
- Add search/filter functionality to invoice and review pages
- Add toggle status (activate/deactivate) to employees page with PATCH /api/admin/employees/{id}
- Align UI styling with NextJS admin panel for visual parity
- Add stat cards to approval page showing counts by status
- Implement graceful empty states for all list views
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-19 13:04:10 +01:00
2026-03-26 06:20:22 +01:00
export default function DepartmentManagementPage() {
const [ mainTab , setMainTab ] = createSignal < 'all' | 'create' > ( 'all' ) ;
const [ createTab , setCreateTab ] = createSignal < 'general' | 'settings' | 'permissions' > ( 'general' ) ;
const [ search , setSearch ] = createSignal ( '' ) ;
const [ rows , setRows ] = createSignal < DepartmentRecord [ ] > ( [ ] ) ;
const [ openMenuId , setOpenMenuId ] = createSignal < string | null > ( null ) ;
const [ editingId , setEditingId ] = createSignal < string | null > ( null ) ;
ui(step-1): match reference layout for dept/designation/employees/roles pages
- All pages: white sticky page header + tab bar with orange underline,
-mx-6 -mt-6 negative margin to stretch headers edge-to-edge
- department: full columns (ID, Name, Description, Created By, etc.),
icon-only action buttons, navy Add Department button
- designation: Designations List / Add Designation tabs, status filter
dropdown, inline create/edit form, full columns with status badge
- employees: View/Add tabs, icon-only action buttons, status badges
- roles/index: clean table with Name+code subtext, Description, actions
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 04:47:05 +01:00
2026-03-26 06:20:22 +01:00
const [ name , setName ] = createSignal ( '' ) ;
const [ code , setCode ] = createSignal ( '' ) ;
const [ description , setDescription ] = createSignal ( '' ) ;
const [ departmentHead , setDepartmentHead ] = createSignal ( '' ) ;
const [ departmentEmail , setDepartmentEmail ] = createSignal ( '' ) ;
const [ status , setStatus ] = createSignal < 'ACTIVE' | 'INACTIVE' > ( 'ACTIVE' ) ;
const [ transfersEnabled , setTransfersEnabled ] = createSignal ( false ) ;
feat(admin): build complete admin panel with UI parity and search/filter
- Implement all admin management pages (employees, users, jobs, leads, orders, companies, customers, candidates, approval, invoices, reviews, support, KB, pricing, coupons, credits, discounts, tax, reports, ledger)
- Implement 9 professional vertical pages (developers, designers, tutors, video editors, photographers, makeup artists, graphic designers, social media managers, fitness trainers)
- Implement internal/external dashboard and role management with builder UI
- Fix tab styling: replace inline border-bottom styles with admin-tab CSS class across 8+ pages
- Add search/filter functionality to invoice and review pages
- Add toggle status (activate/deactivate) to employees page with PATCH /api/admin/employees/{id}
- Align UI styling with NextJS admin panel for visual parity
- Add stat cards to approval page showing counts by status
- Implement graceful empty states for all list views
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-19 13:04:10 +01:00
2026-03-26 06:20:22 +01:00
const load = async ( ) = > {
feat(admin): build complete admin panel with UI parity and search/filter
- Implement all admin management pages (employees, users, jobs, leads, orders, companies, customers, candidates, approval, invoices, reviews, support, KB, pricing, coupons, credits, discounts, tax, reports, ledger)
- Implement 9 professional vertical pages (developers, designers, tutors, video editors, photographers, makeup artists, graphic designers, social media managers, fitness trainers)
- Implement internal/external dashboard and role management with builder UI
- Fix tab styling: replace inline border-bottom styles with admin-tab CSS class across 8+ pages
- Add search/filter functionality to invoice and review pages
- Add toggle status (activate/deactivate) to employees page with PATCH /api/admin/employees/{id}
- Align UI styling with NextJS admin panel for visual parity
- Add stat cards to approval page showing counts by status
- Implement graceful empty states for all list views
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-19 13:04:10 +01:00
try {
2026-03-26 06:20:22 +01:00
const res = await fetch ( ` /api/gateway/api/admin/departments?page=1&limit=100&q= ${ encodeURIComponent ( search ( ) . trim ( ) ) } ` ) ;
if ( res . ok ) {
const payload = await res . json ( ) . catch ( ( ) = > null ) ;
const list = Array . isArray ( payload ) ? payload : Array.isArray ( payload ? . data ) ? payload.data : Array.isArray ( payload ? . items ) ? payload . items : [ ] ;
if ( list . length > 0 ) {
setRows (
list . map ( ( item : any , i : number ) = > ( {
id : String ( item . id ? ? item . department_id ? ? ` dep- ${ i + 1 } ` ) ,
name : String ( item . name ? ? item . department_name ? ? '' ) ,
code : String ( item . code ? ? item . department_code ? ? '' ) ,
description : String ( item . description ? ? '' ) ,
totalEmployees : Number ( item . totalEmployees ? ? item . total_employees ? ? item . employee_count ? ? 0 ) ,
status : String ( item . status ? ? 'ACTIVE' ) . toUpperCase ( ) === 'INACTIVE' ? 'INACTIVE' : 'ACTIVE' ,
updatedAt : String ( item . updatedAt ? ? item . updated_at ? ? new Date ( ) . toISOString ( ) . slice ( 0 , 10 ) ) ,
createdDate : String ( item . createdDate ? ? item . created_at ? ? new Date ( ) . toISOString ( ) . slice ( 0 , 10 ) ) ,
} ) ) ,
) ;
return ;
}
feat(admin): build complete admin panel with UI parity and search/filter
- Implement all admin management pages (employees, users, jobs, leads, orders, companies, customers, candidates, approval, invoices, reviews, support, KB, pricing, coupons, credits, discounts, tax, reports, ledger)
- Implement 9 professional vertical pages (developers, designers, tutors, video editors, photographers, makeup artists, graphic designers, social media managers, fitness trainers)
- Implement internal/external dashboard and role management with builder UI
- Fix tab styling: replace inline border-bottom styles with admin-tab CSS class across 8+ pages
- Add search/filter functionality to invoice and review pages
- Add toggle status (activate/deactivate) to employees page with PATCH /api/admin/employees/{id}
- Align UI styling with NextJS admin panel for visual parity
- Add stat cards to approval page showing counts by status
- Implement graceful empty states for all list views
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-19 13:04:10 +01:00
}
2026-03-26 06:20:22 +01:00
} catch { }
try {
const data = await listModuleRecords < DepartmentRecord > ( 'department' , { q : search ( ) . trim ( ) || undefined } ) ;
setRows ( Array . isArray ( data ) && data . length > 0 ? data : FALLBACK_DEPARTMENTS ) ;
} catch {
setRows ( FALLBACK_DEPARTMENTS ) ;
feat(admin): build complete admin panel with UI parity and search/filter
- Implement all admin management pages (employees, users, jobs, leads, orders, companies, customers, candidates, approval, invoices, reviews, support, KB, pricing, coupons, credits, discounts, tax, reports, ledger)
- Implement 9 professional vertical pages (developers, designers, tutors, video editors, photographers, makeup artists, graphic designers, social media managers, fitness trainers)
- Implement internal/external dashboard and role management with builder UI
- Fix tab styling: replace inline border-bottom styles with admin-tab CSS class across 8+ pages
- Add search/filter functionality to invoice and review pages
- Add toggle status (activate/deactivate) to employees page with PATCH /api/admin/employees/{id}
- Align UI styling with NextJS admin panel for visual parity
- Add stat cards to approval page showing counts by status
- Implement graceful empty states for all list views
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-19 13:04:10 +01:00
}
} ;
2026-03-26 06:20:22 +01:00
onMount ( ( ) = > void load ( ) ) ;
feat(admin): build complete admin panel with UI parity and search/filter
- Implement all admin management pages (employees, users, jobs, leads, orders, companies, customers, candidates, approval, invoices, reviews, support, KB, pricing, coupons, credits, discounts, tax, reports, ledger)
- Implement 9 professional vertical pages (developers, designers, tutors, video editors, photographers, makeup artists, graphic designers, social media managers, fitness trainers)
- Implement internal/external dashboard and role management with builder UI
- Fix tab styling: replace inline border-bottom styles with admin-tab CSS class across 8+ pages
- Add search/filter functionality to invoice and review pages
- Add toggle status (activate/deactivate) to employees page with PATCH /api/admin/employees/{id}
- Align UI styling with NextJS admin panel for visual parity
- Add stat cards to approval page showing counts by status
- Implement graceful empty states for all list views
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-19 13:04:10 +01:00
2026-03-26 06:20:22 +01:00
const resetForm = ( ) = > {
setEditingId ( null ) ;
setName ( '' ) ;
setCode ( '' ) ;
setDescription ( '' ) ;
setDepartmentHead ( '' ) ;
setDepartmentEmail ( '' ) ;
setStatus ( 'ACTIVE' ) ;
setTransfersEnabled ( false ) ;
setCreateTab ( 'general' ) ;
feat(admin): build complete admin panel with UI parity and search/filter
- Implement all admin management pages (employees, users, jobs, leads, orders, companies, customers, candidates, approval, invoices, reviews, support, KB, pricing, coupons, credits, discounts, tax, reports, ledger)
- Implement 9 professional vertical pages (developers, designers, tutors, video editors, photographers, makeup artists, graphic designers, social media managers, fitness trainers)
- Implement internal/external dashboard and role management with builder UI
- Fix tab styling: replace inline border-bottom styles with admin-tab CSS class across 8+ pages
- Add search/filter functionality to invoice and review pages
- Add toggle status (activate/deactivate) to employees page with PATCH /api/admin/employees/{id}
- Align UI styling with NextJS admin panel for visual parity
- Add stat cards to approval page showing counts by status
- Implement graceful empty states for all list views
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-19 13:04:10 +01:00
} ;
2026-03-26 06:20:22 +01:00
const openCreate = ( ) = > {
resetForm ( ) ;
setMainTab ( 'create' ) ;
feat(admin): build complete admin panel with UI parity and search/filter
- Implement all admin management pages (employees, users, jobs, leads, orders, companies, customers, candidates, approval, invoices, reviews, support, KB, pricing, coupons, credits, discounts, tax, reports, ledger)
- Implement 9 professional vertical pages (developers, designers, tutors, video editors, photographers, makeup artists, graphic designers, social media managers, fitness trainers)
- Implement internal/external dashboard and role management with builder UI
- Fix tab styling: replace inline border-bottom styles with admin-tab CSS class across 8+ pages
- Add search/filter functionality to invoice and review pages
- Add toggle status (activate/deactivate) to employees page with PATCH /api/admin/employees/{id}
- Align UI styling with NextJS admin panel for visual parity
- Add stat cards to approval page showing counts by status
- Implement graceful empty states for all list views
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-19 13:04:10 +01:00
} ;
2026-03-26 06:20:22 +01:00
const openEdit = ( row : DepartmentRecord ) = > {
setEditingId ( row . id ) ;
setName ( row . name || '' ) ;
setCode ( String ( row . code || '' ) ) ;
setDescription ( String ( row . description || '' ) ) ;
setDepartmentHead ( String ( row . departmentHead || '' ) ) ;
setDepartmentEmail ( String ( row . departmentEmail || '' ) ) ;
setStatus ( row . status === 'INACTIVE' ? 'INACTIVE' : 'ACTIVE' ) ;
setMainTab ( 'create' ) ;
setCreateTab ( 'general' ) ;
feat(admin): build complete admin panel with UI parity and search/filter
- Implement all admin management pages (employees, users, jobs, leads, orders, companies, customers, candidates, approval, invoices, reviews, support, KB, pricing, coupons, credits, discounts, tax, reports, ledger)
- Implement 9 professional vertical pages (developers, designers, tutors, video editors, photographers, makeup artists, graphic designers, social media managers, fitness trainers)
- Implement internal/external dashboard and role management with builder UI
- Fix tab styling: replace inline border-bottom styles with admin-tab CSS class across 8+ pages
- Add search/filter functionality to invoice and review pages
- Add toggle status (activate/deactivate) to employees page with PATCH /api/admin/employees/{id}
- Align UI styling with NextJS admin panel for visual parity
- Add stat cards to approval page showing counts by status
- Implement graceful empty states for all list views
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-19 13:04:10 +01:00
} ;
2026-03-26 06:20:22 +01:00
const saveDepartment = async ( ) = > {
const payload : Partial < DepartmentRecord > = {
name : name ( ) . trim ( ) || 'New Department' ,
code : code ( ) . trim ( ) || undefined ,
description : description ( ) . trim ( ) ,
departmentHead : departmentHead ( ) . trim ( ) ,
departmentEmail : departmentEmail ( ) . trim ( ) ,
status : status ( ) ,
transfersEnabled : transfersEnabled ( ) ,
} ;
if ( editingId ( ) ) {
await updateModuleRecord < DepartmentRecord > ( 'department' , editingId ( ) ! , payload ) ;
} else {
await createModuleRecord < DepartmentRecord > ( 'department' , payload ) ;
}
setMainTab ( 'all' ) ;
setOpenMenuId ( null ) ;
resetForm ( ) ;
await load ( ) ;
ui(step-1): match reference layout for dept/designation/employees/roles pages
- All pages: white sticky page header + tab bar with orange underline,
-mx-6 -mt-6 negative margin to stretch headers edge-to-edge
- department: full columns (ID, Name, Description, Created By, etc.),
icon-only action buttons, navy Add Department button
- designation: Designations List / Add Designation tabs, status filter
dropdown, inline create/edit form, full columns with status badge
- employees: View/Add tabs, icon-only action buttons, status badges
- roles/index: clean table with Name+code subtext, Description, actions
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 04:47:05 +01:00
} ;
2026-03-26 06:20:22 +01:00
const filteredRows = createMemo ( ( ) = > rows ( ) ? ? [ ] ) ;
const permissionGroups = [
{
title : 'Employee Management' ,
items : [ 'View Employees' , 'Create Employees' , 'Edit Employees' , 'Delete Employees' ] ,
} ,
{
title : 'Role Management' ,
items : [ 'View Roles' , 'Assign Roles' ] ,
} ,
{
title : 'Department Settings' ,
items : [ 'Manage Department Settings' ] ,
} ,
] ;
const formatDate = ( value? : string ) = > {
const input = value || '' ;
if ( /^\d{4}-\d{2}-\d{2}$/ . test ( input ) ) return input ;
const fallback = input || new Date ( ) . toISOString ( ) . slice ( 0 , 10 ) ;
return fallback . slice ( 0 , 10 ) ;
feat(admin): build complete admin panel with UI parity and search/filter
- Implement all admin management pages (employees, users, jobs, leads, orders, companies, customers, candidates, approval, invoices, reviews, support, KB, pricing, coupons, credits, discounts, tax, reports, ledger)
- Implement 9 professional vertical pages (developers, designers, tutors, video editors, photographers, makeup artists, graphic designers, social media managers, fitness trainers)
- Implement internal/external dashboard and role management with builder UI
- Fix tab styling: replace inline border-bottom styles with admin-tab CSS class across 8+ pages
- Add search/filter functionality to invoice and review pages
- Add toggle status (activate/deactivate) to employees page with PATCH /api/admin/employees/{id}
- Align UI styling with NextJS admin panel for visual parity
- Add stat cards to approval page showing counts by status
- Implement graceful empty states for all list views
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-19 13:04:10 +01:00
} ;
return (
< AdminShell >
2026-03-26 06:20:22 +01:00
< div class = "space-y-5" >
< section >
< h1 class = "text-[24px] font-semibold leading-[1.1] tracking-[-0.01em] text-[#050026]" > Department Management < / h1 >
< p class = "mt-2 text-[16px] leading-[1.35] text-[#7a8099]" > Manage all departments and organizational structure < / p >
< / section >
feat(admin): build complete admin panel with UI parity and search/filter
- Implement all admin management pages (employees, users, jobs, leads, orders, companies, customers, candidates, approval, invoices, reviews, support, KB, pricing, coupons, credits, discounts, tax, reports, ledger)
- Implement 9 professional vertical pages (developers, designers, tutors, video editors, photographers, makeup artists, graphic designers, social media managers, fitness trainers)
- Implement internal/external dashboard and role management with builder UI
- Fix tab styling: replace inline border-bottom styles with admin-tab CSS class across 8+ pages
- Add search/filter functionality to invoice and review pages
- Add toggle status (activate/deactivate) to employees page with PATCH /api/admin/employees/{id}
- Align UI styling with NextJS admin panel for visual parity
- Add stat cards to approval page showing counts by status
- Implement graceful empty states for all list views
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-19 13:04:10 +01:00
2026-03-26 06:20:22 +01:00
< section class = "overflow-hidden rounded-[24px] border border-[#d9dde6] bg-[#f7f7f8]" >
< div class = "flex items-center gap-2 border-b border-[#e1e5ee] px-5 pt-4" >
< button onClick = { ( ) = > setMainTab ( 'all' ) } class = { ` relative px-8 pb-4 pt-2 text-[16px] font-semibold ${ mainTab ( ) === 'all' ? 'text-[#0c123f]' : 'text-[#737a96]' } ` } >
All Departments
< Show when = { mainTab ( ) === 'all' } > < span class = "absolute inset-x-0 -bottom-[1px] h-[4px] rounded-full bg-[#0a0a50]" / > < / Show >
< / button >
< button onClick = { openCreate } class = { ` relative px-8 pb-4 pt-2 text-[16px] font-semibold ${ mainTab ( ) === 'create' ? 'text-[#0c123f]' : 'text-[#737a96]' } ` } >
{ editingId ( ) ? 'Edit Department' : 'Create Department' }
< Show when = { mainTab ( ) === 'create' } > < span class = "absolute inset-x-0 -bottom-[1px] h-[4px] rounded-full bg-[#0a0a50]" / > < / Show >
< / button >
< / div >
feat(admin): build complete admin panel with UI parity and search/filter
- Implement all admin management pages (employees, users, jobs, leads, orders, companies, customers, candidates, approval, invoices, reviews, support, KB, pricing, coupons, credits, discounts, tax, reports, ledger)
- Implement 9 professional vertical pages (developers, designers, tutors, video editors, photographers, makeup artists, graphic designers, social media managers, fitness trainers)
- Implement internal/external dashboard and role management with builder UI
- Fix tab styling: replace inline border-bottom styles with admin-tab CSS class across 8+ pages
- Add search/filter functionality to invoice and review pages
- Add toggle status (activate/deactivate) to employees page with PATCH /api/admin/employees/{id}
- Align UI styling with NextJS admin panel for visual parity
- Add stat cards to approval page showing counts by status
- Implement graceful empty states for all list views
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-19 13:04:10 +01:00
2026-03-26 06:20:22 +01:00
< Show when = { mainTab ( ) === 'all' } >
< div class = "space-y-5 p-5" >
< label class = "flex h-[48px] items-center rounded-[14px] border border-[#d9dde6] bg-[#f7f7f8] px-4 text-[16px] text-[#8a90a8]" >
< svg class = "mr-3 h-5 w-5 text-[#8a90a8]" viewBox = "0 0 24 24" fill = "none" stroke = "currentColor" stroke-width = "1.8" aria-hidden = "true" > < circle cx = "11" cy = "11" r = "7" / > < path d = "m20 20-3.5-3.5" / > < / svg >
< input
value = { search ( ) }
onInput = { ( e ) = > {
setSearch ( e . currentTarget . value ) ;
void load ( ) ;
} }
placeholder = "Search departments..."
class = "w-full border-0 bg-transparent text-[16px] text-[#1a2147] outline-none placeholder:text-[#8a90a8]"
/ >
< / label >
2026-03-26 00:01:15 +01:00
2026-03-26 06:20:22 +01:00
< div class = "relative rounded-[18px] border border-[#d8dce6] bg-[#f7f7f8]" >
< table class = "min-w-full table-fixed text-left" >
< thead class = "bg-[#030047] text-white" >
< tr >
< th class = "w-[18%] px-6 py-4 text-[14px] font-semibold" > DEPARTMENT NAME < / th >
< th class = "w-[14%] px-6 py-4 text-[14px] font-semibold" > DEPARTMENT CODE < / th >
< th class = "w-[31%] px-6 py-4 text-[14px] font-semibold" > DESCRIPTION < / th >
< th class = "w-[10%] px-6 py-4 text-[14px] font-semibold" > TOTAL EMPLOYEES < / th >
< th class = "w-[10%] px-6 py-4 text-[14px] font-semibold" > STATUS < / th >
< th class = "w-[10%] px-6 py-4 text-[14px] font-semibold" > CREATED DATE < / th >
< th class = "w-[7%] px-6 py-4 text-[14px] font-semibold" > ACTIONS < / th >
< / tr >
< / thead >
< tbody class = "divide-y divide-[#dde1ea] text-[#222948]" >
< For each = { filteredRows ( ) } >
{ ( row ) = > (
< tr class = "bg-[#f7f7f8]" >
< td class = "px-6 py-4 text-[15px] font-semibold" > { row . name } < / td >
< td class = "px-6 py-4 text-[15px] font-medium text-[#505779]" > { String ( row . code || '' ) } < / td >
< td class = "px-6 py-4 text-[14px] font-medium text-[#6b7393]" > { String ( row . description || '' ) } < / td >
< td class = "px-6 py-4 text-[15px] font-semibold" > { Number ( row . totalEmployees || 0 ) } < / td >
< td class = "px-6 py-4" >
< span class = { ` inline-flex rounded-[10px] border px-3 py-1.5 text-[14px] font-semibold ${ row . status === 'ACTIVE' ? 'border-[#ffc2aa] bg-[#ffeee6] text-[#fd6116]' : 'border-[#c7ccda] bg-[#eceff6] text-[#101848]' } ` } >
{ row . status === 'ACTIVE' ? 'Active' : 'Inactive' }
< / span >
< / td >
< td class = "px-6 py-4 text-[14px] font-medium text-[#6b7393]" > { formatDate ( String ( row . createdDate || row . updatedAt || '' ) ) } < / td >
< td class = "relative px-6 py-4" >
< button onClick = { ( ) = > setOpenMenuId ( openMenuId ( ) === row . id ? null : row . id ) } class = "inline-flex h-10 w-10 items-center justify-center rounded-lg text-[#6c7292] hover:bg-[#eceff5]" aria-label = "More actions" >
< span class = "text-[20px] leading-none" > ⋮ < / span >
< / button >
< Show when = { openMenuId ( ) === row . id } >
< div class = "absolute right-6 top-14 z-20 w-[220px] rounded-2xl border border-[#d6dbe6] bg-white p-2 shadow-[0_16px_28px_rgba(5,0,38,0.16)]" >
< button onClick = { ( ) = > openEdit ( row ) } class = "flex w-full items-center gap-3 rounded-xl px-3 py-2 text-left text-[16px] font-medium text-[#20284d] hover:bg-[#f5f7fb]" >
< svg class = "h-5 w-5 text-[#fd6116]" viewBox = "0 0 24 24" fill = "none" stroke = "currentColor" stroke-width = "2" aria-hidden = "true" > < path d = "M12 20h9" / > < path d = "m16.5 3.5 4 4L7 21H3v-4L16.5 3.5Z" / > < / svg >
Edit Department
< / button >
< button onClick = { async ( ) = > { await updateModuleRecord < DepartmentRecord > ( 'department' , row . id , { status : row.status === 'ACTIVE' ? 'INACTIVE' : 'ACTIVE' } ) ; setOpenMenuId ( null ) ; await load ( ) ; } } class = "flex w-full items-center gap-3 rounded-xl px-3 py-2 text-left text-[16px] font-medium text-[#20284d] hover:bg-[#f5f7fb]" >
< svg class = "h-5 w-5 text-[#fd6116]" viewBox = "0 0 24 24" fill = "none" stroke = "currentColor" stroke-width = "2" aria-hidden = "true" > < circle cx = "12" cy = "12" r = "9" / > < path d = "M8 8l8 8" / > < / svg >
{ row . status === 'ACTIVE' ? 'Deactivate Department' : 'Activate Department' }
< / button >
< button onClick = { async ( ) = > { await deleteModuleRecord ( 'department' , row . id ) ; setOpenMenuId ( null ) ; await load ( ) ; } } class = "flex w-full items-center gap-3 rounded-xl px-3 py-2 text-left text-[16px] font-medium text-[#20284d] hover:bg-[#f5f7fb]" >
< svg class = "h-5 w-5 text-[#fd6116]" viewBox = "0 0 24 24" fill = "none" stroke = "currentColor" stroke-width = "2" aria-hidden = "true" > < path d = "M3 6h18" / > < path d = "M8 6V4h8v2" / > < path d = "M19 6l-1 14H6L5 6" / > < path d = "M10 11v6M14 11v6" / > < / svg >
Delete Department
< / button >
< / div >
< / Show >
< / td >
< / tr >
2026-03-26 00:01:15 +01:00
) }
< / For >
2026-03-26 06:20:22 +01:00
< / tbody >
< / table >
< div class = "flex items-center justify-between border-t border-[#dde1ea] px-6 py-4" >
< p class = "text-[14px] text-[#707895]" > Showing < span class = "font-semibold text-[#283055]" > 1 - { rows ( ) . length } < / span > of < span class = "font-semibold text-[#283055]" > { rows ( ) . length } < / span > departments < / p >
< div class = "flex items-center gap-2" >
< button class = "inline-flex h-10 w-10 items-center justify-center rounded-[12px] border border-[#d5dae6] text-[#8a90a8]" > ‹ < / button >
< button class = "inline-flex h-10 w-10 items-center justify-center rounded-[12px] bg-[#fd6116] font-semibold text-white" > 1 < / button >
< button class = "inline-flex h-10 w-10 items-center justify-center rounded-[12px] border border-[#d5dae6] font-semibold text-[#2a3052]" > 2 < / button >
< button class = "inline-flex h-10 w-10 items-center justify-center rounded-[12px] border border-[#d5dae6] font-semibold text-[#2a3052]" > 3 < / button >
< button class = "inline-flex h-10 w-10 items-center justify-center rounded-[12px] border border-[#d5dae6] text-[#8a90a8]" > › < / button >
2026-03-26 00:01:15 +01:00
< / div >
2026-03-26 06:20:22 +01:00
< / div >
< / div >
< / div >
< / Show >
2026-03-26 00:01:15 +01:00
2026-03-26 06:20:22 +01:00
< Show when = { mainTab ( ) === 'create' } >
< div class = "space-y-6 p-5" >
< div class = "flex items-center gap-2 border-b border-[#e1e5ee] pb-3" >
< button onClick = { ( ) = > setCreateTab ( 'general' ) } class = { ` relative px-6 pb-3 text-[16px] font-semibold ${ createTab ( ) === 'general' ? 'text-[#0b123f]' : 'text-[#767d98]' } ` } > General Information < Show when = { createTab ( ) === 'general' } > < span class = "absolute inset-x-0 -bottom-[2px] h-[4px] rounded-full bg-[#0a0a50]" / > < / Show > < / button >
< button onClick = { ( ) = > setCreateTab ( 'settings' ) } class = { ` relative px-6 pb-3 text-[16px] font-semibold ${ createTab ( ) === 'settings' ? 'text-[#0b123f]' : 'text-[#767d98]' } ` } > Department Settings < Show when = { createTab ( ) === 'settings' } > < span class = "absolute inset-x-0 -bottom-[2px] h-[4px] rounded-full bg-[#0a0a50]" / > < / Show > < / button >
< button onClick = { ( ) = > setCreateTab ( 'permissions' ) } class = { ` relative px-6 pb-3 text-[16px] font-semibold ${ createTab ( ) === 'permissions' ? 'text-[#0b123f]' : 'text-[#767d98]' } ` } > Permissions < Show when = { createTab ( ) === 'permissions' } > < span class = "absolute inset-x-0 -bottom-[2px] h-[4px] rounded-full bg-[#0a0a50]" / > < / Show > < / button >
< / div >
< Show when = { createTab ( ) === 'general' } >
< div class = "space-y-5" >
< div class = "grid gap-5 md:grid-cols-2" >
< label class = "block text-[14px] font-semibold text-[#101848]" > Department Name < span class = "text-[#fd6116]" > * < / span > < input value = { name ( ) } onInput = { ( e ) = > setName ( e . currentTarget . value ) } class = "mt-2 h-[48px] w-full rounded-[14px] border border-[#d9dde6] bg-[#f7f7f8] px-4 text-[16px] text-[#1a2147] outline-none" placeholder = "Enter department name" / > < / label >
< label class = "block text-[14px] font-semibold text-[#101848]" > Department Code < span class = "text-[#fd6116]" > * < / span > < input value = { code ( ) } onInput = { ( e ) = > setCode ( e . currentTarget . value ) } class = "mt-2 h-[48px] w-full rounded-[14px] border border-[#d9dde6] bg-[#f7f7f8] px-4 text-[16px] text-[#1a2147] outline-none" placeholder = "e.g., ENG-001" / > < / label >
< / div >
< label class = "block text-[14px] font-semibold text-[#101848]" > Department Description < textarea value = { description ( ) } onInput = { ( e ) = > setDescription ( e . currentTarget . value ) } class = "mt-2 h-[110px] w-full rounded-[14px] border border-[#d9dde6] bg-[#f7f7f8] px-4 py-3 text-[16px] text-[#1a2147] outline-none" placeholder = "Enter department description" / > < / label >
< div class = "grid gap-5 md:grid-cols-2" >
< label class = "block text-[14px] font-semibold text-[#101848]" > Department Head < input value = { departmentHead ( ) } onInput = { ( e ) = > setDepartmentHead ( e . currentTarget . value ) } class = "mt-2 h-[48px] w-full rounded-[14px] border border-[#d9dde6] bg-[#f7f7f8] px-4 text-[16px] text-[#1a2147] outline-none" / > < / label >
< label class = "block text-[14px] font-semibold text-[#101848]" > Department Email < input value = { departmentEmail ( ) } onInput = { ( e ) = > setDepartmentEmail ( e . currentTarget . value ) } class = "mt-2 h-[48px] w-full rounded-[14px] border border-[#d9dde6] bg-[#f7f7f8] px-4 text-[16px] text-[#1a2147] outline-none" placeholder = "department@example.com" / > < / label >
2026-03-26 00:01:15 +01:00
< / div >
2026-03-26 06:20:22 +01:00
< / div >
< / Show >
ui(step-1): match reference layout for dept/designation/employees/roles pages
- All pages: white sticky page header + tab bar with orange underline,
-mx-6 -mt-6 negative margin to stretch headers edge-to-edge
- department: full columns (ID, Name, Description, Created By, etc.),
icon-only action buttons, navy Add Department button
- designation: Designations List / Add Designation tabs, status filter
dropdown, inline create/edit form, full columns with status badge
- employees: View/Add tabs, icon-only action buttons, status badges
- roles/index: clean table with Name+code subtext, Description, actions
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 04:47:05 +01:00
2026-03-26 06:20:22 +01:00
< Show when = { createTab ( ) === 'settings' } >
< div class = "space-y-6" >
< div >
< p class = "text-[18px] font-semibold text-[#101848]" > Department Status < / p >
< div class = "mt-3 flex gap-3" >
< button onClick = { ( ) = > setStatus ( 'ACTIVE' ) } class = { ` h-[44px] rounded-[12px] border px-6 text-[16px] font-semibold ${ status ( ) === 'ACTIVE' ? 'border-[#fd6116] bg-[#fd6116] text-white' : 'border-[#d3d8e4] bg-[#f7f7f8] text-[#1a2147]' } ` } > Active < / button >
< button onClick = { ( ) = > setStatus ( 'INACTIVE' ) } class = { ` h-[44px] rounded-[12px] border px-6 text-[16px] font-semibold ${ status ( ) === 'INACTIVE' ? 'border-[#fd6116] bg-[#fd6116] text-white' : 'border-[#d3d8e4] bg-[#f7f7f8] text-[#1a2147]' } ` } > Inactive < / button >
< / div >
ui(step-1): match reference layout for dept/designation/employees/roles pages
- All pages: white sticky page header + tab bar with orange underline,
-mx-6 -mt-6 negative margin to stretch headers edge-to-edge
- department: full columns (ID, Name, Description, Created By, etc.),
icon-only action buttons, navy Add Department button
- designation: Designations List / Add Designation tabs, status filter
dropdown, inline create/edit form, full columns with status badge
- employees: View/Add tabs, icon-only action buttons, status badges
- roles/index: clean table with Name+code subtext, Description, actions
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 04:47:05 +01:00
< / div >
2026-03-26 06:20:22 +01:00
< div >
< p class = "text-[18px] font-semibold text-[#101848]" > Department Visibility < / p >
< div class = "mt-3 space-y-3" >
< div class = "rounded-[18px] border border-[#d9dde6] bg-[#f7f7f8] px-6 py-4" >
< p class = "text-[16px] font-semibold text-[#101848]" > Internal < / p >
< p class = "text-[14px] text-[#7d849f]" > Only visible to internal employees < / p >
< / div >
< div class = "rounded-[18px] border border-[#d9dde6] bg-[#f7f7f8] px-6 py-4" >
< p class = "text-[16px] font-semibold text-[#101848]" > External < / p >
< p class = "text-[14px] text-[#7d849f]" > Visible to external users and partners < / p >
2026-03-26 00:01:15 +01:00
< / div >
ui(step-1): match reference layout for dept/designation/employees/roles pages
- All pages: white sticky page header + tab bar with orange underline,
-mx-6 -mt-6 negative margin to stretch headers edge-to-edge
- department: full columns (ID, Name, Description, Created By, etc.),
icon-only action buttons, navy Add Department button
- designation: Designations List / Add Designation tabs, status filter
dropdown, inline create/edit form, full columns with status badge
- employees: View/Add tabs, icon-only action buttons, status badges
- roles/index: clean table with Name+code subtext, Description, actions
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 04:47:05 +01:00
< / div >
2026-03-26 06:20:22 +01:00
< / div >
< div class = "flex items-center justify-between rounded-[18px] border border-[#d9dde6] bg-[#f7f7f8] px-6 py-4" >
< div > < p class = "text-[16px] font-semibold text-[#101848]" > Allow Employee Transfers < / p > < p class = "text-[14px] text-[#7d849f]" > Enable employees to request transfer to this department < / p > < / div >
< button onClick = { ( ) = > setTransfersEnabled ( ( v ) = > ! v ) } class = { ` relative h-9 w-16 rounded-full transition ${ transfersEnabled ( ) ? 'bg-[#fd6116]' : 'bg-[#e0e4ec]' } ` } > < span class = { ` absolute top-1 h-7 w-7 rounded-full bg-white transition ${ transfersEnabled ( ) ? 'left-8' : 'left-1' } ` } / > < / button >
< / div >
< / div >
< / Show >
2026-03-26 00:01:15 +01:00
2026-03-26 06:20:22 +01:00
< Show when = { createTab ( ) === 'permissions' } >
< div class = "space-y-4" >
< p class = "text-[16px] text-[#707895]" > Select permissions for this department < / p >
< For each = { permissionGroups } >
{ ( group ) = > (
< section class = "space-y-3" >
< h3 class = "text-[18px] font-semibold text-[#101848]" > { group . title } < / h3 >
< For each = { group . items } >
{ ( item ) = > < div class = "rounded-[14px] border border-[#d9dde6] bg-[#f7f7f8] px-6 py-3 text-[16px] font-semibold text-[#1c244a]" > { item } < / div > }
< / For >
< / section >
) }
< / For >
2026-03-26 00:01:15 +01:00
< / div >
2026-03-26 06:20:22 +01:00
< / Show >
< div class = "flex justify-end gap-3 border-t border-[#e1e5ee] pt-4" >
< button onClick = { ( ) = > { setMainTab ( 'all' ) ; resetForm ( ) ; } } class = "h-[44px] rounded-[12px] border border-[#d2d8e4] bg-[#f7f7f8] px-6 text-[16px] font-semibold text-[#232b4d]" > Cancel < / button >
< button onClick = { ( ) = > void saveDepartment ( ) } class = "h-[44px] rounded-[12px] bg-[#030047] px-8 text-[16px] font-semibold text-white" > { editingId ( ) ? 'Save Department' : 'Create Department' } < / button >
< / div >
< / div >
< / Show >
< / section >
ui(step-1): match reference layout for dept/designation/employees/roles pages
- All pages: white sticky page header + tab bar with orange underline,
-mx-6 -mt-6 negative margin to stretch headers edge-to-edge
- department: full columns (ID, Name, Description, Created By, etc.),
icon-only action buttons, navy Add Department button
- designation: Designations List / Add Designation tabs, status filter
dropdown, inline create/edit form, full columns with status badge
- employees: View/Add tabs, icon-only action buttons, status badges
- roles/index: clean table with Name+code subtext, Description, actions
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 04:47:05 +01:00
< / div >
feat(admin): build complete admin panel with UI parity and search/filter
- Implement all admin management pages (employees, users, jobs, leads, orders, companies, customers, candidates, approval, invoices, reviews, support, KB, pricing, coupons, credits, discounts, tax, reports, ledger)
- Implement 9 professional vertical pages (developers, designers, tutors, video editors, photographers, makeup artists, graphic designers, social media managers, fitness trainers)
- Implement internal/external dashboard and role management with builder UI
- Fix tab styling: replace inline border-bottom styles with admin-tab CSS class across 8+ pages
- Add search/filter functionality to invoice and review pages
- Add toggle status (activate/deactivate) to employees page with PATCH /api/admin/employees/{id}
- Align UI styling with NextJS admin panel for visual parity
- Add stat cards to approval page showing counts by status
- Implement graceful empty states for all list views
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-19 13:04:10 +01:00
< / AdminShell >
) ;
}