diff --git a/src/components/Activities/Attendance.jsx b/src/components/Activities/Attendance.jsx index 6d751b12..c4f04b7f 100644 --- a/src/components/Activities/Attendance.jsx +++ b/src/components/Activities/Attendance.jsx @@ -12,7 +12,7 @@ import { useQueryClient } from "@tanstack/react-query"; import eventBus from "../../services/eventBus"; import { useSelectedProject } from "../../slices/apiDataManager"; -const Attendance = ({ getRole, handleModalData, searchTerm }) => { +const Attendance = ({ getRole, handleModalData, searchTerm, filters }) => { const queryClient = useQueryClient(); const [loading, setLoading] = useState(false); const navigate = useNavigate(); @@ -50,22 +50,58 @@ const Attendance = ({ getRole, handleModalData, searchTerm }) => { .filter((d) => d.activity === 0) .sort(sortByName); + // 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 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 + let tempData = combinedData; + + // Search filter + if (searchTerm) { + const lowercasedSearchTerm = searchTerm.toLowerCase(); + tempData = tempData.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 + ); + }); + } + + // Organization filter + if (filters?.selectedOrganization) { + tempData = tempData.filter( + (item) => item.organization?.name === filters.selectedOrganization ); - }); - }, [group1, group2, searchTerm]); + } + + // Services filter + if (filters?.selectedServices?.length > 0) { + tempData = tempData.filter((item) => + filters.selectedServices.includes(item.service?.name) + ); + } + + return tempData; + }, [group1, group2, searchTerm, filters]); + const { currentPage, totalPages, currentItems, paginate } = usePagination( @@ -116,7 +152,7 @@ const Attendance = ({ getRole, handleModalData, searchTerm }) => { <>
Date : {formatUTCToLocalTime(todayDate)} diff --git a/src/components/Activities/AttendcesLogs.jsx b/src/components/Activities/AttendcesLogs.jsx index 9aced215..65edb95e 100644 --- a/src/components/Activities/AttendcesLogs.jsx +++ b/src/components/Activities/AttendcesLogs.jsx @@ -33,7 +33,7 @@ const usePagination = (data, itemsPerPage) => { }; }; -const AttendanceLog = ({ handleModalData, searchTerm }) => { +const AttendanceLog = ({ handleModalData, searchTerm, filters }) => { // const selectedProject = useSelector( // (store) => store.localVariables.projectId // ); @@ -139,16 +139,43 @@ const AttendanceLog = ({ handleModalData, searchTerm }) => { }, [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 filteredSearchData = useMemo(() => { - if (!searchTerm) { - return processedData; - } + let tempData = processedData; + + if (searchTerm) { const lowercasedSearchTerm = searchTerm.toLowerCase(); - return processedData.filter((item) => { + tempData = tempData.filter((item) => { const fullName = `${item.firstName} ${item.lastName}`.toLowerCase(); return fullName.includes(lowercasedSearchTerm); }); - }, [processedData, searchTerm]); + } + + if (filters?.selectedOrganization) { + tempData = tempData.filter( + (item) => item.organization?.name === filters.selectedOrganization + ); + } + + if (filters?.selectedServices?.length > 0) { + tempData = tempData.filter((item) => + filters.selectedServices.includes(item.service?.name) + ); + } + + return tempData; +}, [processedData, searchTerm, filters]); + const { currentPage, @@ -344,7 +371,7 @@ const AttendanceLog = ({ handleModalData, searchTerm }) => { ) : ( -
No Record Available !
+
No data available for the selected date range. Please Select another date.
)}
{paginatedAttendances?.length == 0 && filteredSearchData?.length > 0 && ( diff --git a/src/components/Activities/Regularization.jsx b/src/components/Activities/Regularization.jsx index 82c906b5..0a1788d8 100644 --- a/src/components/Activities/Regularization.jsx +++ b/src/components/Activities/Regularization.jsx @@ -10,7 +10,7 @@ import eventBus from "../../services/eventBus"; import { cacheData, clearCacheKey, useSelectedProject } from "../../slices/apiDataManager"; import { useQueryClient } from "@tanstack/react-query"; -const Regularization = ({ handleRequest, searchTerm }) => { +const Regularization = ({ handleRequest, searchTerm,filters }) => { const queryClient = useQueryClient(); // var selectedProject = useSelector((store) => store.localVariables.projectId); const selectedProject = useSelectedProject(); @@ -47,17 +47,47 @@ const Regularization = ({ handleRequest, searchTerm }) => { ); // Filter the data based on the search term and sort it + // const filteredSearchData = useMemo(() => { + // const sortedList = [...regularizesList].sort(sortByName); + // if (!searchTerm) { + // return sortedList; + // } + // const lowercasedSearchTerm = searchTerm.toLowerCase(); + // return sortedList.filter((item) => { + // const fullName = `${item.firstName} ${item.lastName}`.toLowerCase(); + // return fullName.includes(lowercasedSearchTerm); + // }); + // }, [regularizesList, searchTerm]); + const filteredSearchData = useMemo(() => { - const sortedList = [...regularizesList].sort(sortByName); - if (!searchTerm) { - return sortedList; + let sortedList = [...regularizesList].sort(sortByName); + + // Search filter + if (searchTerm) { + const lowercasedSearchTerm = searchTerm.toLowerCase(); + sortedList = sortedList.filter((item) => { + const fullName = `${item.firstName} ${item.lastName}`.toLowerCase(); + return fullName.includes(lowercasedSearchTerm); + }); } - const lowercasedSearchTerm = searchTerm.toLowerCase(); - return sortedList.filter((item) => { - const fullName = `${item.firstName} ${item.lastName}`.toLowerCase(); - return fullName.includes(lowercasedSearchTerm); - }); - }, [regularizesList, searchTerm]); + + // Organization filter + if (filters?.selectedOrganization) { + sortedList = sortedList.filter( + (item) => item.organization?.name === filters.selectedOrganization + ); + } + + // Services filter + if (filters?.selectedServices?.length > 0) { + sortedList = sortedList.filter((item) => + filters.selectedServices.includes(item.service?.name) + ); + } + + return sortedList; + }, [regularizesList, searchTerm, filters]); + const { currentPage, totalPages, currentItems, paginate } = usePagination(filteredSearchData, 20); diff --git a/src/pages/Activities/AttendancePage.jsx b/src/pages/Activities/AttendancePage.jsx index f0e00ad5..01c1b742 100644 --- a/src/pages/Activities/AttendancePage.jsx +++ b/src/pages/Activities/AttendancePage.jsx @@ -22,6 +22,7 @@ import GlobalModel from "../../components/common/GlobalModel"; import CheckCheckOutmodel from "../../components/Activities/CheckCheckOutForm"; import AttendLogs from "../../components/Activities/AttendLogs"; import { useQueryClient } from "@tanstack/react-query"; +import FilterIconOrgServices from "./FilterIconOrgServices"; const AttendancePage = () => { const [activeTab, setActiveTab] = useState("all"); @@ -39,6 +40,10 @@ const AttendancePage = () => { const [modelConfig, setModelConfig] = useState(); const DoRegularized = useHasUserPermission(REGULARIZE_ATTENDANCE); const { projectNames, loading: projectLoading, fetchData } = useProjectName(); + const [appliedFilters, setAppliedFilters] = useState({ + selectedOrganization: "", + selectedServices: [], + }); const [formData, setFormData] = useState({ markTime: "", @@ -95,11 +100,11 @@ const AttendancePage = () => { {(modelConfig?.action === 0 || modelConfig?.action === 1 || modelConfig?.action === 2) && ( - - )} + + )} {/* For view logs */} {modelConfig?.action === 6 && ( @@ -128,9 +133,8 @@ const AttendancePage = () => {
  • {/* Single search input that moves */} -
    +
    + setAppliedFilters(filters)} + /> { style={{ minWidth: "200px" }} />
    +
    @@ -191,6 +197,7 @@ const AttendancePage = () => { handleModalData={handleModalData} getRole={getRole} searchTerm={searchTerm} + filters={appliedFilters} /> )} @@ -199,12 +206,15 @@ const AttendancePage = () => { )} {activeTab === "regularization" && DoRegularized && (
    - +
    )} diff --git a/src/pages/Activities/FilterIconOrgServices.jsx b/src/pages/Activities/FilterIconOrgServices.jsx new file mode 100644 index 00000000..4f665af2 --- /dev/null +++ b/src/pages/Activities/FilterIconOrgServices.jsx @@ -0,0 +1,189 @@ +import React, { useState, useEffect } from "react"; +import { useSelectedProject } from "../../slices/apiDataManager"; +import { useProjectAssignedServices } from "../../hooks/useProjects"; + +const FilterIconOrgServices = ({ onApplyFilters }) => { + const selectedProject = useSelectedProject(); + + // Fetch services from API + const { data: servicesData = [], isLoading } = useProjectAssignedServices(selectedProject); + + // Hardcoded organization list + const organizations = ["Org A", "Org B", "Org C"]; + + const [selectedOrganization, setSelectedOrganization] = useState(""); + const [selectedServices, setSelectedServices] = useState([]); + + const [appliedOrganization, setAppliedOrganization] = useState(""); + const [appliedServices, setAppliedServices] = useState([]); + + useEffect(() => { + setSelectedOrganization(""); + setSelectedServices([]); + setAppliedOrganization(""); + setAppliedServices([]); + }, [selectedProject]); + + const handleFilterChange = (type, value) => { + if (type === "organization") { + setSelectedOrganization(value); + } else if (type === "service") { + setSelectedServices((prev) => + prev.includes(value) ? prev.filter((s) => s !== value) : [...prev, value] + ); + } + }; + + const applyFilters = () => { + setAppliedOrganization(selectedOrganization); + setAppliedServices(selectedServices); + + onApplyFilters({ + selectedOrganization, + selectedServices, + }); + + document.getElementById("filterDropdown").click(); + }; + + const clearAllFilters = () => { + setSelectedOrganization(""); + setSelectedServices([]); + + setAppliedOrganization(""); + setAppliedServices([]); + + onApplyFilters({ + selectedOrganization: "", + selectedServices: [], + }); + }; + + const appliedFilterCount = + (appliedOrganization ? 1 : 0) + appliedServices.length; + + return ( +
    + + + +
    + ); +}; + +export default FilterIconOrgServices;