Files

157 lines
4.4 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 { TrendingUp } from "lucide-react";
import { Area, AreaChart, CartesianGrid, XAxis, YAxis } from "recharts";
import {
Card,
CardContent,
CardDescription,
CardFooter,
CardHeader,
CardTitle,
} from "@/components/ui/card";
import {
type ChartConfig,
ChartContainer,
ChartTooltip,
ChartTooltipContent,
} from "@/components/ui/chart";
import { cn } from "@/lib/utils";
interface ChartCard7Props {
title?: string;
description?: string;
totalValue?: string;
changePercent?: number;
changeLabel?: string;
className?: string;
}
const monthLabel = (monthIndex: number) =>
new Intl.DateTimeFormat("fa-IR", { month: "short" }).format(
new Date(2025, monthIndex, 1),
);
const chartData = [
{ month: monthLabel(0), value: 186 },
{ month: monthLabel(1), value: 305 },
{ month: monthLabel(2), value: 237 },
{ month: monthLabel(3), value: 273 },
{ month: monthLabel(4), value: 209 },
{ month: monthLabel(5), value: 314 },
];
const defaultTotalRevenue = chartData.reduce((sum, item) => sum + item.value, 0);
const periodRangeFormatter = new Intl.DateTimeFormat("fa-IR", {
month: "long",
year: "numeric",
});
const periodRangeStart = new Date(2025, 0, 1);
const periodRangeEnd = new Date(2025, 5, 30);
const defaultPeriodDescription =
typeof periodRangeFormatter.formatRange === "function"
? periodRangeFormatter.formatRange(periodRangeStart, periodRangeEnd)
: `${periodRangeFormatter.format(periodRangeStart)} – ${periodRangeFormatter.format(periodRangeEnd)}`;
const currencyFormatter = new Intl.NumberFormat("fa-IR", {
style: "currency",
currency: "IRR",
minimumFractionDigits: 0,
maximumFractionDigits: 0,
});
const percentFormatter = new Intl.NumberFormat("fa-IR", {
maximumFractionDigits: 1,
});
const chartConfig = {
value: {
label: "درآمد",
color: "var(--chart-1)",
},
} satisfies ChartConfig;
const ChartCard7 = ({
title = "مجموع درآمد",
description = defaultPeriodDescription,
totalValue = currencyFormatter.format(defaultTotalRevenue),
changePercent = 12.5,
changeLabel = "رشد در این بازه",
className,
}: ChartCard7Props) => {
return (
<Card
dir="rtl"
lang="fa"
className={cn("w-full max-w-2xl text-start", className)}
>
<CardHeader>
<CardTitle>{title}</CardTitle>
<CardDescription>{description}</CardDescription>
</CardHeader>
<CardContent>
<ChartContainer config={chartConfig} className="h-48 w-full">
<AreaChart
data={chartData}
margin={{ top: 10, right: 10, left: 0, bottom: 0 }}
>
<defs>
<linearGradient id="chartGradient7" 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="month"
axisLine={false}
tickLine={false}
tickMargin={8}
fontSize={12}
/>
<YAxis hide />
<ChartTooltip
content={
<ChartTooltipContent
formatter={(value) =>
currencyFormatter.format(Number(value))
}
/>
}
cursor={{ stroke: "var(--border)", strokeDasharray: "4 4" }}
/>
<Area
type="monotone"
dataKey="value"
stroke="var(--color-value)"
strokeWidth={2}
fill="url(#chartGradient7)"
/>
</AreaChart>
</ChartContainer>
</CardContent>
<CardFooter className="flex items-center gap-2 text-sm">
<div className="flex items-center gap-1 font-medium">
<TrendingUp className="size-4 text-green-500" aria-hidden="true" />
<span className="text-green-500 tabular-nums">
+{percentFormatter.format(changePercent)}٪
</span>
</div>
<span className="text-muted-foreground">{changeLabel}</span>
</CardFooter>
</Card>
);
};
export { ChartCard7 };