import { cn } from '@/lib/utils'; import { Card, CardContent } from '@/components/ui/card'; import { Button } from '@/components/ui/button'; import { Badge } from '@/components/ui/badge'; import { Input } from '@/components/ui/input'; import { Search, CheckCircle2, XCircle, Eye, Loader2, FileText, } from 'lucide-react'; import { getProgressInfo, renderStepProgress, getApprovalTypeLabel, getApprovalTypeColor, getApprovalTypeIcon, getInstanceType, } from './helpers'; import i18n from 'i18next'; import { useTranslation } from 'react-i18next'; import type { JsonData } from '@/types/common'; // 状态标签页定义 const STATUS_TABS = [ { key: 'all', labelKey: 'common.all', value: '' }, { key: 'pending', labelKey: 'approval.status.pending', value: 'pending' }, { key: 'approved', labelKey: 'approval.status.approved', value: 'approved' }, { key: 'rejected', labelKey: 'approval.status.rejected', value: 'rejected' }, { key: 'processing', labelKey: 'approval.status.pending', value: 'processing' }, { key: 'completed', labelKey: 'common.completed', value: 'completed' }, ]; function getStatusBadge(status: string) { const statusMap: Record = { pending: { labelKey: 'approval.status.pending', className: 'border-amber-500/30 dg-text-yellow bg-amber-500/10', dot: 'bg-amber-400', }, approved: { labelKey: 'approval.status.approved', className: 'border-emerald-500/30 dg-text-green bg-emerald-500/10', dot: 'bg-emerald-400', }, rejected: { labelKey: 'approval.status.rejected', className: 'border-red-500/30 dg-text-red bg-red-500/10', dot: 'bg-red-400', }, processing: { labelKey: 'approval.status.pending', className: 'border-[var(--dg-blue)]/30 text-[var(--dg-blue)] bg-[var(--dg-blue)]/10', dot: 'bg-[var(--dg-blue)]', }, completed: { labelKey: 'common.completed', className: 'border-[var(--dg-border)] text-[var(--dg-text-secondary)] bg-[var(--dg-bg-tertiary)]', dot: 'bg-[var(--dg-text-secondary)]', }, }; const config = statusMap[status] || statusMap.pending; return (
{i18n.t(config.labelKey)} ); } interface ApprovalProcessTabProps { processes: JsonData[]; filteredInstances: JsonData[]; loading: boolean; searchQuery: string; setSearchQuery: (v: string) => void; statusFilter: string; setStatusFilter: (v: string) => void; onView: (instance: JsonData) => void; onApprove: (instance: JsonData) => void; onReject: (instance: JsonData) => void; } export function ApprovalProcessTab({ filteredInstances, loading, searchQuery, setSearchQuery, statusFilter, setStatusFilter, onView, onApprove, onReject, }: ApprovalProcessTabProps) { const { t } = useTranslation(); return ( <> {/* 搜索 + 状态筛选 */}
setSearchQuery(e.target.value)} className="pl-9 h-9 bg-[var(--dg-bg-tertiary)] border-[var(--dg-border)] text-[var(--dg-text-primary)] placeholder:text-[var(--dg-text-muted)]" />
{STATUS_TABS.map((tab) => ( ))}
{/* 流程实例列表 */} {loading ? (
{t('common.loading')}
) : filteredInstances.length === 0 ? (

{t('approval.noInstances')}

{t('approval.noInstancesDesc')}

) : (
{filteredInstances.map((instance) => { const Icon = getApprovalTypeIcon(getInstanceType(instance)); const { percentage } = getProgressInfo(instance); return (

{instance.title}

{getStatusBadge(instance.status)}
{getApprovalTypeLabel(getInstanceType(instance))} {t('approval.detail.applicant')}: {instance.applicant_name || instance.applicant || '--'} {t('approval.detail.submittedAt')} {instance.created_at ? new Date(instance.created_at).toLocaleString() : '--'}
{instance.status === 'pending' && ( <> )}
{/* {t('approval.detail.approvalProgress')}条 */}
{t('approval.detail.approvalProgress')} {percentage}%
{/* 步骤进度 */}
{renderStepProgress(instance)}
); })}
)} ); }