Files

175 lines
5.0 KiB
TypeScript
Raw Permalink 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.
"use client";
import { useState } from "react";
import { Area, AreaChart, CartesianGrid, XAxis, YAxis } from "recharts";
import {
Card,
CardContent,
CardDescription,
CardHeader,
CardTitle,
} from "@/components/ui/card";
import {
type ChartConfig,
ChartContainer,
ChartTooltip,
ChartTooltipContent,
} from "@/components/ui/chart";
import { Tabs, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { cn } from "@/lib/utils";
interface ChartCard2Props {
title?: string;
description?: string;
className?: string;
}
const weekdayFormatter = new Intl.DateTimeFormat("fa-IR", {
weekday: "short",
});
const monthFormatter = new Intl.DateTimeFormat("fa-IR", { month: "short" });
const numberFormatter = new Intl.NumberFormat("fa-IR", {
maximumFractionDigits: 0,
});
const compactNumberFormatter = new Intl.NumberFormat("fa-IR", {
notation: "compact",
maximumFractionDigits: 1,
});
type ChartPoint = { day: string; value: number };
const chartData: Record<"7d" | "30d" | "90d", ChartPoint[]> = {
"7d": [
{ day: weekdayFormatter.format(new Date(2025, 0, 6)), value: 186 },
{ day: weekdayFormatter.format(new Date(2025, 0, 7)), value: 205 },
{ day: weekdayFormatter.format(new Date(2025, 0, 8)), value: 237 },
{ day: weekdayFormatter.format(new Date(2025, 0, 9)), value: 223 },
{ day: weekdayFormatter.format(new Date(2025, 0, 10)), value: 249 },
{ day: weekdayFormatter.format(new Date(2025, 0, 11)), value: 214 },
{ day: weekdayFormatter.format(new Date(2025, 0, 12)), value: 231 },
],
"30d": [
{ day: "هفته ۱", value: 1420 },
{ day: "هفته ۲", value: 1650 },
{ day: "هفته ۳", value: 1580 },
{ day: "هفته ۴", value: 1820 },
],
"90d": [
{ day: monthFormatter.format(new Date(2025, 0, 1)), value: 4200 },
{ day: monthFormatter.format(new Date(2025, 1, 1)), value: 4800 },
{ day: monthFormatter.format(new Date(2025, 2, 1)), value: 5100 },
],
};
const periodTabs = [
{ value: "7d", label: "۷ روز" },
{ value: "30d", label: "۳۰ روز" },
{ value: "90d", label: "۹۰ روز" },
] as const;
const chartConfig = {
value: {
label: "بازدیدکنندگان",
color: "var(--chart-1)",
},
} satisfies ChartConfig;
const ChartCard2 = ({
title = "ترافیک وب‌سایت",
description = "بازدیدکنندگان یکتا در بازه زمانی",
className,
}: ChartCard2Props) => {
const [period, setPeriod] = useState<"7d" | "30d" | "90d">("7d");
return (
<Card
dir="rtl"
lang="fa"
className={cn("w-full max-w-2xl text-start", className)}
>
<CardHeader className="flex flex-row items-center justify-between space-y-0">
<div>
<CardTitle>{title}</CardTitle>
<CardDescription>{description}</CardDescription>
</div>
<Tabs
value={period}
onValueChange={(v) => setPeriod(v as "7d" | "30d" | "90d")}
>
<TabsList>
{periodTabs.map((tab) => (
<TabsTrigger key={tab.value} value={tab.value}>
{tab.label}
</TabsTrigger>
))}
</TabsList>
</Tabs>
</CardHeader>
<CardContent>
<ChartContainer config={chartConfig} className="h-64 w-full">
<AreaChart
data={chartData[period]}
margin={{ top: 10, right: 10, left: 0, bottom: 0 }}
>
<defs>
<linearGradient id="chartGradient2" x1="0" y1="0" x2="0" y2="1">
<stop
offset="0%"
stopColor="var(--color-value)"
stopOpacity={0.3}
/>
<stop
offset="100%"
stopColor="var(--color-value)"
stopOpacity={0}
/>
</linearGradient>
</defs>
<CartesianGrid strokeDasharray="3 3" vertical={false} />
<XAxis
dataKey="day"
axisLine={false}
tickLine={false}
tickMargin={8}
fontSize={12}
/>
<YAxis
axisLine={false}
tickLine={false}
tickMargin={8}
fontSize={10}
width={40}
tickFormatter={(value) =>
compactNumberFormatter.format(Number(value))
}
/>
<ChartTooltip
content={
<ChartTooltipContent
formatter={(value) =>
numberFormatter.format(Number(value))
}
/>
}
cursor={{ stroke: "var(--border)", strokeDasharray: "4 4" }}
/>
<Area
type="monotone"
dataKey="value"
stroke="var(--color-value)"
strokeWidth={2}
fill="url(#chartGradient2)"
/>
</AreaChart>
</ChartContainer>
</CardContent>
</Card>
);
};
export { ChartCard2 };