feat(web): add khu-cong-nghiep, chuyen-nhuong, and reports pages
Add three new frontend page sections: - Industrial parks (khu-cong-nghiep): listing, detail, filter bar - Transfer listings (chuyen-nhuong): search, category tabs, detail - AI reports dashboard: list, create, viewer with TOC Includes components, API clients, hooks, server helpers, i18n keys, navigation links in public and dashboard layouts, and lint fixes. Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
77
apps/web/components/chuyen-nhuong/transfer-item-table.tsx
Normal file
77
apps/web/components/chuyen-nhuong/transfer-item-table.tsx
Normal file
@@ -0,0 +1,77 @@
|
||||
'use client';
|
||||
|
||||
import { Badge } from '@/components/ui/badge';
|
||||
import {
|
||||
type TransferItemData,
|
||||
CATEGORY_LABELS,
|
||||
CONDITION_COLORS,
|
||||
CONDITION_LABELS,
|
||||
} from '@/lib/chuyen-nhuong-api';
|
||||
|
||||
interface TransferItemTableProps {
|
||||
items: TransferItemData[];
|
||||
}
|
||||
|
||||
function formatVND(value: string): string {
|
||||
return new Intl.NumberFormat('vi-VN').format(Number(value)) + ' \u20ab';
|
||||
}
|
||||
|
||||
export function TransferItemTable({ items }: TransferItemTableProps) {
|
||||
if (items.length === 0) {
|
||||
return <p className="text-sm text-muted-foreground">Chưa có danh sách vật phẩm.</p>;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="overflow-x-auto">
|
||||
<table className="w-full text-sm">
|
||||
<thead>
|
||||
<tr className="border-b">
|
||||
<th className="px-3 py-2 text-left font-medium">Tên</th>
|
||||
<th className="px-3 py-2 text-left font-medium">Loại</th>
|
||||
<th className="px-3 py-2 text-left font-medium">Tình trạng</th>
|
||||
<th className="px-3 py-2 text-left font-medium">Thương hiệu</th>
|
||||
<th className="px-3 py-2 text-right font-medium">SL</th>
|
||||
<th className="px-3 py-2 text-right font-medium">Giá yêu cầu</th>
|
||||
<th className="px-3 py-2 text-right font-medium">Giá AI</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{items.map((item) => (
|
||||
<tr key={item.id} className="border-b">
|
||||
<td className="px-3 py-2">
|
||||
<div>
|
||||
<p className="font-medium">{item.name}</p>
|
||||
{item.modelName && (
|
||||
<p className="text-xs text-muted-foreground">{item.modelName}</p>
|
||||
)}
|
||||
</div>
|
||||
</td>
|
||||
<td className="px-3 py-2 text-muted-foreground">
|
||||
{CATEGORY_LABELS[item.category]}
|
||||
</td>
|
||||
<td className="px-3 py-2">
|
||||
<Badge className={CONDITION_COLORS[item.condition]} variant="secondary">
|
||||
{CONDITION_LABELS[item.condition]}
|
||||
</Badge>
|
||||
</td>
|
||||
<td className="px-3 py-2 text-muted-foreground">
|
||||
{item.brand ?? '—'}
|
||||
</td>
|
||||
<td className="px-3 py-2 text-right">{item.quantity}</td>
|
||||
<td className="px-3 py-2 text-right font-medium">
|
||||
{formatVND(item.askingPriceVND)}
|
||||
</td>
|
||||
<td className="px-3 py-2 text-right text-muted-foreground">
|
||||
{item.aiEstimatePriceVND ? (
|
||||
<span title={item.aiConfidence ? `Độ tin cậy: ${Math.round(item.aiConfidence * 100)}%` : undefined}>
|
||||
{formatVND(item.aiEstimatePriceVND)}
|
||||
</span>
|
||||
) : '—'}
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user