mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-29 14:08:11 +00:00
254 lines
6.6 KiB
TypeScript
254 lines
6.6 KiB
TypeScript
import { useState, useEffect } from "react";
|
|
import axios from "axios";
|
|
import { Position } from "./usePositions";
|
|
|
|
interface ApiResponse<T> {
|
|
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<Department[]>([]);
|
|
const [selectedDepartmentId, setSelectedDepartmentId] = useState<string>("");
|
|
const [loading, setLoading] = useState(false);
|
|
const [error, setError] = useState<Error | null>(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<Department>
|
|
): Promise<Department> => {
|
|
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<ApiResponse<Department>>(
|
|
// `/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<Department>
|
|
): Promise<Department> => {
|
|
setLoading(true);
|
|
try {
|
|
// In a real app, this would be an API call
|
|
// const response = await axios.put<ApiResponse<Department>>(
|
|
// `/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<void> => {
|
|
setLoading(true);
|
|
try {
|
|
// In a real app, this would be an API call
|
|
// await axios.delete<ApiResponse<void>>(`/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<Department> => {
|
|
const subdepartment: Partial<Department> = {
|
|
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,
|
|
};
|
|
};
|