diff --git a/src/routes/admin/designation.tsx b/src/routes/admin/designation.tsx index 9d75e1b..43e790b 100644 --- a/src/routes/admin/designation.tsx +++ b/src/routes/admin/designation.tsx @@ -8,6 +8,7 @@ const API = '/api/gateway'; type DesignationRecord = CrudRecord & { code?: string; department?: string; + departmentId?: string; level?: string; description?: string; totalEmployees?: number; @@ -16,14 +17,7 @@ type DesignationRecord = CrudRecord & { canApprove?: boolean; }; -const FALLBACK_DESIGNATIONS: DesignationRecord[] = [ - { id: 'z1', name: 'Senior Software Engineer', code: 'SSE-001', department: 'Engineering', level: 'Senior', totalEmployees: 12, status: 'ACTIVE', updatedAt: '2026-03-01', createdDate: '2026-01-15' }, - { id: 'z2', name: 'Marketing Manager', code: 'MM-002', department: 'Marketing', level: 'Manager', totalEmployees: 8, status: 'ACTIVE', updatedAt: '2026-03-01', createdDate: '2026-01-20' }, - { id: 'z3', name: 'Sales Executive', code: 'SE-003', department: 'Sales', level: 'Executive', totalEmployees: 15, status: 'ACTIVE', updatedAt: '2026-03-01', createdDate: '2026-02-01' }, - { id: 'z4', name: 'HR Specialist', code: 'HRS-004', department: 'Human Resources', level: 'Specialist', totalEmployees: 5, status: 'ACTIVE', updatedAt: '2026-03-01', createdDate: '2026-02-05' }, - { id: 'z5', name: 'Product Manager', code: 'PM-005', department: 'Product', level: 'Manager', totalEmployees: 6, status: 'ACTIVE', updatedAt: '2026-03-01', createdDate: '2026-02-10' }, - { id: 'z6', name: 'Finance Analyst', code: 'FA-006', department: 'Finance', level: 'Analyst', totalEmployees: 9, status: 'INACTIVE', updatedAt: '2026-03-01', createdDate: '2026-02-15' }, -]; +type DepartmentOption = { id: string; name: string }; const permissionGroups = [ { title: 'Employee Management', items: ['View Employees', 'Create Employees', 'Edit Employees', 'Delete Employees'] }, @@ -32,7 +26,6 @@ const permissionGroups = [ ]; const LEVELS = ['Intern', 'Junior', 'Mid-Level', 'Senior', 'Lead', 'Manager', 'Director', 'VP', 'C-Level', 'Executive', 'Specialist', 'Analyst']; -const DEPARTMENTS = ['Engineering', 'Marketing', 'Sales', 'Human Resources', 'Finance', 'Operations', 'Product', 'Customer Success']; type DesignationListResponse = { designations?: any[]; @@ -51,16 +44,17 @@ function normalizeDesignation(item: any, idx: number): DesignationRecord { return { id: String(item.id ?? `des-${idx + 1}`), name: String(item.name ?? ''), - code: String(item.code ?? ''), - department: String(item.department ?? item.department_name ?? ''), - level: String(item.level ?? ''), - description: String(item.description ?? ''), - totalEmployees: Number(item.totalEmployees ?? item.total_employees ?? 0), - canManageTeam: Boolean(item.canManageTeam ?? item.can_manage_team ?? false), - canApprove: Boolean(item.canApprove ?? item.can_approve ?? false), + code: item.code ? String(item.code) : undefined, + department: item.department_name ? String(item.department_name) : undefined, + departmentId: item.department_id ? String(item.department_id) : undefined, + level: item.level ? String(item.level) : undefined, + description: item.description ? String(item.description) : undefined, + totalEmployees: Number(item.total_employees ?? 0), + canManageTeam: Boolean(item.can_manage_team ?? false), + canApprove: Boolean(item.can_approve ?? false), status: isActive ? 'ACTIVE' : 'INACTIVE', - updatedAt: String(item.updatedAt ?? item.updated_at ?? ''), - createdDate: String(item.createdDate ?? item.created_at ?? ''), + updatedAt: String(item.updated_at ?? ''), + createdDate: String(item.created_at ?? ''), }; } @@ -128,7 +122,7 @@ export default function DesignationManagementPage() { const [name, setName] = createSignal(''); const [code, setCode] = createSignal(''); - const [department, setDepartment] = createSignal(''); + const [departmentId, setDepartmentId] = createSignal(''); const [level, setLevel] = createSignal(''); const [description, setDescription] = createSignal(''); const [status, setStatus] = createSignal<'ACTIVE' | 'INACTIVE'>('ACTIVE'); @@ -137,52 +131,61 @@ export default function DesignationManagementPage() { const [isLoading, setIsLoading] = createSignal(false); const [isSaving, setIsSaving] = createSignal(false); const [error, setError] = createSignal(''); + const [departments, setDepartments] = createSignal([]); const load = async () => { setIsLoading(true); setError(''); try { - try { - const params = new URLSearchParams({ - page: '1', - per_page: '100', - q: search().trim(), - }); - if (statusFilter() !== 'all') { - params.set('status', statusFilter()); - } - if (deptFilter() !== 'all') { - params.set('department', deptFilter()); - } - const res = await fetch(`${API}/api/admin/designations?${params.toString()}`); - if (!res.ok) { - throw new Error(`Request failed (${res.status})`); - } - const payload = (await res.json().catch(() => null)) as DesignationListResponse | null; - const list = Array.isArray(payload) - ? payload - : Array.isArray(payload?.designations) - ? payload.designations - : Array.isArray(payload?.data) - ? payload.data - : Array.isArray(payload?.items) - ? payload.items - : []; - if (list.length === 0) { - setRows(FALLBACK_DESIGNATIONS); - } else { - setRows(list.map(normalizeDesignation)); - } - } catch { - setRows(FALLBACK_DESIGNATIONS); - setError('Could not reach designations API, showing fallback data.'); + const params = new URLSearchParams({ + page: '1', + per_page: '100', + q: search().trim(), + }); + if (statusFilter() !== 'all') { + params.set('status', statusFilter()); } + if (deptFilter() !== 'all') { + params.set('department_id', deptFilter()); + } + const res = await fetch(`${API}/api/admin/designations?${params.toString()}`); + if (!res.ok) throw new Error(`Request failed (${res.status})`); + const payload = (await res.json().catch(() => null)) as DesignationListResponse | null; + const list = Array.isArray(payload) + ? payload + : Array.isArray(payload?.designations) + ? payload.designations + : Array.isArray(payload?.data) + ? payload.data + : Array.isArray(payload?.items) + ? payload.items + : []; + setRows(list.map(normalizeDesignation)); + } catch (err: any) { + setError(err?.message || 'Could not reach designations API.'); + setRows([]); } finally { setIsLoading(false); } }; - onMount(() => void load()); + const loadDepartments = async () => { + try { + const res = await fetch(`${API}/api/admin/departments?per_page=100`); + if (!res.ok) return; + const payload = await res.json().catch(() => null); + const list: any[] = Array.isArray(payload) + ? payload + : Array.isArray(payload?.departments) + ? payload.departments + : []; + setDepartments(list.map((d: any) => ({ id: String(d.id), name: String(d.name) }))); + } catch { + // departments dropdown will just be empty + } + }; + + onMount(() => { void load(); void loadDepartments(); }); const filteredRows = createMemo(() => { let r = rows(); @@ -209,7 +212,7 @@ export default function DesignationManagementPage() { }); const resetForm = () => { - setEditingId(null); setName(''); setCode(''); setDepartment(''); + setEditingId(null); setName(''); setCode(''); setDepartmentId(''); setLevel(''); setDescription(''); setStatus('ACTIVE'); setCanManageTeam(false); setCanApprove(false); setFormTab('general'); setError(''); }; @@ -218,9 +221,9 @@ export default function DesignationManagementPage() { const openEdit = (row: DesignationRecord) => { setEditingId(row.id); - setName(row.name || ''); setCode(String(row.code || '')); - setDepartment(String(row.department || '')); setLevel(String(row.level || '')); - setDescription(String(row.description || '')); + setName(row.name || ''); setCode(row.code || ''); + setDepartmentId(row.departmentId || ''); setLevel(row.level || ''); + setDescription(row.description || ''); setStatus(row.status === 'INACTIVE' ? 'INACTIVE' : 'ACTIVE'); setCanManageTeam(Boolean(row.canManageTeam)); setCanApprove(Boolean(row.canApprove)); setFormTab('general'); setView('form'); setOpenMenuId(null); @@ -235,16 +238,18 @@ export default function DesignationManagementPage() { setIsSaving(true); setError(''); - const payload = { + const payload: Record = { name: name().trim(), code: code().trim(), - department: department().trim(), - level: level().trim(), + level: level().trim() || null, description: description().trim() || null, status: status(), can_manage_team: canManageTeam(), can_approve: canApprove(), }; + if (departmentId().trim()) { + payload.department_id = departmentId().trim(); + } try { const endpoint = editingId() @@ -594,9 +599,9 @@ export default function DesignationManagementPage() {
- + - {(d) => } + {(d) => }