62 lines
1.8 KiB
TypeScript
62 lines
1.8 KiB
TypeScript
"use client";
|
|
|
|
import { cn } from "@/lib/utils";
|
|
|
|
interface UsageProgressProps {
|
|
label: string;
|
|
current: number;
|
|
limit: number;
|
|
unit?: string;
|
|
className?: string;
|
|
}
|
|
|
|
export function UsageProgress({ label, current, limit, unit = "", className }: UsageProgressProps) {
|
|
const isUnlimited = limit === -1;
|
|
const percentage = isUnlimited ? 0 : limit > 0 ? Math.min((current / limit) * 100, 100) : 0;
|
|
const isWarning = !isUnlimited && percentage > 80;
|
|
const isCritical = !isUnlimited && percentage > 95;
|
|
|
|
const barColor = isCritical
|
|
? "bg-red-500"
|
|
: isWarning
|
|
? "bg-amber-500"
|
|
: "bg-primary";
|
|
|
|
const textColor = isCritical
|
|
? "text-red-600"
|
|
: isWarning
|
|
? "text-amber-600"
|
|
: "text-gray-900";
|
|
|
|
return (
|
|
<div className={cn("space-y-1.5", className)}>
|
|
<div className="flex items-center justify-between">
|
|
<span className="text-sm text-gray-600">{label}</span>
|
|
<span className={cn("text-sm font-medium", textColor)}>
|
|
{isUnlimited
|
|
? `${current}${unit}`
|
|
: `${current}${unit} / ${limit}${unit}`}
|
|
</span>
|
|
</div>
|
|
{!isUnlimited && (
|
|
<div className="h-2 w-full rounded-full bg-gray-100 overflow-hidden">
|
|
<div
|
|
className={cn("h-full rounded-full transition-all duration-300", barColor)}
|
|
style={{ width: `${percentage}%` }}
|
|
/>
|
|
</div>
|
|
)}
|
|
{isUnlimited && (
|
|
<div className="h-2 w-full rounded-full bg-primary/10 overflow-hidden">
|
|
<div className="h-full w-0 rounded-full bg-primary" />
|
|
</div>
|
|
)}
|
|
{!isUnlimited && isWarning && (
|
|
<p className="text-xs text-amber-600">
|
|
{isCritical ? "额度即将用尽" : "额度使用已超过80%"}
|
|
</p>
|
|
)}
|
|
</div>
|
|
);
|
|
}
|