Optimize attendance logs and regularization APIs to fetch data only when their respective tabs are active

This commit is contained in:
Pramod Mahajan 2025-04-29 00:47:32 +05:30
parent 6dc30f8e2a
commit 6b241b14de
2 changed files with 124 additions and 81 deletions

View File

@ -1,64 +1,69 @@
import React, { useEffect, useState } from "react";
import moment from "moment";
import Avatar from "../common/Avatar";
import { convertShortTime } from "../../utils/dateUtils";
import RenderAttendanceStatus from "./RenderAttendanceStatus";
import { useSelector, useDispatch } from "react-redux";
import { fetchAttendanceData } from "../../slices/apiSlice/attedanceLogsSlice";
import DateRangePicker from "../common/DateRangePicker";
import { getCachedData } from "../../slices/apiDataManager";
import usePagination from "../../hooks/usePagination";
const AttendanceLog = ({ attendance, handleModalData, projectId }) => {
const AttendanceLog = ({ handleModalData, projectId }) => {
const [attendances, setAttendnaces] = useState([]);
const [selectedDate, setSelectedDate] = useState("");
const [dateRange, setDateRange] = useState({ startDate: "", endDate: "" });
const dispatch = useDispatch();
const { data, loading, error } = useSelector((store) => store.attendanceLogs);
// Set the default selected date to the current date
// const currentDate = new Date().toISOString().split("T")[0]; // "YYYY-MM-DD"
const currentDate = new Date().toLocaleDateString('en-CA');
const handleDateChange = (e) => {
const date = e.target.value;
setSelectedDate(date);
if (date) {
dispatch(fetchAttendanceData({ projectId, date: date }));
}
};
const [isRefreshing, setIsRefreshing] = useState(true);
const currentDate = new Date().toLocaleDateString( "en-CA" );
const { currentPage, totalPages, currentItems, paginate } = usePagination(
data,
5
);
useEffect(() => {
// If attendance has check-in time, filter it
setAttendnaces(attendance?.filter((record) => record.checkInTime !== null));
setSelectedDate(currentDate); // Set default selected date to today
}, [attendance]);
const renderAttendanceData =
selectedDate === currentDate ? attendances : data;
const { startDate, endDate } = dateRange;
if (startDate && endDate) {
dispatch(
fetchAttendanceData({
projectId,
fromDate: startDate,
toDate: endDate,
})
);
}
}, [dateRange, projectId, isRefreshing]);
return (
<>
<div
className="dataTables_length text-start py-2"
className="dataTables_length text-start py-2 d-flex justify-content-between"
id="DataTables_Table_0_length"
>
<div className="col-md-3">
<input
className="form-control form-control-sm"
type="date"
placeholder="Select Date"
value={selectedDate}
onChange={handleDateChange}
id="html5-date-input"
<div className="col-md-3 my-0 ">
<DateRangePicker onRangeChange={setDateRange} />
</div>
<div className="col-md-2 m-0 text-end">
<i
className={`bx bx-refresh cursor-pointer fs-4 ${
loading ? "spin":""
}`}
title="Refresh"
onClick={()=>setIsRefreshing(!isRefreshing)}
/>
</div>
</div>
<div className="table-responsive text-nowrap">
{attendance && attendance.length > 0 ? (
{data && data.length > 0 ? (
<table className="table mb-0">
<thead>
<tr>
<th className="border-top-1" colSpan={2}>
Name
</th>
<th className="border-top-1">Role</th>
<th className="border-top-1">Date</th>
<th>
<i className="bx bxs-down-arrow-alt text-success"></i>{" "}
Check-In
@ -72,13 +77,13 @@ const AttendanceLog = ({ attendance, handleModalData, projectId }) => {
<tbody>
{loading && <td colSpan={5}>Loading...</td>}
{error && <td colSpan={5}>{error}</td>}
{selectedDate && renderAttendanceData.length === 0 && (
{data && data.length === 0 && (
<tr>
<td colSpan={5}>No Data Found</td>
</tr>
)}
{renderAttendanceData?.map((attendance, index) => (
{currentItems?.map((attendance, index) => (
<tr key={index}>
<td colSpan={2}>
<div className="d-flex justify-content-start align-items-center">
@ -95,7 +100,10 @@ const AttendanceLog = ({ attendance, handleModalData, projectId }) => {
</div>
</div>
</td>
<td>{attendance.jobRoleName}</td>
<td>
{" "}
{moment(attendance.checkInTime).format("DD-MMM-YYYY")}
</td>
<td>{convertShortTime(attendance.checkInTime)}</td>
<td>
{attendance.checkOutTime
@ -118,6 +126,51 @@ const AttendanceLog = ({ attendance, handleModalData, projectId }) => {
<span>No employee logs</span>
)}
</div>
{!loading && (
<nav aria-label="Page ">
<ul className="pagination pagination-sm justify-content-end py-1">
<li
className={`page-item ${
currentPage === 1 ? "disabled" : ""
}`}
>
<button
className="page-link btn-xs"
onClick={() => paginate(currentPage - 1)}
>
&laquo;
</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)}
>
&raquo;
</button>
</li>
</ul>
</nav>
)}
</>
);
};

View File

@ -20,6 +20,8 @@ import { useHasUserPermission } from "../../hooks/useHasUserPermission";
import { REGULARIZE_ATTENDANCE } from "../../utils/constants";
const AttendancePage = () => {
const [activeTab, setActiveTab] = useState("all");
const loginUser = getCachedProfileData();
var selectedProject = useSelector((store) => store.localVariables.projectId);
const { projects, loading: projectLoading } = useProjects();
@ -121,7 +123,7 @@ const AttendancePage = () => {
<div className="nav-align-top nav-tabs-shadow">
<ul className="nav nav-tabs" role="tablist">
<div
className="dataTables_length text-start py-2 px-2"
className="dataTables_length text-start py-2 px-2 d-flex "
id="DataTables_Table_0_length"
>
{loginUser && loginUser?.projects?.length > 1 && (
@ -152,18 +154,17 @@ const AttendancePage = () => {
</select>
</label>
)}
</div>
</ul>
<ul className="nav nav-tabs" role="tablist">
<li className="nav-item">
<button
type="button"
className="nav-link active"
role="tab"
className={`nav-link ${activeTab === "all" ? "active" : ""}`}
onClick={() => setActiveTab("all")}
data-bs-toggle="tab"
data-bs-target="#navs-top-home"
aria-controls="navs-top-home"
aria-selected="true"
>
All
</button>
@ -171,12 +172,10 @@ const AttendancePage = () => {
<li className="nav-item">
<button
type="button"
className="nav-link"
role="tab"
className={`nav-link ${activeTab === "logs" ? "active" : ""}`}
onClick={() => setActiveTab("logs")}
data-bs-toggle="tab"
data-bs-target="#navs-top-profile"
aria-controls="navs-top-profile"
aria-selected="false"
>
Logs
</button>
@ -184,12 +183,12 @@ const AttendancePage = () => {
<li className={`nav-item ${!DoRegularized && "d-none"}`}>
<button
type="button"
className="nav-link "
role="tab"
className={`nav-link ${
activeTab === "regularization" ? "active" : ""
}`}
onClick={() => setActiveTab("regularization")}
data-bs-toggle="tab"
data-bs-target="#navs-top-messages"
aria-controls="navs-top-messages"
aria-selected="false"
>
Regularization
</button>
@ -198,39 +197,30 @@ const AttendancePage = () => {
<div className="tab-content attedanceTabs py-2">
{projectLoading && <span>Loading..</span>}
{!projectLoading && !attendances && <span>Not Found</span>}
{projects && projects.length > 0 && (
<>
<div
className="tab-pane fade show active py-0"
id="navs-top-home"
role="tabpanel"
key={projects.id}
>
<Attendance
attendance={attendances}
handleModalData={handleModalData}
getRole={getRole}
/>
</div>
<div
className="tab-pane fade"
id="navs-top-profile"
role="tabpanel"
>
<AttendanceLog
attendance={attendances}
handleModalData={handleModalData}
projectId={selectedProject}
/>
</div>
<div
className="tab-pane fade"
id="navs-top-messages"
role="tabpanel"
>
<Regularization handleRequest={handleSubmit} />
</div>
</>
{activeTab === "all" && (
<div className="tab-pane fade show active py-0">
<Attendance
attendance={attendances}
handleModalData={handleModalData}
getRole={getRole}
/>
</div>
)}
{activeTab === "logs" && (
<div className="tab-pane fade show active py-0">
<AttendanceLog
handleModalData={handleModalData}
projectId={selectedProject}
/>
</div>
)}
{activeTab === "regularization" && DoRegularized && (
<div className="tab-pane fade show active py-0">
<Regularization handleRequest={handleSubmit} />
</div>
)}
</div>
</div>