fixed attendance - check In -out and persisted date range from Redux store for attendance logs
This commit is contained in:
parent
ad1bef4f7b
commit
8bcfcc5718
@ -12,7 +12,7 @@ import { useQueryClient } from "@tanstack/react-query";
|
|||||||
import eventBus from "../../services/eventBus";
|
import eventBus from "../../services/eventBus";
|
||||||
import { useSelectedProject } from "../../slices/apiDataManager";
|
import { useSelectedProject } from "../../slices/apiDataManager";
|
||||||
|
|
||||||
const Attendance = ({ getRole, handleModalData, searchTerm, projectId, organizationId, includeInactive, date }) => {
|
const Attendance = ({ getRole, handleModalData, searchTerm, projectId, organizationId, }) => {
|
||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
@ -24,7 +24,7 @@ const Attendance = ({ getRole, handleModalData, searchTerm, projectId, organizat
|
|||||||
loading: attLoading,
|
loading: attLoading,
|
||||||
recall: attrecall,
|
recall: attrecall,
|
||||||
isFetching
|
isFetching
|
||||||
} = useAttendance(selectedProject, organizationId, includeInactive, date);
|
} = useAttendance(selectedProject, organizationId);
|
||||||
const filteredAttendance = ShowPending
|
const filteredAttendance = ShowPending
|
||||||
? attendance?.filter(
|
? attendance?.filter(
|
||||||
(att) => att?.checkInTime !== null && att?.checkOutTime === null
|
(att) => att?.checkInTime !== null && att?.checkOutTime === null
|
||||||
|
@ -5,7 +5,11 @@ import { convertShortTime } from "../../utils/dateUtils";
|
|||||||
import RenderAttendanceStatus from "./RenderAttendanceStatus";
|
import RenderAttendanceStatus from "./RenderAttendanceStatus";
|
||||||
import { useSelector, useDispatch } from "react-redux";
|
import { useSelector, useDispatch } from "react-redux";
|
||||||
import DateRangePicker from "../common/DateRangePicker";
|
import DateRangePicker from "../common/DateRangePicker";
|
||||||
import { clearCacheKey, getCachedData, useSelectedProject } from "../../slices/apiDataManager";
|
import {
|
||||||
|
clearCacheKey,
|
||||||
|
getCachedData,
|
||||||
|
useSelectedProject,
|
||||||
|
} from "../../slices/apiDataManager";
|
||||||
import eventBus from "../../services/eventBus";
|
import eventBus from "../../services/eventBus";
|
||||||
import AttendanceRepository from "../../repositories/AttendanceRepository";
|
import AttendanceRepository from "../../repositories/AttendanceRepository";
|
||||||
import { useAttendancesLogs } from "../../hooks/useAttendance";
|
import { useAttendancesLogs } from "../../hooks/useAttendance";
|
||||||
@ -33,7 +37,7 @@ const usePagination = (data, itemsPerPage) => {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const AttendanceLog = ({ handleModalData, searchTerm ,organizationId}) => {
|
const AttendanceLog = ({ handleModalData, searchTerm, organizationId }) => {
|
||||||
// const selectedProject = useSelector(
|
// const selectedProject = useSelector(
|
||||||
// (store) => store.localVariables.projectId
|
// (store) => store.localVariables.projectId
|
||||||
// );
|
// );
|
||||||
@ -41,7 +45,7 @@ const AttendanceLog = ({ handleModalData, searchTerm ,organizationId}) => {
|
|||||||
const [dateRange, setDateRange] = useState({ startDate: "", endDate: "" });
|
const [dateRange, setDateRange] = useState({ startDate: "", endDate: "" });
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
const [showPending, setShowPending] = useState(false)
|
const [showPending, setShowPending] = useState(false);
|
||||||
|
|
||||||
const [isRefreshing, setIsRefreshing] = useState(false);
|
const [isRefreshing, setIsRefreshing] = useState(false);
|
||||||
const [processedData, setProcessedData] = useState([]);
|
const [processedData, setProcessedData] = useState([]);
|
||||||
@ -151,33 +155,6 @@ const AttendanceLog = ({ handleModalData, searchTerm ,organizationId}) => {
|
|||||||
});
|
});
|
||||||
}, [processedData, searchTerm]);
|
}, [processedData, searchTerm]);
|
||||||
|
|
||||||
// const filteredSearchData = useMemo(() => {
|
|
||||||
// let tempData = processedData;
|
|
||||||
|
|
||||||
// if (searchTerm) {
|
|
||||||
// const lowercasedSearchTerm = searchTerm.toLowerCase();
|
|
||||||
// tempData = tempData.filter((item) => {
|
|
||||||
// const fullName = `${item.firstName} ${item.lastName}`.toLowerCase();
|
|
||||||
// return fullName.includes(lowercasedSearchTerm);
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if (filters?.selectedOrganization) {
|
|
||||||
// tempData = tempData.filter(
|
|
||||||
// (item) => item.organization?.name === filters.selectedOrganization
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if (filters?.selectedServices?.length > 0) {
|
|
||||||
// tempData = tempData.filter((item) =>
|
|
||||||
// filters.selectedServices.includes(item.service?.name)
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
|
|
||||||
// return tempData;
|
|
||||||
// }, [processedData, searchTerm, filters]);
|
|
||||||
|
|
||||||
|
|
||||||
const {
|
const {
|
||||||
currentPage,
|
currentPage,
|
||||||
totalPages,
|
totalPages,
|
||||||
@ -235,7 +212,7 @@ const AttendanceLog = ({ handleModalData, searchTerm ,organizationId}) => {
|
|||||||
// })
|
// })
|
||||||
// );
|
// );
|
||||||
|
|
||||||
refetch()
|
refetch();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[selectedProject, dateRange, data, refetch]
|
[selectedProject, dateRange, data, refetch]
|
||||||
@ -270,11 +247,16 @@ const AttendanceLog = ({ handleModalData, searchTerm ,organizationId}) => {
|
|||||||
<label className="form-check-label ms-0">Show Pending</label>
|
<label className="form-check-label ms-0">Show Pending</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div className="table-responsive text-nowrap" style={{ minHeight: "200px" }}>
|
<div
|
||||||
|
className="table-responsive text-nowrap"
|
||||||
|
style={{ minHeight: "200px" }}
|
||||||
|
>
|
||||||
{isLoading ? (
|
{isLoading ? (
|
||||||
<div className="d-flex justify-content-center align-items-center" style={{ height: "200px" }}>
|
<div
|
||||||
|
className="d-flex justify-content-center align-items-center"
|
||||||
|
style={{ height: "200px" }}
|
||||||
|
>
|
||||||
<p className="text-secondary">Loading...</p>
|
<p className="text-secondary">Loading...</p>
|
||||||
</div>
|
</div>
|
||||||
) : filteredSearchData?.length > 0 ? (
|
) : filteredSearchData?.length > 0 ? (
|
||||||
@ -287,7 +269,8 @@ const AttendanceLog = ({ handleModalData, searchTerm ,organizationId}) => {
|
|||||||
<th className="border-top-1">Date</th>
|
<th className="border-top-1">Date</th>
|
||||||
<th>Organization</th>
|
<th>Organization</th>
|
||||||
<th>
|
<th>
|
||||||
<i className="bx bxs-down-arrow-alt text-success"></i> Check-In
|
<i className="bx bxs-down-arrow-alt text-success"></i>{" "}
|
||||||
|
Check-In
|
||||||
</th>
|
</th>
|
||||||
<th>
|
<th>
|
||||||
<i className="bx bxs-up-arrow-alt text-danger"></i> Check-Out
|
<i className="bx bxs-up-arrow-alt text-danger"></i> Check-Out
|
||||||
@ -303,9 +286,9 @@ const AttendanceLog = ({ handleModalData, searchTerm ,organizationId}) => {
|
|||||||
const previousAttendance = arr[index - 1];
|
const previousAttendance = arr[index - 1];
|
||||||
const previousDate = previousAttendance
|
const previousDate = previousAttendance
|
||||||
? moment(
|
? moment(
|
||||||
previousAttendance.checkInTime ||
|
previousAttendance.checkInTime ||
|
||||||
previousAttendance.checkOutTime
|
previousAttendance.checkOutTime
|
||||||
).format("YYYY-MM-DD")
|
).format("YYYY-MM-DD")
|
||||||
: null;
|
: null;
|
||||||
|
|
||||||
if (!previousDate || currentDate !== previousDate) {
|
if (!previousDate || currentDate !== previousDate) {
|
||||||
@ -344,7 +327,7 @@ const AttendanceLog = ({ handleModalData, searchTerm ,organizationId}) => {
|
|||||||
attendance.checkInTime || attendance.checkOutTime
|
attendance.checkInTime || attendance.checkOutTime
|
||||||
).format("DD-MMM-YYYY")}
|
).format("DD-MMM-YYYY")}
|
||||||
</td>
|
</td>
|
||||||
<td>{attendance.organizationName || "--"}</td>
|
<td>{attendance.organizationName || "--"}</td>
|
||||||
<td>{convertShortTime(attendance.checkInTime)}</td>
|
<td>{convertShortTime(attendance.checkInTime)}</td>
|
||||||
<td>
|
<td>
|
||||||
{attendance.checkOutTime
|
{attendance.checkOutTime
|
||||||
@ -366,7 +349,12 @@ const AttendanceLog = ({ handleModalData, searchTerm ,organizationId}) => {
|
|||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
) : (
|
) : (
|
||||||
<div className="my-12"><span className="text-secondary">No data available for the selected date range. Please Select another date.</span></div>
|
<div className="my-12">
|
||||||
|
<span className="text-secondary">
|
||||||
|
No data available for the selected date range. Please Select
|
||||||
|
another date.
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
{paginatedAttendances?.length == 0 && filteredSearchData?.length > 0 && (
|
{paginatedAttendances?.length == 0 && filteredSearchData?.length > 0 && (
|
||||||
@ -392,8 +380,9 @@ const AttendanceLog = ({ handleModalData, searchTerm ,organizationId}) => {
|
|||||||
(pageNumber) => (
|
(pageNumber) => (
|
||||||
<li
|
<li
|
||||||
key={pageNumber}
|
key={pageNumber}
|
||||||
className={`page-item ${currentPage === pageNumber ? "active" : ""
|
className={`page-item ${
|
||||||
}`}
|
currentPage === pageNumber ? "active" : ""
|
||||||
|
}`}
|
||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
className="page-link"
|
className="page-link"
|
||||||
@ -405,8 +394,9 @@ const AttendanceLog = ({ handleModalData, searchTerm ,organizationId}) => {
|
|||||||
)
|
)
|
||||||
)}
|
)}
|
||||||
<li
|
<li
|
||||||
className={`page-item ${currentPage === totalPages ? "disabled" : ""
|
className={`page-item ${
|
||||||
}`}
|
currentPage === totalPages ? "disabled" : ""
|
||||||
|
}`}
|
||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
className="page-link"
|
className="page-link"
|
||||||
|
@ -96,12 +96,12 @@ const CheckInCheckOut = ({ modeldata, closeModal, handleSubmitForm }) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<form className="row g-2" onSubmit={handleSubmit(onSubmit)}>
|
<form className="row p-2" onSubmit={handleSubmit(onSubmit)}>
|
||||||
<div className="col-12 d-flex justify-content-center">
|
<div className="col-12 d-flex justify-content-center mb-4">
|
||||||
<label className="fs-5 text-dark text-center">
|
<label className="fs-5 tex-semibold text-center">
|
||||||
{modeldata?.checkInTime && !modeldata?.checkOutTime
|
{modeldata?.checkInTime && !modeldata?.checkOutTime
|
||||||
? "Check-out :"
|
? "Check-Out "
|
||||||
: "Check-in :"}
|
: "Check-In "}
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -120,7 +120,7 @@ const CheckInCheckOut = ({ modeldata, closeModal, handleSubmitForm }) => {
|
|||||||
modeldata?.checkInTime && !modeldata?.checkOutTime
|
modeldata?.checkInTime && !modeldata?.checkOutTime
|
||||||
? formatDate(modeldata?.checkInTime?.split("T")[0]) || ""
|
? formatDate(modeldata?.checkInTime?.split("T")[0]) || ""
|
||||||
: formatDate(today)
|
: formatDate(today)
|
||||||
}
|
}
|
||||||
disabled
|
disabled
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
import React, { useEffect, useRef } from "react";
|
import React, { useEffect, useRef } from "react";
|
||||||
import { useController, useFormContext, useWatch } from "react-hook-form";
|
import { useController, useFormContext, useWatch } from "react-hook-form";
|
||||||
|
import { useSelector } from "react-redux";
|
||||||
|
|
||||||
const DateRangePicker = ({
|
const DateRangePicker = ({
|
||||||
md,
|
md,
|
||||||
sm,
|
sm,
|
||||||
@ -9,19 +11,29 @@ const DateRangePicker = ({
|
|||||||
}) => {
|
}) => {
|
||||||
const inputRef = useRef(null);
|
const inputRef = useRef(null);
|
||||||
|
|
||||||
|
const persistedRange = useSelector(
|
||||||
|
(store) => store.localVariables.attendance.defaultDateRange
|
||||||
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const endDate = new Date();
|
let startDate, endDate;
|
||||||
if (endDateMode === "yesterday") {
|
|
||||||
endDate.setDate(endDate.getDate() - 1);
|
if (persistedRange?.startDate && persistedRange?.endDate) {
|
||||||
|
startDate = new Date(persistedRange.startDate);
|
||||||
|
endDate = new Date(persistedRange.endDate);
|
||||||
|
} else {
|
||||||
|
endDate = new Date();
|
||||||
|
if (endDateMode === "yesterday") {
|
||||||
|
endDate.setDate(endDate.getDate() - 1);
|
||||||
|
}
|
||||||
|
endDate.setHours(0, 0, 0, 0);
|
||||||
|
|
||||||
|
startDate = new Date(endDate);
|
||||||
|
startDate.setDate(endDate.getDate() - (DateDifference - 1));
|
||||||
|
startDate.setHours(0, 0, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
endDate.setHours(0, 0, 0, 0);
|
const fp = flatpickr(inputRef.current, {
|
||||||
|
|
||||||
const startDate = new Date(endDate);
|
|
||||||
startDate.setDate(endDate.getDate() - (DateDifference - 1));
|
|
||||||
startDate.setHours(0, 0, 0, 0);
|
|
||||||
|
|
||||||
const fp = flatpickr(inputRef.current, {
|
|
||||||
mode: "range",
|
mode: "range",
|
||||||
dateFormat: "Y-m-d",
|
dateFormat: "Y-m-d",
|
||||||
altInput: true,
|
altInput: true,
|
||||||
@ -41,14 +53,12 @@ const DateRangePicker = ({
|
|||||||
endDate: endDate.toLocaleDateString("en-CA"),
|
endDate: endDate.toLocaleDateString("en-CA"),
|
||||||
});
|
});
|
||||||
|
|
||||||
return () => {
|
return () => fp.destroy();
|
||||||
fp.destroy();
|
}, [onRangeChange, DateDifference, endDateMode, persistedRange]);
|
||||||
};
|
|
||||||
}, [onRangeChange, DateDifference, endDateMode]);
|
|
||||||
|
|
||||||
const handleIconClick = () => {
|
const handleIconClick = () => {
|
||||||
if (inputRef.current) {
|
if (inputRef.current?._flatpickr) {
|
||||||
inputRef.current._flatpickr.open(); // directly opens flatpickr
|
inputRef.current._flatpickr.open();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -63,9 +73,10 @@ const DateRangePicker = ({
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
<i
|
<i
|
||||||
className="bx bx-calendar calendar-icon cursor-pointer position-relative top-50 translate-middle-y " onClick={handleIconClick}
|
className="bx bx-calendar calendar-icon cursor-pointer position-relative top-50 translate-middle-y"
|
||||||
|
onClick={handleIconClick}
|
||||||
style={{ right: "22px", bottom: "-8px" }}
|
style={{ right: "22px", bottom: "-8px" }}
|
||||||
></i>
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
@ -76,6 +87,7 @@ export default DateRangePicker;
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export const DateRangePicker1 = ({
|
export const DateRangePicker1 = ({
|
||||||
startField = "startDate",
|
startField = "startDate",
|
||||||
endField = "endDate",
|
endField = "endDate",
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { cacheData, getCachedData, useSelectedProject } from "../slices/apiDataManager";
|
import {
|
||||||
|
cacheData,
|
||||||
|
getCachedData,
|
||||||
|
useSelectedProject,
|
||||||
|
} from "../slices/apiDataManager";
|
||||||
import AttendanceRepository from "../repositories/AttendanceRepository";
|
import AttendanceRepository from "../repositories/AttendanceRepository";
|
||||||
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
||||||
import showToast from "../services/toastService";
|
import showToast from "../services/toastService";
|
||||||
@ -7,11 +11,8 @@ import { useDispatch, useSelector } from "react-redux";
|
|||||||
import { store } from "../store/store";
|
import { store } from "../store/store";
|
||||||
import { setDefaultDateRange } from "../slices/localVariablesSlice";
|
import { setDefaultDateRange } from "../slices/localVariablesSlice";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ----------------------------Query-----------------------------
|
// ----------------------------Query-----------------------------
|
||||||
|
|
||||||
|
|
||||||
// export const useAttendance = (projectId) => {
|
// export const useAttendance = (projectId) => {
|
||||||
// const dispatch = useDispatch()
|
// const dispatch = useDispatch()
|
||||||
// const {
|
// const {
|
||||||
@ -41,7 +42,10 @@ import { setDefaultDateRange } from "../slices/localVariablesSlice";
|
|||||||
// };
|
// };
|
||||||
// };
|
// };
|
||||||
|
|
||||||
export const useAttendance = (projectId, organizationId, includeInactive = false, date = null) => {
|
export const useAttendance = (
|
||||||
|
projectId,
|
||||||
|
organizationId,
|
||||||
|
) => {
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
|
|
||||||
const {
|
const {
|
||||||
@ -51,13 +55,11 @@ export const useAttendance = (projectId, organizationId, includeInactive = false
|
|||||||
refetch: recall,
|
refetch: recall,
|
||||||
isFetching,
|
isFetching,
|
||||||
} = useQuery({
|
} = useQuery({
|
||||||
queryKey: ["attendance", projectId, organizationId, includeInactive, date], // include filters in cache key
|
queryKey: ["attendance", projectId, organizationId], // include filters in cache key
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const response = await AttendanceRepository.getAttendance(
|
const response = await AttendanceRepository.getAttendance(
|
||||||
projectId,
|
projectId,
|
||||||
organizationId,
|
organizationId,
|
||||||
includeInactive,
|
|
||||||
date
|
|
||||||
);
|
);
|
||||||
return response.data;
|
return response.data;
|
||||||
},
|
},
|
||||||
@ -70,12 +72,17 @@ export const useAttendance = (projectId, organizationId, includeInactive = false
|
|||||||
return { attendance, loading, error, recall, isFetching };
|
return { attendance, loading, error, recall, isFetching };
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useAttendancesLogs = (projectId, fromDate, toDate,organizationId) => {
|
export const useAttendancesLogs = (
|
||||||
|
projectId,
|
||||||
|
fromDate,
|
||||||
|
toDate,
|
||||||
|
organizationId
|
||||||
|
) => {
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
const enabled = !!projectId && !!fromDate && !!toDate;
|
const enabled = !!projectId && !!fromDate && !!toDate;
|
||||||
|
|
||||||
const query = useQuery({
|
const query = useQuery({
|
||||||
queryKey: ['attendanceLogs', projectId, fromDate, toDate,organizationId],
|
queryKey: ["attendanceLogs", projectId, fromDate, toDate, organizationId],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await AttendanceRepository.getAttendanceFilteredByDate(
|
const res = await AttendanceRepository.getAttendanceFilteredByDate(
|
||||||
projectId,
|
projectId,
|
||||||
@ -87,7 +94,7 @@ export const useAttendancesLogs = (projectId, fromDate, toDate,organizationId) =
|
|||||||
},
|
},
|
||||||
enabled,
|
enabled,
|
||||||
});
|
});
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (query.data && fromDate && toDate) {
|
if (query.data && fromDate && toDate) {
|
||||||
dispatch(
|
dispatch(
|
||||||
@ -101,8 +108,6 @@ export const useAttendancesLogs = (projectId, fromDate, toDate,organizationId) =
|
|||||||
return query;
|
return query;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export const useEmployeeAttendacesLog = (id) => {
|
export const useEmployeeAttendacesLog = (id) => {
|
||||||
const {
|
const {
|
||||||
data: logs = [],
|
data: logs = [],
|
||||||
@ -117,7 +122,10 @@ export const useEmployeeAttendacesLog = (id) => {
|
|||||||
},
|
},
|
||||||
enabled: !!id,
|
enabled: !!id,
|
||||||
onError: (error) => {
|
onError: (error) => {
|
||||||
showToast(error.message || "Error while fetching Attendance Logs", "error");
|
showToast(
|
||||||
|
error.message || "Error while fetching Attendance Logs",
|
||||||
|
"error"
|
||||||
|
);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -135,16 +143,22 @@ export const useAttendanceByEmployee = (employeeId, fromDate, toDate) => {
|
|||||||
return useQuery({
|
return useQuery({
|
||||||
queryKey: ["employeeAttendance", employeeId, fromDate, toDate],
|
queryKey: ["employeeAttendance", employeeId, fromDate, toDate],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await AttendanceRepository.getAttendanceByEmployee(employeeId, fromDate, toDate);
|
const res = await AttendanceRepository.getAttendanceByEmployee(
|
||||||
|
employeeId,
|
||||||
|
fromDate,
|
||||||
|
toDate
|
||||||
|
);
|
||||||
return res.data;
|
return res.data;
|
||||||
},
|
},
|
||||||
enabled
|
enabled,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const useRegularizationRequests = (
|
||||||
|
projectId,
|
||||||
export const useRegularizationRequests = (projectId, organizationId, IncludeInActive = false) => {
|
organizationId,
|
||||||
|
IncludeInActive = false
|
||||||
|
) => {
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
|
|
||||||
const {
|
const {
|
||||||
@ -159,7 +173,7 @@ export const useRegularizationRequests = (projectId, organizationId, IncludeInAc
|
|||||||
const response = await AttendanceRepository.getRegularizeList(
|
const response = await AttendanceRepository.getRegularizeList(
|
||||||
projectId,
|
projectId,
|
||||||
organizationId,
|
organizationId,
|
||||||
IncludeInActive,
|
IncludeInActive
|
||||||
);
|
);
|
||||||
return response.data;
|
return response.data;
|
||||||
},
|
},
|
||||||
@ -172,48 +186,61 @@ export const useRegularizationRequests = (projectId, organizationId, IncludeInAc
|
|||||||
return { regularizes, loading, error, recall, isFetching };
|
return { regularizes, loading, error, recall, isFetching };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// -------------------Mutation--------------------------------------
|
// -------------------Mutation--------------------------------------
|
||||||
|
|
||||||
export const useMarkAttendance = () => {
|
export const useMarkAttendance = () => {
|
||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
const selectedProject = useSelectedProject();
|
const selectedProject = useSelectedProject();
|
||||||
const selectedDateRange = useSelector((store)=>store.localVariables.defaultDateRange)
|
const selectedDateRange = useSelector(
|
||||||
|
(store) => store.localVariables.attendance.defaultDateRange
|
||||||
|
);
|
||||||
|
const selectedOrganization = useSelector(
|
||||||
|
(store) => store.localVariables.attendance.SelectedOrg
|
||||||
|
);
|
||||||
|
|
||||||
return useMutation({
|
return useMutation({
|
||||||
mutationFn: async ({payload,forWhichTab}) => {
|
mutationFn: async ({ payload, forWhichTab }) => {
|
||||||
const res = await AttendanceRepository.markAttendance(payload);
|
const res = await AttendanceRepository.markAttendance(payload);
|
||||||
return res.data;
|
return res.data;
|
||||||
},
|
},
|
||||||
|
|
||||||
onSuccess: (data,variables) => {
|
onSuccess: (data, variables) => {
|
||||||
if(variables.forWhichTab == 1){
|
if (variables.forWhichTab == 1) {
|
||||||
queryClient.setQueryData(["attendance",selectedProject], (oldData) => {
|
queryClient.setQueryData(["attendance", selectedProject,selectedOrganization], (oldData) => {
|
||||||
if (!oldData) return oldData;
|
|
||||||
return oldData.map((emp) =>
|
|
||||||
emp.employeeId === data.employeeId ? { ...emp, ...data } : emp
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}else if(variables.forWhichTab == 2){
|
|
||||||
// queryClient.invalidateQueries({
|
|
||||||
// queryKey: ["attendanceLogs"],
|
|
||||||
// });
|
|
||||||
queryClient.setQueryData(["attendanceLogs",selectedProject,selectedDateRange.startDate,selectedDateRange.endDate], (oldData) => {
|
|
||||||
if (!oldData) return oldData;
|
|
||||||
return oldData.map((record) =>
|
|
||||||
record.id === data.id ? { ...record, ...data } : record
|
|
||||||
);
|
|
||||||
});
|
|
||||||
queryClient.invalidateQueries({queryKey:["regularizedList"]})
|
|
||||||
}else(
|
|
||||||
queryClient.setQueryData(["regularizedList",selectedProject], (oldData) => {
|
|
||||||
if (!oldData) return oldData;
|
|
||||||
return oldData.filter((record) => record.id !== data.id)
|
|
||||||
}),
|
|
||||||
queryClient.invalidateQueries({queryKey:["attendanceLogs"]})
|
|
||||||
)
|
|
||||||
|
|
||||||
if(variables.forWhichTab !== 3) showToast("Attendance marked successfully", "success");
|
if (!oldData) return oldData;
|
||||||
|
return oldData.map((emp) =>
|
||||||
|
emp.employeeId === data.employeeId ? { ...emp, ...data } : emp
|
||||||
|
);
|
||||||
|
});
|
||||||
|
} else if (variables.forWhichTab == 2) {
|
||||||
|
queryClient.setQueryData(
|
||||||
|
[
|
||||||
|
"attendanceLogs",
|
||||||
|
selectedProject,
|
||||||
|
selectedDateRange.startDate,
|
||||||
|
selectedDateRange.endDate,selectedOrganization
|
||||||
|
],
|
||||||
|
(oldData) => {
|
||||||
|
if (!oldData) return oldData;
|
||||||
|
return oldData.map((record) =>
|
||||||
|
record.id === data.id ? { ...record, ...data } : record
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
queryClient.invalidateQueries({ queryKey: ["regularizedList"] });
|
||||||
|
} else
|
||||||
|
queryClient.setQueryData(
|
||||||
|
["regularizedList", selectedProject],
|
||||||
|
(oldData) => {
|
||||||
|
if (!oldData) return oldData;
|
||||||
|
return oldData.filter((record) => record.id !== data.id);
|
||||||
|
}
|
||||||
|
),
|
||||||
|
queryClient.invalidateQueries({ queryKey: ["attendanceLogs"] });
|
||||||
|
|
||||||
|
if (variables.forWhichTab !== 3)
|
||||||
|
showToast("Attendance marked successfully", "success");
|
||||||
},
|
},
|
||||||
onError: (error) => {
|
onError: (error) => {
|
||||||
showToast(error.message || "Failed to mark attendance", "error");
|
showToast(error.message || "Failed to mark attendance", "error");
|
||||||
|
@ -16,7 +16,10 @@ import { setProjectId } from "../../slices/localVariablesSlice";
|
|||||||
import { useHasUserPermission } from "../../hooks/useHasUserPermission";
|
import { useHasUserPermission } from "../../hooks/useHasUserPermission";
|
||||||
import { REGULARIZE_ATTENDANCE } from "../../utils/constants";
|
import { REGULARIZE_ATTENDANCE } from "../../utils/constants";
|
||||||
import eventBus from "../../services/eventBus";
|
import eventBus from "../../services/eventBus";
|
||||||
import { useProjectAssignedOrganizations, useProjectName } from "../../hooks/useProjects";
|
import {
|
||||||
|
useProjectAssignedOrganizations,
|
||||||
|
useProjectName,
|
||||||
|
} from "../../hooks/useProjects";
|
||||||
import GlobalModel from "../../components/common/GlobalModel";
|
import GlobalModel from "../../components/common/GlobalModel";
|
||||||
import CheckCheckOutmodel from "../../components/Activities/CheckCheckOutForm";
|
import CheckCheckOutmodel from "../../components/Activities/CheckCheckOutForm";
|
||||||
import AttendLogs from "../../components/Activities/AttendLogs";
|
import AttendLogs from "../../components/Activities/AttendLogs";
|
||||||
@ -101,11 +104,11 @@ const AttendancePage = () => {
|
|||||||
{(modelConfig?.action === 0 ||
|
{(modelConfig?.action === 0 ||
|
||||||
modelConfig?.action === 1 ||
|
modelConfig?.action === 1 ||
|
||||||
modelConfig?.action === 2) && (
|
modelConfig?.action === 2) && (
|
||||||
<CheckCheckOutmodel
|
<CheckCheckOutmodel
|
||||||
modeldata={modelConfig}
|
modeldata={modelConfig}
|
||||||
closeModal={closeModal}
|
closeModal={closeModal}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{/* For view logs */}
|
{/* For view logs */}
|
||||||
{modelConfig?.action === 6 && (
|
{modelConfig?.action === 6 && (
|
||||||
<AttendLogs Id={modelConfig?.id} closeModal={closeModal} />
|
<AttendLogs Id={modelConfig?.id} closeModal={closeModal} />
|
||||||
@ -134,8 +137,9 @@ const AttendancePage = () => {
|
|||||||
<li className="nav-item">
|
<li className="nav-item">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className={`nav-link ${activeTab === "all" ? "active" : ""
|
className={`nav-link ${
|
||||||
} fs-6`}
|
activeTab === "all" ? "active" : ""
|
||||||
|
} fs-6`}
|
||||||
onClick={() => handleTabChange("all")}
|
onClick={() => handleTabChange("all")}
|
||||||
data-bs-toggle="tab"
|
data-bs-toggle="tab"
|
||||||
data-bs-target="#navs-top-home"
|
data-bs-target="#navs-top-home"
|
||||||
@ -146,8 +150,9 @@ const AttendancePage = () => {
|
|||||||
<li className="nav-item">
|
<li className="nav-item">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className={`nav-link ${activeTab === "logs" ? "active" : ""
|
className={`nav-link ${
|
||||||
} fs-6`}
|
activeTab === "logs" ? "active" : ""
|
||||||
|
} fs-6`}
|
||||||
onClick={() => handleTabChange("logs")}
|
onClick={() => handleTabChange("logs")}
|
||||||
data-bs-toggle="tab"
|
data-bs-toggle="tab"
|
||||||
data-bs-target="#navs-top-profile"
|
data-bs-target="#navs-top-profile"
|
||||||
@ -159,8 +164,9 @@ const AttendancePage = () => {
|
|||||||
<li className={`nav-item ${!DoRegularized ? "d-none" : ""}`}>
|
<li className={`nav-item ${!DoRegularized ? "d-none" : ""}`}>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className={`nav-link ${activeTab === "regularization" ? "active" : ""
|
className={`nav-link ${
|
||||||
} fs-6`}
|
activeTab === "regularization" ? "active" : ""
|
||||||
|
} fs-6`}
|
||||||
onClick={() => handleTabChange("regularization")}
|
onClick={() => handleTabChange("regularization")}
|
||||||
data-bs-toggle="tab"
|
data-bs-toggle="tab"
|
||||||
data-bs-target="#navs-top-messages"
|
data-bs-target="#navs-top-messages"
|
||||||
@ -187,8 +193,8 @@ const AttendancePage = () => {
|
|||||||
disabled={orgLoading}
|
disabled={orgLoading}
|
||||||
>
|
>
|
||||||
<option value="">All Organizations</option>
|
<option value="">All Organizations</option>
|
||||||
{organizations?.map((org) => (
|
{organizations?.map((org, ind) => (
|
||||||
<option key={org.id} value={org.id}>
|
<option key={`${org.id}-${ind}`} value={org.id}>
|
||||||
{org.name}
|
{org.name}
|
||||||
</option>
|
</option>
|
||||||
))}
|
))}
|
||||||
@ -204,8 +210,6 @@ const AttendancePage = () => {
|
|||||||
style={{ minWidth: "200px" }}
|
style={{ minWidth: "200px" }}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -4,10 +4,11 @@ const localVariablesSlice = createSlice({
|
|||||||
name: "localVariables",
|
name: "localVariables",
|
||||||
initialState: {
|
initialState: {
|
||||||
selectedMaster: "Application Role",
|
selectedMaster: "Application Role",
|
||||||
regularizationCount: 0,
|
// Attendances
|
||||||
defaultDateRange: {
|
attendance: {
|
||||||
startDate: null,
|
regularizationCount: 0,
|
||||||
endDate: null,
|
defaultDateRange: { startDate: null, endDate: null },
|
||||||
|
SelectedOrg:null,
|
||||||
},
|
},
|
||||||
projectId: null,
|
projectId: null,
|
||||||
reload: false,
|
reload: false,
|
||||||
@ -28,9 +29,20 @@ const localVariablesSlice = createSlice({
|
|||||||
changeMaster: (state, action) => {
|
changeMaster: (state, action) => {
|
||||||
state.selectedMaster = action.payload;
|
state.selectedMaster = action.payload;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
|
// ─── ATTENDANCE ─────────────────────────
|
||||||
updateRegularizationCount: (state, action) => {
|
updateRegularizationCount: (state, action) => {
|
||||||
state.regularizationCount = action.payload;
|
state.attendance.regularizationCount = action.payload;
|
||||||
},
|
},
|
||||||
|
setDefaultDateRange: (state, action) => {
|
||||||
|
state.attendance.defaultDateRange = action.payload;
|
||||||
|
},
|
||||||
|
setOrganization:(state,action)=>{
|
||||||
|
state.attendance.SelectedOrg = action.payload;
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
setProjectId: (state, action) => {
|
setProjectId: (state, action) => {
|
||||||
localStorage.setItem("project", null);
|
localStorage.setItem("project", null);
|
||||||
state.projectId = action.payload;
|
state.projectId = action.payload;
|
||||||
@ -39,10 +51,6 @@ const localVariablesSlice = createSlice({
|
|||||||
refreshData: (state, action) => {
|
refreshData: (state, action) => {
|
||||||
state.reload = action.payload;
|
state.reload = action.payload;
|
||||||
},
|
},
|
||||||
setDefaultDateRange: (state, action) => {
|
|
||||||
state.defaultDateRange = action.payload;
|
|
||||||
},
|
|
||||||
|
|
||||||
openOrgModal: (state, action) => {
|
openOrgModal: (state, action) => {
|
||||||
state.OrganizationModal.isOpen = true;
|
state.OrganizationModal.isOpen = true;
|
||||||
state.OrganizationModal.orgData = action.payload?.orgData || null;
|
state.OrganizationModal.orgData = action.payload?.orgData || null;
|
||||||
@ -83,6 +91,6 @@ export const {
|
|||||||
closeOrgModal,
|
closeOrgModal,
|
||||||
toggleOrgModal,
|
toggleOrgModal,
|
||||||
openAuthModal,
|
openAuthModal,
|
||||||
closeAuthModal,
|
closeAuthModal,setOrganization
|
||||||
} = localVariablesSlice.actions;
|
} = localVariablesSlice.actions;
|
||||||
export default localVariablesSlice.reducer;
|
export default localVariablesSlice.reducer;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user