import { memo, useMemo } from 'react' import { CheckCircle, AlertTriangle, Clock, PauseCircle, Activity, type LucideIcon, } from 'lucide-react' import { cn } from '@/lib/utils' import { statusLabel } from '@/lib/utils' export type StatusSize = 'sm' | 'md' interface StatusBadgeProps { status: string showLabel?: boolean size?: StatusSize className?: string } interface StatusConfig { icon: LucideIcon color: string bg: string label: string } const STATUS_CONFIG: Record> = { running: { icon: CheckCircle, color: 'text-emerald-500', bg: 'bg-emerald-100 text-emerald-700', }, active: { icon: CheckCircle, color: 'text-emerald-500', bg: 'bg-emerald-100 text-emerald-700', }, failed: { icon: AlertTriangle, color: 'text-red-500', bg: 'bg-red-100 text-red-700', }, error: { icon: AlertTriangle, color: 'text-red-500', bg: 'bg-red-100 text-red-700', }, pending: { icon: Clock, color: 'text-amber-500', bg: 'bg-amber-100 text-amber-700', }, stopped: { icon: PauseCircle, color: 'text-slate-400', bg: 'bg-slate-100 text-slate-600', }, inactive: { icon: PauseCircle, color: 'text-slate-400', bg: 'bg-slate-100 text-slate-600', }, deploying: { icon: Activity, color: 'text-blue-500', bg: 'bg-blue-100 text-blue-700', }, } function getStatusConfig(status: string): StatusConfig { const config = STATUS_CONFIG[status] || { icon: Clock, color: 'text-slate-400', bg: 'bg-slate-100 text-slate-600', } return { ...config, label: statusLabel(status), } } const SIZE_MAP: Record = { sm: { icon: 'w-4 h-4', badge: 'px-2 py-0.5 text-xs' }, md: { icon: 'w-5 h-5', badge: 'px-2.5 py-0.5 text-sm' }, } /** * 统一状态徽章组件 * 接收status字符串,返回对应的图标+颜色+标签 * 替换所有页面中重复的getStatusIcon/getStatusColor */ export const StatusBadge = memo(function StatusBadge({ status, showLabel = true, size = 'sm', className, }: StatusBadgeProps) { const config = useMemo(() => getStatusConfig(status), [status]) const sizeClasses = SIZE_MAP[size] const Icon = config.icon return ( {showLabel && {config.label}} ) }) /** 独立状态图标组件(仅图标,无标签) */ export const StatusIcon = memo(function StatusIcon({ status, size = 'sm', className, }: Omit) { const config = useMemo(() => getStatusConfig(status), [status]) const sizeClasses = SIZE_MAP[size] const Icon = config.icon return ( ) }) /** 独立状态颜色工具函数(用于需要className的场景) */ export function getStatusColorClass(status: string): string { return STATUS_CONFIG[status]?.bg || 'bg-slate-100 text-slate-600' } export default StatusBadge