import { For, Show, createMemo, createSignal, onMount } from 'solid-js'; import AdminShell from '~/components/AdminShell'; import { createModuleRecord, deleteModuleRecord, listModuleRecords, updateModuleRecord } from '~/lib/admin/client'; import type { CrudRecord } from '~/lib/admin/types'; type DepartmentRecord = CrudRecord & { code?: string; description?: string; totalEmployees?: number; createdDate?: string; departmentHead?: string; departmentEmail?: string; transfersEnabled?: boolean; }; const FALLBACK_DEPARTMENTS: DepartmentRecord[] = [ { id: 'd1', name: 'Engineering', code: 'ENG-001', description: 'Software development and technical architecture', totalEmployees: 45, departmentHead: 'Arun Kumar', status: 'ACTIVE', updatedAt: '2026-03-01', createdDate: '2026-01-15' }, { id: 'd2', name: 'Marketing', code: 'MKT-002', description: 'Brand management and digital marketing', totalEmployees: 23, departmentHead: 'Priya Sharma', status: 'ACTIVE', updatedAt: '2026-03-01', createdDate: '2026-01-15' }, { id: 'd3', name: 'Human Resources', code: 'HR-003', description: 'Employee relations and talent acquisition', totalEmployees: 12, departmentHead: 'Rekha Nair', status: 'ACTIVE', updatedAt: '2026-03-01', createdDate: '2026-01-20' }, { id: 'd4', name: 'Finance', code: 'FIN-004', description: 'Financial planning and accounting', totalEmployees: 18, departmentHead: 'Suresh Menon', status: 'ACTIVE', updatedAt: '2026-03-01', createdDate: '2026-01-20' }, { id: 'd5', name: 'Operations', code: 'OPS-005', description: 'Business operations and process management', totalEmployees: 31, departmentHead: 'Deepak Verma', status: 'ACTIVE', updatedAt: '2026-03-01', createdDate: '2026-02-01' }, { id: 'd6', name: 'Customer Success', code: 'CS-006', description: 'Client support and relationship management', totalEmployees: 27, departmentHead: 'Anita Pillai', status: 'ACTIVE', updatedAt: '2026-03-01', createdDate: '2026-02-01' }, { id: 'd7', name: 'Product', code: 'PRD-007', description: 'Product strategy and development', totalEmployees: 19, departmentHead: 'Kiran Rao', status: 'INACTIVE', updatedAt: '2026-03-01', createdDate: '2026-02-10' }, { id: 'd8', name: 'Sales', code: 'SAL-008', description: 'Revenue generation and client acquisition', totalEmployees: 34, departmentHead: 'Manoj Iyer', status: 'ACTIVE', updatedAt: '2026-03-01', createdDate: '2026-02-10' }, ]; 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'] }, ]; 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; type?: string }) { return ( ); } export default function DepartmentManagementPage() { const [view, setView] = createSignal<'list' | 'form'>('list'); const [formTab, setFormTab] = createSignal<'general' | 'settings' | 'permissions'>('general'); const [search, setSearch] = createSignal(''); const [statusFilter, setStatusFilter] = createSignal('all'); const [rows, setRows] = createSignal([]); const [openMenuId, setOpenMenuId] = createSignal(null); const [editingId, setEditingId] = createSignal(null); 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); const load = async () => { try { 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 ?? `dep-${i + 1}`), name: String(item.name ?? ''), code: String(item.code ?? ''), description: String(item.description ?? ''), totalEmployees: Number(item.totalEmployees ?? item.total_employees ?? 0), departmentHead: String(item.departmentHead ?? item.department_head ?? ''), status: String(item.status ?? 'ACTIVE').toUpperCase() === 'INACTIVE' ? 'INACTIVE' : 'ACTIVE', updatedAt: String(item.updatedAt ?? item.updated_at ?? ''), createdDate: String(item.createdDate ?? item.created_at ?? ''), }))); return; } } } catch {} try { const data = await listModuleRecords('department', { q: search().trim() || undefined }); setRows(Array.isArray(data) && data.length > 0 ? data : FALLBACK_DEPARTMENTS); } catch { setRows(FALLBACK_DEPARTMENTS); } }; onMount(() => void load()); const filteredRows = createMemo(() => { let r = rows(); if (statusFilter() !== 'all') r = r.filter((d) => d.status === statusFilter().toUpperCase()); const q = search().toLowerCase(); if (q) r = r.filter((d) => d.name.toLowerCase().includes(q) || String(d.code ?? '').toLowerCase().includes(q)); return r; }); const resetForm = () => { setEditingId(null); setName(''); setCode(''); setDescription(''); setDepartmentHead(''); setDepartmentEmail(''); setStatus('ACTIVE'); setTransfersEnabled(false); setFormTab('general'); }; const openCreate = () => { resetForm(); setView('form'); }; 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'); setTransfersEnabled(Boolean(row.transfersEnabled)); setFormTab('general'); setView('form'); setOpenMenuId(null); }; const save = async () => { const payload: Partial = { 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('department', editingId()!, payload); } else { await createModuleRecord('department', payload); } setView('list'); resetForm(); await load(); }; const formatDate = (v?: string) => { const s = v || ''; if (/^\d{4}-\d{2}-\d{2}$/.test(s)) return s; return s.slice(0, 10) || '—'; }; const stats = createMemo(() => ({ total: rows().length, active: rows().filter((d) => d.status === 'ACTIVE').length, inactive: rows().filter((d) => d.status === 'INACTIVE').length, totalEmployees: rows().reduce((acc, d) => acc + Number(d.totalEmployees || 0), 0), })); return (
{/* Page header */}

{view() === 'form' ? 'Department Management' : 'Organisation'}

{view() === 'form' ? (editingId() ? 'Edit Department' : 'Create Department') : 'Department Management'}

{view() === 'form' ? 'Dashboard / Department Management / ' + (editingId() ? 'Edit Department' : 'Create Department') : 'Manage all departments and organisational structure'}

{/* ── LIST VIEW ── */} {/* Summary cards */}
{[ { label: 'Total Departments', value: stats().total, color: 'text-[#FF5E13]', bg: 'bg-[#FFF1EB]' }, { label: 'Active', value: stats().active, color: 'text-[#059669]', bg: 'bg-[#ECFDF5]' }, { label: 'Inactive', value: stats().inactive, color: 'text-[#6B7280]', bg: 'bg-[#F3F4F6]' }, { label: 'Total Employees', value: stats().totalEmployees, color: 'text-[#2563EB]', bg: 'bg-[#EFF6FF]' }, ].map((s) => (
{s.value}

{s.label}

{s.value}

))}
{/* Table card */}
{/* Filters */}
{/* Search */}
{ setSearch(e.currentTarget.value); void load(); }} placeholder="Search departments..." class="h-[40px] w-full rounded-xl border border-[#E5E7EB] bg-[#F9FAFB] pl-10 pr-4 text-[13px] text-[#111827] outline-none placeholder:text-[#9CA3AF] focus:border-[#FF5E13] focus:bg-white focus:ring-2 focus:ring-[rgba(255,94,19,0.08)] transition-colors" />
{/* Status filter */}

{filteredRows().length} departments

{/* Table */}
0} fallback={ } > {(row) => ( )}
Department Name Code Department Head Employees Status Created Actions

No departments found

Create your first department to get started.

{row.name}

{String(row.description || '')}

{String(row.code || '—')} {String(row.departmentHead || '—')} {Number(row.totalEmployees || 0)} {formatDate(String(row.createdDate || row.updatedAt || ''))}
{/* Pagination */} 0}>

Showing 1–{filteredRows().length} of {filteredRows().length} departments

{/* ── FORM VIEW (Create / Edit) ── */}
{/* Tab nav */}
{(['general', 'settings', 'permissions'] as const).map((tab, i) => { const labels = ['General Information', 'Department Settings', 'Permissions']; return ( ); })}
{/* General Information */}