mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-30 07:38:10 +00:00
user management ui
This commit is contained in:
@@ -0,0 +1,230 @@
|
||||
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,
|
||||
};
|
||||
};
|
||||
Reference in New Issue
Block a user