Initial commit for new panel
This commit is contained in:
@@ -0,0 +1,107 @@
|
||||
"use client";
|
||||
|
||||
import { useIsMobile } from "@/hooks/use-mobile";
|
||||
import type { ApexOptions } from "apexcharts";
|
||||
import dynamic from "next/dynamic";
|
||||
|
||||
type PropsType = {
|
||||
data: {
|
||||
received: { x: unknown; y: number }[];
|
||||
due: { x: unknown; y: number }[];
|
||||
};
|
||||
};
|
||||
|
||||
const Chart = dynamic(() => import("react-apexcharts"), {
|
||||
ssr: false,
|
||||
});
|
||||
|
||||
export function PaymentsOverviewChart({ data }: PropsType) {
|
||||
const isMobile = useIsMobile();
|
||||
|
||||
const options: ApexOptions = {
|
||||
legend: {
|
||||
show: false,
|
||||
},
|
||||
colors: ["#5750F1", "#0ABEF9"],
|
||||
chart: {
|
||||
height: 310,
|
||||
type: "area",
|
||||
toolbar: {
|
||||
show: false,
|
||||
},
|
||||
fontFamily: "inherit",
|
||||
},
|
||||
fill: {
|
||||
gradient: {
|
||||
opacityFrom: 0.55,
|
||||
opacityTo: 0,
|
||||
},
|
||||
},
|
||||
responsive: [
|
||||
{
|
||||
breakpoint: 1024,
|
||||
options: {
|
||||
chart: {
|
||||
height: 300,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
breakpoint: 1366,
|
||||
options: {
|
||||
chart: {
|
||||
height: 320,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
stroke: {
|
||||
curve: "smooth",
|
||||
width: isMobile ? 2 : 3,
|
||||
},
|
||||
grid: {
|
||||
strokeDashArray: 5,
|
||||
yaxis: {
|
||||
lines: {
|
||||
show: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
dataLabels: {
|
||||
enabled: false,
|
||||
},
|
||||
tooltip: {
|
||||
marker: {
|
||||
show: true,
|
||||
},
|
||||
},
|
||||
xaxis: {
|
||||
axisBorder: {
|
||||
show: false,
|
||||
},
|
||||
axisTicks: {
|
||||
show: false,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="-ml-4 -mr-5 h-[310px]">
|
||||
<Chart
|
||||
options={options}
|
||||
series={[
|
||||
{
|
||||
name: "Received",
|
||||
data: data.received,
|
||||
},
|
||||
{
|
||||
name: "Due",
|
||||
data: data.due,
|
||||
},
|
||||
]}
|
||||
type="area"
|
||||
height={310}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
import { PeriodPicker } from "@/components/period-picker";
|
||||
import { standardFormat } from "@/lib/format-number";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { getPaymentsOverviewData } from "@/services/charts.services";
|
||||
import { PaymentsOverviewChart } from "./chart";
|
||||
|
||||
type PropsType = {
|
||||
timeFrame?: string;
|
||||
className?: string;
|
||||
};
|
||||
|
||||
export async function PaymentsOverview({
|
||||
timeFrame = "monthly",
|
||||
className,
|
||||
}: PropsType) {
|
||||
const data = await getPaymentsOverviewData(timeFrame);
|
||||
|
||||
return (
|
||||
<div
|
||||
className={cn(
|
||||
"grid gap-2 rounded-[10px] bg-white px-7.5 pb-6 pt-7.5 shadow-1 dark:bg-gray-dark dark:shadow-card",
|
||||
className,
|
||||
)}
|
||||
>
|
||||
<div className="flex flex-wrap items-center justify-between gap-4">
|
||||
<h2 className="text-body-2xlg font-bold text-dark dark:text-white">
|
||||
Payments Overview
|
||||
</h2>
|
||||
|
||||
<PeriodPicker defaultValue={timeFrame} sectionKey="payments_overview" />
|
||||
</div>
|
||||
|
||||
<PaymentsOverviewChart data={data} />
|
||||
|
||||
<dl className="grid divide-stroke text-center dark:divide-dark-3 sm:grid-cols-2 sm:divide-x [&>div]:flex [&>div]:flex-col-reverse [&>div]:gap-1">
|
||||
<div className="dark:border-dark-3 max-sm:mb-3 max-sm:border-b max-sm:pb-3">
|
||||
<dt className="text-xl font-bold text-dark dark:text-white">
|
||||
${standardFormat(data.received.reduce((acc, { y }) => acc + y, 0))}
|
||||
</dt>
|
||||
<dd className="font-medium dark:text-dark-6">Received Amount</dd>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<dt className="text-xl font-bold text-dark dark:text-white">
|
||||
${standardFormat(data.due.reduce((acc, { y }) => acc + y, 0))}
|
||||
</dt>
|
||||
<dd className="font-medium dark:text-dark-6">Due Amount</dd>
|
||||
</div>
|
||||
</dl>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user