diff --git a/src/components/Activities/AttendLogs.jsx b/src/components/Activities/AttendLogs.jsx index b246768b..b94c80c6 100644 --- a/src/components/Activities/AttendLogs.jsx +++ b/src/components/Activities/AttendLogs.jsx @@ -2,12 +2,27 @@ import React, { useEffect, useState } from "react"; import { useEmployeeAttendacesLog } from "../../hooks/useAttendance"; import { convertShortTime } from "../../utils/dateUtils"; import { useNavigate } from "react-router-dom"; +import { THRESH_HOLD } from "../../utils/constants"; const AttendLogs = ({ Id }) => { const { logs, loading } = useEmployeeAttendacesLog(Id); const navigate = useNavigate(); - const whichActivityPerform = (actvity) => { + const isCheckoutRegularized = ( + activityTimeStr, + checkoutTimeStr, + threshHours + ) => { + if (!activityTimeStr || !checkoutTimeStr) return false; + + const activityTime = new Date(activityTimeStr); + const checkoutTime = new Date(checkoutTimeStr); + const threshTimeMs = threshHours * 60 * 60 * 1000; + + return checkoutTime - activityTime > threshTimeMs; + }; + + const whichActivityPerform = (actvity, checkOutTime) => { switch (actvity) { case 1: return ( @@ -24,12 +39,12 @@ const AttendLogs = ({ Id }) => { case 2: return ( ); break; @@ -41,27 +56,47 @@ const AttendLogs = ({ Id }) => { data-bs-offset="0,8" data-bs-placement="top" data-bs-custom-class="tooltip" - title="Regularized" + title="Request Deleted!" > ); break; case 4: - return ( - - ); + if ( + checkOutTime && + isCheckoutRegularized( + logs[0]?.activityTime, + checkOutTime, + THRESH_HOLD + ) + ) { + return ( + + ); + } else { + return ( + + ); + } break; case 5: return ( { const url = `https://www.google.com/maps?q=${lat},${lng}`; window.open(url, "_blank"); // Open in new tab }; + useEffect(() => { const tooltipTriggerList = Array.from( document.querySelectorAll('[data-bs-toggle="tooltip"]') @@ -122,11 +158,13 @@ const AttendLogs = ({ Id }) => { {log.activityTime.slice(0, 10)} {convertShortTime(log.activityTime)} - {whichActivityPerform(log.activity)} + + {whichActivityPerform(log.activity, log.activityTime)} + {log?.latitude != 0 ? ( { }`} - {log?.comment || "--"} + {log?.comment?.length > 50 + ? `${log.comment.slice(0, 50)}...` + : log.comment || "--"} ))} diff --git a/src/hooks/useAttendanceStatus.js b/src/hooks/useAttendanceStatus.js index b1b6180b..4085fba2 100644 --- a/src/hooks/useAttendanceStatus.js +++ b/src/hooks/useAttendanceStatus.js @@ -1,17 +1,16 @@ -import { useEffect, useState } from "react"; -import { timeElapsed } from "../utils/dateUtils"; -import { useSelector } from "react-redux"; -import { THRESH_HOLD } from "../utils/constants"; +import { useEffect, useState } from 'react'; +import { timeElapsed } from '../utils/dateUtils'; // Make sure it calculates in hours +import { THRESH_HOLD } from '../utils/constants'; +// THRESH_HOLD in hours (e.g., 12, 48, or 60) export const ACTIONS = { CHECK_IN: 0, CHECK_OUT: 1, REGULARIZATION: 2, REQUESTED: 3, APPROVED: 4, - REJECTED: 5, + REJECTED: 5 }; -const now = new Date(); const useAttendanceStatus = (attendanceData) => { const [status, setStatus] = useState({ @@ -19,133 +18,100 @@ const useAttendanceStatus = (attendanceData) => { action: null, disabled: true, text: "Unknown", - color: "btn-secondary", + color: 'btn-secondary', }); useEffect(() => { const { checkInTime, checkOutTime, activity } = attendanceData; + const now = new Date(); - if (activity === 0 && checkInTime === null && checkOutTime === null) { - setStatus({ + const isSameDay = (date1, date2) => + new Date(date1).toDateString() === new Date(date2).toDateString(); + + // 1. No check-in/check-out yet → Allow Check-In + if (activity === 0 && !checkInTime && !checkOutTime) { + return setStatus({ status: "Check-In", action: ACTIONS.CHECK_IN, disabled: false, text: "Check In", - color: "btn-primary", + color: 'btn-primary', }); - } else if (activity === 4 && new Date(checkOutTime) < now) { - setStatus({ - status: "Approved", - action: ACTIONS.APPROVED, - disabled: true, - text: "Approved", - color: "btn-success", - }); - } else if ( - activity === 0 && - checkInTime === null && - checkOutTime === null && - !timeElapsed(checkInTime, THRESH_HOLD) - ) { - setStatus({ - status: "Check-In", - action: ACTIONS.CHECK_IN, - disabled: false, - text: "Check In", - color: "btn-primary", - }); - } else if ( - activity === 0 && - checkInTime !== null && - checkOutTime === null && - timeElapsed(checkInTime, THRESH_HOLD) - ) { - setStatus({ - status: "Request Regularize", - action: ACTIONS.REGULARIZATION, - disabled: false, - text: "Regularizes", - color: "btn-warning", - }); - } else if ( - activity === 1 && - checkInTime !== null && - checkOutTime === null && - !timeElapsed(checkInTime, THRESH_HOLD) - ) { - setStatus({ - status: "Check-Out", - action: ACTIONS.CHECK_OUT, - disabled: false, - text: "Check Out", - color: "btn-primary", - }); - } else if ( - activity === 1 && - checkInTime !== null && - checkOutTime === null && - timeElapsed(checkInTime, THRESH_HOLD) - ) { - setStatus({ - status: "Request Regularize", - action: ACTIONS.REGULARIZATION, - disabled: false, - text: "Regularize", - color: "btn-warning", - }); - } else if ( - activity === 4 && - checkInTime !== null && - checkOutTime !== null && - !timeElapsed(checkInTime, THRESH_HOLD) - ) { - if ( - activity === 4 && - checkInTime !== null && - checkOutTime !== null && - new Date(checkOutTime).toDateString() !== new Date().toDateString() - ) { - setStatus({ + } + + // 2. Checked in, no checkout yet + if (checkInTime && !checkOutTime) { + if (timeElapsed(checkInTime, THRESH_HOLD)) { + return setStatus({ + status: "Request Regularize", + action: ACTIONS.REGULARIZATION, + disabled: false, + text: "Regularize", + color: 'btn-warning', + }); + } else { + return setStatus({ + status: "Check-Out", + action: ACTIONS.CHECK_OUT, + disabled: false, + text: "Check Out", + color: 'btn-primary', + }); + } + } + + // 3. Already checked in and out → Handle activity === 4 (Approved) + if (checkInTime && checkOutTime && activity === 4) { + if (!isSameDay(checkOutTime, now) && !timeElapsed(checkOutTime, THRESH_HOLD)) { + return setStatus({ status: "Approved", action: ACTIONS.APPROVED, disabled: true, text: "Approved", - color: "btn-success", + color: 'btn-success', }); - } else { - setStatus({ + } else if (isSameDay(checkOutTime, now)) { + return setStatus({ status: "Check-In", action: ACTIONS.CHECK_IN, disabled: false, text: "Check In", - color: "btn-primary", + color: 'btn-primary', }); } - } else if (activity === 2 && checkInTime !== null) { - setStatus({ + } + + // 4. Regularization Requested + if (activity === 2) { + return setStatus({ status: "Requested", action: ACTIONS.REQUESTED, disabled: true, text: "Requested", - color: "btn-info", + color: 'btn-info', }); - } else if (activity === 5 && checkInTime !== null) { - setStatus({ + } + + // 5. Rejected Regularization + if (activity === 5) { + return setStatus({ status: "Rejected", action: ACTIONS.REJECTED, disabled: true, text: "Rejected", - color: "btn-danger", - }); - } else { - setStatus({ - status: "Approved", - action: ACTIONS.APPROVED, - disabled: true, - text: "Approved", - color: "btn-success", + color: 'btn-danger', }); } + + // Default to Approved if none of the above apply + return setStatus({ + status: "Approved", + action: ACTIONS.APPROVED, + disabled: true, + text: "Approved", + color: 'btn-success', + }); + }, [attendanceData]); return status;