Implemented attendance funcationality in attendance module
This commit is contained in:
parent
369343f1d5
commit
792529776c
@ -7,6 +7,7 @@ import { useSelector, useDispatch } from "react-redux";
|
||||
import { fetchAttendanceData } from "../../slices/apiSlice/attedanceLogsSlice";
|
||||
import DateRangePicker from "../common/DateRangePicker";
|
||||
import { getCachedData } from "../../slices/apiDataManager";
|
||||
import eventBus from "../../services/eventBus";
|
||||
|
||||
const usePagination = (data, itemsPerPage) => {
|
||||
const [currentPage, setCurrentPage] = useState(1);
|
||||
@ -69,7 +70,7 @@ const AttendanceLog = ({ handleModalData, projectId, showOnlyCheckout }) => {
|
||||
setIsRefreshing(false);
|
||||
}, [dateRange, projectId, dispatch, isRefreshing]);
|
||||
|
||||
useEffect(() => {
|
||||
const filtering = (data) => {
|
||||
const filteredData = showOnlyCheckout
|
||||
? data.filter((item) => item.checkOutTime === null)
|
||||
: data;
|
||||
@ -108,6 +109,10 @@ const AttendanceLog = ({ handleModalData, projectId, showOnlyCheckout }) => {
|
||||
// Create the final sorted array
|
||||
const finalData = sortedDates.flatMap((date) => groupedByDate[date]);
|
||||
setProcessedData(finalData);
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
filtering(data)
|
||||
}, [data, showOnlyCheckout]);
|
||||
|
||||
const { currentPage, totalPages, currentItems: paginatedAttendances, paginate, resetPage } = usePagination(
|
||||
@ -120,6 +125,34 @@ const AttendanceLog = ({ handleModalData, projectId, showOnlyCheckout }) => {
|
||||
resetPage();
|
||||
}, [processedData, resetPage]);
|
||||
|
||||
const handler = useCallback(
|
||||
(msg) => {
|
||||
const { startDate, endDate } = dateRange;
|
||||
const checkIn = msg.response.checkInTime.substring(0, 10);
|
||||
|
||||
if (
|
||||
projectId === msg.projectId &&
|
||||
startDate <= checkIn &&
|
||||
checkIn <= endDate
|
||||
) {
|
||||
const updatedAttendance = data.map((item) =>
|
||||
item.employeeId === msg.response.employeeId
|
||||
? { ...item, ...msg.response }
|
||||
: item
|
||||
);
|
||||
|
||||
filtering(updatedAttendance);
|
||||
resetPage();
|
||||
}
|
||||
},
|
||||
[projectId, dateRange, data, filtering, resetPage]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
eventBus.on("attendance_log", handler);
|
||||
return () => eventBus.off("attendance_log", handler);
|
||||
}, [handler]);
|
||||
|
||||
return (
|
||||
<>
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
import React, { useCallback, useEffect, useState } from "react";
|
||||
import Avatar from "../common/Avatar";
|
||||
import { convertShortTime } from "../../utils/dateUtils";
|
||||
import RegularizationActions from "./RegularizationActions";
|
||||
@ -6,6 +6,8 @@ import { useSelector } from "react-redux";
|
||||
import { useRegularizationRequests } from "../../hooks/useAttendance";
|
||||
import moment from "moment";
|
||||
import usePagination from "../../hooks/usePagination";
|
||||
import eventBus from "../../services/eventBus";
|
||||
import { cacheData, clearCacheKey } from "../../slices/apiDataManager";
|
||||
|
||||
const Regularization = ({ handleRequest }) => {
|
||||
var selectedProject = useSelector((store) => store.localVariables.projectId);
|
||||
@ -22,16 +24,38 @@ const Regularization = ({ handleRequest }) => {
|
||||
const nameB = b.firstName.toLowerCase() + b.lastName.toLowerCase();
|
||||
return nameA.localeCompare(nameB);
|
||||
};
|
||||
const filteredData = [...regularizesList]?.sort(sortByName);
|
||||
|
||||
const handler = useCallback(
|
||||
(msg) => {
|
||||
if (selectedProject == msg.projectId) {
|
||||
const updatedAttendance = regularizes?.filter( item => item.id !== msg.response.id );
|
||||
cacheData("regularizedList", {
|
||||
data: updatedAttendance,
|
||||
projectId: selectedProject,
|
||||
});
|
||||
// clearCacheKey("regularizedList")
|
||||
refetch();
|
||||
}
|
||||
},
|
||||
[selectedProject, regularizes]
|
||||
);
|
||||
|
||||
const filteredData = [...regularizesList]?.sort(sortByName);
|
||||
|
||||
const { currentPage, totalPages, currentItems, paginate } = usePagination(
|
||||
filteredData,
|
||||
10
|
||||
);
|
||||
useEffect(() => {
|
||||
eventBus.on("regularization", handler);
|
||||
return () => eventBus.off("regularization", handler);
|
||||
}, [handler]);
|
||||
|
||||
return (
|
||||
<div className="table-responsive text-nowrap" style={{minHeight:"300px"}}>
|
||||
<div
|
||||
className="table-responsive text-nowrap"
|
||||
style={{ minHeight: "300px" }}
|
||||
>
|
||||
<table className="table mb-0">
|
||||
<thead>
|
||||
<tr>
|
||||
@ -47,7 +71,11 @@ const Regularization = ({ handleRequest }) => {
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{loading && <td colSpan={6} className="text-center py-5">Loading...</td>}
|
||||
{loading && (
|
||||
<td colSpan={6} className="text-center py-5">
|
||||
Loading...
|
||||
</td>
|
||||
)}
|
||||
|
||||
{!loading &&
|
||||
(regularizes?.length > 0 ? (
|
||||
@ -55,7 +83,7 @@ const Regularization = ({ handleRequest }) => {
|
||||
<tr key={index}>
|
||||
<td colSpan={2}>
|
||||
<div className="d-flex justify-content-start align-items-center">
|
||||
<Avatar
|
||||
<Avatar
|
||||
firstName={att.firstName}
|
||||
lastName={att.lastName}
|
||||
></Avatar>
|
||||
@ -88,17 +116,22 @@ const Regularization = ({ handleRequest }) => {
|
||||
))
|
||||
) : (
|
||||
<tr>
|
||||
<td colSpan={6}
|
||||
className="text-center" style={{
|
||||
<td
|
||||
colSpan={6}
|
||||
className="text-center"
|
||||
style={{
|
||||
height: "200px",
|
||||
verticalAlign: "middle",
|
||||
borderBottom: "none",
|
||||
}}>No Record Found</td>
|
||||
}}
|
||||
>
|
||||
No Record Found
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
{!loading >10 && (
|
||||
{!loading > 10 && (
|
||||
<nav aria-label="Page ">
|
||||
<ul className="pagination pagination-sm justify-content-end py-1">
|
||||
<li className={`page-item ${currentPage === 1 ? "disabled" : ""}`}>
|
||||
@ -112,8 +145,9 @@ const Regularization = ({ handleRequest }) => {
|
||||
{[...Array(totalPages)].map((_, index) => (
|
||||
<li
|
||||
key={index}
|
||||
className={`page-item ${currentPage === index + 1 ? "active" : ""
|
||||
}`}
|
||||
className={`page-item ${
|
||||
currentPage === index + 1 ? "active" : ""
|
||||
}`}
|
||||
>
|
||||
<button
|
||||
className="page-link "
|
||||
@ -124,8 +158,9 @@ const Regularization = ({ handleRequest }) => {
|
||||
</li>
|
||||
))}
|
||||
<li
|
||||
className={`page-item ${currentPage === totalPages ? "disabled" : ""
|
||||
}`}
|
||||
className={`page-item ${
|
||||
currentPage === totalPages ? "disabled" : ""
|
||||
}`}
|
||||
>
|
||||
<button
|
||||
className="page-link "
|
||||
|
@ -1,9 +1,29 @@
|
||||
import React from "react";
|
||||
import React, { useCallback, useEffect, useState } from "react";
|
||||
import { useDashboardTeamsCardData } from "../../hooks/useDashboard_Data";
|
||||
import eventBus from "../../services/eventBus";
|
||||
|
||||
const Teams = () => {
|
||||
const { teamsCardData } = useDashboardTeamsCardData();
|
||||
const[totalEmployees,setTotalEmployee] = useState(0);
|
||||
const[inToday,setInToday] = useState(0);
|
||||
|
||||
useEffect(() =>{
|
||||
setTotalEmployee(teamsCardData.totalEmployees)
|
||||
setInToday(teamsCardData.inToday)
|
||||
},[teamsCardData.totalEmployees,teamsCardData.inToday])
|
||||
|
||||
const handler = useCallback(
|
||||
(msg) => {
|
||||
if (msg.activity == 1) {
|
||||
setInToday(prev => prev + 1);
|
||||
}
|
||||
},
|
||||
[inToday]
|
||||
);
|
||||
useEffect(() => {
|
||||
eventBus.on("attendance", handler);
|
||||
return () => eventBus.off("attendance", handler);
|
||||
}, [handler]);
|
||||
return (
|
||||
<div className="card p-3 h-100 text-center d-flex justify-content-between">
|
||||
<div className="d-flex justify-content-start align-items-center mb-3">
|
||||
@ -14,13 +34,13 @@ const Teams = () => {
|
||||
<div className="d-flex justify-content-around align-items-start mt-n2">
|
||||
<div>
|
||||
<h4 className="mb-0 fw-bold">
|
||||
{teamsCardData.totalEmployees?.toLocaleString()}
|
||||
{totalEmployees?.toLocaleString()}
|
||||
</h4>
|
||||
<small className="text-muted">Total Employees</small>
|
||||
</div>
|
||||
<div>
|
||||
<h4 className="mb-0 fw-bold">
|
||||
{teamsCardData.inToday?.toLocaleString()}
|
||||
{inToday?.toLocaleString()}
|
||||
</h4>
|
||||
<small className="text-muted">In Today</small>
|
||||
</div>
|
||||
|
@ -43,10 +43,8 @@ const AttendancePage = () => {
|
||||
description: "",
|
||||
date: new Date().toLocaleDateString(),
|
||||
});
|
||||
|
||||
const handler = useCallback(
|
||||
(msg) => {
|
||||
console.log("Equal:", selectedProject == msg.projectId);
|
||||
if (selectedProject == msg.projectId) {
|
||||
const updatedAttendance = attendances.map((item) =>
|
||||
item.employeeId === msg.response.employeeId
|
||||
|
@ -3,15 +3,14 @@ import { clearCacheKey, getCachedData } from "../slices/apiDataManager";
|
||||
import showToast from "./toastService";
|
||||
import eventBus from "./eventBus";
|
||||
import { useSelector } from "react-redux";
|
||||
// const base_Url = process.env.VITE_BASE_URL;
|
||||
const base_Url = "https://devapi.marcoaiot.com";
|
||||
const base_Url = process.env.VITE_BASE_URL;
|
||||
// const base_Url = "https://devapi.marcoaiot.com";
|
||||
let connection = null;
|
||||
|
||||
const targetPath = "";
|
||||
|
||||
export function startSignalR(loggedUser) {
|
||||
var jwtToken = localStorage.getItem("jwtToken");
|
||||
console.log("token", jwtToken);
|
||||
connection = new signalR.HubConnectionBuilder()
|
||||
.withUrl(`${base_Url}/hubs/marco`, {
|
||||
accessTokenFactory: () => jwtToken,
|
||||
@ -20,11 +19,25 @@ export function startSignalR(loggedUser) {
|
||||
})
|
||||
.withAutomaticReconnect()
|
||||
.build();
|
||||
|
||||
const todayDate = new Date();
|
||||
const today = new Date(
|
||||
Date.UTC(todayDate.getFullYear(), todayDate.getMonth(), todayDate.getDate())
|
||||
)
|
||||
.toISOString()
|
||||
.split("T")[0];
|
||||
connection.on("Attendance", (data) => {
|
||||
clearCacheKey("Attendance");
|
||||
const checkIn = data.response.checkInTime.substring(0, 10);
|
||||
if (data.loginUserId != loggedUser?.employeeInfo.id) {
|
||||
eventBus.emit("attendance", data);
|
||||
if (today === checkIn) {
|
||||
eventBus.emit("attendance", data);
|
||||
}
|
||||
var onlyDate = Number(checkIn.substring(8, 10));
|
||||
|
||||
var afterTwoDay = checkIn.substring(0, 8) + (onlyDate + 2).toString().padStart(2, "0");;
|
||||
if(afterTwoDay <= today && (data.response.activity == 4 || data.response.activity == 5)){
|
||||
eventBus.emit("regularization", data);
|
||||
}
|
||||
eventBus.emit("attendance_log", data);
|
||||
}
|
||||
});
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user