From 51190b0d53731c4e75ebec107ae7f23d4891a7c0 Mon Sep 17 00:00:00 2001 From: Vaibhav Surve Date: Fri, 11 Apr 2025 15:44:51 +0530 Subject: [PATCH 1/4] add dashboard data hooks and global repository for API interactions --- src/hooks/useDashboard_Data.jsx | 122 ++++++++++++++++++++++++++ src/repositories/GlobalRepository.jsx | 25 ++++++ 2 files changed, 147 insertions(+) create mode 100644 src/hooks/useDashboard_Data.jsx create mode 100644 src/repositories/GlobalRepository.jsx diff --git a/src/hooks/useDashboard_Data.jsx b/src/hooks/useDashboard_Data.jsx new file mode 100644 index 00000000..55432f8c --- /dev/null +++ b/src/hooks/useDashboard_Data.jsx @@ -0,0 +1,122 @@ +import { useState, useEffect } from "react"; +import GlobalRepository from "../repositories/GlobalRepository"; + +// 🔹 Dashboard Progression Data Hook +export const useDashboard_Data = ({ days, FromDate, projectId }) => { + const [dashboard_data, setDashboard_Data] = useState([]); + const [loading, setLoading] = useState(false); + const [error, setError] = useState(""); + + useEffect(() => { + if (!days) return; + + const fetchData = async () => { + setLoading(true); + setError(""); + + try { + const payload = { + days, + FromDate: FromDate || '', + projectId: projectId || 0, + }; + + const response = await GlobalRepository.getDashboardProgressionData(payload); + setDashboard_Data(response.data); + } catch (err) { + setError("Failed to fetch dashboard data."); + console.error(err); + } finally { + setLoading(false); + } + }; + + fetchData(); + }, [days, FromDate, projectId]); + + return { dashboard_data, loading, error }; +}; + +// 🔹 Dashboard Projects Card Data Hook +export const useDashboardProjectsCardData = () => { + const [projectsCardData, setProjectsData] = useState([]); + const [loading, setLoading] = useState(false); + const [error, setError] = useState(""); + + useEffect(() => { + const fetchProjectsData = async () => { + setLoading(true); + setError(""); + + try { + const response = await GlobalRepository.getDashboardProjectsCardData(); + setProjectsData(response.data); + } catch (err) { + setError("Failed to fetch projects card data."); + console.error(err); + } finally { + setLoading(false); + } + }; + + fetchProjectsData(); + }, []); + + return { projectsCardData, loading, error }; +}; + +// 🔹 Dashboard Teams Card Data Hook +export const useDashboardTeamsCardData = () => { + const [teamsCardData, setTeamsData] = useState([]); + const [loading, setLoading] = useState(false); + const [error, setError] = useState(""); + + useEffect(() => { + const fetchTeamsData = async () => { + setLoading(true); + setError(""); + + try { + const response = await GlobalRepository.getDashboardTeamsCardData(); + setTeamsData(response.data); + } catch (err) { + setError("Failed to fetch teams card data."); + console.error(err); + } finally { + setLoading(false); + } + }; + + fetchTeamsData(); + }, []); + + return { teamsCardData, loading, error }; +}; + +// 🔹 Dashboard Tasks Card Data Hook +export const useDashboardTasksCardData = () => { + const [tasksCardData, setTasksData] = useState([]); + const [loading, setLoading] = useState(false); + const [error, setError] = useState(""); + + useEffect(() => { + const fetchTasksData = async () => { + setLoading(true); + setError(""); + + try { + const response = await GlobalRepository.getDashboardTasksCardData(); + setTasksData(response.data); + } catch (err) { + setError("Failed to fetch tasks card data."); + console.error(err); + } finally { + setLoading(false); + } + }; + + fetchTasksData(); + }, []); + + return { tasksCardData, loading, error }; +}; diff --git a/src/repositories/GlobalRepository.jsx b/src/repositories/GlobalRepository.jsx new file mode 100644 index 00000000..c87df4ec --- /dev/null +++ b/src/repositories/GlobalRepository.jsx @@ -0,0 +1,25 @@ +import { api } from "../utils/axiosClient"; + +const GlobalRepository = { + getDashboardProgressionData: ({ days = '', FromDate = '', projectId = '' }) => { + const params = new URLSearchParams({ + days: days.toString(), + FromDate, + projectId, + }); + + return api.get(`/api/Dashboard/Progression?${params.toString()}`); + }, + getDashboardProjectsCardData: () => { + return api.get(`/api/Dashboard/projects`); + }, + getDashboardTeamsCardData: () => { + return api.get(`/api/Dashboard/teams`); + }, + getDashboardTasksCardData: () => { + return api.get(`/api/Dashboard/tasks`); + }, + +}; + +export default GlobalRepository; From 12aa5c14911dfccbeb647acacf0cfa948f796fc8 Mon Sep 17 00:00:00 2001 From: Vaibhav Surve Date: Fri, 11 Apr 2025 15:44:56 +0530 Subject: [PATCH 2/4] refactor HorizontalBarChart: streamline data handling and improve label visibility --- src/components/Charts/HorizontalBarChart.jsx | 85 ++++++++------------ 1 file changed, 34 insertions(+), 51 deletions(-) diff --git a/src/components/Charts/HorizontalBarChart.jsx b/src/components/Charts/HorizontalBarChart.jsx index 5236a7e5..581fd8ba 100644 --- a/src/components/Charts/HorizontalBarChart.jsx +++ b/src/components/Charts/HorizontalBarChart.jsx @@ -6,19 +6,9 @@ const HorizontalBarChart = ({ seriesData = [], categories = [], colors = [ - "#1E90FF", // Dodger Blue - Primary - "#00BFFF", // Deep Sky Blue - Info - "#9370DB", // Medium Purple - Success (replacing Lime Green) - "#6A0DAD", // Amethyst Purple - On Route (replacing Forest Green) - "#A9A9A9", // Dark Gray - Neutral - "#6A5ACD", // Slate Blue - Secondary - "#FFA500", // Orange - Warning - "#FF4500", // Orange Red - Danger - "#20B2AA", // Light Sea Green - Late - "#708090", // Slate Gray - Muted + "#1E90FF", "#00BFFF", "#9370DB", "#6A0DAD", "#A9A9A9", + "#6A5ACD", "#FFA500", "#FF4500", "#20B2AA", "#708090", ], - - }) => { // Guard clause for invalid or incomplete data const hasValidData = @@ -31,25 +21,34 @@ const HorizontalBarChart = ({ return
No data to display
; } - const chartOptions = { + // Combine seriesData and categories, then sort in descending order + const combined = seriesData.map((value, index) => ({ + value, + label: categories[index], + })); + const sorted = combined.sort((a, b) => b.value - a.value); + // Extract sorted values + const sortedSeriesData = sorted.map(item => item.value); + const sortedCategories = sorted.map(item => item.label); + + // Replace 0 with 1 for visual purposes, but display "0%" in labels + const adjustedSeriesData = sortedSeriesData.map(val => (val === 0 ? 1 : val)); + + const chartOptions = { chart: { type: "bar", height: 380, - toolbar: { - show: false, // This removes the menu - }, - }, - grid: { - show: false + toolbar: { show: false }, }, + grid: { show: false }, plotOptions: { bar: { barHeight: "60%", distributed: true, horizontal: true, dataLabels: { - position: "center", + position: "start", }, }, }, @@ -58,49 +57,33 @@ const HorizontalBarChart = ({ enabled: true, textAnchor: "start", style: { - colors: ["#000"], // Switch to black for better visibility + colors: ["#000"], // Black labels }, - formatter: function (val, opt) { - return `${opt.w.globals.labels[opt.dataPointIndex]}: ${val}`; - }, - offsetX: 10, // Push label slightly to the right - dropShadow: { - enabled: false, + formatter: function (_, opt) { + const originalVal = sortedSeriesData[opt.dataPointIndex]; // Show real value + return `${originalVal}%`; }, + offsetX: 10, + dropShadow: { enabled: false }, }, - stroke: { width: 1, colors: ["#fff"], }, xaxis: { - categories, - axisBorder: { - show: false, - }, - axisTicks: { - show: false, - }, - labels: { - show: false, - }, + categories: sortedCategories, + axisBorder: { show: false }, + axisTicks: { show: false }, + labels: { show: false }, }, yaxis: { - labels: { - show: false, - }, - axisBorder: { - show: false, - }, - axisTicks: { - show: false, - }, + labels: { show: false }, + axisBorder: { show: false }, + axisTicks: { show: false }, }, tooltip: { theme: "dark", - x: { - show: false, - }, + x: { show: true }, y: { title: { formatter: () => "", @@ -113,7 +96,7 @@ const HorizontalBarChart = ({
From 02b0c4ccab9999323d23ce8b2aec48bc6aadb77c Mon Sep 17 00:00:00 2001 From: Vaibhav Surve Date: Fri, 11 Apr 2025 15:45:02 +0530 Subject: [PATCH 3/4] fix(LineChart): enable x-axis labels visibility and adjust styling --- src/components/Charts/LineChart.jsx | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/components/Charts/LineChart.jsx b/src/components/Charts/LineChart.jsx index 1c994329..61efce2c 100644 --- a/src/components/Charts/LineChart.jsx +++ b/src/components/Charts/LineChart.jsx @@ -31,7 +31,7 @@ const LineChart = ({ }, stroke: { curve: 'straight', - width: 2 + width: 2 }, grid: { show: false, @@ -55,11 +55,18 @@ const LineChart = ({ }, xaxis: { categories, - labels: { show: false }, + labels: { + show: true, + rotate: -45, + style: { + fontSize: '12px' + } + }, axisBorder: { show: false }, axisTicks: { show: false }, tooltip: { enabled: false } }, + yaxis: { labels: { show: false }, axisBorder: { show: false }, From 895e3da21905bd5b3640c2dae3601d03d534d355 Mon Sep 17 00:00:00 2001 From: Vaibhav Surve Date: Fri, 11 Apr 2025 15:45:08 +0530 Subject: [PATCH 4/4] refactor(Dashboard): enhance project data handling and improve chart integration --- src/components/Dashboard/Dashboard.jsx | 192 +++++++++++++++++-------- 1 file changed, 132 insertions(+), 60 deletions(-) diff --git a/src/components/Dashboard/Dashboard.jsx b/src/components/Dashboard/Dashboard.jsx index accb9235..6ce7b8ab 100644 --- a/src/components/Dashboard/Dashboard.jsx +++ b/src/components/Dashboard/Dashboard.jsx @@ -1,25 +1,57 @@ -import React from 'react'; +import React, { useState } from 'react'; import HorizontalBarChart from '../Charts/HorizontalBarChart'; import LineChart from '../Charts/LineChart'; -const dummyCategories = ['Project 1', 'Project 2', 'Project 3', 'Project 4', 'Project 5']; -const dummyData = [45, 38, 30, 25, 20]; - -const lineChartseries = [ - { - name: "Planned Projects", - data: [20, 25, 30, 35, 40, 45, 50] - }, - { - name: "Completed Projects", - data: [5, 15, 28, 36, 42, 46, 48] - } -]; - - -const lineChartCategories = ["January", "February", "March", "April", "May", "June", "July"]; - +import { useProjects } from '../../hooks/useProjects'; +import { + useDashboard_Data, + useDashboardProjectsCardData, + useDashboardTeamsCardData, + useDashboardTasksCardData, +} from "../../hooks/useDashboard_Data"; const Dashboard = () => { + const { projects } = useProjects(); + const [selectedProjectId, setSelectedProjectId] = useState('all'); + const [FromDate, setFromDate] = useState(() => { + const today = new Date(); + return today.toISOString().split('T')[0]; // YYYY-MM-DD + }); +const [days, setDays] = useState(10); +const { projectsCardData, } = useDashboardProjectsCardData(); +const { teamsCardData,} = useDashboardTeamsCardData(); +const { tasksCardData, } = useDashboardTasksCardData(); + + const { dashboard_data, loading: lineLoading } = useDashboard_Data({ + days, + FromDate, + projectId: selectedProjectId === 'all' ? 0 : selectedProjectId, + }); + + // Bar chart logic + const projectNames = projects?.map(p => p.name) || []; + const projectProgress = projects?.map(p => { + const completed = p.completedWork || 0; + const planned = p.plannedWork || 1; + const percent = (completed / planned) * 100; + return Math.min(Math.round(percent), 100); + }) || []; + + // Line chart data + const lineChartSeries = [ + { + name: 'Planned Work', + data: dashboard_data.map(d => d.plannedWork || 0), + }, + { + name: 'Completed Work', + data: dashboard_data.map(d => d.completedWork || 0), + }, + ]; + + const lineChartCategories = dashboard_data.map(d => + new Date(d.date).toLocaleDateString('en-US', { month: 'short', day: 'numeric' }) + ); + return (
@@ -28,15 +60,15 @@ const Dashboard = () => {
-
Projects
+
Projects
-

25

+

{projectsCardData.totalProjects?.toLocaleString()}

Total
-

30

+

{projectsCardData.ongoingProjects?.toLocaleString()}

Ongoing
@@ -47,15 +79,15 @@ const Dashboard = () => {
-
Teams
+
Teams
-

500

+

{teamsCardData.totalEmployees?.toLocaleString()}

Total Employees
-

360

+

{teamsCardData.inToday?.toLocaleString()}

In Today
@@ -66,66 +98,106 @@ const Dashboard = () => {
-
Tasks
+
Tasks
-

10,000

+

{tasksCardData.totalTasks?.toLocaleString()}

Total
-

4,000

+

{tasksCardData.completedTasks?.toLocaleString()}

Completed
- {/* Chart Section */} -
-
-
-
-
Projects
-

Total Projects Overview

+ + {/* Bar Chart */} +
+
+
+
+
Projects
+

Total Projects Overview

-
+
-
-
-
-
-
Project Progress
-

Progress Overview by Project

+ + {/* Line Chart */} +
+
+
+
+
Project Progress
+

Progress Overview by Project

-
- - - +
+ {/* Project Dropdown */} +
+ + +
    +
  • + +
  • + {projects?.map((project) => ( +
  • + +
  • + ))} +
+
+ + {/* From Date */} + setFromDate(e.target.value)} + style={{ maxWidth: '150px' }} + /> + + {/* Days */} + setDays(Number(e.target.value))} + style={{ maxWidth: '100px' }} + />
-
- +
+ + {lineLoading &&

Loading...

}
+
);