diff --git a/src/components/Activities/AttendLogs.jsx b/src/components/Activities/AttendLogs.jsx index 43a38907..fd40bb66 100644 --- a/src/components/Activities/AttendLogs.jsx +++ b/src/components/Activities/AttendLogs.jsx @@ -84,7 +84,7 @@ const AttendLogs = ({ Id }) => { document.querySelectorAll('[data-bs-toggle="tooltip"]') ); tooltipTriggerList.forEach((el) => new bootstrap.Tooltip(el)); - }, [] ); + }, []); return (
@@ -106,13 +106,12 @@ const AttendLogs = ({ Id }) => { - - - - - - - + + + + + + @@ -141,13 +140,14 @@ const AttendLogs = ({ Id }) => { "--" )} - - - ))} diff --git a/src/components/Activities/Attendance.jsx b/src/components/Activities/Attendance.jsx index 69f3de10..9d4de50a 100644 --- a/src/components/Activities/Attendance.jsx +++ b/src/components/Activities/Attendance.jsx @@ -1,4 +1,4 @@ -import React, { useState,useEffect } from "react"; +import React, { useState, useEffect } from "react"; import moment from "moment"; import Avatar from "../common/Avatar"; import { convertShortTime } from "../../utils/dateUtils"; @@ -32,7 +32,7 @@ const Attendance = ({ attendance, getRole, handleModalData }) => { const { currentPage, totalPages, currentItems, paginate } = usePagination( filteredData, - 5 + 10 ); return ( <> @@ -116,7 +116,7 @@ const Attendance = ({ attendance, getRole, handleModalData }) => { ))} - {!attendance && ( + {!attendance && ( No employees assigned to the project )} diff --git a/src/components/Activities/AttendcesLogs.jsx b/src/components/Activities/AttendcesLogs.jsx index a62b4e7c..498d5413 100644 --- a/src/components/Activities/AttendcesLogs.jsx +++ b/src/components/Activities/AttendcesLogs.jsx @@ -16,42 +16,57 @@ const AttendanceLog = ({ handleModalData, projectId }) => { const dispatch = useDispatch(); const { data, loading, error } = useSelector((store) => store.attendanceLogs); const [isRefreshing, setIsRefreshing] = useState(true); + const [dates, setDates] = useState([]); const today = new Date(); today.setHours(0, 0, 0, 0); // Strip time to compare dates only - + const isSameDay = (dateStr) => { if (!dateStr) return false; const d = new Date(dateStr); d.setHours(0, 0, 0, 0); return d.getTime() === today.getTime(); }; - + const isBeforeToday = (dateStr) => { if (!dateStr) return false; const d = new Date(dateStr); d.setHours(0, 0, 0, 0); return d.getTime() < today.getTime(); }; - + 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 group1 = data.filter(d => d.activity === 1 && isSameDay(d.checkInTime)).sort(sortByName); - const group2 = data.filter(d => d.activity === 4 && isSameDay(d.checkOutTime)).sort(sortByName); - const group3 = data.filter(d => d.activity === 1 && isBeforeToday(d.checkInTime)).sort(sortByName); - const group4 = data.filter(d => d.activity === 4 && isBeforeToday(d.checkOutTime)).sort(sortByName); - const group5 = data.filter(d => d.activity === 5).sort(sortByName); - - const sortedFinalList = [...group1, ...group2, ...group3, ...group4, ...group5]; - const currentDate = new Date().toLocaleDateString( "en-CA" ); + const group1 = data + .filter((d) => d.activity === 1 && isSameDay(d.checkInTime)) + .sort(sortByName); + const group2 = data + .filter((d) => d.activity === 4 && isSameDay(d.checkOutTime)) + .sort(sortByName); + const group3 = data + .filter((d) => d.activity === 1 && isBeforeToday(d.checkInTime)) + .sort(sortByName); + const group4 = data + .filter((d) => d.activity === 4 && isBeforeToday(d.checkOutTime)) + .sort(sortByName); + const group5 = data.filter((d) => d.activity === 5).sort(sortByName); + + const sortedFinalList = [ + ...group1, + ...group2, + ...group3, + ...group4, + ...group5, + ]; + + const currentDate = new Date().toLocaleDateString("en-CA"); const { currentPage, totalPages, currentItems, paginate } = usePagination( sortedFinalList, - 5 + 10 ); useEffect(() => { @@ -65,9 +80,17 @@ const AttendanceLog = ({ handleModalData, projectId }) => { }) ); } - }, [ dateRange, projectId, isRefreshing ] ); - - + }, [dateRange, projectId, isRefreshing]); + + useEffect(() => { + const attendanceDate = [ + ...new Set(sortedFinalList.map((item) => item.checkInTime.split("T")[0])), + ].sort((a, b) => new Date(b) - new Date(a)); + if (attendanceDate != dates) { + setDates(attendanceDate); + } + }, [data]); + return ( <>
{
setIsRefreshing( !isRefreshing )} - + onClick={() => setIsRefreshing(!isRefreshing)} />
- {(data && data.length > 0 ) && ( + {data && data.length > 0 && (
DateTimeActivityLocationRecored ByDescriptionDateTimeActivityLocationRecored ByDescription
- {`${logs[0]?.updatedByEmployee?.firstName ?? ''} ${logs[0]?.updatedByEmployee?.lastName ?? ''}`} + + {`${log?.updatedByEmployee?.firstName ?? ""} ${ + log?.updatedByEmployee?.lastName ?? "" + }`} + {log?.comment || "--"}
@@ -109,95 +131,111 @@ const AttendanceLog = ({ handleModalData, projectId }) => { {loading && } - {currentItems?.map( ( attendance, index ) => ( - - - - - - - - ) )} + {dates.map((date, i) => { + return ( + + {currentItems.some( + (item) => item.checkInTime.split("T")[0] === date + ) && ( + + + + )} + {currentItems + ?.filter((item) => item.checkInTime.includes(date)) + .map((attendance, index) => ( + + + + + + + + ))} + + ); + })}
Loading...
- - - {" "} - {moment( attendance.checkInTime ).format( "DD-MMM-YYYY" )} - {convertShortTime( attendance.checkInTime )} - {attendance.checkOutTime - ? convertShortTime( attendance.checkOutTime ) - : "--"} - - -
+ {date} +
+ + + {" "} + {moment(attendance.checkInTime).format( + "DD-MMM-YYYY" + )} + {convertShortTime(attendance.checkInTime)} + {attendance.checkOutTime + ? convertShortTime(attendance.checkOutTime) + : "--"} + + +
- ) } - {(!loading && data.length === 0) && - No employee logs - } - {error && {error}} + )} + {!loading && data.length === 0 && No employee logs} + {error && {error}}
{!loading && ( - + )} ); diff --git a/src/components/Activities/Regularization.jsx b/src/components/Activities/Regularization.jsx index 8b9f9cf1..32025941 100644 --- a/src/components/Activities/Regularization.jsx +++ b/src/components/Activities/Regularization.jsx @@ -23,11 +23,11 @@ const Regularization = ({ handleRequest }) => { return nameA.localeCompare(nameB); }; - const filteredData = regularizesList.sort(sortByName) - + const filteredData = regularizesList.sort(sortByName); + const { currentPage, totalPages, currentItems, paginate } = usePagination( filteredData, - 5 + 10 ); return ( @@ -94,50 +94,46 @@ const Regularization = ({ handleRequest }) => { {!loading && ( - - )} + + )}
); }; diff --git a/src/components/Employee/EmployeeNav.jsx b/src/components/Employee/EmployeeNav.jsx index f9c12961..32c94b20 100644 --- a/src/components/Employee/EmployeeNav.jsx +++ b/src/components/Employee/EmployeeNav.jsx @@ -5,8 +5,7 @@ const EmployeeNav = ({ onPillClick, activePill }) => {
    - -
  • +
  • { Attendances
  • -
  • +
  • { Documents
  • - -
  • + +
  • { }; const handleProfilePage = () => { - navigate(`/employee/${profile?.employeeInfo?.id}?for=account`); + navigate(`/employee/${profile?.employeeInfo?.id}?for=attendance`); }; return (
- -
-
- -
-
-
- {renderContent()} +
+
+ +
+
+
{renderContent()}
-
); }; diff --git a/src/utils/axiosClient.jsx b/src/utils/axiosClient.jsx index faa97157..93e96bc5 100644 --- a/src/utils/axiosClient.jsx +++ b/src/utils/axiosClient.jsx @@ -21,8 +21,7 @@ axiosClient.interceptors.request.use( if (token) { config.headers["Authorization"] = `Bearer ${token}`; config._retry = true; - } - else{ + } else { config._retry = false; } } @@ -37,7 +36,6 @@ axiosClient.interceptors.response.use( (response) => response, async (error) => { - const originalRequest = error.config; if (!originalRequest) { @@ -81,17 +79,17 @@ axiosClient.interceptors.response.use( } else if (error.response) { if (error.config.url.indexOf("refresh-token") != -1) { //showToast("Server is unreachable. Try again later!", "error"); - } + } // else { // // showToast(error.response.data.message, "error"); // repeted toast // } - if (error.response.status === 401 && !originalRequest._retry) { + if (error.response.status === 401) { originalRequest._retry = true; try { // Get the refresh token from secure storage const refreshToken = localStorage.getItem("refreshToken"); - if (!refreshToken) { + if (!refreshToken || error.response.data.errors === "Invalid or expired refresh token.") { // Redirect to login if refresh token is not available redirectToLogin(); return Promise.reject(error); @@ -108,7 +106,7 @@ axiosClient.interceptors.response.use( const { token, refreshToken: newRefreshToken } = response.data.data; localStorage.setItem("jwtToken", token); - localStorage.setItem("refreshToken", newRefreshToken); + localStorage.setItem("refreshToken", newRefreshToken); // Retry the original request with the new token originalRequest.headers["Authorization"] = `Bearer ${token}`; @@ -116,7 +114,6 @@ axiosClient.interceptors.response.use( // Retry the original request return axiosClient(originalRequest); } catch (err) { - // Redirect to login if token refresh fails redirectToLogin(); return Promise.reject(err); @@ -192,5 +189,5 @@ export const api = { }; //export default axiosClient; function redirectToLogin() { - // window.location.href = "/auth/login"; + window.location.href = "/auth/login"; }