web-humas-fe/components/main/dashboard/chart/pie-chart-browser.tsx

198 lines
6.0 KiB
TypeScript
Raw Normal View History

2025-07-02 10:20:43 +00:00
"use client";
const dummy = [
{ name: "Chrome", value: 42 },
{ name: "Firefox", value: 23 },
{ name: "Edge", value: 15 },
{ name: "Safari", value: 37 },
{ name: "Opera", value: 8 },
{ name: "Brave", value: 29 },
];
interface BrowserVisitor {
browserName: string;
totalVisitor: number;
}
import { getStatisticVisitorsBrowser } from "@/services/article";
2025-07-02 10:20:43 +00:00
import {
convertDateFormatNoTime,
convertDateFormatNoTimeV2,
} from "@/utils/global";
import {
Calendar,
Popover,
PopoverContent,
PopoverTrigger,
} from "@heroui/react";
import { parseDate } from "@internationalized/date";
import { Fragment, useEffect, useState } from "react";
import ReactApexChart from "react-apexcharts";
export default function PieChartLoginBrowser() {
const [series, setSeries] = useState<number[]>([]);
const [labels, setLabels] = useState<string[]>([]);
const [data, setData] = useState<BrowserVisitor[]>([]);
2025-07-02 10:20:43 +00:00
const [total, setTotal] = useState(0);
const [selectedLabel, setSelectedLabel] = useState<string>("");
2025-08-29 11:39:32 +00:00
const [visitorBrowserDate, setVisitorBrowserDate] = useState<any>({
2025-07-02 10:20:43 +00:00
startDate: parseDate(
convertDateFormatNoTimeV2(
new Date(new Date().setDate(new Date().getDate() - 7))
)
),
endDate: parseDate(convertDateFormatNoTimeV2(new Date())),
});
useEffect(() => {
fetchData();
}, [visitorBrowserDate.startDate, visitorBrowserDate.endDate]);
2025-07-02 10:20:43 +00:00
const fetchData = async () => {
const getDate = (data: any) => {
return `${data.year}-${data.month < 10 ? `0${data.month}` : data.month}-${
data.day < 10 ? `0${data.day}` : data.day
}`;
};
const res = await getStatisticVisitorsBrowser(
getDate(visitorBrowserDate.startDate),
getDate(visitorBrowserDate.endDate)
);
const data: BrowserVisitor[] = res?.data?.data;
2025-07-02 10:20:43 +00:00
setData(data);
const label = data.map((a) => a.browserName);
const seriesNow = data.map((a) => a.totalVisitor);
2025-07-02 10:20:43 +00:00
const totalNow = seriesNow.reduce((a, c) => a + c, 0);
setTotal(totalNow);
setLabels(label);
setSeries(seriesNow);
};
const getPersentage = (value: number) => {
const count = ((value / total) * 100).toFixed(1);
return `${count}%`;
};
return (
<div className="flex flex-col lg:flex-row w-full mt-5 gap-4">
<div className="w-full lg:w-1/2 border-1 rounded-lg p-4">
2025-07-02 10:20:43 +00:00
<p className="font-bold">Browser Statistics</p>
<ReactApexChart
options={{
chart: {
width: 600,
type: "pie" as const,
events: {
dataPointSelection: function (
event: any,
chartContext: any,
config: any
) {
const selectedIndex = config.dataPointIndex;
const selected = labels[selectedIndex];
setSelectedLabel(selected);
},
},
},
labels: labels,
responsive: [
{
breakpoint: 480,
options: {
chart: {
width: 200,
},
legend: {
position: "bottom",
},
},
},
],
}}
series={series}
type="pie"
width={600}
/>
</div>
<div className="w-full lg:w-1/2 flex flex-col border-1 rounded-lg p-4">
2025-07-02 10:20:43 +00:00
<div className="flex flex-row gap-1 justify-center">
<p> Browser Statistics from</p>
<Popover
placement="bottom"
classNames={{ content: ["!bg-transparent", "p-0"] }}
>
<PopoverTrigger>
<a className="cursor-pointer underline">
{convertDateFormatNoTime(visitorBrowserDate.startDate)}
2025-07-02 10:20:43 +00:00
</a>
</PopoverTrigger>
<PopoverContent className="bg-transparent">
<Calendar
value={visitorBrowserDate.startDate}
2025-07-02 10:20:43 +00:00
onChange={(e) =>
setVisitorBrowserDate({
2025-07-02 10:20:43 +00:00
startDate: e,
endDate: visitorBrowserDate.endDate,
2025-07-02 10:20:43 +00:00
})
}
maxValue={visitorBrowserDate.endDate}
2025-07-02 10:20:43 +00:00
/>
</PopoverContent>
</Popover>
<p>to</p>
<Popover
placement="bottom"
classNames={{ content: ["!bg-transparent", "p-0"] }}
>
<PopoverTrigger>
<a className="cursor-pointer underline">
{convertDateFormatNoTime(visitorBrowserDate.endDate)}
2025-07-02 10:20:43 +00:00
</a>
</PopoverTrigger>
<PopoverContent className="bg-transparent">
<Calendar
value={visitorBrowserDate.endDate}
2025-07-02 10:20:43 +00:00
onChange={(e) =>
setVisitorBrowserDate({
startDate: visitorBrowserDate.startDate,
2025-07-02 10:20:43 +00:00
endDate: e,
})
}
minValue={visitorBrowserDate.startDate}
2025-07-02 10:20:43 +00:00
/>
</PopoverContent>
</Popover>
</div>
<div className="flex flex-col mt-5 overflow-auto gap-3 p-4">
<div className="grid grid-cols-3 p-4">
<p>Browser</p>
<p>Visitors</p>
<p>Persentage</p>
</div>
{data &&
data?.map((list, index) => (
2025-07-02 10:20:43 +00:00
<div
key={list.browserName}
2025-07-02 10:20:43 +00:00
className={`grid grid-cols-3 p-4 ${
selectedLabel === list.browserName
2025-07-02 10:20:43 +00:00
? "bg-slate-600 text-white"
: index % 2 == 0
? "bg-gray-200"
: "bg-white"
}`}
>
<p className="font-semibold">{list.browserName}</p>
<p>{list.totalVisitor}</p>
<p>{getPersentage(list.totalVisitor)}</p>
2025-07-02 10:20:43 +00:00
</div>
))}
</div>
</div>
</div>
);
}