Initial commit for new panel

This commit is contained in:
AmirReza Jamali
2025-09-09 11:20:26 +03:30
commit 1d4ccb3575
343 changed files with 20031 additions and 0 deletions
@@ -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>
);
}