import { useState, useEffect } from "react"; import axios from "axios"; import { Position } from "./usePositions"; interface ApiResponse { success: boolean; data: T; message?: string; } export interface Department { id: string; name: string; positions: Position[]; isExpanded?: boolean; parentDepartmentId?: string; } export const useDepartments = (unitId: string) => { const [departments, setDepartments] = useState([]); const [selectedDepartmentId, setSelectedDepartmentId] = useState(""); const [loading, setLoading] = useState(false); const [error, setError] = useState(null); // Fetch departments for a unit const fetchDepartments = async () => { if (!unitId) { setDepartments([]); setSelectedDepartmentId(""); return; } setLoading(true); try { // In a real app, this would be an API call setTimeout(() => { // Mock departments for this unit const mockDepartments: Department[] = [ { id: "dept1", name: "Directorate", positions: [], isExpanded: true, }, { id: "dept2", name: "Development", positions: [], isExpanded: false, }, { id: "dept3", name: "Operations", positions: [], isExpanded: false, }, ]; setDepartments(mockDepartments); if (mockDepartments.length > 0) { setSelectedDepartmentId(mockDepartments[0].id); } else { setSelectedDepartmentId(""); } setLoading(false); }, 500); } catch (err) { setError( err instanceof Error ? err : new Error("Failed to fetch departments") ); setLoading(false); } }; // Create a new department const createDepartment = async ( departmentData: Partial ): Promise => { if (!unitId) { throw new Error("No unit selected"); } setLoading(true); try { // In a real app, this would be an API call // const response = await axios.post>( // `/api/units/${unitId}/departments`, // departmentData // ); // const newDepartment = response.data.data; // For now, simulate API response const newDepartment: Department = { id: `dept-${Date.now()}`, name: departmentData.name || "New Department", positions: [], isExpanded: false, parentDepartmentId: departmentData.parentDepartmentId, }; setDepartments((prev) => [...prev, newDepartment]); setLoading(false); return newDepartment; } catch (err) { setError( err instanceof Error ? err : new Error("Failed to create department") ); setLoading(false); throw err; } }; // Update an existing department const updateDepartment = async ( departmentId: string, updates: Partial ): Promise => { setLoading(true); try { // In a real app, this would be an API call // const response = await axios.put>( // `/api/departments/${departmentId}`, // updates // ); // const updatedDepartment = response.data.data; // For now, simulate API response const updatedDepartments = departments.map((department) => department.id === departmentId ? { ...department, ...updates } : department ); setDepartments(updatedDepartments); setLoading(false); const updatedDepartment = updatedDepartments.find( (d) => d.id === departmentId ); if (!updatedDepartment) { throw new Error("Department not found after update"); } return updatedDepartment; } catch (err) { setError( err instanceof Error ? err : new Error("Failed to update department") ); setLoading(false); throw err; } }; // Delete a department const deleteDepartment = async (departmentId: string): Promise => { setLoading(true); try { // In a real app, this would be an API call // await axios.delete>(`/api/departments/${departmentId}`); // For now, simulate API response setDepartments((prev) => prev.filter((department) => department.id !== departmentId) ); // If the deleted department was selected, select another department if (selectedDepartmentId === departmentId) { const remaining = departments.filter( (department) => department.id !== departmentId ); if (remaining.length > 0) { setSelectedDepartmentId(remaining[0].id); } else { setSelectedDepartmentId(""); } } setLoading(false); } catch (err) { setError( err instanceof Error ? err : new Error("Failed to delete department") ); setLoading(false); throw err; } }; // Add a sub-department const addSubDepartment = async ( parentDepartmentId: string, name: string ): Promise => { const subdepartment: Partial = { name, parentDepartmentId, }; return createDepartment(subdepartment); }; // Toggle expand/collapse for a department const toggleDepartmentExpand = (departmentId: string) => { setDepartments((prev) => prev.map((department) => department.id === departmentId ? { ...department, isExpanded: !department.isExpanded } : department ) ); }; // Get root-level departments (no parent) const getRootDepartments = () => { return departments.filter((department) => !department.parentDepartmentId); }; // Get sub-departments of a department const getSubDepartments = (parentDepartmentId: string) => { return departments.filter( (department) => department.parentDepartmentId === parentDepartmentId ); }; // Select a department const selectDepartment = (departmentId: string) => { setSelectedDepartmentId(departmentId); }; // Load departments when unitId changes useEffect(() => { fetchDepartments(); }, [unitId]); return { departments, selectedDepartmentId, selectedDepartment: departments.find( (department) => department.id === selectedDepartmentId ), loading, error, fetchDepartments, createDepartment, updateDepartment, deleteDepartment, addSubDepartment, toggleDepartmentExpand, getRootDepartments, getSubDepartments, selectDepartment, }; };