diff --git a/frontend/package/components/ShipmentCard/ShipmentCard.tsx b/frontend/package/components/ShipmentCard/ShipmentCard.tsx new file mode 100644 index 00000000..0e6d02e5 --- /dev/null +++ b/frontend/package/components/ShipmentCard/ShipmentCard.tsx @@ -0,0 +1,94 @@ +'use client'; + +import { Card, CardContent, CardHeader } from '@/components/ui/card'; +import { StatusBadge } from '@/components/shipment/status-badge'; +import type { Shipment } from '@/types/shipment.types'; + +const STATUS_STYLES: Record = { + pending: { label: 'Pending', className: 'bg-gray-100 text-gray-600' }, + accepted: { label: 'Accepted', className: 'bg-blue-100 text-blue-700' }, + in_transit: { label: 'In Transit', className: 'bg-amber-100 text-amber-700' }, + delivered: { label: 'Delivered', className: 'bg-green-100 text-green-700' }, + completed: { label: 'Completed', className: 'bg-teal-100 text-teal-700' }, + cancelled: { label: 'Cancelled', className: 'bg-red-100 text-red-700' }, + disputed: { label: 'Disputed', className: 'bg-red-100 text-red-700' }, +}; + +export interface ShipmentCardProps { + shipment: Shipment; + onViewDetails?: (id: string) => void; +} + +export function ShipmentCard({ shipment, onViewDetails }: ShipmentCardProps) { + const statusConfig = STATUS_STYLES[shipment.status] ?? { + label: shipment.status, + className: 'bg-gray-100 text-gray-600', + }; + + const formattedPrice = new Intl.NumberFormat('en-US', { + style: 'currency', + currency: shipment.currency || 'USD', + }).format(Number(shipment.price)); + + const createdDate = shipment.createdAt + ? new Date(shipment.createdAt).toLocaleDateString('en-US', { + month: 'short', + day: 'numeric', + year: 'numeric', + }) + : ''; + + return ( + + +
+
+

+ {shipment.trackingNumber} +

+

+ {shipment.origin} → {shipment.destination} +

+
+ + {statusConfig.label} + +
+
+ +

+ {shipment.cargoDescription || 'No description'} +

+
+
+ {shipment.weightKg != null && ( + {Number(shipment.weightKg).toLocaleString()} kg + )} + {shipment.volumeCbm && ( + {Number(shipment.volumeCbm)} m³ + )} +
+ {formattedPrice} +
+ {createdDate && ( +

{createdDate}

+ )} + {onViewDetails && ( +
+ +
+ )} +
+
+ ); +} diff --git a/frontend/package/components/ShipmentCard/index.ts b/frontend/package/components/ShipmentCard/index.ts new file mode 100644 index 00000000..adf5b272 --- /dev/null +++ b/frontend/package/components/ShipmentCard/index.ts @@ -0,0 +1,2 @@ +export { ShipmentCard } from './ShipmentCard'; +export type { ShipmentCardProps } from './ShipmentCard';