/** * Track & Trace Page * * Allows users to track their shipments by entering tracking numbers * and selecting the carrier. Includes search history and vessel position map. */ 'use client'; import { useState, useEffect } from 'react'; import { Card, CardHeader, CardTitle, CardDescription, CardContent } from '@/components/ui/card'; import { Input } from '@/components/ui/input'; import { Button } from '@/components/ui/button'; import { Search, Package, FileText, ClipboardList, Lightbulb, History, MapPin, X, Clock, Ship, ExternalLink, Maximize2, Minimize2, Globe, Anchor, } from 'lucide-react'; // Search history item type interface SearchHistoryItem { id: string; trackingNumber: string; carrierId: string; carrierName: string; timestamp: Date; } // Carrier tracking URLs with official brand colors const carriers = [ { id: 'maersk', name: 'Maersk', color: '#00243D', // Maersk dark blue textColor: 'text-white', trackingUrl: 'https://www.maersk.com/tracking/', placeholder: 'Ex: MSKU1234567', description: 'N° conteneur ou B/L', logo: '/assets/logos/carriers/maersk.svg', }, { id: 'msc', name: 'MSC', color: '#002B5C', // MSC blue textColor: 'text-white', trackingUrl: 'https://www.msc.com/track-a-shipment?query=', placeholder: 'Ex: MSCU1234567', description: 'N° conteneur, B/L ou réservation', logo: '/assets/logos/carriers/msc.svg', }, { id: 'cma-cgm', name: 'CMA CGM', color: '#E30613', // CMA CGM red textColor: 'text-white', trackingUrl: 'https://www.cma-cgm.com/ebusiness/tracking/search?SearchBy=Container&Reference=', placeholder: 'Ex: CMAU1234567', description: 'N° conteneur ou B/L', logo: '/assets/logos/carriers/cmacgm.svg', }, { id: 'hapag-lloyd', name: 'Hapag-Lloyd', color: '#FF6600', // Hapag orange textColor: 'text-white', trackingUrl: 'https://www.hapag-lloyd.com/en/online-business/track/track-by-container-solution.html?container=', placeholder: 'Ex: HLCU1234567', description: 'N° conteneur', logo: '/assets/logos/carriers/hapag.svg', }, { id: 'cosco', name: 'COSCO', color: '#003A70', // COSCO blue textColor: 'text-white', trackingUrl: 'https://elines.coscoshipping.com/ebusiness/cargoTracking?trackingNumber=', placeholder: 'Ex: COSU1234567', description: 'N° conteneur ou B/L', logo: '/assets/logos/carriers/cosco.svg', }, { id: 'one', name: 'ONE', color: '#FF00FF', // ONE magenta textColor: 'text-white', trackingUrl: 'https://ecomm.one-line.com/one-ecom/manage-shipment/cargo-tracking?trkNoParam=', placeholder: 'Ex: ONEU1234567', description: 'N° conteneur ou B/L', logo: '/assets/logos/carriers/one.svg', }, { id: 'evergreen', name: 'Evergreen', color: '#006633', // Evergreen green textColor: 'text-white', trackingUrl: 'https://www.shipmentlink.com/servlet/TDB1_CargoTracking.do?BL=', placeholder: 'Ex: EGHU1234567', description: 'N° conteneur ou B/L', logo: '/assets/logos/carriers/evergreen.svg', }, { id: 'yangming', name: 'Yang Ming', color: '#FFD700', // Yang Ming yellow textColor: 'text-gray-900', trackingUrl: 'https://www.yangming.com/e-service/Track_Trace/track_trace_cargo_tracking.aspx?rdolType=CT&str=', placeholder: 'Ex: YMLU1234567', description: 'N° conteneur', logo: '/assets/logos/carriers/yangming.svg', }, { id: 'zim', name: 'ZIM', color: '#1E3A8A', // ZIM blue textColor: 'text-white', trackingUrl: 'https://www.zim.com/tools/track-a-shipment?consnumber=', placeholder: 'Ex: ZIMU1234567', description: 'N° conteneur ou B/L', logo: '/assets/logos/carriers/zim.svg', }, { id: 'hmm', name: 'HMM', color: '#E65100', // HMM orange textColor: 'text-white', trackingUrl: 'https://www.hmm21.com/cms/business/ebiz/trackTrace/trackTrace/index.jsp?type=1&number=', placeholder: 'Ex: HDMU1234567', description: 'N° conteneur ou B/L', logo: '/assets/logos/carriers/hmm.svg', }, ]; // Local storage keys const HISTORY_KEY = 'xpeditis_track_history'; export default function TrackTracePage() { const [trackingNumber, setTrackingNumber] = useState(''); const [selectedCarrier, setSelectedCarrier] = useState(''); const [error, setError] = useState(''); const [searchHistory, setSearchHistory] = useState([]); const [showMap, setShowMap] = useState(false); const [isMapFullscreen, setIsMapFullscreen] = useState(false); const [isMapLoading, setIsMapLoading] = useState(true); // Load history from localStorage on mount useEffect(() => { const savedHistory = localStorage.getItem(HISTORY_KEY); if (savedHistory) { try { const parsed = JSON.parse(savedHistory); setSearchHistory(parsed.map((item: any) => ({ ...item, timestamp: new Date(item.timestamp) }))); } catch (e) { console.error('Failed to parse search history:', e); } } }, []); // Save to localStorage const saveHistory = (history: SearchHistoryItem[]) => { localStorage.setItem(HISTORY_KEY, JSON.stringify(history)); setSearchHistory(history); }; const handleTrack = () => { if (!trackingNumber.trim()) { setError('Veuillez entrer un numéro de tracking'); return; } if (!selectedCarrier) { setError('Veuillez sélectionner un transporteur'); return; } setError(''); const carrier = carriers.find(c => c.id === selectedCarrier); if (carrier) { // Add to history const newHistoryItem: SearchHistoryItem = { id: Date.now().toString(), trackingNumber: trackingNumber.trim(), carrierId: carrier.id, carrierName: carrier.name, timestamp: new Date(), }; // Keep only last 10 unique searches const updatedHistory = [newHistoryItem, ...searchHistory.filter( h => !(h.trackingNumber === newHistoryItem.trackingNumber && h.carrierId === newHistoryItem.carrierId) )].slice(0, 10); saveHistory(updatedHistory); const trackingUrl = carrier.trackingUrl + encodeURIComponent(trackingNumber.trim()); window.open(trackingUrl, '_blank', 'noopener,noreferrer'); } }; const handleHistoryClick = (item: SearchHistoryItem) => { setTrackingNumber(item.trackingNumber); setSelectedCarrier(item.carrierId); }; const handleDeleteHistory = (id: string) => { const updatedHistory = searchHistory.filter(h => h.id !== id); saveHistory(updatedHistory); }; const handleClearHistory = () => { saveHistory([]); }; const handleKeyPress = (e: React.KeyboardEvent) => { if (e.key === 'Enter') { handleTrack(); } }; const selectedCarrierData = carriers.find(c => c.id === selectedCarrier); const formatTimeAgo = (date: Date) => { const now = new Date(); const diffMs = now.getTime() - date.getTime(); const diffMins = Math.floor(diffMs / 60000); const diffHours = Math.floor(diffMs / 3600000); const diffDays = Math.floor(diffMs / 86400000); if (diffMins < 1) return 'À l\'instant'; if (diffMins < 60) return `Il y a ${diffMins}min`; if (diffHours < 24) return `Il y a ${diffHours}h`; if (diffDays < 7) return `Il y a ${diffDays}j`; return date.toLocaleDateString('fr-FR'); }; return (
{/* Header */}

