ocdp v1
This commit is contained in:
72
frontend/src/shared/components/data-display/StatsCard.tsx
Normal file
72
frontend/src/shared/components/data-display/StatsCard.tsx
Normal file
@ -0,0 +1,72 @@
|
||||
/**
|
||||
* 统一的 StatsCard 组件
|
||||
* 用于显示统计数据卡片
|
||||
*/
|
||||
import React from "react";
|
||||
import type { LucideIcon } from "lucide-react";
|
||||
|
||||
export type StatsCardVariant = "blue" | "green" | "purple" | "orange" | "red";
|
||||
|
||||
export interface StatsCardProps {
|
||||
title: string;
|
||||
value: string | number;
|
||||
icon: LucideIcon;
|
||||
variant?: StatsCardVariant;
|
||||
subtitle?: string;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
const variantStyles: Record<StatsCardVariant, { container: string; iconBg: string; iconColor: string }> = {
|
||||
blue: {
|
||||
container: "bg-gradient-to-br from-blue-600/20 to-blue-800/20 border-blue-500/30",
|
||||
iconBg: "bg-blue-600/30",
|
||||
iconColor: "text-blue-300",
|
||||
},
|
||||
green: {
|
||||
container: "bg-gradient-to-br from-green-600/20 to-green-800/20 border-green-500/30",
|
||||
iconBg: "bg-green-600/30",
|
||||
iconColor: "text-green-300",
|
||||
},
|
||||
purple: {
|
||||
container: "bg-gradient-to-br from-purple-600/20 to-purple-800/20 border-purple-500/30",
|
||||
iconBg: "bg-purple-600/30",
|
||||
iconColor: "text-purple-300",
|
||||
},
|
||||
orange: {
|
||||
container: "bg-gradient-to-br from-orange-600/20 to-orange-800/20 border-orange-500/30",
|
||||
iconBg: "bg-orange-600/30",
|
||||
iconColor: "text-orange-300",
|
||||
},
|
||||
red: {
|
||||
container: "bg-gradient-to-br from-red-600/20 to-red-800/20 border-red-500/30",
|
||||
iconBg: "bg-red-600/30",
|
||||
iconColor: "text-red-300",
|
||||
},
|
||||
};
|
||||
|
||||
export const StatsCard: React.FC<StatsCardProps> = ({
|
||||
title,
|
||||
value,
|
||||
icon: Icon,
|
||||
variant = "blue",
|
||||
subtitle,
|
||||
className = "",
|
||||
}) => {
|
||||
const styles = variantStyles[variant];
|
||||
|
||||
return (
|
||||
<div className={`border rounded-lg p-4 ${styles.container} ${className}`.trim()}>
|
||||
<div className="flex items-center gap-3">
|
||||
<div className={`p-2 rounded-lg ${styles.iconBg}`}>
|
||||
<Icon className={`w-6 h-6 ${styles.iconColor}`} />
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-2xl font-bold text-white">{value}</p>
|
||||
<p className="text-sm text-gray-400">{title}</p>
|
||||
{subtitle && <p className="text-xs text-gray-500 mt-0.5">{subtitle}</p>}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user