import { memo, useMemo } from 'react' import { Clock } from 'lucide-react' import { cn } from '@/lib/utils' import { useTranslation } from 'react-i18next' import { STATUS_CONFIG } from './status-config' export type StatusSize = 'sm' | 'md' interface StatusBadgeProps { status: string showLabel?: boolean size?: StatusSize className?: string } function getStatusConfig(status: string): { icon: typeof Clock; color: string; bg: string } { return STATUS_CONFIG[status] || { icon: Clock, color: 'text-muted-foreground', bg: 'bg-muted text-muted-foreground', } } // 状态标签走 common.status.*;未收录的状态原样展示(数据层保留英文状态值) function statusLabelOf(t: (k: string) => string, status: string): string { const key = `status.${status}` const label = t(key) return label === key ? status : label } 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 { t } = useTranslation() const config = useMemo(() => getStatusConfig(status), [status]) const label = statusLabelOf(t, status) const sizeClasses = SIZE_MAP[size] const Icon = config.icon return ( {showLabel && {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 ( ) }) export default StatusBadge