changed
This commit is contained in:
128
src/widgets/cabinet/ui/tables/SiTable.tsx
Normal file
128
src/widgets/cabinet/ui/tables/SiTable.tsx
Normal file
@@ -0,0 +1,128 @@
|
||||
import React from 'react';
|
||||
import { FileText, Clock, CheckCircle, XCircle } from 'lucide-react';
|
||||
import type { SiCheck } from '../../lib/types';
|
||||
|
||||
// ─── Helpers ───────────────────────────────────────────────────────────────────
|
||||
|
||||
const STATUS_MAP = {
|
||||
completed: {
|
||||
label: 'Yakunlandi',
|
||||
icon: CheckCircle,
|
||||
cls: 'text-emerald-600 bg-emerald-50',
|
||||
},
|
||||
pending: {
|
||||
label: 'Kutilmoqda',
|
||||
icon: Clock,
|
||||
cls: 'text-amber-600 bg-amber-50',
|
||||
},
|
||||
failed: { label: 'Xato', icon: XCircle, cls: 'text-red-600 bg-red-50' },
|
||||
} as const;
|
||||
|
||||
const SiPercentBadge: React.FC<{ value: number }> = ({ value }) => {
|
||||
const cls =
|
||||
value < 20
|
||||
? 'text-emerald-700 bg-emerald-50'
|
||||
: value < 40
|
||||
? 'text-amber-700 bg-amber-50'
|
||||
: 'text-red-700 bg-red-50';
|
||||
return (
|
||||
<span
|
||||
className={`inline-block px-2 py-0.5 rounded-md text-xs font-semibold ${cls}`}
|
||||
>
|
||||
{value}%
|
||||
</span>
|
||||
);
|
||||
};
|
||||
|
||||
// ─── Component ─────────────────────────────────────────────────────────────────
|
||||
|
||||
interface SiTableProps {
|
||||
data: SiCheck[];
|
||||
}
|
||||
|
||||
export const SiTable: React.FC<SiTableProps> = ({ data }) => (
|
||||
<div className="space-y-4">
|
||||
<div>
|
||||
<h2 className="text-xl font-bold text-slate-900">SI detektor</h2>
|
||||
<p className="text-sm text-slate-500 mt-0.5">
|
||||
{data.length} ta tekshiruv
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="bg-white rounded-2xl border border-slate-100 shadow-sm overflow-hidden">
|
||||
<div className="overflow-x-auto">
|
||||
<table className="w-full text-sm">
|
||||
<thead>
|
||||
<tr className="bg-slate-50 border-b border-slate-100">
|
||||
{['#', 'Fayl', "So'z", 'SI%', 'Sana', 'Holat', 'Hisobot'].map(
|
||||
(h) => (
|
||||
<th
|
||||
key={h}
|
||||
className="text-left px-5 py-3 text-[11px] font-semibold text-slate-400 uppercase tracking-wider whitespace-nowrap last:text-center"
|
||||
>
|
||||
{h}
|
||||
</th>
|
||||
),
|
||||
)}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody className="divide-y divide-slate-50">
|
||||
{data.map((row) => {
|
||||
const s = STATUS_MAP[row.status];
|
||||
const Icon = s.icon;
|
||||
return (
|
||||
<tr
|
||||
key={row.id}
|
||||
className="hover:bg-slate-50/60 transition-colors"
|
||||
>
|
||||
<td className="px-5 py-3.5 text-slate-400 font-mono text-xs">
|
||||
{String(row.id).padStart(2, '0')}
|
||||
</td>
|
||||
<td className="px-5 py-3.5">
|
||||
<span className="text-slate-800 font-medium max-w-[150px] truncate block">
|
||||
{row.file}
|
||||
</span>
|
||||
</td>
|
||||
<td className="px-5 py-3.5 text-slate-500 tabular-nums">
|
||||
{row.words.toLocaleString()}
|
||||
</td>
|
||||
<td className="px-5 py-3.5">
|
||||
{row.status === 'pending' ? (
|
||||
<span className="text-slate-300 text-xs">—</span>
|
||||
) : (
|
||||
<SiPercentBadge value={row.siPercent} />
|
||||
)}
|
||||
</td>
|
||||
<td className="px-5 py-3.5 text-slate-500 whitespace-nowrap">
|
||||
{row.date}
|
||||
</td>
|
||||
<td className="px-5 py-3.5">
|
||||
<span
|
||||
className={`inline-flex items-center gap-1.5 px-2.5 py-1 rounded-lg text-xs font-medium ${s.cls}`}
|
||||
>
|
||||
<Icon size={12} />
|
||||
{s.label}
|
||||
</span>
|
||||
</td>
|
||||
<td className="px-5 py-3.5 text-center">
|
||||
{row.reportUrl ? (
|
||||
<a
|
||||
href={row.reportUrl}
|
||||
className="inline-flex items-center justify-center w-8 h-8 rounded-lg text-slate-400 hover:text-violet-600 hover:bg-violet-50 transition-colors"
|
||||
aria-label="Hisobot"
|
||||
>
|
||||
<FileText size={15} />
|
||||
</a>
|
||||
) : (
|
||||
<span className="text-slate-200 text-xs">—</span>
|
||||
)}
|
||||
</td>
|
||||
</tr>
|
||||
);
|
||||
})}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
Reference in New Issue
Block a user