91 lines
3.2 KiB
TypeScript
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>
|
|
)
|
|
}
|