diff --git a/public/assets/vendor/css/core.css b/public/assets/vendor/css/core.css
index aca2dc05..d95f46c2 100644
--- a/public/assets/vendor/css/core.css
+++ b/public/assets/vendor/css/core.css
@@ -836,7 +836,7 @@ progress {
}
.row {
- --bs-gutter-x: 0.500rem;
+ --bs-gutter-x: 1.625rem;
--bs-gutter-y: 0;
display: flex;
flex-wrap: wrap;
diff --git a/src/components/Charts/Skelton.jsx b/src/components/Charts/Skelton.jsx
new file mode 100644
index 00000000..804653b8
--- /dev/null
+++ b/src/components/Charts/Skelton.jsx
@@ -0,0 +1,15 @@
+import React from "react";
+
+const ChartSkeleton = () => {
+ return (
+
-
-
- {tasksCardData.totalTasks?.toLocaleString()}
-
-
Total
+
+ {loading ? (
+ // Loader will be displayed when loading is true
+
-
-
- {tasksCardData.completedTasks?.toLocaleString()}
-
-
Completed
+ ) : error ? (
+ // Error message if there's an error
+
{error}
+ ) : (
+ // Actual data when loaded successfully
+
+
+
+ {tasksCardData?.totalTasks?.toLocaleString()}
+
+ Total
+
+
+
+ {tasksCardData?.completedTasks?.toLocaleString()}
+
+ Completed
+
-
+ )}
);
};
diff --git a/src/components/Dashboard/Teams.jsx b/src/components/Dashboard/Teams.jsx
index f495caa7..00e881f5 100644
--- a/src/components/Dashboard/Teams.jsx
+++ b/src/components/Dashboard/Teams.jsx
@@ -1,29 +1,33 @@
import React, { useCallback, useEffect, useState } from "react";
+import { useSelector } from "react-redux";
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);
+ const projectId = useSelector((store) => store.localVariables?.projectId);
+ const { teamsCardData, loading, error } = useDashboardTeamsCardData(projectId);
- useEffect(() =>{
- setTotalEmployee(teamsCardData.totalEmployees)
- setInToday(teamsCardData.inToday)
- },[teamsCardData.totalEmployees,teamsCardData.inToday])
+ const [totalEmployees, setTotalEmployee] = useState(0);
+ const [inToday, setInToday] = useState(0);
+
+ // Update state when API data arrives
+ useEffect(() => {
+ setTotalEmployee(teamsCardData?.totalEmployees || 0);
+ setInToday(teamsCardData?.inToday || 0);
+ }, [teamsCardData]);
+
+ // Handle real-time updates via eventBus
+ const handler = useCallback((msg) => {
+ if (msg.activity === 1) {
+ setInToday((prev) => prev + 1);
+ }
+ }, []);
- 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 (
@@ -31,20 +35,30 @@ const Teams = () => {
Teams
-
-
-
- {totalEmployees?.toLocaleString()}
-
-
Total Employees
+
+ {loading ? (
+ // Blue spinner loader
+
-
-
- {inToday?.toLocaleString()}
-
-
In Today
+ ) : error ? (
+ // Error message if data fetching fails
+
{error}
+ ) : (
+ // Display data once loaded
+
+
+
{totalEmployees.toLocaleString()}
+ Total Employees
+
+
+
{inToday.toLocaleString()}
+ In Today
+
-
+ )}
);
};
diff --git a/src/components/Project/ProjectOverview.jsx b/src/components/Project/ProjectOverview.jsx
index bdf0562b..27c6d27e 100644
--- a/src/components/Project/ProjectOverview.jsx
+++ b/src/components/Project/ProjectOverview.jsx
@@ -165,7 +165,7 @@ const ProjectOverview = ({ project }) => {
}, [selectedProject]);
return (
-
+
{" "}
diff --git a/src/hooks/useDashboard_Data.jsx b/src/hooks/useDashboard_Data.jsx
index a46aa0c8..831d9092 100644
--- a/src/hooks/useDashboard_Data.jsx
+++ b/src/hooks/useDashboard_Data.jsx
@@ -39,32 +39,32 @@ export const useDashboard_Data = ({ days, FromDate, projectId }) => {
export const useDashboard_AttendanceData = (date, projectId) => {
- const [dashboard_Attendancedata, setDashboard_AttendanceData] = useState([]);
- const [isLineChartLoading, setLoading] = useState(false);
- const [error, setError] = useState("");
+ const [dashboard_Attendancedata, setDashboard_AttendanceData] = useState([]);
+ const [isLineChartLoading, setLoading] = useState(false);
+ const [error, setError] = useState("");
- useEffect(() => {
- const fetchData = async () => {
- setLoading(true);
- setError("");
+ useEffect(() => {
+ const fetchData = async () => {
+ setLoading(true);
+ setError("");
- try {
- const response = await GlobalRepository.getDashboardAttendanceData(date,projectId); // date in 2nd param
- setDashboard_AttendanceData(response.data);
- } catch (err) {
- setError("Failed to fetch dashboard data.");
- console.error(err);
- } finally {
- setLoading(false);
- }
- };
+ try {
+ const response = await GlobalRepository.getDashboardAttendanceData(date, projectId); // date in 2nd param
+ setDashboard_AttendanceData(response.data);
+ } catch (err) {
+ setError("Failed to fetch dashboard data.");
+ console.error(err);
+ } finally {
+ setLoading(false);
+ }
+ };
- if (date && projectId !== null) {
- fetchData();
- }
- }, [date, projectId]);
+ if (date && projectId !== null) {
+ fetchData();
+ }
+ }, [date, projectId]);
- return { dashboard_Attendancedata, isLineChartLoading: isLineChartLoading, error };
+ return { dashboard_Attendancedata, isLineChartLoading: isLineChartLoading, error };
};
@@ -97,36 +97,38 @@ export const useDashboardProjectsCardData = () => {
};
// 🔹 Dashboard Teams Card Data Hook
-export const useDashboardTeamsCardData = () => {
- const [teamsCardData, setTeamsData] = useState([]);
+export const useDashboardTeamsCardData = (projectId) => {
+ const [teamsCardData, setTeamsData] = useState({});
const [loading, setLoading] = useState(false);
const [error, setError] = useState("");
useEffect(() => {
const fetchTeamsData = async () => {
+ if (!projectId) return; // ✅ Skip if projectId is not provided
+
setLoading(true);
setError("");
try {
- const response = await GlobalRepository.getDashboardTeamsCardData();
- setTeamsData(response.data);
+ const response = await GlobalRepository.getDashboardTeamsCardData(projectId);
+ setTeamsData(response.data); // ✅ Handle undefined/null
} catch (err) {
setError("Failed to fetch teams card data.");
console.error(err);
+ setTeamsData({});
} finally {
setLoading(false);
}
};
fetchTeamsData();
- }, []);
+ }, [projectId]);
return { teamsCardData, loading, error };
};
-// 🔹 Dashboard Tasks Card Data Hook
-export const useDashboardTasksCardData = () => {
- const [tasksCardData, setTasksData] = useState([]);
+export const useDashboardTasksCardData = (projectId) => {
+ const [tasksCardData, setTasksData] = useState({});
const [loading, setLoading] = useState(false);
const [error, setError] = useState("");
@@ -136,18 +138,47 @@ export const useDashboardTasksCardData = () => {
setError("");
try {
- const response = await GlobalRepository.getDashboardTasksCardData();
+ const response = await GlobalRepository.getDashboardTasksCardData(projectId);
setTasksData(response.data);
} catch (err) {
setError("Failed to fetch tasks card data.");
console.error(err);
+ setTasksData({});
} finally {
setLoading(false);
}
};
fetchTasksData();
- }, []);
+ }, [projectId]);
return { tasksCardData, loading, error };
};
+
+
+export const useAttendanceOverviewData = (projectId, days) => {
+ const [attendanceOverviewData, setAttendanceOverviewData] = useState([]);
+ const [loading, setLoading] = useState(false);
+ const [error, setError] = useState("");
+
+ useEffect(() => {
+ if (!projectId || !days) return;
+ const fetchAttendanceOverview = async () => {
+ setLoading(true);
+ setError("");
+
+ try {
+ const response = await GlobalRepository.getAttendanceOverview(projectId, days);
+ setAttendanceOverviewData(response.data);
+ } catch (err) {
+ setError("Failed to fetch attendance overview data.");
+ } finally {
+ setLoading(false);
+ }
+ };
+
+ fetchAttendanceOverview();
+ }, [projectId, days]);
+
+ return { attendanceOverviewData, loading, error };
+};
diff --git a/src/pages/employee/EmployeeList.jsx b/src/pages/employee/EmployeeList.jsx
index f04ec0cd..6d3b66b4 100644
--- a/src/pages/employee/EmployeeList.jsx
+++ b/src/pages/employee/EmployeeList.jsx
@@ -294,8 +294,8 @@ const EmployeeList = () => {
>
{ViewTeamMember ? (
-
-
) : (
diff --git a/src/pages/project/ProjectDetails.jsx b/src/pages/project/ProjectDetails.jsx
index ff1be7bb..a80efa4e 100644
--- a/src/pages/project/ProjectDetails.jsx
+++ b/src/pages/project/ProjectDetails.jsx
@@ -1,4 +1,4 @@
-import { useSelector } from "react-redux"; // Import useSelector
+import { useSelector, useDispatch } from "react-redux"; // Import useSelector
import React, { useState, useEffect, useCallback } from "react";
import ProjectOverview from "../../components/Project/ProjectOverview";
@@ -22,14 +22,25 @@ import { ComingSoonPage } from "../Misc/ComingSoonPage";
import Directory from "../Directory/Directory";
import eventBus from "../../services/eventBus";
import ProjectProgressChart from "../../components/Dashboard/ProjectProgressChart";
+import { useProjectName } from "../../hooks/useProjects";
+import AttendanceOverview from "../../components/Dashboard/AttendanceChart";
const ProjectDetails = () => {
const projectId = useSelector((store) => store.localVariables.projectId);
+ const { projectNames, fetchData } = useProjectName();
+ const dispatch = useDispatch()
+
+ useEffect(() => {
+ if (projectId == null) {
+ dispatch(setProjectId(projectNames[0]?.id));
+ }
+ }, [projectNames])
+
const {
- projects_Details,
+ projects_Details,
loading: projectLoading,
error: projectError,
refetch,
@@ -71,6 +82,8 @@ const ProjectDetails = () => {
>
diff --git a/src/repositories/GlobalRepository.jsx b/src/repositories/GlobalRepository.jsx
index eda5312e..d3367fa6 100644
--- a/src/repositories/GlobalRepository.jsx
+++ b/src/repositories/GlobalRepository.jsx
@@ -26,12 +26,22 @@ const GlobalRepository = {
getDashboardProjectsCardData: () => {
return api.get(`/api/Dashboard/projects`);
},
- getDashboardTeamsCardData: () => {
- return api.get(`/api/Dashboard/teams`);
- },
- getDashboardTasksCardData: () => {
- return api.get(`/api/Dashboard/tasks`);
- },
+
+ getDashboardTeamsCardData: (projectId) => {
+ const url = projectId
+ ? `/api/Dashboard/teams?projectId=${projectId}`
+ : `/api/Dashboard/teams`;
+ return api.get(url);
+},
+
+ getDashboardTasksCardData: (projectId) => {
+ const url = projectId
+ ? `/api/Dashboard/tasks?projectId=${projectId}`
+ : `/api/Dashboard/tasks`;
+ return api.get(url);
+},
+
+ getAttendanceOverview:(projectId,days)=>api.get(`/api/dashboard/attendance-overview/${projectId}?days=${days}`)
};