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 (
);
}