Adding Filter Icon in Attendance tab and add functionality in all Attendance component.
This commit is contained in:
parent
133024bc5c
commit
9bdcc74486
@ -12,7 +12,7 @@ import { useQueryClient } from "@tanstack/react-query";
|
|||||||
import eventBus from "../../services/eventBus";
|
import eventBus from "../../services/eventBus";
|
||||||
import { useSelectedProject } from "../../slices/apiDataManager";
|
import { useSelectedProject } from "../../slices/apiDataManager";
|
||||||
|
|
||||||
const Attendance = ({ getRole, handleModalData, searchTerm }) => {
|
const Attendance = ({ getRole, handleModalData, searchTerm, filters }) => {
|
||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
@ -50,22 +50,58 @@ const Attendance = ({ getRole, handleModalData, searchTerm }) => {
|
|||||||
.filter((d) => d.activity === 0)
|
.filter((d) => d.activity === 0)
|
||||||
.sort(sortByName);
|
.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 finalFilteredData = useMemo(() => {
|
||||||
const combinedData = [...group1, ...group2];
|
const combinedData = [...group1, ...group2];
|
||||||
if (!searchTerm) {
|
|
||||||
return combinedData;
|
|
||||||
}
|
|
||||||
const lowercasedSearchTerm = searchTerm.toLowerCase();
|
|
||||||
|
|
||||||
return combinedData.filter((item) => {
|
let tempData = combinedData;
|
||||||
const fullName = `${item.firstName} ${item.lastName}`.toLowerCase();
|
|
||||||
const role = item.jobRoleName?.toLowerCase() || "";
|
// Search filter
|
||||||
return (
|
if (searchTerm) {
|
||||||
fullName.includes(lowercasedSearchTerm) ||
|
const lowercasedSearchTerm = searchTerm.toLowerCase();
|
||||||
role.includes(lowercasedSearchTerm) // ✅ also search by role
|
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(
|
const { currentPage, totalPages, currentItems, paginate } = usePagination(
|
||||||
@ -116,7 +152,7 @@ const Attendance = ({ getRole, handleModalData, searchTerm }) => {
|
|||||||
<>
|
<>
|
||||||
<div
|
<div
|
||||||
className="table-responsive text-nowrap h-100"
|
className="table-responsive text-nowrap h-100"
|
||||||
style={{ minHeight: "200px" }} // 🔹 Ensures fixed height
|
style={{ minHeight: "200px" }} // Ensures fixed height
|
||||||
>
|
>
|
||||||
<div className="d-flex text-start align-items-center py-2">
|
<div className="d-flex text-start align-items-center py-2">
|
||||||
<strong>Date : {formatUTCToLocalTime(todayDate)}</strong>
|
<strong>Date : {formatUTCToLocalTime(todayDate)}</strong>
|
||||||
|
@ -33,7 +33,7 @@ const usePagination = (data, itemsPerPage) => {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const AttendanceLog = ({ handleModalData, searchTerm }) => {
|
const AttendanceLog = ({ handleModalData, searchTerm, filters }) => {
|
||||||
// const selectedProject = useSelector(
|
// const selectedProject = useSelector(
|
||||||
// (store) => store.localVariables.projectId
|
// (store) => store.localVariables.projectId
|
||||||
// );
|
// );
|
||||||
@ -139,16 +139,43 @@ const AttendanceLog = ({ handleModalData, searchTerm }) => {
|
|||||||
}, [data, showPending]);
|
}, [data, showPending]);
|
||||||
|
|
||||||
// New useEffect to handle search filtering
|
// 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(() => {
|
const filteredSearchData = useMemo(() => {
|
||||||
if (!searchTerm) {
|
let tempData = processedData;
|
||||||
return processedData;
|
|
||||||
}
|
if (searchTerm) {
|
||||||
const lowercasedSearchTerm = searchTerm.toLowerCase();
|
const lowercasedSearchTerm = searchTerm.toLowerCase();
|
||||||
return processedData.filter((item) => {
|
tempData = tempData.filter((item) => {
|
||||||
const fullName = `${item.firstName} ${item.lastName}`.toLowerCase();
|
const fullName = `${item.firstName} ${item.lastName}`.toLowerCase();
|
||||||
return fullName.includes(lowercasedSearchTerm);
|
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 {
|
const {
|
||||||
currentPage,
|
currentPage,
|
||||||
@ -344,7 +371,7 @@ const AttendanceLog = ({ handleModalData, searchTerm }) => {
|
|||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
) : (
|
) : (
|
||||||
<div className="my-4"><span className="text-secondary">No Record Available !</span></div>
|
<div className="my-12"><span className="text-secondary">No data available for the selected date range. Please Select another date.</span></div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
{paginatedAttendances?.length == 0 && filteredSearchData?.length > 0 && (
|
{paginatedAttendances?.length == 0 && filteredSearchData?.length > 0 && (
|
||||||
|
@ -10,7 +10,7 @@ import eventBus from "../../services/eventBus";
|
|||||||
import { cacheData, clearCacheKey, useSelectedProject } from "../../slices/apiDataManager";
|
import { cacheData, clearCacheKey, useSelectedProject } from "../../slices/apiDataManager";
|
||||||
import { useQueryClient } from "@tanstack/react-query";
|
import { useQueryClient } from "@tanstack/react-query";
|
||||||
|
|
||||||
const Regularization = ({ handleRequest, searchTerm }) => {
|
const Regularization = ({ handleRequest, searchTerm,filters }) => {
|
||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
// var selectedProject = useSelector((store) => store.localVariables.projectId);
|
// var selectedProject = useSelector((store) => store.localVariables.projectId);
|
||||||
const selectedProject = useSelectedProject();
|
const selectedProject = useSelectedProject();
|
||||||
@ -47,17 +47,47 @@ const Regularization = ({ handleRequest, searchTerm }) => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Filter the data based on the search term and sort it
|
// 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 filteredSearchData = useMemo(() => {
|
||||||
const sortedList = [...regularizesList].sort(sortByName);
|
let sortedList = [...regularizesList].sort(sortByName);
|
||||||
if (!searchTerm) {
|
|
||||||
return sortedList;
|
// 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) => {
|
// Organization filter
|
||||||
const fullName = `${item.firstName} ${item.lastName}`.toLowerCase();
|
if (filters?.selectedOrganization) {
|
||||||
return fullName.includes(lowercasedSearchTerm);
|
sortedList = sortedList.filter(
|
||||||
});
|
(item) => item.organization?.name === filters.selectedOrganization
|
||||||
}, [regularizesList, searchTerm]);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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 } =
|
const { currentPage, totalPages, currentItems, paginate } =
|
||||||
usePagination(filteredSearchData, 20);
|
usePagination(filteredSearchData, 20);
|
||||||
|
@ -22,6 +22,7 @@ import GlobalModel from "../../components/common/GlobalModel";
|
|||||||
import CheckCheckOutmodel from "../../components/Activities/CheckCheckOutForm";
|
import CheckCheckOutmodel from "../../components/Activities/CheckCheckOutForm";
|
||||||
import AttendLogs from "../../components/Activities/AttendLogs";
|
import AttendLogs from "../../components/Activities/AttendLogs";
|
||||||
import { useQueryClient } from "@tanstack/react-query";
|
import { useQueryClient } from "@tanstack/react-query";
|
||||||
|
import FilterIconOrgServices from "./FilterIconOrgServices";
|
||||||
|
|
||||||
const AttendancePage = () => {
|
const AttendancePage = () => {
|
||||||
const [activeTab, setActiveTab] = useState("all");
|
const [activeTab, setActiveTab] = useState("all");
|
||||||
@ -39,6 +40,10 @@ const AttendancePage = () => {
|
|||||||
const [modelConfig, setModelConfig] = useState();
|
const [modelConfig, setModelConfig] = useState();
|
||||||
const DoRegularized = useHasUserPermission(REGULARIZE_ATTENDANCE);
|
const DoRegularized = useHasUserPermission(REGULARIZE_ATTENDANCE);
|
||||||
const { projectNames, loading: projectLoading, fetchData } = useProjectName();
|
const { projectNames, loading: projectLoading, fetchData } = useProjectName();
|
||||||
|
const [appliedFilters, setAppliedFilters] = useState({
|
||||||
|
selectedOrganization: "",
|
||||||
|
selectedServices: [],
|
||||||
|
});
|
||||||
|
|
||||||
const [formData, setFormData] = useState({
|
const [formData, setFormData] = useState({
|
||||||
markTime: "",
|
markTime: "",
|
||||||
@ -95,11 +100,11 @@ const AttendancePage = () => {
|
|||||||
{(modelConfig?.action === 0 ||
|
{(modelConfig?.action === 0 ||
|
||||||
modelConfig?.action === 1 ||
|
modelConfig?.action === 1 ||
|
||||||
modelConfig?.action === 2) && (
|
modelConfig?.action === 2) && (
|
||||||
<CheckCheckOutmodel
|
<CheckCheckOutmodel
|
||||||
modeldata={modelConfig}
|
modeldata={modelConfig}
|
||||||
closeModal={closeModal}
|
closeModal={closeModal}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{/* For view logs */}
|
{/* For view logs */}
|
||||||
{modelConfig?.action === 6 && (
|
{modelConfig?.action === 6 && (
|
||||||
<AttendLogs Id={modelConfig?.id} closeModal={closeModal} />
|
<AttendLogs Id={modelConfig?.id} closeModal={closeModal} />
|
||||||
@ -128,9 +133,8 @@ const AttendancePage = () => {
|
|||||||
<li className="nav-item">
|
<li className="nav-item">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className={`nav-link ${
|
className={`nav-link ${activeTab === "all" ? "active" : ""
|
||||||
activeTab === "all" ? "active" : ""
|
} fs-6`}
|
||||||
} fs-6`}
|
|
||||||
onClick={() => handleTabChange("all")}
|
onClick={() => handleTabChange("all")}
|
||||||
data-bs-toggle="tab"
|
data-bs-toggle="tab"
|
||||||
data-bs-target="#navs-top-home"
|
data-bs-target="#navs-top-home"
|
||||||
@ -141,9 +145,8 @@ const AttendancePage = () => {
|
|||||||
<li className="nav-item">
|
<li className="nav-item">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className={`nav-link ${
|
className={`nav-link ${activeTab === "logs" ? "active" : ""
|
||||||
activeTab === "logs" ? "active" : ""
|
} fs-6`}
|
||||||
} fs-6`}
|
|
||||||
onClick={() => handleTabChange("logs")}
|
onClick={() => handleTabChange("logs")}
|
||||||
data-bs-toggle="tab"
|
data-bs-toggle="tab"
|
||||||
data-bs-target="#navs-top-profile"
|
data-bs-target="#navs-top-profile"
|
||||||
@ -155,9 +158,8 @@ const AttendancePage = () => {
|
|||||||
<li className={`nav-item ${!DoRegularized ? "d-none" : ""}`}>
|
<li className={`nav-item ${!DoRegularized ? "d-none" : ""}`}>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className={`nav-link ${
|
className={`nav-link ${activeTab === "regularization" ? "active" : ""
|
||||||
activeTab === "regularization" ? "active" : ""
|
} fs-6`}
|
||||||
} fs-6`}
|
|
||||||
onClick={() => handleTabChange("regularization")}
|
onClick={() => handleTabChange("regularization")}
|
||||||
data-bs-toggle="tab"
|
data-bs-toggle="tab"
|
||||||
data-bs-target="#navs-top-messages"
|
data-bs-target="#navs-top-messages"
|
||||||
@ -169,7 +171,10 @@ const AttendancePage = () => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Single search input that moves */}
|
{/* Single search input that moves */}
|
||||||
<div className="col-12 col-md-auto mt-2 mt-md-0 ms-md-auto px-2">
|
<div className="col-12 col-md-auto mt-2 mt-md-0 ms-md-auto d-flex gap-2 align-items-center">
|
||||||
|
<FilterIconOrgServices
|
||||||
|
onApplyFilters={(filters) => setAppliedFilters(filters)}
|
||||||
|
/>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
className="form-control form-control-sm"
|
className="form-control form-control-sm"
|
||||||
@ -179,6 +184,7 @@ const AttendancePage = () => {
|
|||||||
style={{ minWidth: "200px" }}
|
style={{ minWidth: "200px" }}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -191,6 +197,7 @@ const AttendancePage = () => {
|
|||||||
handleModalData={handleModalData}
|
handleModalData={handleModalData}
|
||||||
getRole={getRole}
|
getRole={getRole}
|
||||||
searchTerm={searchTerm}
|
searchTerm={searchTerm}
|
||||||
|
filters={appliedFilters}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
@ -199,12 +206,15 @@ const AttendancePage = () => {
|
|||||||
<AttendanceLog
|
<AttendanceLog
|
||||||
handleModalData={handleModalData}
|
handleModalData={handleModalData}
|
||||||
searchTerm={searchTerm}
|
searchTerm={searchTerm}
|
||||||
|
filters={appliedFilters}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{activeTab === "regularization" && DoRegularized && (
|
{activeTab === "regularization" && DoRegularized && (
|
||||||
<div className="tab-pane fade show active py-0">
|
<div className="tab-pane fade show active py-0">
|
||||||
<Regularization searchTerm={searchTerm} />
|
<Regularization
|
||||||
|
searchTerm={searchTerm}
|
||||||
|
filters={appliedFilters} />
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
|
189
src/pages/Activities/FilterIconOrgServices.jsx
Normal file
189
src/pages/Activities/FilterIconOrgServices.jsx
Normal file
@ -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 (
|
||||||
|
<div className="dropdown" style={{ marginLeft: "-14px", position: "relative" }}>
|
||||||
|
<a
|
||||||
|
className="dropdown-toggle hide-arrow cursor-pointer"
|
||||||
|
id="filterDropdown"
|
||||||
|
data-bs-toggle="dropdown"
|
||||||
|
aria-expanded="false"
|
||||||
|
>
|
||||||
|
<div style={{ position: "relative", display: "inline-block" }}>
|
||||||
|
<i
|
||||||
|
className="bx bx-slider-alt"
|
||||||
|
style={{
|
||||||
|
color: appliedFilterCount > 0 ? "#7161EF" : "gray",
|
||||||
|
fontSize: "20px",
|
||||||
|
}}
|
||||||
|
></i>
|
||||||
|
{appliedFilterCount > 0 && (
|
||||||
|
<span
|
||||||
|
style={{
|
||||||
|
position: "absolute",
|
||||||
|
top: "-11px",
|
||||||
|
right: "-6px",
|
||||||
|
backgroundColor: "#FFC107",
|
||||||
|
color: "white",
|
||||||
|
fontSize: "10px",
|
||||||
|
fontWeight: "bold",
|
||||||
|
borderRadius: "50%",
|
||||||
|
width: "18px",
|
||||||
|
height: "18px",
|
||||||
|
display: "flex",
|
||||||
|
alignItems: "center",
|
||||||
|
justifyContent: "center",
|
||||||
|
border: "1px solid white",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{appliedFilterCount}
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<ul
|
||||||
|
className="dropdown-menu p-2 mt-2"
|
||||||
|
aria-labelledby="filterDropdown"
|
||||||
|
style={{ minWidth: "300px", fontSize: "13px" }}
|
||||||
|
onClick={(e) => e.stopPropagation()}
|
||||||
|
>
|
||||||
|
{/* Organization */}
|
||||||
|
<li>
|
||||||
|
<div className="fw-bold text-dark mb-3 mt-3">Organization</div>
|
||||||
|
<select
|
||||||
|
className="form-select form-select-sm"
|
||||||
|
value={selectedOrganization}
|
||||||
|
onChange={(e) => handleFilterChange("organization", e.target.value)}
|
||||||
|
>
|
||||||
|
<option value="">Select Organization</option>
|
||||||
|
{organizations.map((org, idx) => (
|
||||||
|
<option key={idx} value={org}>
|
||||||
|
{org}
|
||||||
|
</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
{/* Services */}
|
||||||
|
<li><hr className="my-1" /></li>
|
||||||
|
<li>
|
||||||
|
<div className="fw-bold text-dark mb-3 mt-5">Services</div>
|
||||||
|
<div className="row">
|
||||||
|
{isLoading ? (
|
||||||
|
<div className="col-12 text-muted">Loading services...</div>
|
||||||
|
) : servicesData.length > 0 ? (
|
||||||
|
servicesData.map((service, idx) => (
|
||||||
|
<div className="col-6" key={idx}>
|
||||||
|
<div className="form-check mb-1">
|
||||||
|
<input
|
||||||
|
className="form-check-input"
|
||||||
|
type="checkbox"
|
||||||
|
id={`service-${service.name || service}`}
|
||||||
|
checked={selectedServices.includes(service.name || service)}
|
||||||
|
onChange={() => handleFilterChange("service", service.name || service)}
|
||||||
|
/>
|
||||||
|
<label
|
||||||
|
className="form-check-label"
|
||||||
|
htmlFor={`service-${service.name || service}`}
|
||||||
|
>
|
||||||
|
{service.name || service}
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
))
|
||||||
|
) : (
|
||||||
|
<div className="col-12 text-muted">No services found.</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
{/* Actions */}
|
||||||
|
<li><hr className="my-1" /></li>
|
||||||
|
{(appliedFilterCount > 0 ||
|
||||||
|
selectedOrganization ||
|
||||||
|
selectedServices.length > 0) && (
|
||||||
|
<li className="d-flex justify-content-end gap-2 px-2 mt-5 mb-2">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="btn btn-label-secondary btn-sm py-0 px-2"
|
||||||
|
onClick={clearAllFilters}
|
||||||
|
>
|
||||||
|
Clear
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="btn btn-primary btn-sm py-0 px-2"
|
||||||
|
onClick={applyFilters}
|
||||||
|
>
|
||||||
|
Apply
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
)}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default FilterIconOrgServices;
|
Loading…
x
Reference in New Issue
Block a user