From b68f8306fda6399cc50c179ad6212293b236b321 Mon Sep 17 00:00:00 2001 From: "pramod.mahajan" Date: Mon, 17 Nov 2025 12:44:01 +0530 Subject: [PATCH] added confirmation modal inside serviceproject employee list --- src/components/ServiceProject/ManageJob.jsx | 13 +- .../ServiceProject/ServiceProjectSchema.jsx | 15 +- .../ServiceProjectTeamAllocation.jsx | 264 ++++++++++-------- src/components/common/DatePicker.jsx | 3 +- src/hooks/useEmployees.js | 62 ++-- src/hooks/useServiceProject.jsx | 2 +- 6 files changed, 208 insertions(+), 151 deletions(-) diff --git a/src/components/ServiceProject/ManageJob.jsx b/src/components/ServiceProject/ManageJob.jsx index 5b31a048..8f151da3 100644 --- a/src/components/ServiceProject/ManageJob.jsx +++ b/src/components/ServiceProject/ManageJob.jsx @@ -54,6 +54,7 @@ const ManageJob = ({ Job }) => { isError: isJobError, error: jobError, } = useServiceProjectJobDetails(Job); + // const {} = useSer const { mutate: CreateJob, isPending } = useCreateServiceProjectJob(() => { reset(); @@ -67,7 +68,7 @@ const ManageJob = ({ Job }) => { formData.startDate = localToUtc(formData.startDate); formData.dueDate = localToUtc(formData.dueDate); - CreateJob(formData) + CreateJob(formData); }; useEffect(() => { @@ -80,7 +81,7 @@ const ManageJob = ({ Job }) => { assignees: assignedEmployees, startDate: JobData.startDate ?? null, dueDate: JobData.dueDate ?? null, - tags: [], + tags: JobData.tags ?? [], }); }, [JobData]); @@ -102,9 +103,9 @@ const ManageJob = ({ Job }) => { control={control} render={({ field }) => ( { name="startDate" control={control} placeholder="DD-MM-YYYY" - className="w-full form-control-md" + className="w-full" + size="md" />
@@ -131,6 +133,7 @@ const ManageJob = ({ Job }) => { minDate={watch("startDate")} name="dueDate" className="w-full" + size="md" />
diff --git a/src/components/ServiceProject/ServiceProjectSchema.jsx b/src/components/ServiceProject/ServiceProjectSchema.jsx index 7f3228d4..22c8949d 100644 --- a/src/components/ServiceProject/ServiceProjectSchema.jsx +++ b/src/components/ServiceProject/ServiceProjectSchema.jsx @@ -3,15 +3,9 @@ import { PROJECT_STATUS } from "../../utils/constants"; //#region Service Project export const projectSchema = z.object({ - name: z - .string() - .trim() - .min(1, "Name is required"), + name: z.string().trim().min(1, "Name is required"), - shortName: z - .string() - .trim() - .min(1, "Short name is required"), + shortName: z.string().trim().min(1, "Short name is required"), clientId: z.string().trim().min(1, { message: "Client is required" }), @@ -38,10 +32,7 @@ export const projectSchema = z.object({ .min(7, "Invalid phone number") .max(15, "Phone number too long"), - contactEmail: z - .string() - .trim() - .email("Invalid email address"), + contactEmail: z.string().trim().email("Invalid email address"), }); export const defaultProjectValues = { diff --git a/src/components/ServiceProject/ServiceProjectTeam/ServiceProjectTeamAllocation.jsx b/src/components/ServiceProject/ServiceProjectTeam/ServiceProjectTeamAllocation.jsx index b3d5b16c..50b834ac 100644 --- a/src/components/ServiceProject/ServiceProjectTeam/ServiceProjectTeamAllocation.jsx +++ b/src/components/ServiceProject/ServiceProjectTeam/ServiceProjectTeamAllocation.jsx @@ -15,17 +15,21 @@ import { } from "../../../hooks/useServiceProject"; import { SpinnerLoader } from "../../common/Loader"; import showToast from "../../../services/toastService"; +import ConfirmModal from "../../common/ConfirmModal"; const ServiceProjectTeamAllocation = () => { const { isOpen, onClose, data: Project } = useModal("ServiceTeamAllocation"); - const [deletingId, setSeletingId] = useState(null); + const [deletingEmp, setSeletingEmp] = useState({ + employee: null, + isOpen: false, + }); const { data: Team, isLoading: isTeamLoading, isError: isTeamError, error: teamError, } = useServiceProjectTeam(Project?.projectId, true); - const [isManageEmployee, setIsMenageEmployee] = useState(false); + const [isAddEmployee, setIsAddEmployee] = useState(false); const [nonDuplicateEmployee, setNonDuplicateEmployee] = useState([]); const [selectedTeam, setSelectTeam] = useState(null); const [selectedEmployees, setSelectedEmployees] = useState([]); @@ -44,7 +48,10 @@ const ServiceProjectTeamAllocation = () => { const { mutate: AllocationTeam, isPending } = useAllocationServiceProjectTeam( () => { setSelectedEmployees([]); - setSeletingId(null); + setSeletingEmp({ + employee: null, + isOpen: false, + }); } ); @@ -61,7 +68,6 @@ const ServiceProjectTeamAllocation = () => { }; const handleDeAllocation = (emp) => { - setSeletingId(emp?.id); let payload = [ { projectId: Project?.projectId, @@ -76,7 +82,7 @@ const ServiceProjectTeamAllocation = () => { useEffect(() => { if (selectedEmployees?.length > 0 && !selectedTeam) { handleRemove(selectedEmployees[0]?.id); - showToast(`Please select a first role`, "warning"); + showToast(`Please select a role`, "warning"); } if (Team?.length > 0 && selectedEmployees?.length > 0) { setNonDuplicateEmployee((prev) => { @@ -103,125 +109,151 @@ const ServiceProjectTeamAllocation = () => { }, [Team, selectedEmployees, selectedTeam]); const TeamAllocationBody = ( -
-
-
- + <> + setSeletingEmp({ employee: null, isOpen: false })} + loading={isPending} + paramData={deletingEmp.employee} + isOpen={deletingEmp.isOpen} + /> +
+
+
+ {!isAddEmployee && } +
+ + {isAddEmployee && ( + <> +
+ { + setSelectedEmployees([]); + setSelectTeam(e); + }} + isLoading={isLoading} + /> +
+ +
+ +
+
+ {selectedEmployees.map((e) => ( + + ))} +
+ + )}
- - {isManageEmployee && ( - <> -
- { - setSelectedEmployees([]); - setSelectTeam(e); - }} - isLoading={isLoading} - /> -
- -
- -
-
- {selectedEmployees.map((e) => ( - - ))} -
- + { isAddEmployee && ( +
+ {" "} + + +
)} -
- {selectedEmployees?.length > 0 && isManageEmployee && ( -
- {" "} - -
- )} -
- - - - - - - - +
+
NameRoleAction
+ + + + + + + - - {Team?.length > 0 ? ( - Team?.map((emp) => ( - - - - + {Team?.length > 0 ? ( + Team?.map((emp) => ( + + + + + + )) + ) : ( + + - )) - ) : ( - - - - )} - -
NameRoleAction
-
- {" "} - - {`${emp?.employee?.firstName} ${emp?.employee?.lastName}`} -
-
{emp?.teamRole?.name} - {deletingId === emp.id ? ( -
+
+
+ {" "} + + {`${emp?.employee?.firstName} ${emp?.employee?.lastName}`} +
+
{emp?.teamRole?.name} + {deletingEmp?.emplyee?.id === emp.id && isPending ? ( +
+ ) : ( + + + setSeletingEmp({ employee: emp, isOpen: true }) + } + > + + )} +
+ {isTeamLoading ? ( + ) : ( - - handleDeAllocation(emp)} - > - +
+ +

+ {" "} + Please Add a Employee{" "} +

+
)}
- {isTeamLoading ? ( - - ) : ( -
- -

Please Add a Employee

-
- )} -
+ )} + + +
-
+ ); return ( diff --git a/src/components/common/DatePicker.jsx b/src/components/common/DatePicker.jsx index 74d1cc8f..c3592bc9 100644 --- a/src/components/common/DatePicker.jsx +++ b/src/components/common/DatePicker.jsx @@ -4,6 +4,7 @@ import { useController } from "react-hook-form"; const DatePicker = ({ name, control, + size="sm", placeholder = "DD-MM-YYYY", className = "", allowText = false, @@ -51,7 +52,7 @@ const DatePicker = ({
{ diff --git a/src/hooks/useEmployees.js b/src/hooks/useEmployees.js index b4e40df2..cb87c39b 100644 --- a/src/hooks/useEmployees.js +++ b/src/hooks/useEmployees.js @@ -1,4 +1,4 @@ -import { useEffect, useState } from "react"; +import { useEffect, useState,useCallback } from "react"; import { cacheData, getCachedData } from "../slices/apiDataManager"; import { RolesRepository } from "../repositories/MastersRepository"; import EmployeeRepository from "../repositories/EmployeeRepository"; @@ -9,6 +9,36 @@ import { useSelector } from "react-redux"; import { store } from "../store/store"; import { queryClient } from "../layouts/AuthLayout"; + +export const useUserCache = () => { + const [userCache, setUserCache] = useState({}); + + const addToCache = (id, user) => { + setUserCache((prev) => ({ ...prev, [id]: user })); + }; + + const getUser = async (id) => { + if (userCache[id]) return userCache[id]; + + try { + const res = await EmployeeRepository.getEmployeeProfile(id); + if (res?.data) { + addToCache(id, res.data); + return res.data; + } + } catch (err) { + console.error("User not found", id); + return null; + } + }; + + return { + userCache, + getUser, + addToCache, + }; +}; + // Query --------------------------------------------------------------------------- export const useEmployee = (employeeId) => { @@ -342,25 +372,25 @@ export const useUpdateEmployeeRoles = ({ }; }; - -export const useOrganizationHierarchy=(employeeId)=>{ -return useQuery({ - queryKey:["organizationHierarchy",employeeId], - queryFn:async()=> { - const resp = await EmployeeRepository.getOrganizaionHierarchy(employeeId); - return resp.data; - }, - enabled:!!employeeId -}) -} - - +export const useOrganizationHierarchy = (employeeId) => { + return useQuery({ + queryKey: ["organizationHierarchy", employeeId], + queryFn: async () => { + const resp = await EmployeeRepository.getOrganizaionHierarchy(employeeId); + return resp.data; + }, + enabled: !!employeeId, + }); +}; export const useManageEmployeeHierarchy = (employeeId, onSuccessCallBack) => { const queryClient = useQueryClient(); return useMutation({ mutationFn: async (payload) => { - return await EmployeeRepository.manageOrganizationHierarchy(employeeId, payload); + return await EmployeeRepository.manageOrganizationHierarchy( + employeeId, + payload + ); }, onSuccess: (_, variables) => { queryClient.invalidateQueries({ @@ -378,4 +408,4 @@ export const useManageEmployeeHierarchy = (employeeId, onSuccessCallBack) => { ); }, }); -}; \ No newline at end of file +}; diff --git a/src/hooks/useServiceProject.jsx b/src/hooks/useServiceProject.jsx index c5527163..67679964 100644 --- a/src/hooks/useServiceProject.jsx +++ b/src/hooks/useServiceProject.jsx @@ -132,7 +132,7 @@ export const useAllocationServiceProjectTeam = (onSuccessCallback) => { "success" ); } else { - showToast(`Employee DeAllocated successfully`, "success"); + showToast(`Employee removed successfully`, "success"); } }, onError: (error) => {