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, useEmployeesByOrganization, useSuspendEmployee, } from "../../hooks/useEmployees"; import { useProjectName, useProjects } from "../../hooks/useProjects"; import { useProfile } from "../../hooks/useProfile"; import { ITEMS_PER_PAGE, MANAGE_EMPLOYEES, VIEW_ALL_EMPLOYEES, VIEW_TEAM_MEMBERS, } from "../../utils/constants"; import { clearCacheKey } from "../../slices/apiDataManager"; 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 { useDispatch, useSelector } from "react-redux"; import eventBus from "../../services/eventBus"; import { newlineChars } from "pdf-lib"; import GlobalModel from "../../components/common/GlobalModel"; import usePagination from "../../hooks/usePagination"; import { setProjectId } from "../../slices/localVariablesSlice"; import { useHasUserPermission } from "../../hooks/useHasUserPermission"; import Pagination from "../../components/common/Pagination"; const EmployeeList = () => { const selectedProjectId = useSelector( (store) => store.localVariables.projectId ); const { projectNames, loading: projectLoading, fetchData } = useProjectName(); const dispatch = useDispatch(); const [showInactive, setShowInactive] = useState(false); const Manage_Employee = useHasUserPermission(MANAGE_EMPLOYEES); const { data: employees, isLoading: loading, error, refetch: recallEmployeeData, } = useEmployeesByOrganization(showInactive); const [employeeList, setEmployeeList] = useState([]); const [modelConfig, setModelConfig] = useState(); const [EmpForManageRole, setEmpForManageRole] = useState(null); // 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 ViewTeamMember = useHasUserPermission(VIEW_TEAM_MEMBERS); const { mutate: suspendEmployee, isPending: empLodaing } = useSuspendEmployee( { setIsDeleteModalOpen, setemployeeLodaing, } ); useEffect(() => { if (selectedProjectId === null) { dispatch(setProjectId(projectNames[0]?.id)); } }, [selectedProjectId]); const navigate = useNavigate(); const applySearchFilter = (data, text) => { if (!text) { return data; } const lowercasedText = text.toLowerCase().trim(); return data.filter((item) => { const firstName = item.firstName || ""; const middleName = item.middleName || ""; const lastName = item.lastName || ""; const fullName = `${firstName} ${middleName} ${lastName}` .toLowerCase() .trim() .replace(/\s+/g, " "); const email = item.email?.toLowerCase() || ""; const phoneNumber = item.phoneNumber?.toLowerCase() || ""; const 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); }; const displayData = searchText ? filteredData : employeeList; const { currentPage, totalPages, currentItems, paginate, setCurrentPage } = usePagination(displayData, ITEMS_PER_PAGE); const openModal = () => { setIsCreateModalOpen(true); }; const handleConfigData = (config) => { setModelConfig(config); }; const tableRef = useRef(null); const handleExport = (type) => { // Export full list (filtered if search applied) const dataToExport = searchText ? filteredData : employeeList; if (!dataToExport || dataToExport.length === 0) return; // Map and format employee data for export const exportData = dataToExport.map((item) => ({ "First Name": item.firstName || "", "Middle Name": item.middleName || "", "Last Name": item.lastName || "", "Email": item.email || "", "Gender": item.gender || "", "Birth Date": item.birthdate ? moment(item.birthdate).format("DD-MMM-YYYY") : "", "Joining Date": item.joiningDate ? moment(item.joiningDate).format("DD-MMM-YYYY") : "", "Permanent Address": item.permanentAddress || "", "Current Address": item.currentAddress || "", "Phone Number": item.phoneNumber || "", "Emergency Phone Number": item.emergencyPhoneNumber || "", "Emergency Contact Person": item.emergencyContactPerson || "", "Is Active": item.isActive ? "Active" : "Inactive", "Job Role": item.jobRole || "", })); switch (type) { case "csv": exportToCSV(exportData, "employees"); break; case "excel": exportToExcel(exportData, "employees"); break; case "pdf": exportToPDF( dataToExport.map((item) => ({ Name: `${item.firstName || ""} ${item.lastName || ""}`.trim(), Email: item.email || "", "Phone Number": item.phoneNumber || "", "Job Role": item.jobRole || "", "Joining Date": item.joiningDate ? moment(item.joiningDate).format("DD-MMM-YYYY") : "", Gender: item.gender || "", Status: item.isActive ? "Active" : "Inactive", })), "employees", [ "Name", "Email", "Phone Number", "Job Role", "Joining Date", "Gender", "Status", ] ); break; case "print": printTable(tableRef.current); break; default: break; } }; const handleAllEmployeesToggle = (e) => { const isChecked = e.target.checked; setShowInactive(false); // setShowAllEmployees(isChecked); }; const handleEmployeeModel = (id) => { setSelecedEmployeeId(id); setShowModal(true); }; const handleOpenDelete = (employee) => { setSelectedEmpFordelete(employee); setIsDeleteModalOpen(true); }; useEffect(() => { const filtered = applySearchFilter(employeeList, searchText); setFilteredData(filtered); }, [searchText, employeeList]); useEffect(() => { 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((prevList) => { const prevJSON = JSON.stringify(prevList); const nextJSON = JSON.stringify(sorted); if (prevJSON !== nextJSON) { return sorted; } return prevList; }); setFilteredData((prev) => { const prevJSON = JSON.stringify(prev); const nextJSON = JSON.stringify(sorted); if (prevJSON !== nextJSON) { return sorted; } return prev; }); setCurrentPage((prevPage) => (prevPage !== 1 ? 1 : prevPage)); } }, [loading, employees, selectedProjectId, showInactive]); const handler = useCallback( (msg) => { if (employees.some((item) => item.id == msg.employeeId)) { setEmployeeList([]); recallEmployeeData(showInactive); } }, [employees, showInactive, showInactive, selectedProjectId] // Add all relevant dependencies ); useEffect(() => { eventBus.on("employee", handler); return () => eventBus.off("employee", handler); }, [handler]); return ( <> {EmpForManageRole && ( setEmpForManageRole(null)} > setEmpForManageRole(null)} /> )} {showModal && ( setShowModal(false)} > setShowModal(false)} /> )} {IsDeleteModalOpen && ( suspendEmployee({ employeeId: id, active: !selectedEmpFordelete.isActive, }) } onClose={() => setIsDeleteModalOpen(false)} loading={employeeLodaing} paramData={selectedEmpFordelete.id} /> )}
{ViewTeamMember ? ( //
{/* Switches: All Employees + Inactive */}
{/* All Employees Switch */} {/* Show Inactive Employees Switch */}
setShowInactive(e.target.checked)} />
{/* Right side: Search + Export + Add Employee */}
{/* Search Input - ALWAYS ENABLED */}
{/* Export Dropdown */} {/* Add Employee Button */} {Manage_Employee && ( )}
{loading && ( )} {!loading && displayData?.length === 0 && (!searchText) ? ( ) : null} {!loading && displayData?.length === 0 && (searchText) ? ( ) : null} {/* Render current items */} {currentItems && !loading && currentItems.map((item) => ( {Manage_Employee && ( )} ))}
Name
Email
Contact
Designation
Joining Date Status Actions

Loading...

No Data Found
{`No match record found ${searchText} `}
{item.email ? ( {item.email} ) : ( NA )} {item.phoneNumber} {item.jobRole || "Not Assign Yet"} {item.joiningDate ? ( moment(item.joiningDate).format("DD-MMM-YYYY") ) : ( NA )} {showInactive ? ( Inactive ) : ( Active )}
{/* View always visible */} {/* If ACTIVE employee */} {item.isActive && ( <> {/* Suspend only when active */} {item.isActive && ( )} )} {/* If INACTIVE employee AND inactive toggle is ON */} {!item.isActive && showInactive && ( )}
{displayData?.length > 0 && ( )}
) : (

Access Denied: You don't have permission to perform this action. !

)}
); }; export default EmployeeList;