- Delete duplicate page-new.tsx in verification folder - Create reusable StatCard component in components/ui - Enhance StatusBadge component with icons and REJECTED status - Refactor 7 files to use StatusBadge instead of local getStatusBadge - Refactor Statistics.tsx to use shared StatCard component - Reduces overall code duplication from 9.85% to lower 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
61 lines
2.0 KiB
TypeScript
61 lines
2.0 KiB
TypeScript
'use client';
|
|
|
|
import React from 'react';
|
|
import { cn } from '@/utils/helpers';
|
|
|
|
type ColorVariant = 'blue' | 'green' | 'yellow' | 'red' | 'purple' | 'orange' | 'gray';
|
|
|
|
interface StatCardProps {
|
|
title: string;
|
|
value: number | string;
|
|
icon?: React.ReactNode;
|
|
color?: ColorVariant;
|
|
subtitle?: string;
|
|
className?: string;
|
|
}
|
|
|
|
const colorClasses: Record<ColorVariant, { bg: string; text: string; iconBg: string }> = {
|
|
blue: { bg: 'bg-blue-50', text: 'text-blue-600', iconBg: 'bg-blue-100 text-blue-600' },
|
|
green: { bg: 'bg-green-50', text: 'text-green-600', iconBg: 'bg-green-100 text-green-600' },
|
|
yellow: { bg: 'bg-yellow-50', text: 'text-yellow-600', iconBg: 'bg-yellow-100 text-yellow-600' },
|
|
red: { bg: 'bg-red-50', text: 'text-red-600', iconBg: 'bg-red-100 text-red-600' },
|
|
purple: { bg: 'bg-purple-50', text: 'text-purple-600', iconBg: 'bg-purple-100 text-purple-600' },
|
|
orange: { bg: 'bg-orange-50', text: 'text-orange-600', iconBg: 'bg-orange-100 text-orange-600' },
|
|
gray: { bg: 'bg-gray-50', text: 'text-gray-600', iconBg: 'bg-gray-100 text-gray-600' },
|
|
};
|
|
|
|
export const StatCard: React.FC<StatCardProps> = ({
|
|
title,
|
|
value,
|
|
icon,
|
|
color = 'blue',
|
|
subtitle,
|
|
className,
|
|
}) => {
|
|
const colors = colorClasses[color];
|
|
const formattedValue = typeof value === 'number' ? value.toLocaleString('fr-FR') : value;
|
|
|
|
return (
|
|
<div className={cn('bg-white rounded-lg shadow-sm border border-gray-200 p-6', className)}>
|
|
<div className="flex items-center justify-between">
|
|
<div>
|
|
<p className="text-sm font-medium text-gray-600">{title}</p>
|
|
<p className={cn('text-3xl font-bold mt-2', colors.text)}>
|
|
{formattedValue}
|
|
</p>
|
|
{subtitle && (
|
|
<p className="text-xs text-gray-500 mt-1">{subtitle}</p>
|
|
)}
|
|
</div>
|
|
{icon && (
|
|
<div className={cn('p-3 rounded-lg', colors.iconBg)}>
|
|
{icon}
|
|
</div>
|
|
)}
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default StatCard;
|