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