91 lines
3.6 KiB
TypeScript
91 lines
3.6 KiB
TypeScript
import React from 'react';
|
|
import { OcrDocument, OcrDocumentStatus } from '../../types';
|
|
|
|
interface OcrDocumentsTableProps {
|
|
documents: OcrDocument[];
|
|
onReview: (doc: OcrDocument) => void;
|
|
}
|
|
|
|
const statusConfig: { [key in OcrDocumentStatus]: { text: string; color: string; icon: string } } =
|
|
{
|
|
Processing: {
|
|
text: 'Memproses',
|
|
color: 'bg-blue-100 text-blue-700',
|
|
icon: 'fa-spin fa-spinner',
|
|
},
|
|
'Needs Review': {
|
|
text: 'Perlu Tinjauan',
|
|
color: 'bg-yellow-100 text-yellow-700',
|
|
icon: 'fa-user-check',
|
|
},
|
|
Completed: { text: 'Selesai', color: 'bg-green-100 text-green-700', icon: 'fa-check-circle' },
|
|
Failed: { text: 'Gagal', color: 'bg-red-100 text-red-700', icon: 'fa-times-circle' },
|
|
};
|
|
|
|
const OcrDocumentsTable: React.FC<OcrDocumentsTableProps> = ({ documents, onReview }) => {
|
|
const sortedDocs = [...documents].sort((a, b) => b.uploadedAt.getTime() - a.uploadedAt.getTime());
|
|
|
|
return (
|
|
<div className="bg-white p-6 rounded-xl shadow-sm">
|
|
<h2 className="text-xl font-bold mb-4">Dokumen Terproses</h2>
|
|
<div className="overflow-x-auto">
|
|
<table className="min-w-full text-sm">
|
|
<thead className="bg-gray-100 text-left text-gray-600">
|
|
<tr>
|
|
<th className="p-3 font-semibold">Nama File</th>
|
|
<th className="p-3 font-semibold">Waktu Unggah</th>
|
|
<th className="p-3 font-semibold">Jenis Dokumen</th>
|
|
<th className="p-3 font-semibold">Akurasi</th>
|
|
<th className="p-3 font-semibold">Status</th>
|
|
<th className="p-3 font-semibold text-right">Aksi</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody className="divide-y divide-gray-100">
|
|
{sortedDocs.map((doc) => {
|
|
const config = statusConfig[doc.status];
|
|
const accuracyColor =
|
|
doc.accuracy > 95
|
|
? 'text-green-600'
|
|
: doc.accuracy > 80
|
|
? 'text-yellow-600'
|
|
: 'text-red-600';
|
|
return (
|
|
<tr key={doc.id} className="hover:bg-gray-50">
|
|
<td className="p-3 font-semibold text-gray-800 truncate" title={doc.fileName}>
|
|
{doc.fileName}
|
|
</td>
|
|
<td className="p-3 text-gray-600">{doc.uploadedAt.toLocaleString('id-ID')}</td>
|
|
<td className="p-3 text-gray-600">{doc.documentType}</td>
|
|
<td className={`p-3 font-bold ${accuracyColor}`}>
|
|
{doc.accuracy > 0 ? `${doc.accuracy}%` : '-'}
|
|
</td>
|
|
<td className="p-3">
|
|
<span
|
|
className={`inline-flex items-center space-x-1.5 px-2 py-0.5 rounded-full text-xs font-medium ${config.color}`}
|
|
>
|
|
<i className={`fa-solid ${config.icon}`}></i>
|
|
<span>{config.text}</span>
|
|
</span>
|
|
</td>
|
|
<td className="p-3 text-right">
|
|
{(doc.status === 'Needs Review' || doc.status === 'Completed') && (
|
|
<button
|
|
onClick={() => onReview(doc)}
|
|
className="text-blue-600 hover:text-blue-800 font-semibold"
|
|
>
|
|
<i className="fa-solid fa-search mr-1"></i> Tinjau
|
|
</button>
|
|
)}
|
|
</td>
|
|
</tr>
|
|
);
|
|
})}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default OcrDocumentsTable;
|