From ae973bf1a1dc537fbab5b2e760f57f5ab3f334ae Mon Sep 17 00:00:00 2001 From: Kartik Sharma Date: Tue, 22 Jul 2025 16:47:26 +0530 Subject: [PATCH] Enhancement implemented in the Attendance component to include search functionality. --- src/components/Activities/AttendcesLogs.jsx | 2 +- src/components/Activities/Regularization.jsx | 2 + src/pages/Activities/AttendancePage.jsx | 153 ++++++++++++++----- 3 files changed, 118 insertions(+), 39 deletions(-) diff --git a/src/components/Activities/AttendcesLogs.jsx b/src/components/Activities/AttendcesLogs.jsx index f9ebba8f..d207906c 100644 --- a/src/components/Activities/AttendcesLogs.jsx +++ b/src/components/Activities/AttendcesLogs.jsx @@ -36,7 +36,7 @@ const usePagination = (data, itemsPerPage) => { totalPages: maxPage, currentItems, paginate, - resetPage, + resetPage, // Ensure resetPage is returned here }; }; diff --git a/src/components/Activities/Regularization.jsx b/src/components/Activities/Regularization.jsx index fa1f6b3c..043e94d3 100644 --- a/src/components/Activities/Regularization.jsx +++ b/src/components/Activities/Regularization.jsx @@ -49,6 +49,7 @@ const Regularization = ({ handleRequest, searchQuery }) => { [regularizes] ); + useEffect(() => { useEffect(() => { eventBus.on("regularization", handler); return () => eventBus.off("regularization", handler); @@ -182,3 +183,4 @@ const Regularization = ({ handleRequest, searchQuery }) => { export default Regularization; + diff --git a/src/pages/Activities/AttendancePage.jsx b/src/pages/Activities/AttendancePage.jsx index f65d06c8..c434290a 100644 --- a/src/pages/Activities/AttendancePage.jsx +++ b/src/pages/Activities/AttendancePage.jsx @@ -8,7 +8,7 @@ import { import Breadcrumb from "../../components/common/Breadcrumb"; import AttendanceLog from "../../components/Activities/AttendcesLogs"; import Attendance from "../../components/Activities/Attendance"; -// import AttendanceModel from "../../components/Activities/AttendanceModel"; +import AttendanceModel from "../../components/Activities/AttendanceModel"; import showToast from "../../services/toastService"; import Regularization from "../../components/Activities/Regularization"; import { useAttendance } from "../../hooks/useAttendance"; @@ -18,26 +18,25 @@ import { markCurrentAttendance } from "../../slices/apiSlice/attendanceAllSlice" import { useHasUserPermission } from "../../hooks/useHasUserPermission"; import { REGULARIZE_ATTENDANCE } from "../../utils/constants"; import eventBus from "../../services/eventBus"; -// import AttendanceRepository from "../../repositories/AttendanceRepository"; +import AttendanceRepository from "../../repositories/AttendanceRepository"; import { useProjectName } from "../../hooks/useProjects"; -import GlobalModel from "../../components/common/GlobalModel"; -import CheckCheckOutmodel from "../../components/Activities/CheckCheckOutForm"; -import AttendLogs from "../../components/Activities/AttendLogs"; -// import Confirmation from "../../components/Activities/Confirmation"; -import { useQueryClient } from "@tanstack/react-query"; const AttendancePage = () => { const [activeTab, setActiveTab] = useState("all"); const [showPending, setShowPending] = useState(false); // Renamed for consistency const [searchQuery, setSearchQuery] = useState(""); + const [showPending, setShowPending] = useState(false); // Renamed for consistency + const [searchQuery, setSearchQuery] = useState(""); const loginUser = getCachedProfileData(); const selectedProject = useSelector((store) => store.localVariables.projectId); const dispatch = useDispatch(); + const selectedProject = useSelector((store) => store.localVariables.projectId); + const dispatch = useDispatch(); const { attendance, loading: attLoading, recall: attrecall, - } = useAttendace(selectedProject); + } = useAttendance(selectedProject); // Corrected typo: useAttendace to useAttendance const [attendances, setAttendances] = useState(); const [empRoles, setEmpRoles] = useState(null); const [isCreateModalOpen, setIsCreateModalOpen] = useState(false); @@ -46,6 +45,7 @@ const AttendancePage = () => { const { projectNames, loading: projectLoading, fetchData } = useProjectName(); + const [formData, setFormData] = useState({ markTime: "", description: "", @@ -94,6 +94,7 @@ const AttendancePage = () => { if (!empRoles) return "Unassigned"; if (!roleId) return "Unassigned"; const role = empRoles.find((b) => b.id === roleId); + const role = empRoles.find((b) => b.id === roleId); return role ? role.role : "Unassigned"; }; @@ -117,6 +118,10 @@ const AttendancePage = () => { if (modalBackdrop) { modalBackdrop.remove(); } + const modalBackdrop = document.querySelector(".modal-backdrop"); + if (modalBackdrop) { + modalBackdrop.remove(); + } } }; @@ -150,13 +155,21 @@ const AttendancePage = () => { const handleToggle = (event) => { setShowPending(event.target.checked); + setShowPending(event.target.checked); }; + useEffect(() => { if (selectedProject === null && projectNames.length > 0) { dispatch(setProjectId(projectNames[0]?.id)); } }, [selectedProject, projectNames, dispatch]); + // Open modal when modelConfig is set + if (selectedProject === null && projectNames.length > 0) { + dispatch(setProjectId(projectNames[0]?.id)); + } + }, [selectedProject, projectNames, dispatch]); + // Open modal when modelConfig is set useEffect(() => { if (modelConfig !== null) { @@ -168,10 +181,15 @@ const AttendancePage = () => { setAttendances(attendance); }, [attendance]); + // Filter and search logic for the 'Today's' tab (Attendance component) + const filteredAndSearchedTodayAttendance = useCallback(() => { + let currentData = attendances; // Filter and search logic for the 'Today's' tab (Attendance component) const filteredAndSearchedTodayAttendance = useCallback(() => { let currentData = attendances; + if (showPending) { + currentData = currentData?.filter( if (showPending) { currentData = currentData?.filter( (att) => att?.checkInTime !== null && att?.checkOutTime === null @@ -198,23 +216,47 @@ const AttendancePage = () => { }, [attendances, showPending, searchQuery]); + // Event bus listeners + ); + } + + if (searchQuery) { + const lowerCaseSearchQuery = searchQuery.toLowerCase(); + currentData = currentData?.filter((att) => { + // Combine first, middle, and last names for a comprehensive search + const fullName = [att.firstName, att.middleName, att.lastName] + .filter(Boolean) // Remove null or undefined parts + .join(" ") + .toLowerCase(); + + return ( + att.employeeName?.toLowerCase().includes(lowerCaseSearchQuery) || + att.employeeId?.toLowerCase().includes(lowerCaseSearchQuery) || + fullName.includes(lowerCaseSearchQuery) + ); + }); + } + return currentData; + }, [attendances, showPending, searchQuery]); + + // Event bus listeners useEffect(() => { eventBus.on("attendance", handler); return () => eventBus.off("attendance", handler); }, [handler]); - // useEffect(() => { - // eventBus.on("employee", employeeHandler); - // return () => eventBus.off("employee", employeeHandler); - // }, [employeeHandler]); + useEffect(() => { + eventBus.on("employee", employeeHandler); + return () => eventBus.off("employee", employeeHandler); + }, [employeeHandler]); return ( <> - {/* {isCreateModalOpen && modelConfig && ( + {isCreateModalOpen && modelConfig && ( - )} */} - {isCreateModalOpen && modelConfig && ( - - {(modelConfig?.action === 0 || - modelConfig?.action === 1 || - modelConfig?.action === 2) && ( - - )} - {/* For view logs */} - {modelConfig?.action === 6 && ( - - )} - {modelConfig?.action === 7 && ( - - )} - )}
@@ -306,9 +325,60 @@ const AttendancePage = () => { />
+
{activeTab === "all" && ( + <> + {!attLoading && (
{ {!attLoading && filteredAndSearchedTodayAttendance()?.length === 0 && (

{" "} + {showPending {showPending ? "No Pending Available" : "No Employee assigned yet."}{" "}

)} - +
)} {activeTab === "logs" && (
@@ -337,6 +408,8 @@ const AttendancePage = () => { setshowOnlyCheckout={setShowPending} showOnlyCheckout={showPending} searchQuery={searchQuery} // Pass search query to AttendanceLog + showOnlyCheckout={showPending} + searchQuery={searchQuery} // Pass search query to AttendanceLog />
)} @@ -346,6 +419,10 @@ const AttendancePage = () => { handleRequest={handleSubmit} searchQuery={searchQuery} // ✅ Pass it here /> +
)}