95 lines
3.0 KiB
TypeScript
95 lines
3.0 KiB
TypeScript
import React from "react";
|
|
import { formatNumber } from "~/lib/utils";
|
|
import {
|
|
Tooltip,
|
|
TooltipContent,
|
|
TooltipTrigger,
|
|
} from "~/components/ui/tooltip"
|
|
|
|
interface DataItem {
|
|
label: string;
|
|
value: number;
|
|
color: string;
|
|
}
|
|
|
|
interface DashboardCustomBarChartProps {
|
|
title: string;
|
|
data: DataItem[];
|
|
loading?: boolean;
|
|
}
|
|
|
|
export function DashboardCustomBarChart({
|
|
title,
|
|
data,
|
|
loading = false,
|
|
}: DashboardCustomBarChartProps) {
|
|
if (loading) {
|
|
return (
|
|
<div className="w-full">
|
|
<h3 className="text-sm font-bold text-white font-persian mb-4 text-right border-b-2 border-gray-500/20 pb-3">
|
|
{title}
|
|
</h3>
|
|
<div className="space-y-3">
|
|
{[1, 2, 3].map((i) => (
|
|
<div key={i} className="animate-pulse">
|
|
<div className="h-12 bg-gray-600/30 rounded-lg"></div>
|
|
</div>
|
|
))}
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
// Calculate the maximum value for scaling
|
|
const maxValue = Math.max(...data.map((item) => item.value));
|
|
|
|
return (
|
|
<div className="w-full">
|
|
<h3 className="text-sm font-bold text-white font-persian mb-6 py-2 px-4 text-right border-b-2 border-gray-500/20">
|
|
{title}
|
|
</h3>
|
|
<div className="px-4">
|
|
{data.map((item, index) => {
|
|
const widthPercentage =
|
|
maxValue > 0 ? (item.value / maxValue) * 100 : 0;
|
|
|
|
return (
|
|
<div key={index} className="relative">
|
|
{/* Bar container */}
|
|
<div className="flex-row-reverse items-center gap-2 flex min-h-6 h-10 rounded-lg overflow-hidden">
|
|
{/* Animated bar */}
|
|
<div
|
|
className={`h-auto gap-2 overflow-hidden ${item.color} rounded-lg transition-all duration-1000 ease-out flex items-center justify-end px-2`}
|
|
style={{ width: `${widthPercentage}%` }}
|
|
>
|
|
{ widthPercentage > 20 ? (
|
|
<span className="text-[#3F415A] min-w-max text-left font-persian font-medium text-sm py-1 w-max">
|
|
{item.label}
|
|
</span>
|
|
) : (
|
|
<Tooltip>
|
|
<TooltipTrigger className={`${item.color}`} asChild>
|
|
<span className="text-[#3F415A] text-left font-persian font-medium text-sm py-1">
|
|
<span className="invisible">""</span>
|
|
</span>
|
|
|
|
</TooltipTrigger>
|
|
<TooltipContent className={`${item.color} ${item.color.replace("bg","fill")}`}>
|
|
<p className="font-persian text-sm">{item.label}</p>
|
|
</TooltipContent>
|
|
|
|
</Tooltip>
|
|
) }
|
|
</div>
|
|
<span className="text-white font-bold text-base">
|
|
{formatNumber(item.value)}
|
|
</span>
|
|
</div>
|
|
</div>
|
|
);
|
|
})}
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|