Files
reui-blocks/blocks/chart-card2.tsx
T

175 lines
5.0 KiB
TypeScript
Raw Normal View History

"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 };