Add File
This commit is contained in:
69
src/family/components/MetricCard.tsx
Normal file
69
src/family/components/MetricCard.tsx
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { LucideIcon } from 'lucide-react';
|
||||||
|
|
||||||
|
interface MetricCardProps {
|
||||||
|
title: string;
|
||||||
|
value: string | number;
|
||||||
|
subtitle?: string;
|
||||||
|
icon: LucideIcon;
|
||||||
|
trend?: 'up' | 'down' | 'neutral';
|
||||||
|
trendValue?: string;
|
||||||
|
color?: 'blue' | 'green' | 'yellow' | 'red';
|
||||||
|
onClick?: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 指标卡片组件
|
||||||
|
* 用于 Dashboard 展示关键数据
|
||||||
|
*/
|
||||||
|
export const MetricCard: React.FC<MetricCardProps> = ({
|
||||||
|
title,
|
||||||
|
value,
|
||||||
|
subtitle,
|
||||||
|
icon: Icon,
|
||||||
|
trend,
|
||||||
|
trendValue,
|
||||||
|
color = 'blue',
|
||||||
|
onClick,
|
||||||
|
}) => {
|
||||||
|
const colorClasses = {
|
||||||
|
blue: 'bg-blue-50 text-blue-600',
|
||||||
|
green: 'bg-green-50 text-green-600',
|
||||||
|
yellow: 'bg-yellow-50 text-yellow-600',
|
||||||
|
red: 'bg-red-50 text-red-600',
|
||||||
|
};
|
||||||
|
|
||||||
|
const trendColors = {
|
||||||
|
up: 'text-green-600',
|
||||||
|
down: 'text-red-600',
|
||||||
|
neutral: 'text-gray-600',
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
onClick={onClick}
|
||||||
|
className={`
|
||||||
|
card p-6
|
||||||
|
${onClick ? 'cursor-pointer hover:shadow-xl transition-shadow' : ''}
|
||||||
|
`}
|
||||||
|
>
|
||||||
|
<div className="flex items-start justify-between">
|
||||||
|
<div className="flex-1">
|
||||||
|
<p className="text-sm text-gray-600 font-medium mb-2">{title}</p>
|
||||||
|
<p className="text-3xl font-bold text-gray-900 mb-1">{value}</p>
|
||||||
|
{subtitle && (
|
||||||
|
<p className="text-sm text-gray-500">{subtitle}</p>
|
||||||
|
)}
|
||||||
|
{trend && trendValue && (
|
||||||
|
<p className={`text-sm font-medium mt-2 ${trendColors[trend]}`}>
|
||||||
|
{trend === 'up' ? '↑' : trend === 'down' ? '↓' : '→'} {trendValue}
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<div className={`p-3 rounded-xl ${colorClasses[color]}`}>
|
||||||
|
<Icon size={24} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user