Files
OCR/frontend/src/components/ResultsTable.tsx
beabigegg da700721fa first
2025-11-12 22:53:17 +08:00

91 lines
3.2 KiB
TypeScript

import { useTranslation } from 'react-i18next'
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'
import { Badge } from '@/components/ui/badge'
import { Button } from '@/components/ui/button'
import type { FileResult } from '@/types/api'
interface ResultsTableProps {
files: FileResult[]
onViewResult?: (fileId: number) => void
onDownloadPDF?: (fileId: number) => void
}
export default function ResultsTable({ files, onViewResult, onDownloadPDF }: ResultsTableProps) {
const { t } = useTranslation()
const getStatusBadge = (status: FileResult['status']) => {
switch (status) {
case 'completed':
return <Badge variant="success">{t('processing.completed')}</Badge>
case 'processing':
return <Badge variant="default">{t('processing.processing')}</Badge>
case 'failed':
return <Badge variant="destructive">{t('processing.failed')}</Badge>
default:
return <Badge variant="secondary">{t('processing.pending')}</Badge>
}
}
const formatTime = (seconds?: number) => {
if (!seconds) return 'N/A'
return `${seconds.toFixed(2)}s`
}
return (
<div className="rounded-md border">
<Table>
<TableHeader>
<TableRow>
<TableHead>{t('results.filename')}</TableHead>
<TableHead>{t('results.status')}</TableHead>
<TableHead>{t('results.processingTime')}</TableHead>
<TableHead className="text-right">{t('results.actions')}</TableHead>
</TableRow>
</TableHeader>
<TableBody>
{files.length === 0 ? (
<TableRow>
<TableCell colSpan={4} className="text-center text-muted-foreground">
{t('results.noResults')}
</TableCell>
</TableRow>
) : (
files.map((file) => (
<TableRow key={file.id}>
<TableCell className="font-medium">{file.filename}</TableCell>
<TableCell>{getStatusBadge(file.status)}</TableCell>
<TableCell>{formatTime(file.processing_time)}</TableCell>
<TableCell className="text-right">
<div className="flex justify-end gap-2">
{file.status === 'completed' && (
<>
<Button
variant="outline"
size="sm"
onClick={() => onViewResult?.(file.id)}
>
{t('results.viewMarkdown')}
</Button>
<Button
variant="outline"
size="sm"
onClick={() => onDownloadPDF?.(file.id)}
>
{t('results.downloadPDF')}
</Button>
</>
)}
{file.status === 'failed' && file.error && (
<span className="text-sm text-destructive">{file.error}</span>
)}
</div>
</TableCell>
</TableRow>
))
)}
</TableBody>
</Table>
</div>
)
}