1. Filter the view to show only "Today's" attendance. 2. Display today's date prominently above the names in that tab.
244 lines
8.2 KiB
JavaScript
244 lines
8.2 KiB
JavaScript
import React, { useState, useEffect } from "react";
|
|
import {
|
|
cacheData,
|
|
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 { useProjects } from "../../hooks/useProjects";
|
|
import Regularization from "../../components/Activities/Regularization";
|
|
import { useAttendace } from "../../hooks/useAttendance";
|
|
import { useDispatch, useSelector } from "react-redux";
|
|
import { setProjectId } from "../../slices/localVariablesSlice";
|
|
import { markCurrentAttendance } from "../../slices/apiSlice/attendanceAllSlice";
|
|
import { hasUserPermission } from "../../utils/authUtils";
|
|
import { useHasUserPermission } from "../../hooks/useHasUserPermission";
|
|
import { REGULARIZE_ATTENDANCE } from "../../utils/constants";
|
|
|
|
const AttendancePage = () => {
|
|
const [activeTab, setActiveTab] = useState("all");
|
|
|
|
const loginUser = getCachedProfileData();
|
|
var selectedProject = useSelector((store) => store.localVariables.projectId);
|
|
const { projects, loading: projectLoading } = useProjects();
|
|
const { attendance, loading: attLoading } = useAttendace(selectedProject);
|
|
const [attendances, setAttendances] = useState();
|
|
const [empRoles, setEmpRoles] = useState(null);
|
|
const [isCreateModalOpen, setIsCreateModalOpen] = useState(false);
|
|
const [modelConfig, setModelConfig] = useState();
|
|
const DoRegularized = useHasUserPermission(REGULARIZE_ATTENDANCE);
|
|
const dispatch = useDispatch();
|
|
|
|
const [formData, setFormData] = useState({
|
|
markTime: "",
|
|
description: "",
|
|
date: new Date().toLocaleDateString(),
|
|
});
|
|
|
|
const getRole = (roleId) => {
|
|
if (!empRoles) return "Unassigned";
|
|
if (!roleId) return "Unassigned";
|
|
const role = empRoles.find((b) => b.id == roleId);
|
|
return role ? role.role : "Unassigned";
|
|
};
|
|
|
|
const openModel = () => {
|
|
setIsCreateModalOpen(true);
|
|
};
|
|
|
|
const handleModalData = (employee) => {
|
|
setModelConfig(employee);
|
|
};
|
|
|
|
const closeModal = () => {
|
|
setModelConfig(null);
|
|
setIsCreateModalOpen(false);
|
|
const modalElement = document.getElementById("check-Out-modal");
|
|
if (modalElement) {
|
|
modalElement.classList.remove("show");
|
|
modalElement.style.display = "none";
|
|
document.body.classList.remove("modal-open");
|
|
document.querySelector(".modal-backdrop")?.remove();
|
|
}
|
|
};
|
|
|
|
const handleSubmit = (formData) => {
|
|
dispatch(markCurrentAttendance(formData))
|
|
.then((action) => {
|
|
const updatedAttendance = attendances.map((item) =>
|
|
item.employeeId === action.payload.employeeId
|
|
? { ...item, ...action.payload }
|
|
: item
|
|
);
|
|
cacheData("Attendance", {
|
|
data: updatedAttendance,
|
|
projectId: selectedProject,
|
|
});
|
|
setAttendances(updatedAttendance);
|
|
showToast("Attedance Marked Successfully", "success");
|
|
})
|
|
.catch((error) => {
|
|
showToast(error.message, "error");
|
|
});
|
|
};
|
|
|
|
useEffect(() => {
|
|
if (modelConfig !== null) {
|
|
openModel();
|
|
}
|
|
}, [modelConfig, isCreateModalOpen]);
|
|
useEffect(() => {
|
|
setAttendances(attendance);
|
|
}, [attendance]);
|
|
|
|
useEffect(() => {
|
|
if (selectedProject === 1 || selectedProject === undefined) {
|
|
dispatch(setProjectId(loginUser?.projects[0]));
|
|
}
|
|
}, [selectedProject, loginUser?.projects]);
|
|
return (
|
|
<>
|
|
{isCreateModalOpen && modelConfig && (
|
|
<div
|
|
className="modal fade show"
|
|
style={{ display: "block" }}
|
|
id="check-Out-modal"
|
|
tabIndex="-1"
|
|
aria-hidden="true"
|
|
>
|
|
<AttendanceModel
|
|
modelConfig={modelConfig}
|
|
closeModal={closeModal}
|
|
handleSubmitForm={handleSubmit}
|
|
/>
|
|
</div>
|
|
)}
|
|
|
|
<div className="container-xxl flex-grow-1 container-p-y">
|
|
<Breadcrumb
|
|
data={[
|
|
{ label: "Home", link: "/dashboard" },
|
|
{ label: "Attendance", link: null },
|
|
]}
|
|
></Breadcrumb>
|
|
<div className="nav-align-top nav-tabs-shadow">
|
|
<ul className="nav nav-tabs" role="tablist">
|
|
<div
|
|
className="dataTables_length text-start py-2 px-2 d-flex "
|
|
id="DataTables_Table_0_length"
|
|
>
|
|
{loginUser && loginUser?.projects?.length > 1 && (
|
|
<label>
|
|
<select
|
|
name="DataTables_Table_0_length"
|
|
aria-controls="DataTables_Table_0"
|
|
className="form-select form-select-sm"
|
|
value={selectedProject}
|
|
onChange={(e) => dispatch(setProjectId(e.target.value))}
|
|
aria-label=""
|
|
>
|
|
{!projectLoading &&
|
|
projects
|
|
?.filter((project) =>
|
|
loginUser?.projects?.map(String).includes(project.id)
|
|
)
|
|
.map((project) => (
|
|
<option value={project.id} key={project.id}>
|
|
{project.name}
|
|
</option>
|
|
))}
|
|
{projectLoading && (
|
|
<option value="Loading..." disabled>
|
|
Loading...
|
|
</option>
|
|
)}
|
|
</select>
|
|
</label>
|
|
)}
|
|
</div>
|
|
</ul>
|
|
|
|
<ul className="nav nav-tabs" role="tablist">
|
|
<li className="nav-item">
|
|
<button
|
|
type="button"
|
|
className={`nav-link ${activeTab === "all" ? "active" : ""}`}
|
|
onClick={() => setActiveTab("all")}
|
|
data-bs-toggle="tab"
|
|
data-bs-target="#navs-top-home"
|
|
>
|
|
Today's
|
|
</button>
|
|
</li>
|
|
<li className="nav-item">
|
|
<button
|
|
type="button"
|
|
className={`nav-link ${activeTab === "logs" ? "active" : ""}`}
|
|
onClick={() => setActiveTab("logs")}
|
|
data-bs-toggle="tab"
|
|
data-bs-target="#navs-top-profile"
|
|
>
|
|
Logs
|
|
</button>
|
|
</li>
|
|
<li className={`nav-item ${!DoRegularized && "d-none"}`}>
|
|
<button
|
|
type="button"
|
|
className={`nav-link ${
|
|
activeTab === "regularization" ? "active" : ""
|
|
}`}
|
|
onClick={() => setActiveTab("regularization")}
|
|
data-bs-toggle="tab"
|
|
data-bs-target="#navs-top-messages"
|
|
>
|
|
Regularization
|
|
</button>
|
|
</li>
|
|
</ul>
|
|
<div className="tab-content attedanceTabs py-2">
|
|
{projectLoading && <span>Loading..</span>}
|
|
{!projectLoading && !attendances && <span>Not Found</span>}
|
|
|
|
{activeTab === "all" && (
|
|
<>
|
|
{!projectLoading && attendances.length === 0 && (
|
|
<p>No Employee assigned yet.</p>
|
|
)}
|
|
<div className="tab-pane fade show active py-0">
|
|
<Attendance
|
|
attendance={attendances}
|
|
handleModalData={handleModalData}
|
|
getRole={getRole}
|
|
/>
|
|
</div>
|
|
</>
|
|
)}
|
|
|
|
|
|
{activeTab === "logs" && (
|
|
<div className="tab-pane fade show active py-0">
|
|
<AttendanceLog
|
|
handleModalData={handleModalData}
|
|
projectId={selectedProject}
|
|
/>
|
|
</div>
|
|
)}
|
|
|
|
{activeTab === "regularization" && DoRegularized && (
|
|
<div className="tab-pane fade show active py-0">
|
|
<Regularization handleRequest={handleSubmit} />
|
|
</div>
|
|
)}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</>
|
|
);
|
|
};
|
|
|
|
export default AttendancePage;
|