diff --git a/src/components/Activities/Attendance.jsx b/src/components/Activities/Attendance.jsx index fed34f34..64f9371f 100644 --- a/src/components/Activities/Attendance.jsx +++ b/src/components/Activities/Attendance.jsx @@ -1,4 +1,4 @@ -import React, { useState, useEffect, useCallback } from "react"; +import React, { useState, useEffect, useCallback, useMemo } from "react"; import moment from "moment"; import Avatar from "../common/Avatar"; import { convertShortTime } from "../../utils/dateUtils"; @@ -11,7 +11,7 @@ import { useSelector } from "react-redux"; import { useQueryClient } from "@tanstack/react-query"; import eventBus from "../../services/eventBus"; -const Attendance = ({ getRole, handleModalData }) => { +const Attendance = ({ getRole, handleModalData, searchTerm }) => { const queryClient = useQueryClient(); const [loading, setLoading] = useState(false); const navigate = useNavigate(); @@ -28,8 +28,8 @@ const Attendance = ({ getRole, handleModalData }) => { } = useAttendance(selectedProject); const filteredAttendance = ShowPending ? attendance?.filter( - (att) => att?.checkInTime !== null && att?.checkOutTime === null - ) + (att) => att?.checkInTime !== null && att?.checkOutTime === null + ) : attendance; const attendanceList = Array.isArray(filteredAttendance) @@ -48,18 +48,40 @@ const Attendance = ({ getRole, handleModalData }) => { .filter((d) => d.activity === 0) .sort(sortByName); - const filteredData = [...group1, ...group2]; + const finalFilteredData = useMemo(() => { + const combinedData = [...group1, ...group2]; + if (!searchTerm) { + return combinedData; + } + const lowercasedSearchTerm = searchTerm.toLowerCase(); + + return combinedData.filter((item) => { + const fullName = `${item.firstName} ${item.lastName}`.toLowerCase(); + const role = item.jobRoleName?.toLowerCase() || ""; + return ( + fullName.includes(lowercasedSearchTerm) || + role.includes(lowercasedSearchTerm) // ✅ also search by role + ); + }); + }, [group1, group2, searchTerm]); + + const { currentPage, totalPages, currentItems, paginate } = usePagination( - filteredData, + finalFilteredData, ITEMS_PER_PAGE ); + // Reset pagination when the filter or search term changes + useEffect(() => { + }, [finalFilteredData]); + + const handler = useCallback( (msg) => { if (selectedProject == msg.projectId) { queryClient.setQueryData(["attendance", selectedProject], (oldData) => { if (!oldData) { - queryClient.invalidateQueries({queryKey:["attendance"]}) + queryClient.invalidateQueries({ queryKey: ["attendance"] }) }; return oldData.map((record) => record.employeeId === msg.response.employeeId ? { ...record, ...msg.response } : record @@ -72,7 +94,7 @@ const Attendance = ({ getRole, handleModalData }) => { const employeeHandler = useCallback( (msg) => { - if (attendances.some((item) => item.employeeId == msg.employeeId)) { + if (attendance.some((item) => item.employeeId == msg.employeeId)) { attrecall(); } }, @@ -106,7 +128,9 @@ const Attendance = ({ getRole, handleModalData }) => { - {Array.isArray(attendance) && attendance.length > 0 ? ( + {attLoading ? ( +
Loading...
+ ) : currentItems?.length > 0 ? ( <> @@ -188,13 +212,12 @@ const Attendance = ({ getRole, handleModalData }) => {
- {!loading && filteredData.length > 20 && ( + {!loading && finalFilteredData.length > ITEMS_PER_PAGE && ( )} - ) : attLoading ? ( -
Loading...
) : ( -
- {Array.isArray(attendance) - ? "No employees assigned to the project" - : "Attendance data unavailable"} +
+ {searchTerm + ? "No results found for your search." + : attendanceList.length === 0 + ? "No employees assigned to the project." + : "No pending records available."}
)} - - {currentItems?.length == 0 && attendance.length > 0 && ( -
No Pending Record Available !
- )}
); diff --git a/src/components/Activities/AttendcesLogs.jsx b/src/components/Activities/AttendcesLogs.jsx index 0a28ffd3..889747a7 100644 --- a/src/components/Activities/AttendcesLogs.jsx +++ b/src/components/Activities/AttendcesLogs.jsx @@ -33,9 +33,7 @@ const usePagination = (data, itemsPerPage) => { }; }; -const AttendanceLog = ({ - handleModalData, -}) => { +const AttendanceLog = ({ handleModalData, searchTerm }) => { const selectedProject = useSelector( (store) => store.localVariables.projectId ); @@ -139,17 +137,29 @@ const AttendanceLog = ({ filtering(data); }, [data, showPending]); + // New useEffect to handle search filtering + const filteredSearchData = useMemo(() => { + if (!searchTerm) { + return processedData; + } + const lowercasedSearchTerm = searchTerm.toLowerCase(); + return processedData.filter((item) => { + const fullName = `${item.firstName} ${item.lastName}`.toLowerCase(); + return fullName.includes(lowercasedSearchTerm); + }); + }, [processedData, searchTerm]); + const { currentPage, totalPages, currentItems: paginatedAttendances, paginate, resetPage, - } = usePagination(processedData, 20); + } = usePagination(filteredSearchData, 20); useEffect(() => { resetPage(); - }, [processedData, resetPage]); + }, [filteredSearchData, resetPage]); const handler = useCallback( (msg) => { @@ -160,20 +170,23 @@ const AttendanceLog = ({ startDate <= checkIn && checkIn <= endDate ) { - queryClient.setQueriesData(["attendanceLogs"],(oldData)=>{ - if(!oldData) { - queryClient.invalidateQueries({queryKey:["attendanceLogs"]}) + queryClient.setQueriesData(["attendanceLogs"], (oldData) => { + if (!oldData) { + queryClient.invalidateQueries({ queryKey: ["attendanceLogs"] }); + return; } - return oldData.map((record) => - record.id === msg.response.id ? { ...record, ...msg.response } : record - ); - }) - - filtering(updatedAttendance); + const updatedAttendance = oldData.map((record) => + record.id === msg.response.id + ? { ...record, ...msg.response } + : record + ); + filtering(updatedAttendance); + return updatedAttendance; + }); resetPage(); } }, - [selectedProject, dateRange, data, filtering, resetPage] + [selectedProject, dateRange, filtering, resetPage] ); useEffect(() => { @@ -196,7 +209,7 @@ const AttendanceLog = ({ refetch() } }, - [selectedProject, dateRange, data] + [selectedProject, dateRange, data, refetch] ); useEffect(() => { @@ -240,8 +253,10 @@ const AttendanceLog = ({
{isLoading ? ( -

Loading...

- ) : data?.length > 0 ? ( +
+

Loading...

+
+ ) : filteredSearchData?.length > 0 ? ( @@ -332,10 +347,12 @@ const AttendanceLog = ({
No Record Available !
)} - {paginatedAttendances?.length == 0 && data?.length > 0 && ( -
No Pending Record Available !
- )} - {processedData.length > 10 && ( + {paginatedAttendances?.length == 0 && filteredSearchData?.length > 0 && ( +
+ No Pending Record Available ! +
+ )} + {filteredSearchData.length > 10 && (
) : (
- {" "} - No Requests Found ! + + {searchTerm ? "No results found for your search." : "No Requests Found !"} +
)} {!loading && totalPages > 1 && ( diff --git a/src/pages/Activities/AttendancePage.jsx b/src/pages/Activities/AttendancePage.jsx index d6a3463b..f466f856 100644 --- a/src/pages/Activities/AttendancePage.jsx +++ b/src/pages/Activities/AttendancePage.jsx @@ -25,6 +25,7 @@ import { useQueryClient } from "@tanstack/react-query"; const AttendancePage = () => { const [activeTab, setActiveTab] = useState("all"); const [ShowPending, setShowPending] = useState(false); + const [searchTerm, setSearchTerm] = useState(""); // 🔹 New state for search const queryClient = useQueryClient(); const loginUser = getCachedProfileData(); const selectedProject = useSelector((store) => store.localVariables.projectId); @@ -69,17 +70,18 @@ const AttendancePage = () => { setIsCreateModalOpen(false); }; - const handleToggle = (event) => { - setShowOnlyCheckout(event.target.checked); - }; - - useEffect(() => { if (modelConfig !== null) { openModel(); } }, [modelConfig, isCreateModalOpen]); + // Handler to change tab and reset search term + const handleTabChange = (tabName) => { + setActiveTab(tabName); + setSearchTerm(""); // Reset search term when tab changes + }; + return ( <> {isCreateModalOpen && modelConfig && ( @@ -91,11 +93,11 @@ const AttendancePage = () => { {(modelConfig?.action === 0 || modelConfig?.action === 1 || modelConfig?.action === 2) && ( - - )} + + )} {/* For view logs */} {modelConfig?.action === 6 && ( @@ -120,8 +122,8 @@ const AttendancePage = () => { type="button" className={`nav-link ${ activeTab === "all" ? "active" : "" - } fs-6`} - onClick={() => setActiveTab("all")} + } fs-6`} + onClick={() => handleTabChange("all")} data-bs-toggle="tab" data-bs-target="#navs-top-home" > @@ -133,8 +135,8 @@ const AttendancePage = () => { type="button" className={`nav-link ${ activeTab === "logs" ? "active" : "" - } fs-6`} - onClick={() => setActiveTab("logs")} + } fs-6`} + onClick={() => handleTabChange("logs")} data-bs-toggle="tab" data-bs-target="#navs-top-profile" > @@ -146,40 +148,60 @@ const AttendancePage = () => { type="button" className={`nav-link ${ activeTab === "regularization" ? "active" : "" - } fs-6`} - onClick={() => setActiveTab("regularization")} + } fs-6`} + onClick={() => handleTabChange("regularization")} data-bs-toggle="tab" data-bs-target="#navs-top-messages" > Regularization + + {/* 🔹 Search box placed after Regularization tab */} +
  • + setSearchTerm(e.target.value)} + style={{ minWidth: "200px" }} + /> +
  • +
    - {selectedProject ? ( - <> - {activeTab === "all" && ( -
    - -
    - )} - {activeTab === "logs" && ( -
    - -
    - )} - {activeTab === "regularization" && DoRegularized && ( -
    - -
    - )} - - ) : ( -
    - Please Select Project! -
    - )} -
    + {selectedProject ? ( + <> + {activeTab === "all" && ( +
    + +
    + )} + {activeTab === "logs" && ( +
    + +
    + )} + {activeTab === "regularization" && DoRegularized && ( +
    + +
    + )} + + ) : ( +
    + Please Select Project! +
    + )} +