fixed attendoverview chart
This commit is contained in:
parent
c1b4fc277a
commit
77a516c278
@ -1,11 +1,13 @@
|
||||
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";
|
||||
|
||||
const formatDate_DayMonth = (dateStr) => moment(dateStr).format("DD MMM YY");
|
||||
|
||||
const AttendanceOverview = () => {
|
||||
const [dayRange, setDayRange] = useState(7);
|
||||
@ -22,6 +24,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,32 +52,58 @@ 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 (
|
||||
<div className="bg-white p-4 rounded shadow d-flex flex-column position-relative">
|
||||
{/* Header */}
|
||||
<div className="row mb-3 align-items-center">
|
||||
<div className="col-md-6 text-start">
|
||||
<p className="mb-1 fs-6 fs-md-5 fw-medium">Attendance Overview</p>
|
||||
@ -84,6 +113,7 @@ const AttendanceOverview = () => {
|
||||
</div>
|
||||
|
||||
<div className="col-md-6 d-flex flex-column align-items-end gap-2">
|
||||
{/* Day range dropdown */}
|
||||
<select
|
||||
className="form-select form-select-sm w-auto"
|
||||
value={dayRange}
|
||||
@ -94,11 +124,11 @@ const AttendanceOverview = () => {
|
||||
<option value={30}>Last 30 Days</option>
|
||||
</select>
|
||||
|
||||
{/* View toggle buttons */}
|
||||
<div className="d-flex gap-2 justify-content-end">
|
||||
<button
|
||||
className={`btn btn-sm p-1 ${
|
||||
view === "chart" ? "btn-primary" : "btn-outline-primary"
|
||||
}`}
|
||||
className={`btn btn-sm p-1 ${view === "chart" ? "btn-primary" : "btn-outline-primary"
|
||||
}`}
|
||||
onClick={() => setView("chart")}
|
||||
title="Chart View"
|
||||
>
|
||||
@ -106,9 +136,8 @@ const AttendanceOverview = () => {
|
||||
</button>
|
||||
|
||||
<button
|
||||
className={`btn btn-sm p-1 ${
|
||||
view === "table" ? "btn-primary" : "btn-outline-primary"
|
||||
}`}
|
||||
className={`btn btn-sm p-1 ${view === "table" ? "btn-primary" : "btn-outline-primary"
|
||||
}`}
|
||||
onClick={() => setView("table")}
|
||||
title="Table View"
|
||||
>
|
||||
@ -118,15 +147,13 @@ const AttendanceOverview = () => {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Content Section */}
|
||||
{/* Content */}
|
||||
<div className="flex-grow-1 d-flex align-items-center justify-content-center position-relative">
|
||||
{isLoading && (
|
||||
{isLoading ? (
|
||||
<div className="position-absolute top-0 start-0 w-100 h-100 d-flex align-items-center justify-content-center bg-white bg-opacity-50">
|
||||
<span>Loading...</span>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{!isLoading && (!attendanceData || attendanceData.length === 0) ? (
|
||||
) : !attendanceData || attendanceData.length === 0 ? (
|
||||
<div
|
||||
className="text-muted fw-semibold d-flex align-items-center justify-content-center"
|
||||
style={{ minHeight: "250px" }}
|
||||
@ -139,7 +166,7 @@ const AttendanceOverview = () => {
|
||||
options={chartOptions}
|
||||
series={chartSeries}
|
||||
type="bar"
|
||||
height={300}
|
||||
height={350}
|
||||
/>
|
||||
</div>
|
||||
) : (
|
||||
@ -156,7 +183,7 @@ const AttendanceOverview = () => {
|
||||
<th style={{ background: "#f8f9fa" }}>Role</th>
|
||||
{dates.map((date, idx) => (
|
||||
<th key={idx} style={{ background: "#f8f9fa" }}>
|
||||
{date}
|
||||
{moment(date, "DD MMM YY").format("DD MMM")}
|
||||
</th>
|
||||
))}
|
||||
</tr>
|
||||
@ -165,15 +192,13 @@ const AttendanceOverview = () => {
|
||||
<tbody>
|
||||
{roles.map((role) => (
|
||||
<tr key={role}>
|
||||
<td className="fw-medium text-start table-cell">{role}</td>
|
||||
<td className="fw-medium text-start">{role}</td>
|
||||
{tableData.map((row, idx) => {
|
||||
const value = row[role];
|
||||
return (
|
||||
<td
|
||||
key={idx}
|
||||
style={
|
||||
value > 0 ? { backgroundColor: "#e9ecef" } : {}
|
||||
}
|
||||
style={value > 0 ? { backgroundColor: "#d5d5d5" } : {}}
|
||||
>
|
||||
{value}
|
||||
</td>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user