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"; // ------------------------------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: projectList = [], 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 useProjectsAllocationByEmployee = (employeeId) => { const { data: projectList = [], isLoading, error, refetch, } = useQuery({ queryKey: ["ProjectsAllocationByEmployee", employeeId], queryFn: async () => { const res = await ProjectRepository.getProjectsAllocationByEmployee( employeeId ); const sortedProjects = [...res.data].sort((a, b) => a.projectName.localeCompare(b.projectName) ); return sortedProjects || res; //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, isError } = 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,isError }; }; 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 }; }; export const useProjectTasksByEmployee = ( employeeId, fromDate, toDate, ) => { return useQuery({ queryKey: ["TasksByEmployee", employeeId], queryFn: async () => { const res = await ProjectRepository.getProjectTasksByEmployee( employeeId, fromDate, toDate ); return res.data; }, enabled: !!employeeId && !!fromDate && !!toDate, onError: (error) => { showToast(error.message || "Error while Fetching project Tasks", "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(); }, }); };