Merge branch 'Feature_Task_Management' of https://git.marcoaiot.com/admin/marco.pms.web into Feature_Task_Management
This commit is contained in:
commit
1151c81c99
@ -9,7 +9,18 @@ const HorizontalBarChart = ({
|
|||||||
"#1E90FF", "#00BFFF", "#9370DB", "#6A0DAD", "#A9A9A9",
|
"#1E90FF", "#00BFFF", "#9370DB", "#6A0DAD", "#A9A9A9",
|
||||||
"#6A5ACD", "#FFA500", "#FF4500", "#20B2AA", "#708090",
|
"#6A5ACD", "#FFA500", "#FF4500", "#20B2AA", "#708090",
|
||||||
],
|
],
|
||||||
|
loading = false,
|
||||||
}) => {
|
}) => {
|
||||||
|
// Show loading state
|
||||||
|
if (loading) {
|
||||||
|
return (
|
||||||
|
<div className="w-full h-[380px] flex items-center justify-center bg-gray-100 rounded-xl">
|
||||||
|
<span className="text-gray-500 text-sm">Loading chart...</span>
|
||||||
|
{/* Replace this with a skeleton or spinner if you prefer */}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// Guard clause for invalid or incomplete data
|
// Guard clause for invalid or incomplete data
|
||||||
const hasValidData =
|
const hasValidData =
|
||||||
Array.isArray(seriesData) &&
|
Array.isArray(seriesData) &&
|
||||||
@ -48,14 +59,14 @@ const HorizontalBarChart = ({
|
|||||||
distributed: true,
|
distributed: true,
|
||||||
horizontal: true,
|
horizontal: true,
|
||||||
dataLabels: {
|
dataLabels: {
|
||||||
position: "start",
|
position: "center",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
colors,
|
colors,
|
||||||
dataLabels: {
|
dataLabels: {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
textAnchor: "start",
|
textAnchor: "center",
|
||||||
style: {
|
style: {
|
||||||
colors: ["#000"], // Black labels
|
colors: ["#000"], // Black labels
|
||||||
},
|
},
|
||||||
@ -108,6 +119,7 @@ HorizontalBarChart.propTypes = {
|
|||||||
seriesData: PropTypes.arrayOf(PropTypes.number),
|
seriesData: PropTypes.arrayOf(PropTypes.number),
|
||||||
categories: PropTypes.arrayOf(PropTypes.string),
|
categories: PropTypes.arrayOf(PropTypes.string),
|
||||||
colors: PropTypes.arrayOf(PropTypes.string),
|
colors: PropTypes.arrayOf(PropTypes.string),
|
||||||
|
loading: PropTypes.bool,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default HorizontalBarChart;
|
export default HorizontalBarChart;
|
||||||
|
|||||||
@ -5,7 +5,8 @@ import PropTypes from "prop-types";
|
|||||||
const LineChart = ({
|
const LineChart = ({
|
||||||
seriesData = [],
|
seriesData = [],
|
||||||
categories = [],
|
categories = [],
|
||||||
colors = ["#1E90FF", "#FF6347"], // default: Dodger Blue & Tomato
|
colors = ["#1E90FF", "#FF6347"],
|
||||||
|
loading = false
|
||||||
}) => {
|
}) => {
|
||||||
const hasValidData =
|
const hasValidData =
|
||||||
Array.isArray(seriesData) &&
|
Array.isArray(seriesData) &&
|
||||||
@ -13,6 +14,15 @@ const LineChart = ({
|
|||||||
Array.isArray(categories) &&
|
Array.isArray(categories) &&
|
||||||
categories.length > 0;
|
categories.length > 0;
|
||||||
|
|
||||||
|
if (loading) {
|
||||||
|
return (
|
||||||
|
<div className="flex justify-center items-center h-[350px] text-gray-500">
|
||||||
|
<div className="animate-spin rounded-full h-8 w-8 border-t-2 border-b-2 border-blue-500 mr-2" />
|
||||||
|
Loading chart...
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if (!hasValidData) {
|
if (!hasValidData) {
|
||||||
return <div className="text-center text-gray-500">No data to display</div>;
|
return <div className="text-center text-gray-500">No data to display</div>;
|
||||||
}
|
}
|
||||||
@ -105,7 +115,8 @@ LineChart.propTypes = {
|
|||||||
),
|
),
|
||||||
categories: PropTypes.arrayOf(PropTypes.string),
|
categories: PropTypes.arrayOf(PropTypes.string),
|
||||||
colors: PropTypes.arrayOf(PropTypes.string),
|
colors: PropTypes.arrayOf(PropTypes.string),
|
||||||
title: PropTypes.string
|
title: PropTypes.string,
|
||||||
|
loading: PropTypes.bool
|
||||||
};
|
};
|
||||||
|
|
||||||
export default LineChart;
|
export default LineChart;
|
||||||
|
|||||||
@ -10,7 +10,7 @@ import {
|
|||||||
} from "../../hooks/useDashboard_Data";
|
} from "../../hooks/useDashboard_Data";
|
||||||
|
|
||||||
const Dashboard = () => {
|
const Dashboard = () => {
|
||||||
const { projects } = useProjects();
|
const { projects,loading } = useProjects();
|
||||||
const [selectedProjectId, setSelectedProjectId] = useState('all');
|
const [selectedProjectId, setSelectedProjectId] = useState('all');
|
||||||
const [FromDate, setFromDate] = useState(() => {
|
const [FromDate, setFromDate] = useState(() => {
|
||||||
const today = new Date();
|
const today = new Date();
|
||||||
@ -21,7 +21,7 @@ const { projectsCardData, } = useDashboardProjectsCardData();
|
|||||||
const { teamsCardData,} = useDashboardTeamsCardData();
|
const { teamsCardData,} = useDashboardTeamsCardData();
|
||||||
const { tasksCardData, } = useDashboardTasksCardData();
|
const { tasksCardData, } = useDashboardTasksCardData();
|
||||||
|
|
||||||
const { dashboard_data, loading: lineLoading } = useDashboard_Data({
|
const { dashboard_data, loading: isLineChartLoading } = useDashboard_Data({
|
||||||
days,
|
days,
|
||||||
FromDate,
|
FromDate,
|
||||||
projectId: selectedProjectId === 'all' ? 0 : selectedProjectId,
|
projectId: selectedProjectId === 'all' ? 0 : selectedProjectId,
|
||||||
@ -40,11 +40,11 @@ const { tasksCardData, } = useDashboardTasksCardData();
|
|||||||
const lineChartSeries = [
|
const lineChartSeries = [
|
||||||
{
|
{
|
||||||
name: 'Planned Work',
|
name: 'Planned Work',
|
||||||
data: dashboard_data.map(d => d.plannedWork || 0),
|
data: dashboard_data.map(d => d.plannedTask || 0),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Completed Work',
|
name: 'Completed Work',
|
||||||
data: dashboard_data.map(d => d.completedWork || 0),
|
data: dashboard_data.map(d => d.completedTask || 0),
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
@ -126,6 +126,7 @@ const { tasksCardData, } = useDashboardTasksCardData();
|
|||||||
<HorizontalBarChart
|
<HorizontalBarChart
|
||||||
categories={projectNames}
|
categories={projectNames}
|
||||||
seriesData={projectProgress}
|
seriesData={projectProgress}
|
||||||
|
loading={loading}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -192,8 +193,7 @@ const { tasksCardData, } = useDashboardTasksCardData();
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="card-body ">
|
<div className="card-body ">
|
||||||
<LineChart seriesData={lineChartSeries} categories={lineChartCategories} />
|
<LineChart seriesData={lineChartSeries} categories={lineChartCategories} loading={isLineChartLoading} />
|
||||||
{lineLoading && <p className="text-center mt-3">Loading...</p>}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import GlobalRepository from "../repositories/GlobalRepository";
|
|||||||
// 🔹 Dashboard Progression Data Hook
|
// 🔹 Dashboard Progression Data Hook
|
||||||
export const useDashboard_Data = ({ days, FromDate, projectId }) => {
|
export const useDashboard_Data = ({ days, FromDate, projectId }) => {
|
||||||
const [dashboard_data, setDashboard_Data] = useState([]);
|
const [dashboard_data, setDashboard_Data] = useState([]);
|
||||||
const [loading, setLoading] = useState(false);
|
const [isLineChartLoading, setLoading] = useState(false);
|
||||||
const [error, setError] = useState("");
|
const [error, setError] = useState("");
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -34,7 +34,7 @@ export const useDashboard_Data = ({ days, FromDate, projectId }) => {
|
|||||||
fetchData();
|
fetchData();
|
||||||
}, [days, FromDate, projectId]);
|
}, [days, FromDate, projectId]);
|
||||||
|
|
||||||
return { dashboard_data, loading, error };
|
return { dashboard_data, loading: isLineChartLoading, error };
|
||||||
};
|
};
|
||||||
|
|
||||||
// 🔹 Dashboard Projects Card Data Hook
|
// 🔹 Dashboard Projects Card Data Hook
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user