199 lines
		
	
	
		
			7.1 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			199 lines
		
	
	
		
			7.1 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
import React, { useState, useEffect } from "react";
 | 
						|
import moment from "moment";
 | 
						|
import Avatar from "../common/Avatar";
 | 
						|
import { convertShortTime } from "../../utils/dateUtils";
 | 
						|
import RenderAttendanceStatus from "./RenderAttendanceStatus";
 | 
						|
import usePagination from "../../hooks/usePagination";
 | 
						|
import { useNavigate } from "react-router-dom";
 | 
						|
import { ITEMS_PER_PAGE } from "../../utils/constants";
 | 
						|
 | 
						|
const Attendance = ({
 | 
						|
  attendance,
 | 
						|
  getRole,
 | 
						|
  handleModalData,
 | 
						|
  setshowOnlyCheckout,
 | 
						|
  showOnlyCheckout,
 | 
						|
}) => {
 | 
						|
  const [loading, setLoading] = useState(false);
 | 
						|
  const navigate = useNavigate();
 | 
						|
  const [todayDate, setTodayDate] = useState(new Date());
 | 
						|
 | 
						|
  // Ensure attendance is an array
 | 
						|
  const attendanceList = Array.isArray(attendance) ? attendance : [];
 | 
						|
 | 
						|
  // Function to sort by first and last name
 | 
						|
  const sortByName = (a, b) => {
 | 
						|
    const nameA = (a.firstName + a.lastName).toLowerCase();
 | 
						|
    const nameB = (b.firstName + b.lastName).toLowerCase();
 | 
						|
    return nameA?.localeCompare(nameB);
 | 
						|
  };
 | 
						|
 | 
						|
  // Filter employees based on activity
 | 
						|
  const group1 = attendanceList
 | 
						|
    .filter((d) => d.activity === 1 || d.activity === 4)
 | 
						|
    .sort(sortByName);
 | 
						|
  const group2 = attendanceList
 | 
						|
    .filter((d) => d.activity === 0)
 | 
						|
    .sort(sortByName);
 | 
						|
 | 
						|
  const filteredData = [...group1, ...group2];
 | 
						|
 | 
						|
  const { currentPage, totalPages, currentItems, paginate } = usePagination(
 | 
						|
    filteredData,
 | 
						|
    ITEMS_PER_PAGE
 | 
						|
  );
 | 
						|
  return (
 | 
						|
    <>
 | 
						|
      <div className="table-responsive text-nowrap">
 | 
						|
        <div className="d-flex text-start align-items-center py-2">
 | 
						|
          <strong>Date : {todayDate.toLocaleDateString("en-GB")}</strong>
 | 
						|
 | 
						|
          <div className="form-check form-switch text-start m-0 ms-5">
 | 
						|
            <input
 | 
						|
              type="checkbox"
 | 
						|
              className="form-check-input"
 | 
						|
              role="switch"
 | 
						|
              id="inactiveEmployeesCheckbox"
 | 
						|
              checked={showOnlyCheckout}
 | 
						|
              onChange={(e) => setshowOnlyCheckout(e.target.checked)}
 | 
						|
            />
 | 
						|
            <label className="form-check-label ms-0">Show Pending</label>
 | 
						|
          </div>
 | 
						|
        </div>
 | 
						|
        {attendance && attendance.length > 0 && (
 | 
						|
          <>
 | 
						|
            <table className="table ">
 | 
						|
              <thead>
 | 
						|
                <tr className="border-top-1">
 | 
						|
                  <th colSpan={2}>Name</th>
 | 
						|
                  <th>Role</th>
 | 
						|
                  <th>
 | 
						|
                    <i className="bx bxs-down-arrow-alt text-success"></i>
 | 
						|
                    Check-In
 | 
						|
                  </th>
 | 
						|
                  <th>
 | 
						|
                    <i className="bx bxs-up-arrow-alt text-danger"></i>Check-Out
 | 
						|
                  </th>
 | 
						|
                  <th>Actions</th>
 | 
						|
                </tr>
 | 
						|
              </thead>
 | 
						|
              <tbody className="table-border-bottom-0 ">
 | 
						|
                {currentItems &&
 | 
						|
                  currentItems
 | 
						|
                    .sort((a, b) => {
 | 
						|
                      // If checkInTime exists, compare it, otherwise, treat null as earlier than a date
 | 
						|
                      const checkInA = a?.checkInTime
 | 
						|
                        ? new Date(a.checkInTime)
 | 
						|
                        : new Date(0);
 | 
						|
                      const checkInB = b?.checkInTime
 | 
						|
                        ? new Date(b.checkInTime)
 | 
						|
                        : new Date(0);
 | 
						|
                      return checkInB - checkInA; // Sort in descending order of checkInTime
 | 
						|
                    })
 | 
						|
                    .map((item) => (
 | 
						|
                      <tr key={item.employeeId}>
 | 
						|
                        <td colSpan={2}>
 | 
						|
                          <div className="d-flex justify-content-start align-items-center">
 | 
						|
                            <Avatar
 | 
						|
                              firstName={item.firstName}
 | 
						|
                              lastName={item.lastName}
 | 
						|
                            ></Avatar>
 | 
						|
                            <div className="d-flex flex-column">
 | 
						|
                              <a
 | 
						|
                                onClick={(e) =>
 | 
						|
                                  navigate(
 | 
						|
                                    `/employee/${item.employeeId}?for=attendance`
 | 
						|
                                  )
 | 
						|
                                }
 | 
						|
                                className="text-heading text-truncate cursor-pointer"
 | 
						|
                              >
 | 
						|
                                <span className="fw-normal">
 | 
						|
                                  {item.firstName} {item.lastName}
 | 
						|
                                </span>
 | 
						|
                              </a>
 | 
						|
                            </div>
 | 
						|
                          </div>
 | 
						|
                        </td>
 | 
						|
 | 
						|
                        <td>{item.jobRoleName}</td>
 | 
						|
                        <td>
 | 
						|
                          {item.checkInTime
 | 
						|
                            ? convertShortTime(item.checkInTime)
 | 
						|
                            : "--"}
 | 
						|
                        </td>
 | 
						|
                        <td>
 | 
						|
                          {item.checkOutTime
 | 
						|
                            ? convertShortTime(item.checkOutTime)
 | 
						|
                            : "--"}
 | 
						|
                        </td>
 | 
						|
 | 
						|
                        <td className="text-center">
 | 
						|
                          <RenderAttendanceStatus
 | 
						|
                            attendanceData={item}
 | 
						|
                            handleModalData={handleModalData}
 | 
						|
                            Tab={1}
 | 
						|
                            currentDate={null}
 | 
						|
                          />
 | 
						|
                        </td>
 | 
						|
                      </tr>
 | 
						|
                    ))}
 | 
						|
                {!attendance && (
 | 
						|
                  <span>No employees assigned to the project</span>
 | 
						|
                )}
 | 
						|
              </tbody>
 | 
						|
            </table>
 | 
						|
 | 
						|
            {!loading > 20 && (
 | 
						|
              <nav aria-label="Page ">
 | 
						|
                <ul className="pagination pagination-sm justify-content-end py-1">
 | 
						|
                  <li
 | 
						|
                    className={`page-item  ${
 | 
						|
                      currentPage === 1 ? "disabled" : ""
 | 
						|
                    }`}
 | 
						|
                  >
 | 
						|
                    <button
 | 
						|
                      className="page-link btn-xs"
 | 
						|
                      onClick={() => paginate(currentPage - 1)}
 | 
						|
                    >
 | 
						|
                      «
 | 
						|
                    </button>
 | 
						|
                  </li>
 | 
						|
                  {[...Array(totalPages)].map((_, index) => (
 | 
						|
                    <li
 | 
						|
                      key={index}
 | 
						|
                      className={`page-item ${
 | 
						|
                        currentPage === index + 1 ? "active" : ""
 | 
						|
                      }`}
 | 
						|
                    >
 | 
						|
                      <button
 | 
						|
                        className="page-link "
 | 
						|
                        onClick={() => paginate(index + 1)}
 | 
						|
                      >
 | 
						|
                        {index + 1}
 | 
						|
                      </button>
 | 
						|
                    </li>
 | 
						|
                  ))}
 | 
						|
                  <li
 | 
						|
                    className={`page-item ${
 | 
						|
                      currentPage === totalPages ? "disabled" : ""
 | 
						|
                    }`}
 | 
						|
                  >
 | 
						|
                    <button
 | 
						|
                      className="page-link "
 | 
						|
                      onClick={() => paginate(currentPage + 1)}
 | 
						|
                    >
 | 
						|
                      »
 | 
						|
                    </button>
 | 
						|
                  </li>
 | 
						|
                </ul>
 | 
						|
              </nav>
 | 
						|
            )}
 | 
						|
          </>
 | 
						|
        )}
 | 
						|
      </div>
 | 
						|
    </>
 | 
						|
  );
 | 
						|
};
 | 
						|
 | 
						|
export default Attendance;
 |