201 lines
6.7 KiB
JavaScript
201 lines
6.7 KiB
JavaScript
import React, { useCallback, useEffect, useState, useMemo } from "react";
|
|
import Avatar from "../common/Avatar";
|
|
import { convertShortTime } from "../../utils/dateUtils";
|
|
import RegularizationActions from "./RegularizationActions";
|
|
import { useSelector } from "react-redux";
|
|
import { useRegularizationRequests } from "../../hooks/useAttendance";
|
|
import moment from "moment";
|
|
import usePagination from "../../hooks/usePagination";
|
|
import eventBus from "../../services/eventBus";
|
|
import { cacheData, clearCacheKey, useSelectedProject } from "../../slices/apiDataManager";
|
|
import { useQueryClient } from "@tanstack/react-query";
|
|
|
|
const Regularization = ({ handleRequest, searchTerm }) => {
|
|
const queryClient = useQueryClient();
|
|
// var selectedProject = useSelector((store) => store.localVariables.projectId);
|
|
const selectedProject = useSelectedProject();
|
|
const [regularizesList, setregularizedList] = useState([]);
|
|
const { regularizes, loading, error, refetch } =
|
|
useRegularizationRequests(selectedProject);
|
|
|
|
useEffect(() => {
|
|
setregularizedList(regularizes);
|
|
}, [regularizes]);
|
|
|
|
const sortByName = (a, b) => {
|
|
const nameA = a.firstName.toLowerCase() + a.lastName.toLowerCase();
|
|
const nameB = b.firstName.toLowerCase() + b.lastName.toLowerCase();
|
|
return nameA?.localeCompare(nameB);
|
|
};
|
|
|
|
const handler = useCallback(
|
|
(msg) => {
|
|
if (selectedProject == msg.projectId) {
|
|
queryClient.setQueryData(
|
|
["regularizedList", selectedProject],
|
|
(oldData) => {
|
|
if (!oldData) {
|
|
queryClient.invalidateQueries({ queryKey: ["regularizedList"] });
|
|
}
|
|
return oldData.filter((record) => record.id !== msg.response.id);
|
|
}
|
|
),
|
|
queryClient.invalidateQueries({ queryKey: ["attendanceLogs"] });
|
|
}
|
|
},
|
|
[selectedProject, regularizes]
|
|
);
|
|
|
|
// 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 { currentPage, totalPages, currentItems, paginate } =
|
|
usePagination(filteredSearchData, 20);
|
|
|
|
// Reset pagination when the search term or data changes
|
|
useEffect(() => {
|
|
|
|
}, [filteredSearchData]);
|
|
|
|
useEffect(() => {
|
|
eventBus.on("regularization", handler);
|
|
return () => eventBus.off("regularization", handler);
|
|
}, [handler]);
|
|
|
|
const employeeHandler = useCallback(
|
|
(msg) => {
|
|
if (regularizes.some((item) => item.employeeId == msg.employeeId)) {
|
|
refetch();
|
|
}
|
|
},
|
|
[regularizes]
|
|
);
|
|
|
|
useEffect(() => {
|
|
eventBus.on("employee", employeeHandler);
|
|
return () => eventBus.off("employee", employeeHandler);
|
|
}, [employeeHandler]);
|
|
|
|
return (
|
|
<div className="table-responsive text-nowrap pb-4" style={{ minHeight: "200px" }}>
|
|
{loading ? (
|
|
<div className="d-flex justify-content-center align-items-center" style={{ height: "200px" }}>
|
|
<p className="text-secondary">Loading...</p>
|
|
</div>
|
|
) : currentItems?.length > 0 ? (
|
|
<table className="table mb-0">
|
|
<thead>
|
|
<tr>
|
|
<th colSpan={2}>Name</th>
|
|
<th>Date</th>
|
|
<th>
|
|
<i className="bx bxs-down-arrow-alt text-success"></i>Check-In
|
|
</th>
|
|
<th>
|
|
<i className="bx bxs-up-arrow-alt text-danger"></i>Check-Out
|
|
</th>
|
|
<th>Action</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{currentItems?.map((att, index) => (
|
|
<tr key={index}>
|
|
<td colSpan={2}>
|
|
<div className="d-flex justify-content-start align-items-center">
|
|
<Avatar
|
|
firstName={att.firstName}
|
|
lastName={att.lastName}
|
|
></Avatar>
|
|
<div className="d-flex flex-column">
|
|
<a href="#" className="text-heading text-truncate">
|
|
<span className="fw-normal">
|
|
{att.firstName} {att.lastName}
|
|
</span>
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</td>
|
|
<td>{moment(att.checkOutTime).format("DD-MMM-YYYY")}</td>
|
|
<td>{convertShortTime(att.checkInTime)}</td>
|
|
<td>
|
|
{att.checkOutTime ? convertShortTime(att.checkOutTime) : "--"}
|
|
</td>
|
|
<td className="text-center ">
|
|
<RegularizationActions
|
|
attendanceData={att}
|
|
handleRequest={handleRequest}
|
|
refresh={refetch}
|
|
/>
|
|
{/* </div> */}
|
|
</td>
|
|
</tr>
|
|
))}
|
|
</tbody>
|
|
</table>
|
|
) : (
|
|
<div
|
|
className="d-flex justify-content-center align-items-center"
|
|
style={{ height: "200px" }}
|
|
>
|
|
<span className="text-secondary">
|
|
{searchTerm
|
|
? "No results found for your search."
|
|
: "No Requests Found !"}
|
|
</span>
|
|
</div>
|
|
)}
|
|
{!loading && totalPages > 1 && (
|
|
<nav aria-label="Page ">
|
|
<ul className="pagination pagination-sm justify-content-end py-1 mt-3">
|
|
<li className={`page-item ${currentPage === 1 ? "disabled" : ""}`}>
|
|
<button
|
|
className="page-link btn-xs"
|
|
onClick={() => paginate(currentPage - 1)}
|
|
>
|
|
«
|
|
</button>
|
|
</li>
|
|
{[...Array(totalPages)].map((_, index) => (
|
|
<li
|
|
key={index}
|
|
className={`page-item ${currentPage === index + 1 ? "active" : ""
|
|
}`}
|
|
>
|
|
<button
|
|
className="page-link "
|
|
onClick={() => paginate(index + 1)}
|
|
>
|
|
{index + 1}
|
|
</button>
|
|
</li>
|
|
))}
|
|
<li
|
|
className={`page-item ${currentPage === totalPages ? "disabled" : ""
|
|
}`}
|
|
>
|
|
<button
|
|
className="page-link "
|
|
onClick={() => paginate(currentPage + 1)}
|
|
>
|
|
»
|
|
</button>
|
|
</li>
|
|
</ul>
|
|
</nav>
|
|
)}
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default Regularization;
|