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

120 lines
3.5 KiB
TypeScript

"use client";
import {
Card,
CardContent,
CardDescription,
CardHeader,
CardTitle,
} from "@/components/ui/card";
import { cn } from "@/lib/utils";
interface FunnelStep {
label: string;
value: number;
color?: string;
}
interface ChartCard21Props {
title?: string;
description?: string;
data?: FunnelStep[];
className?: string;
}
const numberFormatter = new Intl.NumberFormat("fa-IR", {
maximumFractionDigits: 0,
});
const oneDecimalFormatter = new Intl.NumberFormat("fa-IR", {
maximumFractionDigits: 1,
minimumFractionDigits: 1,
});
const defaultData: FunnelStep[] = [
{ label: "بازدیدکنندگان", value: 10000 },
{ label: "سرنخ‌ها", value: 6500 },
{ label: "واجد شرایط", value: 3200 },
{ label: "پیشنهادها", value: 1800 },
{ label: "بسته‌شده", value: 950 },
];
const ChartCard21 = ({
title = "قیف فروش",
description = "نرخ تبدیل در مراحل قیف",
data = defaultData,
className,
}: ChartCard21Props) => {
const maxValue = Math.max(...data.map((d) => d.value));
const colors = [
"ارزش افزوده(--chart-1)",
"ارزش افزوده(--chart-2)",
"ارزش افزوده(--chart-3)",
"ارزش افزوده(--chart-4)",
"ارزش افزوده(--chart-5)",
];
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>
<div className="space-y-3">
{data.map((step, index) => {
const widthPercent = (step.value / maxValue) * 100;
const conversionRate =
index > 0
? (step.value / data[index - 1].value) * 100
: null;
return (
<div key={step.label} className="space-y-1">
<div className="flex items-center justify-between text-sm">
<span className="font-medium">{step.label}</span>
<div className="flex items-center gap-2 tabular-nums">
<span className="text-muted-foreground">
{numberFormatter.format(step.value)}
</span>
{conversionRate !== null && (
<span className="text-xs text-muted-foreground">
({oneDecimalFormatter.format(conversionRate)}٪)
</span>
)}
</div>
</div>
<div className="h-8 w-full rounded-sm bg-muted">
<div
className="flex h-full items-center justify-center rounded-sm transition-all duration-500"
style={{
width: `${widthPercent}%`,
backgroundColor:
step.color || colors[index % colors.length],
}}
>
{widthPercent > 15 && (
<span className="text-xs font-medium text-white tabular-nums">
{numberFormatter.format(
Math.round((step.value / maxValue) * 100),
)}
٪
</span>
)}
</div>
</div>
</div>
);
})}
</div>
</CardContent>
</Card>
);
};
export { ChartCard21 };