'use client'; import { useEffect, useState, useRef } from 'react'; import { useParams } from 'next/navigation'; import { FileText, Download, Loader2, XCircle, Package, Ship, Clock, AlertCircle, ArrowRight, } from 'lucide-react'; interface Document { id: string; type: string; fileName: string; mimeType: string; size: number; downloadUrl: string; } interface BookingSummary { id: string; carrierName: string; origin: string; destination: string; routeDescription: string; volumeCBM: number; weightKG: number; palletCount: number; price: number; currency: string; transitDays: number; containerType: string; acceptedAt: string; } interface CarrierDocumentsData { booking: BookingSummary; documents: Document[]; } const documentTypeLabels: Record = { BILL_OF_LADING: 'Connaissement', PACKING_LIST: 'Liste de colisage', COMMERCIAL_INVOICE: 'Facture commerciale', CERTIFICATE_OF_ORIGIN: "Certificat d'origine", OTHER: 'Autre document', }; const formatFileSize = (bytes: number): string => { if (bytes < 1024) return `${bytes} B`; if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`; return `${(bytes / (1024 * 1024)).toFixed(1)} MB`; }; const getFileIcon = (mimeType: string) => { if (mimeType.includes('pdf')) return '📄'; if (mimeType.includes('image')) return '🖼️'; if (mimeType.includes('spreadsheet') || mimeType.includes('excel')) return '📊'; if (mimeType.includes('word') || mimeType.includes('document')) return '📝'; return '📎'; }; export default function CarrierDocumentsPage() { const params = useParams(); const token = params.token as string; const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [data, setData] = useState(null); const [downloading, setDownloading] = useState(null); const hasCalledApi = useRef(false); const fetchDocuments = async () => { if (!token) { setError('Lien invalide'); setLoading(false); return; } try { const apiUrl = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:4000'; const response = await fetch(`${apiUrl}/api/v1/csv-booking-actions/documents/${token}`, { method: 'GET', headers: { 'Content-Type': 'application/json', }, }); if (!response.ok) { let errorData; try { errorData = await response.json(); } catch { errorData = { message: `Erreur HTTP ${response.status}` }; } const errorMessage = errorData.message || 'Erreur lors du chargement des documents'; if (errorMessage.includes('pas encore été acceptée') || errorMessage.includes('not accepted')) { throw new Error('Cette réservation n\'a pas encore été acceptée. Les documents seront disponibles après l\'acceptation.'); } else if (errorMessage.includes('introuvable') || errorMessage.includes('not found')) { throw new Error('Réservation introuvable. Vérifiez que le lien est correct.'); } throw new Error(errorMessage); } const responseData = await response.json(); setData(responseData); setLoading(false); } catch (err) { console.error('Error fetching documents:', err); setError(err instanceof Error ? err.message : 'Erreur lors du chargement'); setLoading(false); } }; useEffect(() => { if (hasCalledApi.current) return; hasCalledApi.current = true; fetchDocuments(); }, [token]); const handleDownload = async (doc: Document) => { setDownloading(doc.id); try { // The downloadUrl is already a signed URL, open it directly window.open(doc.downloadUrl, '_blank'); } catch (err) { console.error('Error downloading document:', err); alert('Erreur lors du téléchargement. Veuillez réessayer.'); } finally { // Small delay to show loading state setTimeout(() => setDownloading(null), 500); } }; const handleRefresh = () => { setLoading(true); setError(null); hasCalledApi.current = false; fetchDocuments(); }; if (loading) { return (

Chargement des documents...

Veuillez patienter

); } if (error) { return (

Erreur

{error}

); } if (!data) return null; const { booking, documents } = data; return (
{/* Header */}
Xpeditis
{/* Booking Summary Card */}
{booking.origin} {booking.destination}

Volume

{booking.volumeCBM} CBM

Poids

{booking.weightKG} kg

Transit

{booking.transitDays} jours

Type

{booking.containerType}

Transporteur: {booking.carrierName} Ref: {booking.id.substring(0, 8).toUpperCase()}
{/* Documents Section */}

Documents ({documents.length})

{documents.length === 0 ? (

Aucun document disponible pour le moment.

Les documents apparaîtront ici une fois ajoutés.

) : (
{documents.map((doc) => (
{getFileIcon(doc.mimeType)}

{doc.fileName}

{documentTypeLabels[doc.type] || doc.type} {formatFileSize(doc.size)}
))}
)}
{/* Info */}

Cette page affiche toujours les documents les plus récents de la réservation.

{/* Footer */}
); }