import { cn } from '@/lib/utils'; import { Package, Truck, Factory, CornerDownRight, Box, ShoppingCart } from 'lucide-react'; import { formatDate } from '@/lib/date'; export interface TraceabilityNode { id: string; type: 'target_batch' | 'source_batch' | 'production_order' | 'material_batch' | 'goods_receipt' | 'outbound_transaction'; label: string; batch_number?: string; date?: string; vendor_id?: number | string; product_name?: string; spec?: string; quantity?: number | string; unit?: string; warehouse_name?: string; children?: TraceabilityNode[]; } interface TreeViewProps { data: TraceabilityNode; } const getNodeIcon = (type: TraceabilityNode['type']) => { switch (type) { case 'target_batch': case 'source_batch': return ; case 'production_order': return ; case 'material_batch': return ; case 'goods_receipt': return ; case 'outbound_transaction': return ; default: return ; } }; const getNodeColor = (type: TraceabilityNode['type']) => { switch (type) { case 'target_batch': case 'source_batch': return 'border-primary-light bg-primary-lightest'; case 'production_order': return 'border-orange-200 bg-orange-50'; case 'material_batch': return 'border-primary-light bg-primary-lightest'; case 'goods_receipt': return 'border-blue-200 bg-blue-50'; case 'outbound_transaction': return 'border-emerald-200 bg-emerald-50'; default: return 'border-gray-200 bg-gray-50'; } }; const TreeNode = ({ node, isLast, level = 0 }: { node: TraceabilityNode; isLast: boolean; level?: number }) => { const hasChildren = node.children && node.children.length > 0; return (
{/* 連接線 (上層到此節點) */} {level > 0 && (
)} {/* 橫向連接線 */} {level > 0 && (
)}
{level > 0 && (
)}
{getNodeIcon(node.type)}

{node.label}

{node.date && (
{formatDate(node.date)}
)}
{(node.product_name || node.warehouse_name || (node.quantity !== undefined && node.quantity !== null)) && (
{node.product_name && (
品名 / 規格 {node.product_name} {node.spec && ({node.spec})}
)} {node.warehouse_name && (
倉庫 {node.warehouse_name}
)} {node.quantity !== undefined && node.quantity !== null && (
數量 {Number(node.quantity).toLocaleString()} {node.unit || 'PCS'}
)}
)}
{hasChildren && (
{node.children!.map((child, index) => ( ))}
)}
); }; export default function TreeView({ data }: TreeViewProps) { if (!data) return null; return (
); }