import { useCallback, useEffect, useState } from "react"; import { cacheData, getCachedData } from "../slices/apiDataManager"; import ProjectRepository from "../repositories/ProjectRepository"; import { useProfile } from "./useProfile"; import { useDispatch, useSelector } from "react-redux"; import { setProjectId } from "../slices/localVariablesSlice"; import EmployeeList from "../components/Directory/EmployeeList"; import eventBus from "../services/eventBus"; import { Mutation, useMutation, useQuery, useQueryClient, } from "@tanstack/react-query"; import showToast from "../services/toastService"; // export const useProjects = () => { // const loggedUser = useSelector((store) => store.globalVariables.loginUser); // const [projects, setProjects] = useState([]); // const [loading, setLoading] = useState(true); // const [error, setError] = useState(""); // const fetchData = async () => { // const projectIds = loggedUser?.projects || []; // const filterProjects = (projectsList) => { // return projectsList // .filter((proj) => projectIds.includes(String(proj.id))) // .sort((a, b) => a?.name?.localeCompare(b.name)); // }; // const projects_cache = getCachedData("projectslist"); // if (!projects_cache) { // setLoading(true); // try { // const response = await ProjectRepository.getProjectList(); // const allProjects = response.data; // const filtered = filterProjects(allProjects); // setProjects(filtered); // cacheData("projectslist", allProjects); // } catch (err) { // setError("Failed to fetch data."); // } finally { // setLoading(false); // } // } else { // if (!projects.length) { // const filtered = filterProjects(projects_cache); // setProjects(filtered); // setLoading(false); // } // } // }; // useEffect(() => { // if (loggedUser) { // fetchData(); // } // }, [loggedUser]); // return { projects, loading, error, refetch: fetchData }; // }; // export const useEmployeesByProjectAllocated = (selectedProject) => { // const [projectEmployees, setEmployeeList] = useState([]); // const [loading, setLoading] = useState(true); // const [projects, setProjects] = useState([]); // const fetchData = async (projectid) => { // try { // let EmployeeByProject_Cache = getCachedData("empListByProjectAllocated"); // if ( // !EmployeeByProject_Cache || // !EmployeeByProject_Cache.projectId === projectid // ) { // let response = await ProjectRepository.getProjectAllocation(projectid); // setEmployeeList(response.data); // cacheData("empListByProjectAllocated", { // data: response.data, // projectId: projectid, // }); // setLoading(false); // } else { // setEmployeeList(EmployeeByProject_Cache.data); // setLoading(false); // } // } catch (err) { // setError("Failed to fetch data."); // setLoading(false); // } // }; // useEffect(() => { // if (selectedProject) { // fetchData(selectedProject); // } // }, [selectedProject]); // return { projectEmployees, loading, projects }; // }; // export const useProjectDetails = (projectId) => { // const { profile } = useProfile(); // const [projects_Details, setProject_Details] = useState(null); // const [loading, setLoading] = useState(true); // const [error, setError] = useState(""); // const fetchData = async () => { // setLoading(true); // const project_cache = getCachedData("projectInfo"); // if (!project_cache || project_cache?.projectId != projectId) { // ProjectRepository.getProjectByprojectId(projectId) // .then((response) => { // setProject_Details(response.data); // cacheData("projectInfo", { // projectId: projectId, // data: response.data, // }); // setLoading(false); // }) // .catch((error) => { // console.error(error); // setError("Failed to fetch data."); // setLoading(false); // }); // } else { // setProject_Details(project_cache.data); // setLoading(false); // } // }; // useEffect(() => { // if (profile && projectId != undefined) { // fetchData(); // } // }, [projectId, profile]); // return { projects_Details, loading, error, refetch: fetchData }; // }; // export const useProjectsByEmployee = (employeeId) => { // const [projectList, setProjectList] = useState([]); // const [loading, setLoading] = useState(false); // const [error, setError] = useState(""); // const fetchProjects = async (id) => { // try { // setLoading(true); // setError(""); // clear previous error // const res = await ProjectRepository.getProjectsByEmployee(id); // setProjectList(res.data); // cacheData("ProjectsByEmployee", { data: res.data, employeeId: id }); // setLoading(false); // } catch (err) { // setError(err?.message || "Failed to fetch projects"); // setLoading(false); // } // }; // useEffect(() => { // if (!employeeId) return; // const cache_project = getCachedData("ProjectsByEmployee"); // if (!cache_project?.data || cache_project?.employeeId !== employeeId) { // fetchProjects(employeeId); // } else { // setProjectList(cache_project.data); // } // }, [employeeId]); // return { // projectList, // loading, // error, // refetch: fetchProjects, // }; // }; // export const useProjectName = () => { // const [loading, setLoading] = useState(true); // const [projectNames, setProjectName] = useState([]); // const [Error, setError] = useState(); // const dispatch = useDispatch(); // const fetchData = async () => { // try { // let response = await ProjectRepository.projectNameList(); // setProjectName(response.data); // cacheData("basicProjectNameList", response.data); // setLoading(false); // if(response.data.length === 1){ // dispatch(setProjectId(response.data[0]?.id)); // } // } catch (err) { // setError("Failed to fetch data."); // setLoading(false); // } // }; // useEffect(() => { // fetchData(); // }, []); // return { projectNames, loading, Error, fetchData }; // }; // ------------------------------Query------------------- export const useProjects = () => { const loggedUser = useSelector((store) => store.globalVariables.loginUser); const { data: projects = [], isLoading: loading, error, refetch, } = useQuery({ queryKey: ["ProjectsList"], queryFn: async () => { const response = await ProjectRepository.getProjectList(); return response.data; }, enabled: !!loggedUser, }); return { projects, loading, error, refetch, }; }; export const useEmployeesByProjectAllocated = (selectedProject) => { const { data = [], isLoading, refetch, error, } = useQuery({ queryKey: ["empListByProjectAllocated", selectedProject], queryFn: async () => { const res = await ProjectRepository.getProjectAllocation(selectedProject); return res.data || res; }, enabled: !!selectedProject, onError: (error) => { showToast( error.message || "Error while Fetching project Allocated Employees", "error" ); }, }); return { projectEmployees: data, loading: isLoading, error, refetch, }; }; export const useProjectDetails = (projectId, isAuto = true) => { const { data: projects_Details, isLoading, error, refetch, } = useQuery({ queryKey: ["projectInfo", projectId], queryFn: async () => { const res = await ProjectRepository.getProjectByprojectId(projectId); return res.data || res; }, enabled: !!projectId && isAuto, onError: (error) => { showToast( error.message || "Error while Fetching project Details", "error" ); }, }); return { projects_Details, loading: isLoading, error, refetch }; }; export const useProjectsByEmployee = (employeeId) => { const { data: projectNameList = [], isLoading, error, refetch, } = useQuery({ queryKey: ["ProjectsByEmployee", employeeId], queryFn: async () => { const res = await ProjectRepository.getProjectsByEmployee(employeeId); return res.data || res; }, enabled: !!employeeId, onError: (error) => { showToast( error.message || "Error while Fetching project Employee", "error" ); }, }); return { projectList, loading: isLoading, error, refetch }; }; export const useProjectName = () => { const { data = [], isLoading, error, refetch, } = useQuery({ queryKey: ["basicProjectNameList"], queryFn: async () => { const res = await ProjectRepository.projectNameList(); return res.data || res; }, onError: (error) => { showToast(error.message || "Error while Fetching project Name", "error"); }, }); return { projectNames: data, loading: isLoading, Error: error, refetch }; }; export const useProjectInfra = (projectId) => { const { data: projectInfra, isLoading, error, } = useQuery({ queryKey: ["ProjectInfra", projectId], queryFn: async () => { const res = await ProjectRepository.getProjectInfraByproject(projectId); return res.data; }, enabled: !!projectId, onError: (error) => { showToast(error.message || "Error while fetching project infra", "error"); }, }); return { projectInfra, isLoading, error }; }; export const useProjectTasks = (workAreaId, IsExpandedArea = false) => { const { data: ProjectTaskList, isLoading, error, } = useQuery({ queryKey: ["WorkItems", workAreaId], queryFn: async () => { const res = await ProjectRepository.getProjectTasksByWorkArea(workAreaId); return res.data; }, enabled: !!workAreaId && !!IsExpandedArea, onError: (error) => { showToast(error.message || "Error while Fetching project Tasks", "error"); }, }); return { ProjectTaskList, isLoading, error }; }; // -- -------------Mutation------------------------------- export const useCreateProject = ({ onSuccessCallback }) => { const queryClient = useQueryClient(); return useMutation({ mutationFn: async (newProject) => { const res = await ProjectRepository.manageProject(newProject); return res.data; }, onSuccess: (data) => { // Invalidate the cache queryClient.invalidateQueries({ queryKey: ["ProjectsList"] }); queryClient.invalidateQueries({ queryKey: ["basicProjectNameList"] }); // Emit event for consumers (like useProjects or others) eventBus.emit("project", { keyword: "Create_Project", response: data, }); showToast("Project Created successfully.", "success"); if (onSuccessCallback) { onSuccessCallback(data); } }, onError: (error) => { showToast(error.message || "Error while creating project", "error"); }, }); }; export const useUpdateProject = ({ onSuccessCallback }) => { const queryClient = useQueryClient(); const { mutate, isPending, isSuccess, isError } = useMutation({ mutationFn: async ({ projectId, updatedData }) => { return await ProjectRepository.updateProject(projectId, updatedData); }, onSuccess: (data, variables) => { const { projectId } = variables; queryClient.invalidateQueries({ queryKey: ["ProjectsList"] }); queryClient.invalidateQueries({ queryKey: ["projectInfo", projectId] }); queryClient.invalidateQueries({ queryKey: ["basicProjectNameList"] }); eventBus.emit("project", { keyword: "Update_Project", response: data, }); showToast("Project updated successfully.", "success"); if (onSuccessCallback) { onSuccessCallback(data); } }, onError: (error) => { console.log(error); showToast(error?.message || "Error while updating project", "error"); }, }); return { mutate, isPending, isSuccess, isError, }; }; export const useManageProjectInfra = ({ onSuccessCallback }) => { const queryClient = useQueryClient(); return useMutation({ mutationFn: async ({ infraObject, projectId }) => { return await ProjectRepository.manageProjectInfra(infraObject); }, onSuccess: (data, variables) => { const { projectId } = variables; queryClient.invalidateQueries({ queryKey: ["ProjectInfra", projectId] }); if (onSuccessCallback) onSuccessCallback(data, variables); }, onError: (error) => { showToast(error.message || "Failed to update Project Infra", "error"); }, }); }; export const useManageProjectAllocation = ({ onSuccessCallback, onErrorCallback, }) => { const queryClient = useQueryClient(); const { mutate, isPending, isSuccess, isError } = useMutation({ mutationFn: async ({ items }) => { const response = await ProjectRepository.manageProjectAllocation(items); return response.data; }, onSuccess: (data, variables, context) => { queryClient.invalidateQueries({ queryKey: ["empListByProjectAllocated"], }); queryClient.removeQueries({ queryKey: ["projectEmployees"] }); if (variables?.added) { showToast("Employee Assigned Successfully", "success"); } else { showToast("Removed Employee Successfully", "success"); } if (onSuccessCallback) onSuccessCallback(data, context); }, onError: (error) => { const message = error?.response?.data?.message || error.message || "Error occurred during API call"; showToast(message, "error"); if (onErrorCallback) onErrorCallback(error); }, }); return { mutate, isPending, isSuccess, isError, }; }; export const useManageTask = ({ onSuccessCallback }) => { const queryClient = useQueryClient(); const selectedProject = useSelector( (store) => store.localVariables.projectId ); return useMutation({ mutationFn: async ({ payload, PreviousPlannedWork, previousCompletedWork, buildingId, floorId, workAreaId, }) => await ProjectRepository.manageProjectTasks(payload), onSuccess: (data, variables) => { const { workAreaId, buildingId, floorId, PreviousPlannedWork, previousCompletedWork, } = variables; queryClient.invalidateQueries({ queryKey: ["WorkItems"] }); const getPlannedDelta = (previous, current) => current - previous; queryClient.setQueryData(["ProjectInfra", selectedProject], (oldData) => { if (!oldData) return oldData; const { workAreaId, floorId, buildingId } = variables; const updatedData = JSON.parse(JSON.stringify(oldData)); return updatedData.map((building) => { if (building.id !== buildingId) return building; return { ...building, floors: building.floors.map((floor) => { if (floor.id !== floorId) return floor; return { ...floor, workAreas: floor.workAreas.map((area) => { if (area.id !== workAreaId) return area; const previousPlanned = PreviousPlannedWork ?? 0; const currentPlanned = data?.data[0]?.workItem.plannedWork ?? 0; const plannedWorkDelta = getPlannedDelta( previousPlanned, currentPlanned ); const updatedPlannedWork = (area.plannedWork ?? 0) + plannedWorkDelta; const previousCompleted = previousCompletedWork; const currentCompleted = data?.data[0]?.workItem.completedWork ?? 0; const completedWorkDelta = getPlannedDelta( previousCompleted, currentCompleted ); const updatedCompletedWork = (area.completedWork ?? 0) + completedWorkDelta; return { ...area, plannedWork: updatedPlannedWork, completedWork: updatedCompletedWork, }; }), }; }), }; }); }); queryClient.setQueryData(["ProjectsList"], (projects) => { if (!projects) return projects; return projects.map((project) => { if (project.id !== selectedProject) return project; const previousPlanned = PreviousPlannedWork ?? 0; const currentPlanned = data?.data[0]?.workItem.plannedWork ?? 0; const plannedWorkDelta = getPlannedDelta( previousPlanned, currentPlanned ); const updatedPlannedWork = (project.plannedWork ?? 0) + plannedWorkDelta; const previousCompleted = previousCompletedWork; const currentCompleted = data?.data[0]?.workItem.completedWork ?? 0; const completedWorkDelta = getPlannedDelta( previousCompleted, currentCompleted ); const updatedCompletedWork = (project.completedWork ?? 0) + completedWorkDelta; return { ...project, plannedWork: updatedPlannedWork, completedWork: updatedCompletedWork, }; }); }); if (onSuccessCallback) onSuccessCallback(data); }, onError: (error) => { const message = error?.response?.data?.message || error.message || "Error occurred during API call"; showToast(message, "error"); }, }); }; export const useDeleteProjectTask = (onSuccessCallback) => { const queryClient = useQueryClient(); const selectedProject = useSelector( (store) => store.localVariables.projectId ); return useMutation({ mutationFn: async ({ workItemId, workAreaId, completedTask, plannedTask, }) => { return await ProjectRepository.deleteProjectTask(workItemId); }, onSuccess: (_, variables) => { const { completedTask, plannedTask, workAreaId, buildingId, floorId } = variables; queryClient.invalidateQueries({ queryKey: ["WorkItems", variables.workAreaId], }); queryClient.setQueryData(["ProjectInfra", selectedProject], (oldData) => { if (!oldData) return oldData; const { workAreaId, floorId, buildingId, plannedTask, completedTask } = variables; const updatedData = JSON.parse(JSON.stringify(oldData)); return updatedData.map((building) => { if (building.id !== buildingId) return building; return { ...building, floors: building.floors.map((floor) => { if (floor.id !== floorId) return floor; return { ...floor, workAreas: floor.workAreas.map((area) => { if (area.id !== workAreaId) return area; return { ...area, plannedWork: (area.plannedWork ?? 0) - plannedTask, completedWork: (area.completedWork ?? 0) - completedTask, }; }), }; }), }; }); }); queryClient.setQueryData(["ProjectsList"], (projects) => { if (!projects) return projects; return projects.map((project) => { if (project.id !== selectedProject) return project; return { ...project, plannedWork: (project.plannedWork ?? 0) - plannedTask, completedWork: (project.completedWork ?? 0) - completedTask, }; }); }); showToast("Task deleted successfully", "success"); if (onSuccessCallback) onSuccessCallback(); }, onError: (error) => { showToast( error?.response?.data?.message || error.message || "Failed to delete task", "error" ); if (onSuccessCallback) onSuccessCallback(); }, }); };