marco.pms.web/src/components/Dashboard/CollectionOverview.jsx

346 lines
8.5 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import React from "react";
import Chart from "react-apexcharts";
import { useGetCollectionOverview } from "../../hooks/useDashboard_Data";
import { formatFigure } from "../../utils/appUtils";
const CollectionOverview = ({ data, isLoading }) => {
const borderColor = "#ddd";
const labelColor = "#6c757d";
// Extract bucket values
const labels = ["030 Days", "3060 Days", "6090 Days", "90+ Days"];
const amounts = [
data.bucket0To30Amount,
data.bucket30To60Amount,
data.bucket60To90Amount,
data.bucket90PlusAmount,
];
// Colors (Zoho-style distributed)
const colors = ["#7367F0", "#00cfe8", "#28c76f", "#ea5455"];
const options = {
chart: {
type: "bar",
height: 260,
toolbar: { show: false },
},
plotOptions: {
bar: {
horizontal: true,
barHeight: "65%",
distributed: true,
borderRadius: 8,
startingShape: "rounded",
},
},
colors: colors,
grid: {
borderColor: borderColor,
strokeDashArray: 6,
padding: { top: -10, bottom: -10 },
xaxis: { lines: { show: true } },
},
dataLabels: {
enabled: true,
formatter: (_, opts) => labels[opts.dataPointIndex],
style: {
colors: ["#fff"],
fontSize: "13px",
fontWeight: 500,
},
offsetX: 0,
},
xaxis: {
categories: amounts.map((a) => a),
labels: {
style: { colors: labelColor, fontSize: "12px" },
formatter: (val) => `${val.toLocaleString()}`,
},
},
yaxis: {
labels: {
style: {
colors: labelColor,
fontSize: "13px",
},
formatter: () => "", // hide duplicate labels
},
},
tooltip: {
custom: ({ series, seriesIndex, dataPointIndex }) => {
return `
<div class="px-2 py-1">
<strong>${labels[dataPointIndex]}</strong><br>
${series[seriesIndex][dataPointIndex].toLocaleString()}
</div>
`;
},
},
legend: { show: false },
};
const series = [
{
name: "Amount",
data: amounts,
},
];
return (
<div>
<Chart options={options} series={series} type="bar" height={260} />
</div>
);
};
export default CollectionOverview;
export const TopicBarChart = ({ data,isLoading }) => {
const data1 = {
totalDueAmount: 213590,
totalCollectedAmount: 5000,
totalValue: 218590,
pendingPercentage: 97.71,
collectedPercentage: 2.29,
bucket0To30Invoices: 10,
bucket30To60Invoices: 4,
bucket60To90Invoices: 2,
bucket90PlusInvoices: 1,
bucket0To30Amount: 2130,
bucket30To60Amount: 2003,
bucket60To90Amount: 4500,
bucket90PlusAmount: 8800,
topClientBalance: 55300,
topClient: {
id: "4e3a6d31-c640-40f7-8d67-6c109fcdb9ea",
name: "Marco Secure Solutions Ltd.",
email: "admin@marcoaiot.com",
contactPerson: "Admin",
address:
"2nd Floor, Fullora Building, Tejas CHS, behind Kothrud Stand, Tejas Society, Dahanukar Colony, Kothrud, Pune, Maharashtra 411038",
gstNumber: null,
contactNumber: "123456789",
sprid: 5400,
},
};
const borderColor = "#ddd";
const labelColor = "#6c757d";
// COLORS
const config = {
colors: {
b0: "#7367F0",
b30: "#00cfe8",
b60: "#28c76f",
b90: "#ea5455",
},
};
// NEW LABELS (BUCKETS)
const chartLabels = ["030 Days", "3060 Days", "6090 Days", "90+ Days"];
// NEW VALUES (BUCKET AMOUNT)
const chartValues = [
data.bucket0To30Amount,
data.bucket30To60Amount,
data.bucket60To90Amount,
data.bucket90PlusAmount,
];
const options = {
chart: {
height: 300,
type: "bar",
toolbar: { show: false },
},
plotOptions: {
bar: {
horizontal: true,
barHeight: "40%",
distributed: true,
startingShape: "rounded",
borderRadius: 7,
},
},
grid: {
strokeDashArray: 10,
borderColor,
xaxis: { lines: { show: true } },
yaxis: { lines: { show: false } },
padding: { top: -35, bottom: -12 },
},
colors: [
config.colors.b0,
config.colors.b30,
config.colors.b60,
config.colors.b90,
],
labels: chartLabels,
fill: { opacity: 1 },
dataLabels: {
enabled: true,
style: {
colors: ["#fff"],
fontWeight: 400,
fontSize: "13px",
fontFamily: "Public Sans",
},
formatter: (_, opts) => chartLabels[opts.dataPointIndex],
},
xaxis: {
categories: chartValues.map((x) => formatFigure(x, { type: "currency" })),
axisBorder: { show: false },
axisTicks: { show: false },
labels: {
style: {
colors: labelColor,
fontFamily: "Public Sans",
fontSize: "13px",
},
formatter: (val) => `${Number(val).toLocaleString()}`,
},
},
yaxis: {
labels: {
style: {
colors: labelColor,
fontFamily: "Public Sans",
fontSize: "13px",
},
},
},
tooltip: {
enabled: true,
custom: ({ series, seriesIndex, dataPointIndex }) => {
return `
<div class="px-3 py-2">
<span>₹${series[seriesIndex][
dataPointIndex
].toLocaleString()}</span>
</div>
`;
},
},
legend: { show: false },
};
const series = [
{
data: chartValues,
},
];
return (
<div className="row p-2">
<div className="col-md-8">
<div class="card-header d-flex align-items-center justify-content-between">
<h5 class="card-title m-0 me-2">Collection Overview</h5>
</div>
<div className="w-100 d-flex align-items-center text-start px-6">
<p className="text-secondary fs-6 m-0">Due Amount</p>
<span className="ms-2 fs-5">
{formatFigure(data.totalDueAmount, { type: "currency" })}
</span>
<p className="text-secondary fs-6 m-0 ms-1">Collected Amount</p>
<span className="ms-2 fs-5">
{formatFigure(data.totalCollectedAmount, { type: "currency" })}
</span>
</div>
<Chart options={options} series={series} type="bar" height={300} />
</div>
<div className="col-md-4 d-flex flex-column gap-2">
<div class="card-header d-flex align-items-end justify-content-between"></div>
<div className="p-1 m-1 text-start">
{/* <p className="fs-5 fs-5">Top Client</p>
<small> {data.topClient.name}</small> */}
</div>
{/* 030 Days */}
<div
className="p-1 rounded-3 text-start mx-1"
style={{
background: "var(--bs-primary-bg-subtle)",
borderLeft: "4px solid var(--bs-primary)",
minWidth: "170px",
}}
>
<h5 className="fw-bold mb-0">
{formatFigure(data.bucket0To30Amount, { type: "currency" })}
</h5>
<p className="text-secondary mb-0 small">030 Days</p>
</div>
{/* 3060 Days */}
<div
className="p-1 rounded-3 text-start mx-1"
style={{
background: "var(--bs-info-bg-subtle)",
borderLeft: "4px solid var(--bs-info)",
minWidth: "170px",
}}
>
<h5 className="fw-bold mb-0">
{formatFigure(data.bucket30To60Amount, { type: "currency" })}
</h5>
<p className="text-secondary mb-0 small">3060 Days</p>
</div>
{/* 6090 Days */}
<div
className="p-1 rounded-3 text-start mx-1"
style={{
background: "var(--bs-warning-bg-subtle)",
borderLeft: "4px solid var(--bs-warning)",
minWidth: "170px",
}}
>
<h5 className="fw-bold mb-0">
{formatFigure(data.bucket60To90Amount, { type: "currency" })}
</h5>
<p className="text-secondary mb-0 small">6090 Days</p>
</div>
{/* 90+ Days */}
<div
className="p-1 rounded-3 text-start mx-1"
style={{
background: "var(--bs-danger-bg-subtle)",
borderLeft: "4px solid var(--bs-danger)",
minWidth: "170px",
}}
>
<h5 className="fw-bold mb-0">
{formatFigure(data.bucket90PlusAmount, { type: "currency" })}
</h5>
<p className="text-secondary mb-0 small">90+ Days</p>
</div>
</div>
</div>
);
};