diff --git a/src/components/Dashboard/Dashboard.jsx b/src/components/Dashboard/Dashboard.jsx index b45f330d..774d311f 100644 --- a/src/components/Dashboard/Dashboard.jsx +++ b/src/components/Dashboard/Dashboard.jsx @@ -85,7 +85,7 @@ const Dashboard = () => { {!isAllProjectsSelected && (canRegularize || canTeamAttendance || canSelfAttendance) && ( -
+
)} diff --git a/src/components/Dashboard/ProjectWiseTeamCount.jsx b/src/components/Dashboard/ProjectWiseTeamCount.jsx index 4a097148..3e5abb8f 100644 --- a/src/components/Dashboard/ProjectWiseTeamCount.jsx +++ b/src/components/Dashboard/ProjectWiseTeamCount.jsx @@ -1,82 +1,83 @@ import React from "react"; import { useProjectName } from "../../hooks/useProjects"; +import { BUCKET_BG_CLASSES } from "../../utils/constants"; +import { useAttendaceProjectWiseOveriew } from "../../hooks/useDashboard_Data"; +import { AppColors, localToUtc } from "../../utils/appUtils"; +import DatePicker from "../common/DatePicker"; +import { useAppForm, useAppWatch } from "../../hooks/appHooks/useAppForm"; +import { zodResolver } from "@hookform/resolvers/zod"; +import { z } from "zod"; const ProjectWiseTeamCount = () => { - const { projectNames, loading, isError, Errorr } = useProjectName(); + const { control } = useAppForm({ + resolver: zodResolver( + z.object({ + date: z.string().optional(), + }) + ), + defaultValues: { + date: new Date().toISOString().slice(0, 10), + }, + }); - if (loading) { - return ( -
- Loading... -
- ); - } + const selectedDate = useAppWatch({ control, name: "date" }); - if (isError) { - return ( -
- Error: {Errorr?.message || "Something went wrong"} -
- ); - } + const { data, isLoading, isFetching, isError, error } = + useAttendaceProjectWiseOveriew(localToUtc(selectedDate)); + + const percent = (teamCount, attendanceCount) => { + return teamCount > 0 ? Math.round((attendanceCount / teamCount) * 100) : 0; + }; return ( -
-
-
Project wise Employee
+
+ {/* Header */} +
+
Project wise Employee
+
+ + {/* Only show spinner for new data, not full component */} + {isFetching && !isLoading && ( +
Updating…
+ )} + + {/* Table */}
- + - - - - + + + + {/* */}
NoProjectVisitsData In Percentage + Project + Team Size + Logged In + Percentage
- {(projectNames ?? []).map((item, index) => ( - - - - - - - - + + + + {/* */} ))} diff --git a/src/hooks/appHooks/useAppForm.js b/src/hooks/appHooks/useAppForm.js index f4ccbac0..77f34620 100644 --- a/src/hooks/appHooks/useAppForm.js +++ b/src/hooks/appHooks/useAppForm.js @@ -1,6 +1,7 @@ -import { useForm, Controller, FormProvider, useFormContext } from "react-hook-form"; +import { useForm, Controller, FormProvider, useFormContext, useWatch } from "react-hook-form"; export const useAppForm = (config) => useForm(config); export const AppFormProvider = FormProvider; export const AppFormController = Controller; export const useAppFormContext = useFormContext; +export const useAppWatch = useWatch; diff --git a/src/hooks/useDashboard_Data.jsx b/src/hooks/useDashboard_Data.jsx index fb20d806..75a371d9 100644 --- a/src/hooks/useDashboard_Data.jsx +++ b/src/hooks/useDashboard_Data.jsx @@ -1,6 +1,6 @@ import { useState, useEffect } from "react"; import GlobalRepository from "../repositories/GlobalRepository"; -import { useQuery } from "@tanstack/react-query"; +import { keepPreviousData, useQuery } from "@tanstack/react-query"; export const useDashboard_Data = ({ days, FromDate, projectId }) => { const [dashboard_data, setDashboard_Data] = useState([]); @@ -211,4 +211,17 @@ export const useJobsProgression = (projectId) => { return resp.data; }, }); -}; \ No newline at end of file +}; + +export const useAttendaceProjectWiseOveriew = (date) => { + return useQuery({ + queryKey: ["attendaceOverview", date], + queryFn: async () => { + const resp = await GlobalRepository.getAttendanceProjectWiseOverview( + date + ); + return resp.data; + }, + keepPreviousData: true, + }); +}; diff --git a/src/repositories/GlobalRepository.jsx b/src/repositories/GlobalRepository.jsx index 39046f37..9a88c67c 100644 --- a/src/repositories/GlobalRepository.jsx +++ b/src/repositories/GlobalRepository.jsx @@ -1,7 +1,11 @@ import { api } from "../utils/axiosClient"; const GlobalRepository = { - getDashboardProgressionData: ({ days = '', FromDate = '', projectId = '' }) => { + getDashboardProgressionData: ({ + days = "", + FromDate = "", + projectId = "", + }) => { let params; if (projectId == null) { params = new URLSearchParams({ @@ -18,12 +22,13 @@ const GlobalRepository = { return api.get(`/api/Dashboard/Progression?${params.toString()}`); }, - getProjectCompletionStatus:()=>api.get(`/api/Dashboard/project-completion-status`), - + getProjectCompletionStatus: () => + api.get(`/api/Dashboard/project-completion-status`), getDashboardAttendanceData: (date, projectId) => { - - return api.get(`/api/Dashboard/project-attendance/${projectId}?date=${date}`); + return api.get( + `/api/Dashboard/project-attendance/${projectId}?date=${date}` + ); }, getDashboardProjectsCardData: () => { return api.get(`/api/Dashboard/projects`); @@ -44,7 +49,7 @@ const GlobalRepository = { }, getExpenseData: (projectId, startDate, endDate) => { - let url = `api/Dashboard/expense/type` + let url = `api/Dashboard/expense/type`; const queryParams = []; if (projectId) { queryParams.push(`projectId=${projectId}`); @@ -62,10 +67,15 @@ const GlobalRepository = { return api.get(url); }, - getExpenseStatus: (projectId) => api.get(`/api/Dashboard/expense/pendings${projectId ? `?projectId=${projectId}` : ""}`), + getExpenseStatus: (projectId) => + api.get( + `/api/Dashboard/expense/pendings${ + projectId ? `?projectId=${projectId}` : "" + }` + ), getExpenseDataByProject: (projectId, categoryId, months) => { - let url = `api/Dashboard/expense/monthly` + let url = `api/Dashboard/expense/monthly`; const queryParams = []; if (projectId) { queryParams.push(`projectId=${projectId}`); @@ -82,13 +92,21 @@ const GlobalRepository = { return api.get(url); }, - getAttendanceOverview: (projectId, days) => api.get(`/api/dashboard/attendance-overview/${projectId}?days=${days}`), + getAttendanceOverview: (projectId, days) => + api.get(`/api/dashboard/attendance-overview/${projectId}?days=${days}`), - getCollectionOverview:(projectId) =>api.get(`/api/Dashboard/collection-overview`), - - getJobsProgression: (projectId) => api.get(`/api/Dashboard/job/progression${projectId ? `?projectId=${projectId}` : ""}`), + getCollectionOverview: (projectId) => + api.get(`/api/Dashboard/collection-overview`), + getJobsProgression: (projectId) => + api.get( + `/api/Dashboard/job/progression${ + projectId ? `?projectId=${projectId}` : "" + }` + ), + + getAttendanceProjectWiseOverview: (date) => + api.get(`/api/dashboard/project/attendance-overview?date=${date}`), }; - export default GlobalRepository; diff --git a/src/utils/appUtils.js b/src/utils/appUtils.js index 7b983d2b..80cc13a8 100644 --- a/src/utils/appUtils.js +++ b/src/utils/appUtils.js @@ -24,6 +24,11 @@ export const AppColorconfig = { borderColor: "#eceef1", }, }; + + +export const AppColors = [ + "primary","secodary","warning","info","danger" +] export const getColorNameFromHex = (hex) => { const normalizedHex = hex?.replace(/'/g, "").toLowerCase(); const colors = AppColorconfig.colors;
{index + 1} -
- {item.img && ( - {item.shortName} - )} - {item.name} -
-
{item.visits} -
-
-
-
- {item.percent}% + {(data ?? []).map((item, index) => ( +
+
+ {item.projectName}
{item.teamCount}{item.attendanceCount}{percent(item.teamCount, item.attendanceCount)}%