87 lines
2.3 KiB
TypeScript
87 lines
2.3 KiB
TypeScript
"use client";
|
|
|
|
import { cn } from "@/lib/utils";
|
|
import { TrendingUp, TrendingDown, Minus } from "lucide-react";
|
|
|
|
interface ROICardProps {
|
|
roiPercentage: number;
|
|
valueGenerated: number;
|
|
subscriptionCost: number;
|
|
className?: string;
|
|
}
|
|
|
|
export function ROICard({
|
|
roiPercentage,
|
|
valueGenerated,
|
|
subscriptionCost,
|
|
className,
|
|
}: ROICardProps) {
|
|
const isPositive = roiPercentage > 0;
|
|
const isNeutral = roiPercentage === 0;
|
|
|
|
const TrendIcon = isNeutral ? Minus : isPositive ? TrendingUp : TrendingDown;
|
|
const trendColor = isNeutral
|
|
? "text-gray-500"
|
|
: isPositive
|
|
? "text-emerald-600"
|
|
: "text-red-600";
|
|
|
|
const formatCurrency = (value: number) =>
|
|
new Intl.NumberFormat("zh-CN", {
|
|
style: "currency",
|
|
currency: "CNY",
|
|
maximumFractionDigits: 0,
|
|
}).format(value);
|
|
|
|
return (
|
|
<div
|
|
className={cn(
|
|
"bg-white rounded-xl border border-gray-200 p-6",
|
|
className
|
|
)}
|
|
>
|
|
<div className="flex items-center justify-between mb-4">
|
|
<p className="text-sm font-medium text-gray-500">投资回报率 (ROI)</p>
|
|
<div className={cn("flex items-center gap-1", trendColor)}>
|
|
<TrendIcon className="h-4 w-4" />
|
|
<span className="text-sm font-medium">
|
|
{isPositive ? "+" : ""}
|
|
{roiPercentage.toFixed(1)}%
|
|
</span>
|
|
</div>
|
|
</div>
|
|
|
|
<p className={cn("text-4xl font-bold leading-none", trendColor)}>
|
|
{roiPercentage.toFixed(1)}%
|
|
</p>
|
|
|
|
<div className="mt-4 grid grid-cols-2 gap-4">
|
|
<div>
|
|
<p className="text-xs text-gray-500">创造价值</p>
|
|
<p className="text-lg font-semibold text-emerald-600">
|
|
{formatCurrency(valueGenerated)}
|
|
</p>
|
|
</div>
|
|
<div>
|
|
<p className="text-xs text-gray-500">订阅成本</p>
|
|
<p className="text-lg font-semibold text-gray-900">
|
|
{formatCurrency(subscriptionCost)}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="mt-4 h-2 w-full rounded-full bg-gray-100 overflow-hidden">
|
|
<div
|
|
className={cn(
|
|
"h-full rounded-full transition-all duration-300",
|
|
isPositive ? "bg-emerald-500" : "bg-red-500"
|
|
)}
|
|
style={{
|
|
width: `${Math.min(Math.abs(roiPercentage), 100)}%`,
|
|
}}
|
|
/>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|