diff --git a/src/components/Dashboard/AttendanceOverview.jsx b/src/components/Dashboard/AttendanceOverview.jsx
index 522aa193..e3774278 100644
--- a/src/components/Dashboard/AttendanceOverview.jsx
+++ b/src/components/Dashboard/AttendanceOverview.jsx
@@ -1,11 +1,14 @@
import React, { useState, useMemo } from "react";
import { useSelector } from "react-redux";
import ReactApexChart from "react-apexcharts";
+import moment from "moment";
import { useAttendanceOverviewData } from "../../hooks/useDashboard_Data";
import flatColors from "../Charts/flatColor";
import ChartSkeleton from "../Charts/Skelton";
import { useSelectedProject } from "../../slices/apiDataManager";
-import { formatDate_DayMonth } from "../../utils/dateUtils";
+import { SpinnerLoader } from "../common/Loader";
+
+const formatDate_DayMonth = (dateStr) => moment(dateStr).format("DD MMM YY");
const AttendanceOverview = () => {
const [dayRange, setDayRange] = useState(7);
@@ -22,6 +25,7 @@ const AttendanceOverview = () => {
// Use empty array while loading
const attendanceData = attendanceOverviewData || [];
+ // Prepare data for chart and table
const { tableData, roles, dates } = useMemo(() => {
if (!attendanceData || attendanceData.length === 0) {
return { tableData: [], roles: [], dates: [] };
@@ -49,34 +53,60 @@ const AttendanceOverview = () => {
return { tableData, roles: uniqueRoles, dates: sortedDates };
}, [attendanceData]);
+ // Chart data
const chartSeries = roles.map((role) => ({
name: role,
data: tableData.map((row) => row[role]),
}));
+ // Chart options
const chartOptions = {
chart: {
type: "bar",
- stacked: true,
+ stacked: true, // make false if you want side-by-side bars
height: 400,
toolbar: { show: false },
},
- plotOptions: { bar: { borderRadius: 2, columnWidth: "60%" } },
- xaxis: { categories: tableData.map((row) => row.date) },
- yaxis: {
- show: true,
- axisBorder: { show: true, color: "#78909C" },
- axisTicks: { show: true, color: "#78909C", width: 6 },
+ plotOptions: {
+ bar: {
+ borderRadius: 4,
+ columnWidth: "55%",
+ },
+ },
+ xaxis: {
+ categories: tableData.map((row) => row.date),
+ labels: {
+ rotate: -45,
+ style: { fontSize: "12px" },
+ },
+ },
+ yaxis: {
+ axisBorder: { show: true, color: "#78909C" },
+ axisTicks: { show: true, color: "#78909C" },
+ },
+ legend: {
+ position: "bottom",
+ horizontalAlign: "center",
+ fontSize: "12px",
+ },
+ grid: {
+ borderColor: "#e0e0e0",
+ strokeDashArray: 3,
},
- legend: { position: "bottom" },
fill: { opacity: 1 },
colors: roles.map((_, i) => flatColors[i % flatColors.length]),
+ tooltip: {
+ y: {
+ formatter: (val) => `${val} present`,
+ },
+ },
};
return (
-
+
+ {/* Header */}
-
+
Attendance Overview
Role-wise present count
@@ -84,6 +114,7 @@ const AttendanceOverview = () => {
+ {/* Day range dropdown */}
+ {/* View toggle buttons */}
- {/* Content Section */}
-
- {isLoading && (
+ {/* Content */}
+
+ {/* {isLoading ? (
Loading...
- )}
-
- {!isLoading && (!attendanceData || attendanceData.length === 0) ? (
+ ) : !attendanceData || attendanceData.length === 0 ? (
No data found
+ ) : view === "chart" ? ( */}
+ {isLoading ? (
+
+ ) : error ? (
+
{error}
+ ) : attendanceOverviewData.length === 0 ||
+ attendanceOverviewData.every((item) => item.present === 0) ? (
+
No data found
) : view === "chart" ? (
) : (
@@ -156,7 +192,7 @@ const AttendanceOverview = () => {
Role |
{dates.map((date, idx) => (
- {date}
+ {moment(date, "DD MMM YY").format("DD MMM")}
|
))}
@@ -165,15 +201,13 @@ const AttendanceOverview = () => {
{roles.map((role) => (
- | {role} |
+ {role} |
{tableData.map((row, idx) => {
const value = row[role];
return (
0 ? { backgroundColor: "#e9ecef" } : {}
- }
+ style={value > 0 ? { backgroundColor: "#d5d5d5" } : {}}
>
{value}
|
@@ -190,4 +224,4 @@ const AttendanceOverview = () => {
);
};
-export default AttendanceOverview;
+export default AttendanceOverview;
\ No newline at end of file
diff --git a/src/components/Dashboard/Dashboard.jsx b/src/components/Dashboard/Dashboard.jsx
index c720c960..059c0165 100644
--- a/src/components/Dashboard/Dashboard.jsx
+++ b/src/components/Dashboard/Dashboard.jsx
@@ -59,7 +59,7 @@ const Dashboard = () => {
)}
-
+
{!isAllProjectsSelected && (
diff --git a/src/components/Dashboard/ExpenseAnalysis.jsx b/src/components/Dashboard/ExpenseAnalysis.jsx
index 6bea4db3..630005cc 100644
--- a/src/components/Dashboard/ExpenseAnalysis.jsx
+++ b/src/components/Dashboard/ExpenseAnalysis.jsx
@@ -5,6 +5,7 @@ import { useSelectedProject } from "../../slices/apiDataManager";
import { DateRangePicker1 } from "../common/DateRangePicker";
import { FormProvider, useForm } from "react-hook-form";
import { formatCurrency, localToUtc } from "../../utils/appUtils";
+import { SpinnerLoader } from "../common/Loader";
const ExpenseAnalysis = () => {
const projectId = useSelectedProject();
@@ -54,32 +55,32 @@ const ExpenseAnalysis = () => {
},
},
},
- responsive: [
- {
- breakpoint: 1200,
- options: {
- chart: { width: "100%", height: 350 },
- legend: { position: "bottom" },
- },
- },
- {
- breakpoint: 992,
- options: {
- chart: { width: "100%", height: 300 },
- dataLabels: { style: { fontSize: "11px" } },
- },
- },
- {
- breakpoint: 576,
- options: {
- chart: { width: "100%", height: 250 },
- legend: { fontSize: "10px" },
- plotOptions: {
- pie: { donut: { size: "65%" } },
+ responsive: [
+ {
+ breakpoint: 1200,
+ options: {
+ chart: { width: "100%", height: 350 },
+ legend: { position: "bottom" },
},
},
- },
- ],
+ {
+ breakpoint: 992,
+ options: {
+ chart: { width: "100%", height: 300 },
+ dataLabels: { style: { fontSize: "11px" } },
+ },
+ },
+ {
+ breakpoint: 576,
+ options: {
+ chart: { width: "100%", height: 250 },
+ legend: { fontSize: "10px" },
+ plotOptions: {
+ pie: { donut: { size: "65%" } },
+ },
+ },
+ },
+ ],
};
return (
@@ -98,19 +99,24 @@ const ExpenseAnalysis = () => {
-
+
{isLoading && (
- Loading...
+
)}
{!isLoading && report.length === 0 && (
-
No data found
+
+ No data found
+
)}
{!isLoading && report.length > 0 && (
diff --git a/src/components/Dashboard/ExpenseByProject.jsx b/src/components/Dashboard/ExpenseByProject.jsx
index 7c0e829f..ca1e7191 100644
--- a/src/components/Dashboard/ExpenseByProject.jsx
+++ b/src/components/Dashboard/ExpenseByProject.jsx
@@ -5,6 +5,7 @@ import { useSelector } from "react-redux";
import { useExpenseDataByProject } from "../../hooks/useDashboard_Data";
import { formatCurrency } from "../../utils/appUtils";
import { formatDate_DayMonth } from "../../utils/dateUtils";
+import { SpinnerLoader } from "../common/Loader";
const ExpenseByProject = () => {
const projectId = useSelector((store) => store.localVariables.projectId);
@@ -74,10 +75,10 @@ const ExpenseByProject = () => {
]
return (
-
+
{/* Header */}
-
+
Monthly Expense -
Detailed project expenses
@@ -93,7 +94,7 @@ const ExpenseByProject = () => {
{ExpenseCategoryType.map((cat) => (
- -
+
-
- {/* Chart */}
+ {/* Chart */}
{isLoading ? (
-
Loading chart...
+
+
+
) : !expenseApiData || expenseApiData.length === 0 ? (
-
No data found
+
No data found
) : (
)}
+
diff --git a/src/components/common/Loader.jsx b/src/components/common/Loader.jsx
index 7caaa324..04b5c18e 100644
--- a/src/components/common/Loader.jsx
+++ b/src/components/common/Loader.jsx
@@ -20,13 +20,13 @@ const Loader = () => {
export default Loader;
-export const SpinnerLoader = ()=>{
+export const SpinnerLoader = () => {
return (
-
-
- Loading...
-
-
Loading data... Please wait
-
+
+
+ Loading...
+
+
Loading data...
+
)
}
\ No newline at end of file