Initial commit for new panel
This commit is contained in:
@@ -0,0 +1,97 @@
|
||||
"use client";
|
||||
|
||||
import { compactFormat } from "@/lib/format-number";
|
||||
import type { ApexOptions } from "apexcharts";
|
||||
import dynamic from "next/dynamic";
|
||||
|
||||
type PropsType = {
|
||||
data: { name: string; amount: number }[];
|
||||
};
|
||||
|
||||
const Chart = dynamic(() => import("react-apexcharts"), {
|
||||
ssr: false,
|
||||
});
|
||||
|
||||
export function DonutChart({ data }: PropsType) {
|
||||
const chartOptions: ApexOptions = {
|
||||
chart: {
|
||||
type: "donut",
|
||||
fontFamily: "inherit",
|
||||
},
|
||||
colors: ["#5750F1", "#5475E5", "#8099EC", "#ADBCF2"],
|
||||
labels: data.map((item) => item.name),
|
||||
legend: {
|
||||
show: true,
|
||||
position: "bottom",
|
||||
itemMargin: {
|
||||
horizontal: 10,
|
||||
vertical: 5,
|
||||
},
|
||||
formatter: (legendName, opts) => {
|
||||
const { seriesPercent } = opts.w.globals;
|
||||
return `${legendName}: ${seriesPercent[opts.seriesIndex]}%`;
|
||||
},
|
||||
},
|
||||
plotOptions: {
|
||||
pie: {
|
||||
donut: {
|
||||
size: "80%",
|
||||
background: "transparent",
|
||||
labels: {
|
||||
show: true,
|
||||
total: {
|
||||
show: true,
|
||||
showAlways: true,
|
||||
label: "Visitors",
|
||||
fontSize: "16px",
|
||||
fontWeight: "400",
|
||||
},
|
||||
value: {
|
||||
show: true,
|
||||
fontSize: "28px",
|
||||
fontWeight: "bold",
|
||||
formatter: (val) => compactFormat(+val),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
dataLabels: {
|
||||
enabled: false,
|
||||
},
|
||||
responsive: [
|
||||
{
|
||||
breakpoint: 2600,
|
||||
options: {
|
||||
chart: {
|
||||
width: 415,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
breakpoint: 640,
|
||||
options: {
|
||||
chart: {
|
||||
width: "100%",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
breakpoint: 370,
|
||||
options: {
|
||||
chart: {
|
||||
width: 260,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
return (
|
||||
<Chart
|
||||
options={chartOptions}
|
||||
series={data.map((item) => item.amount)}
|
||||
type="donut"
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
import { PeriodPicker } from "@/components/period-picker";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { getDevicesUsedData } from "@/services/charts.services";
|
||||
import { DonutChart } from "./chart";
|
||||
|
||||
type PropsType = {
|
||||
timeFrame?: string;
|
||||
className?: string;
|
||||
};
|
||||
|
||||
export async function UsedDevices({
|
||||
timeFrame = "monthly",
|
||||
className,
|
||||
}: PropsType) {
|
||||
const data = await getDevicesUsedData(timeFrame);
|
||||
|
||||
return (
|
||||
<div
|
||||
className={cn(
|
||||
"grid grid-cols-1 grid-rows-[auto_1fr] gap-9 rounded-[10px] bg-white p-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">
|
||||
Used Devices
|
||||
</h2>
|
||||
|
||||
<PeriodPicker defaultValue={timeFrame} sectionKey="used_devices" />
|
||||
</div>
|
||||
|
||||
<div className="grid place-items-center">
|
||||
<DonutChart data={data} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user