import React, { useState, useEffect, useRef, useCallback } from "react"; import moment from "moment"; import showToast from "../../services/toastService"; import { Link, NavLink, useNavigate } from "react-router-dom"; import Avatar from "../../components/common/Avatar"; import Breadcrumb from "../../components/common/Breadcrumb"; import ManageEmp from "../../components/Employee/ManageRole"; import { useEmployeesAllOrByProjectId } from "../../hooks/useEmployees"; import { useProjects } from "../../hooks/useProjects"; // Keep if you use projects elsewhere import { useProfile } from "../../hooks/useProfile"; // Keep if you use profile elsewhere import { hasUserPermission } from "../../utils/authUtils"; // Keep if you use this elsewhere import { ITEMS_PER_PAGE, MANAGE_EMPLOYEES } from "../../utils/constants"; import { clearCacheKey } from "../../slices/apiDataManager"; import { useHasUserPermission } from "../../hooks/useHasUserPermission"; import SuspendEmp from "../../components/Employee/SuspendEmp"; // Keep if you use SuspendEmp import { exportToCSV, exportToExcel, printTable, exportToPDF, } from "../../utils/tableExportUtils"; import EmployeeRepository from "../../repositories/EmployeeRepository"; import ManageEmployee from "../../components/Employee/ManageEmployee"; import ConfirmModal from "../../components/common/ConfirmModal"; import { useSelector } from "react-redux"; import eventBus from "../../services/eventBus"; import { newlineChars } from "pdf-lib"; import GlobalModel from "../../components/common/GlobalModel"; const EmployeeList = () => { const selectedProjectId = useSelector( (store) => store.localVariables.projectId ); const [showInactive, setShowInactive] = useState(false); const [showAllEmployees, setShowAllEmployees] = useState(false); const Manage_Employee = useHasUserPermission(MANAGE_EMPLOYEES); const { employees, loading, setLoading, error, recallEmployeeData } = useEmployeesAllOrByProjectId( showAllEmployees ? null : selectedProjectId, // Use selectedProjectId here showInactive ); const [employeeList, setEmployeeList] = useState([]); const [modelConfig, setModelConfig] = useState(); const [currentPage, setCurrentPage] = useState(1); const [itemsPerPage] = useState(ITEMS_PER_PAGE); const [isCreateModalOpen, setIsCreateModalOpen] = useState(false); const [searchText, setSearchText] = useState(""); const [filteredData, setFilteredData] = useState([]); const [showModal, setShowModal] = useState(false); const [selectedEmployeeId, setSelecedEmployeeId] = useState(null); const [IsDeleteModalOpen, setIsDeleteModalOpen] = useState(false); const [selectedEmpFordelete, setSelectedEmpFordelete] = useState(null); const [employeeLodaing, setemployeeLodaing] = useState(false); const navigate = useNavigate(); /** * Applies the search filter to a given array of employee data. * @param {Array} data - The array of employee objects to filter. * @param {string} text - The search text. * @returns {Array} The filtered array. */ const applySearchFilter = (data, text) => { if (!text) { return data; } const lowercasedText = text.toLowerCase(); return data.filter((item) => { const fullName = `${item.firstName} ${item.middleName} ${item.lastName}`.toLowerCase(); const email = item.email ? item.email.toLowerCase() : ""; const phoneNumber = item.phoneNumber ? item.phoneNumber.toLowerCase() : ""; const jobRole = item.jobRole ? item.jobRole.toLowerCase() : ""; return ( fullName.includes(lowercasedText) || email.includes(lowercasedText) || phoneNumber.includes(lowercasedText) || jobRole.includes(lowercasedText) ); }); }; const handleSearch = (e) => { const value = e.target.value; setSearchText(value); setCurrentPage(1); }; useEffect(() => { setCurrentPage(1); if (!loading && Array.isArray(employees)) { const sorted = [...employees].sort((a, b) => { const nameA = `${a.firstName || ""}${a.middleName || ""}${a.lastName || ""}`.toLowerCase(); const nameB = `${b.firstName || ""}${b.middleName || ""}${b.lastName || ""}`.toLowerCase(); return nameA?.localeCompare(nameB); }); setEmployeeList(sorted); const results = applySearchFilter(sorted, searchText); setFilteredData(results); } else if (!loading && !employees) { setEmployeeList([]); setFilteredData([]); } }, [loading, employees, showAllEmployees, searchText, selectedProjectId]); // Add selectedProjectId to dependencies const displayData = filteredData; const indexOfLastItem = currentPage * itemsPerPage; const indexOfFirstItem = indexOfLastItem - itemsPerPage; const currentItems = Array.isArray(displayData) ? displayData.slice(indexOfFirstItem, indexOfLastItem) : []; const paginate = (pageNumber) => setCurrentPage(pageNumber); const totalPages = Array.isArray(displayData) ? Math.ceil(displayData.length / itemsPerPage) : 0; const openModal = () => { setIsCreateModalOpen(true); }; const closeModal = () => { setIsCreateModalOpen(false); const modalElement = document.getElementById("managerole-modal"); if (modalElement && !showModal) { modalElement.classList.remove("show"); modalElement.style.display = "none"; document.body.classList.remove("modal-open"); document.querySelector(".modal-backdrop")?.remove(); // Use optional chaining for safety } setShowModal(false); clearCacheKey("employeeProfile"); recallEmployeeData(showInactive, showAllEmployees ? null : selectedProjectId); // Use selectedProjectId here }; const handleShow = () => setShowModal(true); const handleClose = () => setShowModal(false); const suspendEmployee = (id) => { setemployeeLodaing(true); EmployeeRepository.deleteEmployee(id) .then((response) => { showToast("Employee deleted successfully.", "success"); clearCacheKey("employeeListByProject"); clearCacheKey("allEmployeeList"); clearCacheKey("allInactiveEmployeeList"); clearCacheKey("employeeProfile"); // Recall data based on current filter states after deletion to refresh the table recallEmployeeData(showInactive, showAllEmployees ? null : selectedProjectId); // Use selectedProjectId here setemployeeLodaing(false); setIsDeleteModalOpen(false); }) .catch((error) => { const message = error.response?.data?.message || error.message || "An unexpected error occurred"; showToast(message, "error"); setemployeeLodaing(false); setIsDeleteModalOpen(false); }); }; const handleConfigData = (config) => { setModelConfig(config); }; useEffect(() => { if (modelConfig !== null) { openModal(); } }, [modelConfig, isCreateModalOpen]); const tableRef = useRef(null); const handleExport = (type) => { if (!currentItems || currentItems.length === 0) return; switch (type) { case "csv": exportToCSV(currentItems, "employees"); break; case "excel": exportToExcel(currentItems, "employees"); break; case "pdf": exportToPDF(currentItems, "employees"); break; case "print": printTable(tableRef.current); break; default: break; } }; const handleToggle = (e) => { setShowInactive(e.target.checked); recallEmployeeData(e.target.checked, showAllEmployees ? null : selectedProjectId); // Use selectedProjectId here }; const handleAllEmployeesToggle = (e) => { const isChecked = e.target.checked; setShowInactive(false); setShowAllEmployees(isChecked); if (!isChecked) { setSelectedProject(selectedProjectId || ""); } }; const handleEmployeeModel = (id) => { setSelecedEmployeeId(id); setShowModal(true); }; const handleOpenDelete = (employee) => { setSelectedEmpFordelete(employee); setIsDeleteModalOpen(true); }; useEffect(() => { if (!showAllEmployees) { recallEmployeeData(showInactive, selectedProjectId); } }, [selectedProjectId, showInactive, showAllEmployees, recallEmployeeData]); const handler = useCallback( (msg) => { if(employees.some((item) => item.id == msg.employeeId)){ setEmployeeList([]); recallEmployeeData(showInactive, showAllEmployees ? null : selectedProjectId); // Use selectedProjectId here } },[employees, showInactive, showAllEmployees, selectedProjectId] // Add all relevant dependencies ); useEffect(() => { eventBus.on("employee",handler); return () => eventBus.off("employee",handler) },[handler]) return ( <> {isCreateModalOpen && ( )} {/* {showModal && (
)} */} {showModal && ( setShowModal(false)}> setShowModal(false)} /> )} {IsDeleteModalOpen && (
setIsDeleteModalOpen(false)} loading={employeeLodaing} paramData={selectedEmpFordelete} />
)}
{/* Switches: All Employees + Inactive */}
{/* All Employees Switch */}
{/* Show Inactive Employees Switch */} {showAllEmployees && (
)}
{/* Right side: Search + Export + Add Employee */}
{/* Search Input - ALWAYS ENABLED */}
{/* Export Dropdown */} {/* Add Employee Button */} {Manage_Employee && ( )}
{loading && ( )} {/* Conditional messages for no data or no search results */} {!loading && displayData?.length === 0 && searchText && !showAllEmployees ? ( ) : null} {!loading && displayData?.length === 0 && (!searchText || showAllEmployees) ? ( ) : null} {/* Render current items */} {currentItems && !loading && currentItems.map((item) => ( {Manage_Employee && ( )} ))}
Name
Email
Contact
Role
Joining Date Status Actions

Loading...

'{searchText}' employee not found {" "}
No Data Found
{item.email ? ( {item.email} ) : ( NA )} {item.phoneNumber} {item.jobRole || "Not Assign Yet"} {moment(item.joiningDate)?.format("DD-MMM-YYYY")} {/* Assuming 'isActive' property exists to determine status */} {item.isActive ? ( Active ) : ( Inactive )}
{!item.isSystem && ( <> )}
{/* Pagination */} {!loading && displayData.length > itemsPerPage && ( )}
); }; export default EmployeeList;