From 141bb866d29a10d824d8eb9332b2f54c7e9e7717 Mon Sep 17 00:00:00 2001 From: "kartik.sharma" Date: Thu, 22 May 2025 16:39:42 +0530 Subject: [PATCH 1/3] Adding Switch button in attendence component. --- src/components/Activities/AttendcesLogs.jsx | 25 +++++++---- src/pages/Activities/AttendancePage.jsx | 48 +++++++++++++++++---- 2 files changed, 56 insertions(+), 17 deletions(-) diff --git a/src/components/Activities/AttendcesLogs.jsx b/src/components/Activities/AttendcesLogs.jsx index c42ce1ab..5c62c912 100644 --- a/src/components/Activities/AttendcesLogs.jsx +++ b/src/components/Activities/AttendcesLogs.jsx @@ -9,7 +9,7 @@ import DateRangePicker from "../common/DateRangePicker"; import { getCachedData } from "../../slices/apiDataManager"; import usePagination from "../../hooks/usePagination"; -const AttendanceLog = ({ handleModalData, projectId }) => { +const AttendanceLog = ({ handleModalData, projectId, showOnlyCheckout }) => { const [dateRange, setDateRange] = useState({ startDate: "", endDate: "" }); const dispatch = useDispatch(); const { data, loading, error } = useSelector((store) => store.attendanceLogs); @@ -56,21 +56,26 @@ const AttendanceLog = ({ handleModalData, projectId }) => { }, [dateRange, projectId, isRefreshing]); useEffect(() => { - const group1 = data + // Filter the raw data based on showOnlyCheckout + const filteredData = showOnlyCheckout + ? data.filter((item) => item.checkInTime && item.checkOutTime) + : data; + + const group1 = filteredData .filter((d) => d.activity === 1 && isSameDay(d.checkInTime)) .sort(sortByName); - const group2 = data + const group2 = filteredData .filter((d) => d.activity === 4 && isSameDay(d.checkOutTime)) .sort(sortByName); - const group3 = data + const group3 = filteredData .filter((d) => d.activity === 1 && isBeforeToday(d.checkInTime)) .sort(sortByName); - const group4 = data + const group4 = filteredData .filter((d) => d.activity === 4 && isBeforeToday(d.checkOutTime)); - const group5 = data + const group5 = filteredData .filter((d) => d.activity === 2 && isBeforeToday(d.checkOutTime)) .sort(sortByName); - const group6 = data.filter((d) => d.activity === 5).sort(sortByName); + const group6 = filteredData.filter((d) => d.activity === 5).sort(sortByName); const sortedList = [...group1, ...group2, ...group3, ...group4, ...group5, ...group6]; @@ -90,7 +95,7 @@ const AttendanceLog = ({ handleModalData, projectId }) => { // Create the final sorted array const finalData = sortedDates.flatMap((date) => groupedByDate[date]); setProcessedData(finalData); - }, [data]); + }, [data, showOnlyCheckout]); // Re-run this effect when data or showOnlyCheckout changes const { currentPage, totalPages, currentItems: paginatedAttendances, paginate } = usePagination( processedData, @@ -226,4 +231,6 @@ const AttendanceLog = ({ handleModalData, projectId }) => { ); }; -export default AttendanceLog; \ No newline at end of file +export default AttendanceLog; + + diff --git a/src/pages/Activities/AttendancePage.jsx b/src/pages/Activities/AttendancePage.jsx index 85ec52fe..6f4c6c0b 100644 --- a/src/pages/Activities/AttendancePage.jsx +++ b/src/pages/Activities/AttendancePage.jsx @@ -21,7 +21,7 @@ import { REGULARIZE_ATTENDANCE } from "../../utils/constants"; const AttendancePage = () => { const [activeTab, setActiveTab] = useState("all"); - + const [showOnlyCheckout, setShowOnlyCheckout] = useState(false); const loginUser = getCachedProfileData(); var selectedProject = useSelector((store) => store.localVariables.projectId); const { projects, loading: projectLoading } = useProjects(); @@ -86,6 +86,10 @@ const AttendancePage = () => { }); }; + const handleToggle = (event) => { + setShowOnlyCheckout(event.target.checked); + }; + useEffect(() => { if (modelConfig !== null) { openModel(); @@ -100,6 +104,16 @@ const AttendancePage = () => { dispatch(setProjectId(loginUser?.projects[0])); } }, [selectedProject, loginUser?.projects]); + + + // Filter attendance data based on the toggle + const filteredAttendance = showOnlyCheckout + ? attendances?.filter( + (att) => att?.checkOutTime !== null && att?.checkInTime !== null + ) + : attendances; + + return ( <> {isCreateModalOpen && modelConfig && ( @@ -161,7 +175,7 @@ const AttendancePage = () => { )} - +
{projectLoading && Loading..} @@ -205,25 +236,26 @@ const AttendancePage = () => { {activeTab === "all" && ( <> - {!projectLoading && attendances.length === 0 && ( + {!projectLoading && filteredAttendance?.length === 0 && (

No Employee assigned yet.

)}
)} - + {activeTab === "logs" && (
)} -- 2.43.0 From 2b18f80b56bed9b41bfd9e950bbe9c96f8b7d2ce Mon Sep 17 00:00:00 2001 From: "kartik.sharma" Date: Sat, 24 May 2025 13:30:40 +0530 Subject: [PATCH 2/3] Changes in Attendance Switch on-off button. --- src/components/Activities/AttendcesLogs.jsx | 78 ++++++++++++++------- src/pages/Activities/AttendancePage.jsx | 13 ++-- 2 files changed, 59 insertions(+), 32 deletions(-) diff --git a/src/components/Activities/AttendcesLogs.jsx b/src/components/Activities/AttendcesLogs.jsx index 5c62c912..b57a9c75 100644 --- a/src/components/Activities/AttendcesLogs.jsx +++ b/src/components/Activities/AttendcesLogs.jsx @@ -1,4 +1,4 @@ -import React, { useEffect, useState } from "react"; +import React, { useEffect, useState, useMemo, useCallback } from "react"; import moment from "moment"; import Avatar from "../common/Avatar"; import { convertShortTime } from "../../utils/dateUtils"; @@ -7,13 +7,28 @@ import { useSelector, useDispatch } from "react-redux"; import { fetchAttendanceData } from "../../slices/apiSlice/attedanceLogsSlice"; import DateRangePicker from "../common/DateRangePicker"; import { getCachedData } from "../../slices/apiDataManager"; -import usePagination from "../../hooks/usePagination"; + +const usePagination = (data, itemsPerPage) => { + const [currentPage, setCurrentPage] = useState(1); + const maxPage = Math.ceil(data.length / itemsPerPage); + + const currentItems = useMemo(() => { + const startIndex = (currentPage - 1) * itemsPerPage; + const endIndex = startIndex + itemsPerPage; + return data.slice(startIndex, endIndex); + }, [data, currentPage, itemsPerPage]); + + const paginate = useCallback((pageNumber) => setCurrentPage(pageNumber), []); + const resetPage = useCallback(() => setCurrentPage(1), []); + + return { currentPage, totalPages: maxPage, currentItems, paginate, resetPage }; +}; const AttendanceLog = ({ handleModalData, projectId, showOnlyCheckout }) => { const [dateRange, setDateRange] = useState({ startDate: "", endDate: "" }); const dispatch = useDispatch(); const { data, loading, error } = useSelector((store) => store.attendanceLogs); - const [isRefreshing, setIsRefreshing] = useState(true); + const [isRefreshing, setIsRefreshing] = useState(false); const [processedData, setProcessedData] = useState([]); const today = new Date(); @@ -44,21 +59,19 @@ const AttendanceLog = ({ handleModalData, projectId, showOnlyCheckout }) => { useEffect(() => { const { startDate, endDate } = dateRange; - if (startDate && endDate) { - dispatch( - fetchAttendanceData({ - projectId, - fromDate: startDate, - toDate: endDate, - }) - ); - } - }, [dateRange, projectId, isRefreshing]); + dispatch( + fetchAttendanceData({ + projectId, + fromDate: startDate, + toDate: endDate, + }) + ); + setIsRefreshing(false); + }, [dateRange, projectId, dispatch, isRefreshing]); useEffect(() => { - // Filter the raw data based on showOnlyCheckout const filteredData = showOnlyCheckout - ? data.filter((item) => item.checkInTime && item.checkOutTime) + ? data.filter((item) => item.checkOutTime === null) : data; const group1 = filteredData @@ -95,13 +108,18 @@ const AttendanceLog = ({ handleModalData, projectId, showOnlyCheckout }) => { // Create the final sorted array const finalData = sortedDates.flatMap((date) => groupedByDate[date]); setProcessedData(finalData); - }, [data, showOnlyCheckout]); // Re-run this effect when data or showOnlyCheckout changes + }, [data, showOnlyCheckout]); - const { currentPage, totalPages, currentItems: paginatedAttendances, paginate } = usePagination( + const { currentPage, totalPages, currentItems: paginatedAttendances, paginate, resetPage } = usePagination( processedData, 10 ); + // Reset to the first page whenever processedData changes (due to switch on/off) + useEffect(() => { + resetPage(); + }, [processedData, resetPage]); + return ( <>
{
setIsRefreshing(!isRefreshing)} + onClick={() => setIsRefreshing(true)} />
@@ -139,8 +157,12 @@ const AttendanceLog = ({ handleModalData, projectId, showOnlyCheckout }) => { - {loading && Loading...} - {paginatedAttendances.reduce((acc, attendance, index, arr) => { + {(loading || isRefreshing) && ( + + Loading... + + )} + {!loading && !isRefreshing && paginatedAttendances.reduce((acc, attendance, index, arr) => { const currentDate = moment(attendance.checkInTime || attendance.checkOutTime).format("YYYY-MM-DD"); const previousAttendance = arr[index - 1]; const previousDate = previousAttendance ? moment(previousAttendance.checkInTime || previousAttendance.checkOutTime).format("YYYY-MM-DD") : null; @@ -196,10 +218,14 @@ const AttendanceLog = ({ handleModalData, projectId, showOnlyCheckout }) => { )} - {!loading && data.length === 0 && No employee logs} - {error && {error}} + {!loading && !isRefreshing && data.length === 0 && No employee logs} + {error && !loading && !isRefreshing && ( + + {error} + + )} - {!loading && processedData.length > 10 && ( + {!loading && !isRefreshing && processedData.length > 10 && (