Files
reui-blocks/blocks/leaderboard3.tsx
T

114 lines
3.2 KiB
TypeScript

import { Minus, TrendingDown, TrendingUp } from "lucide-react";
import {
Card,
CardContent,
CardDescription,
CardHeader,
CardTitle,
} from "@/components/ui/card";
import { cn } from "@/lib/utils";
const formatNumber = (value: number) => value.toLocaleString("fa-IR");
const formatChangeAmount = (value: number) =>
new Intl.NumberFormat("fa-IR", {
signDisplay: "exceptZero",
}).format(value);
interface LeaderboardItem {
name: string;
value: string;
change: "up" | "down" | "same";
changeAmount?: string;
}
interface Leaderboard3Props {
title?: string;
description?: string;
items?: LeaderboardItem[];
className?: string;
}
const defaultItems: LeaderboardItem[] = [
{
name: "SEO و محتوای ارگانیک",
value: formatNumber(12450),
change: "up",
changeAmount: formatChangeAmount(2340),
},
{
name: "ورود مستقیم",
value: formatNumber(8230),
change: "up",
changeAmount: formatChangeAmount(890),
},
{
name: "شبکه‌های اجتماعی B2B",
value: formatNumber(5120),
change: "down",
changeAmount: formatChangeAmount(-320),
},
{
name: "ارجاع همکاران",
value: formatNumber(3890),
change: "same",
},
{
name: "ایمیل بازاریابی",
value: formatNumber(2150),
change: "up",
changeAmount: formatChangeAmount(180),
},
];
const Leaderboard3 = ({
title = "کانال‌های جذب سرنخ",
description = "سهم هر کانال از سرنخ‌های واجد شرایط",
items = defaultItems,
className,
}: Leaderboard3Props) => {
return (
<Card dir="rtl" lang="fa" className={cn("w-full max-w-2xl", className)}>
<CardHeader>
<CardTitle>{title}</CardTitle>
<CardDescription>{description}</CardDescription>
</CardHeader>
<CardContent>
<div className="space-y-4">
{items.map((item, index) => (
<div key={index} className="flex items-center justify-between">
<div className="flex items-center gap-3">
<span className="flex size-8 items-center justify-center rounded-full bg-muted text-sm font-medium">
{formatNumber(index + 1)}
</span>
<span className="font-medium">{item.name}</span>
</div>
<div className="flex items-center gap-3">
<span className="text-sm font-semibold">{item.value}</span>
<div
className={cn(
"flex items-center gap-1 text-sm",
item.change === "up" && "text-green-500",
item.change === "down" && "text-red-500",
item.change === "same" && "text-muted-foreground",
)}
>
{item.change === "up" && <TrendingUp className="size-4" />}
{item.change === "down" && (
<TrendingDown className="size-4" />
)}
{item.change === "same" && <Minus className="size-4" />}
{item.changeAmount && <span>{item.changeAmount}</span>}
</div>
</div>
</div>
))}
</div>
</CardContent>
</Card>
);
};
export { Leaderboard3 };