import React, { useState, useEffect, useCallback } from "react"; import { cacheData, clearCacheKey, getCachedData, getCachedProfileData, } from "../../slices/apiDataManager"; import Breadcrumb from "../../components/common/Breadcrumb"; import AttendanceLog from "../../components/Activities/AttendcesLogs"; import Attendance from "../../components/Activities/Attendance"; import AttendanceModel from "../../components/Activities/AttendanceModel"; import showToast from "../../services/toastService"; import Regularization from "../../components/Activities/Regularization"; import { useAttendance } from "../../hooks/useAttendance"; import { useDispatch, useSelector } from "react-redux"; import { setProjectId } from "../../slices/localVariablesSlice"; import { markCurrentAttendance } from "../../slices/apiSlice/attendanceAllSlice"; import { useHasUserPermission } from "../../hooks/useHasUserPermission"; import { REGULARIZE_ATTENDANCE } from "../../utils/constants"; import eventBus from "../../services/eventBus"; import AttendanceRepository from "../../repositories/AttendanceRepository"; import { useProjectName } from "../../hooks/useProjects"; const AttendancePage = () => { const [activeTab, setActiveTab] = useState("all"); const [showPending, setShowPending] = useState(false); const [searchQuery, setSearchQuery] = useState(""); const loginUser = getCachedProfileData(); const selectedProject = useSelector((store) => store.localVariables.projectId); const dispatch = useDispatch(); const { attendance, loading: attLoading, recall: attrecall, } = useAttendance(selectedProject); const [attendances, setAttendances] = useState(); const [empRoles, setEmpRoles] = useState(null); const [isCreateModalOpen, setIsCreateModalOpen] = useState(false); const [modelConfig, setModelConfig] = useState(null); // Initialize as null const DoRegularized = useHasUserPermission(REGULARIZE_ATTENDANCE); const { projectNames, loading: projectLoading, fetchData } = useProjectName(); const [formData, setFormData] = useState({ markTime: "", description: "", date: new Date().toLocaleDateString(), }); const handler = useCallback( (msg) => { if (selectedProject === msg.projectId) { const updatedAttendance = attendances ? attendances.map((item) => item.employeeId === msg.response.employeeId ? { ...item, ...msg.response } : item ) : [msg.response]; cacheData("Attendance", { data: updatedAttendance, projectId: selectedProject, }); setAttendances(updatedAttendance); } }, [selectedProject, attendances] ); const employeeHandler = useCallback( (msg) => { // This logic seems fine for refetching if an employee ID exists in current attendances if (attendances?.some((item) => item.employeeId === msg.employeeId)) { AttendanceRepository.getAttendance(selectedProject) .then((response) => { cacheData("Attendance", { data: response.data, selectedProject }); setAttendances(response.data); }) .catch((error) => { console.error(error); }); } }, [selectedProject, attendances] ); const getRole = (roleId) => { if (!empRoles) return "Unassigned"; if (!roleId) return "Unassigned"; const role = empRoles.find((b) => b.id === roleId); return role ? role.role : "Unassigned"; }; // Simplified and moved modal opening logic const handleModalData = useCallback((employee) => { setModelConfig(employee); setIsCreateModalOpen(true); // Open the modal directly when data is set }, []); const closeModal = useCallback(() => { setModelConfig(null); setIsCreateModalOpen(false); // Directly manipulating the DOM is generally not recommended in React. // React handles modal visibility via state. If you must, ensure it's // for external libraries or for very specific, controlled reasons. // For a typical Bootstrap modal, just setting `isCreateModalOpen` to false // should be enough if the modal component itself handles the Bootstrap classes. const modalElement = document.getElementById("check-Out-modal"); if (modalElement) { modalElement.classList.remove("show"); modalElement.style.display = "none"; document.body.classList.remove("modal-open"); const modalBackdrop = document.querySelector(".modal-backdrop"); if (modalBackdrop) { modalBackdrop.remove(); } } }, []); const handleSubmit = useCallback((formData) => { dispatch(markCurrentAttendance(formData)) .then((action) => { if (action.payload && action.payload.employeeId) { const updatedAttendance = attendances ? attendances.map((item) => item.employeeId === action.payload.employeeId ? { ...item, ...action.payload } : item ) : [action.payload]; cacheData("Attendance", { data: updatedAttendance, projectId: selectedProject, }); setAttendances(updatedAttendance); showToast("Attendance Marked Successfully", "success"); } else { showToast("Failed to mark attendance: Invalid response", "error"); } }) .catch((error) => { showToast(error.message, "error"); }); }, [dispatch, attendances, selectedProject]); const handleToggle = (event) => { setShowPending(event.target.checked); }; useEffect(() => { if (selectedProject === null && projectNames.length > 0) { dispatch(setProjectId(projectNames[0]?.id)); } }, [selectedProject, projectNames, dispatch]); useEffect(() => { setAttendances(attendance); }, [attendance]); const filteredAndSearchedTodayAttendance = useCallback(() => { let currentData = attendances; if (showPending) { currentData = currentData?.filter( (att) => att?.checkInTime !== null && att?.checkOutTime === null ); } if (searchQuery) { const lowerCaseSearchQuery = searchQuery.toLowerCase(); currentData = currentData?.filter((att) => { const fullName = [att.firstName, att.middleName, att.lastName] .filter(Boolean) .join(" ") .toLowerCase(); return ( att.employeeName?.toLowerCase().includes(lowerCaseSearchQuery) || att.employeeId?.toLowerCase().includes(lowerCaseSearchQuery) || fullName.includes(lowerCaseSearchQuery) ); }); } return currentData; }, [attendances, showPending, searchQuery]); useEffect(() => { eventBus.on("attendance", handler); return () => eventBus.off("attendance", handler); }, [handler]); useEffect(() => { eventBus.on("employee", employeeHandler); return () => eventBus.off("employee", employeeHandler); }, [employeeHandler]); return ( <> {isCreateModalOpen && modelConfig && ( )}
{activeTab === "all" && ( <> {!attLoading && (
)} {!attLoading && filteredAndSearchedTodayAttendance()?.length === 0 && (

{" "} {showPending ? "No Pending Available" : "No Employee assigned yet."}{" "}

)} )} {activeTab === "logs" && (
)} {activeTab === "regularization" && DoRegularized && (
)} {!attLoading && !attendances && Not Found}
); }; export default AttendancePage;