mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-28 23:00:57 +00:00
231 lines
5.9 KiB
TypeScript
231 lines
5.9 KiB
TypeScript
import { useState, useEffect } from "react";
|
|
import axios from "axios";
|
|
|
|
interface ApiResponse<T> {
|
|
success: boolean;
|
|
data: T;
|
|
message?: string;
|
|
}
|
|
|
|
export interface Department {
|
|
id: string;
|
|
name: string;
|
|
positions: any[];
|
|
isExpanded?: boolean;
|
|
}
|
|
|
|
export interface Unit {
|
|
id: string;
|
|
name: string;
|
|
departments: Department[];
|
|
isExpanded?: boolean;
|
|
}
|
|
|
|
export const useUnits = (organizationId: string) => {
|
|
const [units, setUnits] = useState<Unit[]>([]);
|
|
const [selectedUnitId, setSelectedUnitId] = useState<string>("");
|
|
const [loading, setLoading] = useState(false);
|
|
const [error, setError] = useState<Error | null>(null);
|
|
|
|
// Fetch units for an organization
|
|
const fetchUnits = async () => {
|
|
if (!organizationId) {
|
|
setUnits([]);
|
|
setSelectedUnitId("");
|
|
return;
|
|
}
|
|
|
|
setLoading(true);
|
|
};
|
|
|
|
// Create a new unit
|
|
const createUnit = async (unitData: Partial<Unit>): Promise<Unit> => {
|
|
if (!organizationId) {
|
|
throw new Error("No organization selected");
|
|
}
|
|
|
|
setLoading(true);
|
|
try {
|
|
// In a real app, this would be an API call
|
|
// const response = await axios.post<ApiResponse<Unit>>(
|
|
// `/api/organizations/${organizationId}/units`,
|
|
// unitData
|
|
// );
|
|
// const newUnit = response.data.data;
|
|
|
|
// For now, simulate API response
|
|
const newUnit: Unit = {
|
|
id: `unit-${Date.now()}`,
|
|
name: unitData.name || "New Unit",
|
|
departments: [],
|
|
isExpanded: false,
|
|
};
|
|
|
|
setUnits((prev) => [...prev, newUnit]);
|
|
setLoading(false);
|
|
return newUnit;
|
|
} catch (err) {
|
|
setError(err instanceof Error ? err : new Error("Failed to create unit"));
|
|
setLoading(false);
|
|
throw err;
|
|
}
|
|
};
|
|
|
|
// Update an existing unit
|
|
const updateUnit = async (
|
|
unitId: string,
|
|
updates: Partial<Unit>
|
|
): Promise<Unit> => {
|
|
setLoading(true);
|
|
try {
|
|
// In a real app, this would be an API call
|
|
// const response = await axios.put<ApiResponse<Unit>>(
|
|
// `/api/units/${unitId}`,
|
|
// updates
|
|
// );
|
|
// const updatedUnit = response.data.data;
|
|
|
|
// For now, simulate API response
|
|
const updatedUnits = units.map((unit) =>
|
|
unit.id === unitId ? { ...unit, ...updates } : unit
|
|
);
|
|
|
|
setUnits(updatedUnits);
|
|
setLoading(false);
|
|
|
|
const updatedUnit = updatedUnits.find((u) => u.id === unitId);
|
|
if (!updatedUnit) {
|
|
throw new Error("Unit not found after update");
|
|
}
|
|
|
|
return updatedUnit;
|
|
} catch (err) {
|
|
setError(err instanceof Error ? err : new Error("Failed to update unit"));
|
|
setLoading(false);
|
|
throw err;
|
|
}
|
|
};
|
|
|
|
// Delete a unit
|
|
const deleteUnit = async (unitId: string): Promise<void> => {
|
|
setLoading(true);
|
|
try {
|
|
// In a real app, this would be an API call
|
|
// await axios.delete<ApiResponse<void>>(`/api/units/${unitId}`);
|
|
|
|
// For now, simulate API response
|
|
setUnits((prev) => prev.filter((unit) => unit.id !== unitId));
|
|
|
|
// If the deleted unit was selected, select another unit
|
|
if (selectedUnitId === unitId) {
|
|
const remaining = units.filter((unit) => unit.id !== unitId);
|
|
if (remaining.length > 0) {
|
|
setSelectedUnitId(remaining[0].id);
|
|
} else {
|
|
setSelectedUnitId("");
|
|
}
|
|
}
|
|
|
|
setLoading(false);
|
|
} catch (err) {
|
|
setError(err instanceof Error ? err : new Error("Failed to delete unit"));
|
|
setLoading(false);
|
|
throw err;
|
|
}
|
|
};
|
|
|
|
// Add department to a unit
|
|
const addDepartment = async (
|
|
unitId: string,
|
|
departmentName: string
|
|
): Promise<Department> => {
|
|
setLoading(true);
|
|
try {
|
|
// In a real app, this would be an API call
|
|
// const response = await axios.post<ApiResponse<Department>>(
|
|
// `/api/units/${unitId}/departments`,
|
|
// { name: departmentName }
|
|
// );
|
|
// const newDepartment = response.data.data;
|
|
|
|
// For now, simulate API response
|
|
const newDepartment: Department = {
|
|
id: `dept-${Date.now()}`,
|
|
name: departmentName,
|
|
positions: [],
|
|
isExpanded: false,
|
|
};
|
|
|
|
setUnits((prev) =>
|
|
prev.map((unit) =>
|
|
unit.id === unitId
|
|
? { ...unit, departments: [...unit.departments, newDepartment] }
|
|
: unit
|
|
)
|
|
);
|
|
|
|
setLoading(false);
|
|
return newDepartment;
|
|
} catch (err) {
|
|
setError(
|
|
err instanceof Error ? err : new Error("Failed to add department")
|
|
);
|
|
setLoading(false);
|
|
throw err;
|
|
}
|
|
};
|
|
|
|
// Toggle expand/collapse for a unit
|
|
const toggleUnitExpand = (unitId: string) => {
|
|
setUnits((prev) =>
|
|
prev.map((unit) =>
|
|
unit.id === unitId ? { ...unit, isExpanded: !unit.isExpanded } : unit
|
|
)
|
|
);
|
|
};
|
|
|
|
// Toggle expand/collapse for a department
|
|
const toggleDepartmentExpand = (unitId: string, deptId: string) => {
|
|
setUnits((prev) =>
|
|
prev.map((unit) => {
|
|
if (unit.id !== unitId) return unit;
|
|
|
|
return {
|
|
...unit,
|
|
departments: unit.departments.map((dept) =>
|
|
dept.id === deptId
|
|
? { ...dept, isExpanded: !dept.isExpanded }
|
|
: dept
|
|
),
|
|
};
|
|
})
|
|
);
|
|
};
|
|
|
|
// Select a unit
|
|
const selectUnit = (unitId: string) => {
|
|
setSelectedUnitId(unitId);
|
|
};
|
|
|
|
// Load units when organizationId changes
|
|
useEffect(() => {
|
|
fetchUnits();
|
|
}, [organizationId]);
|
|
|
|
return {
|
|
units,
|
|
selectedUnitId,
|
|
selectedUnit: units.find((unit) => unit.id === selectedUnitId),
|
|
loading,
|
|
error,
|
|
fetchUnits,
|
|
createUnit,
|
|
updateUnit,
|
|
deleteUnit,
|
|
addDepartment,
|
|
toggleUnitExpand,
|
|
toggleDepartmentExpand,
|
|
selectUnit,
|
|
};
|
|
};
|