Suivi des expéditions

Suivez vos expéditions en temps réel. Entrez votre numéro de tracking et sélectionnez le transporteur.

{/* Search Form */} Rechercher une expédition Entrez votre numéro de conteneur, connaissement (B/L) ou référence de réservation {/* Carrier Selection - US 5.1: Professional carrier cards with brand colors */}
{carriers.map(carrier => ( ))}
{/* Tracking Number Input */}
{ setTrackingNumber(e.target.value.toUpperCase()); setError(''); }} onKeyPress={handleKeyPress} placeholder={selectedCarrierData?.placeholder || 'Ex: MSKU1234567'} className="text-lg font-mono border-gray-300 focus:border-blue-500 h-12" /> {selectedCarrierData && (

{selectedCarrierData.description}

)}
{/* US 5.2: Harmonized button color */}
{/* Action Button - Map */}
{/* Error Message */} {error && (

{error}

)}
{/* Vessel Position Map - Large immersive display */} {showMap && (
{/* Map Header */}

Carte Maritime Mondiale

Position des navires en temps réel

{/* Fullscreen Toggle */} {/* Close Button */}
{/* Map Container */}
{/* Loading State */} {isMapLoading && (

Chargement de la carte...

Connexion à MarineTraffic

)} {/* MarineTraffic Map */}