'use client'; import { useEffect, useState } from 'react'; import { useRouter, useSearchParams } from 'next/navigation'; import { searchCsvRatesWithOffers } from '@/lib/api/rates'; import type { CsvRateSearchResult } from '@/types/rates'; interface BestOptions { eco: CsvRateSearchResult; standard: CsvRateSearchResult; fast: CsvRateSearchResult; } export default function SearchResultsPage() { const router = useRouter(); const searchParams = useSearchParams(); const [results, setResults] = useState([]); const [isLoading, setIsLoading] = useState(true); const [error, setError] = useState(null); // Parse search parameters from URL const origin = searchParams.get('origin') || ''; const destination = searchParams.get('destination') || ''; const volumeCBM = parseFloat(searchParams.get('volumeCBM') || '0'); const weightKG = parseFloat(searchParams.get('weightKG') || '0'); const palletCount = parseInt(searchParams.get('palletCount') || '0'); useEffect(() => { if (!origin || !destination || !volumeCBM || !weightKG) { router.push('/dashboard/search-advanced'); return; } performSearch(); }, [origin, destination, volumeCBM, weightKG, palletCount]); const performSearch = async () => { setIsLoading(true); setError(null); try { const response = await searchCsvRatesWithOffers({ origin, destination, volumeCBM, weightKG, palletCount, hasDangerousGoods: searchParams.get('hasDangerousGoods') === 'true', requiresSpecialHandling: searchParams.get('requiresSpecialHandling') === 'true', requiresTailgate: searchParams.get('requiresTailgate') === 'true', requiresStraps: searchParams.get('requiresStraps') === 'true', requiresThermalCover: searchParams.get('requiresThermalCover') === 'true', hasRegulatedProducts: searchParams.get('hasRegulatedProducts') === 'true', requiresAppointment: searchParams.get('requiresAppointment') === 'true', }); setResults(response.results); } catch (err) { console.error('Search error:', err); setError(err instanceof Error ? err.message : 'Une erreur est survenue lors de la recherche'); } finally { setIsLoading(false); } }; const getBestOptions = (): BestOptions | null => { if (results.length === 0) return null; // Filter results by serviceLevel (backend generates 3 offers per rate) const economic = results.find(r => r.serviceLevel === 'ECONOMIC'); const standard = results.find(r => r.serviceLevel === 'STANDARD'); const rapid = results.find(r => r.serviceLevel === 'RAPID'); // If we have all 3 service levels, return them if (economic && standard && rapid) { return { eco: economic, standard: standard, fast: rapid, }; } // Fallback: if serviceLevel is not present (old endpoint), use sorting const sorted = [...results].sort((a, b) => a.priceEUR - b.priceEUR); const fastest = [...results].sort((a, b) => a.transitDays - b.transitDays); return { eco: sorted[0], standard: sorted[Math.floor(sorted.length / 2)] || sorted[0], fast: fastest[0], }; }; const bestOptions = getBestOptions(); const formatPrice = (price: number) => { return new Intl.NumberFormat('fr-FR', { style: 'currency', currency: 'EUR', }).format(price); }; if (isLoading) { return (

Recherche des meilleurs tarifs en cours...

{origin} → {destination}

); } if (error) { return (

Erreur

{error}

); } if (results.length === 0) { return (
🔍

Aucun résultat trouvé

Aucun tarif ne correspond à votre recherche pour le trajet {origin} → {destination}

💡 Suggestions :

  • Ports disponibles : NLRTM, DEHAM, FRLEH, BEGNE (origine) → USNYC, USLAX, CNSHG, SGSIN (destination)
  • Volume : Essayez entre 1 et 200 CBM
  • Poids : Essayez entre 100 et 30000 kg
); } const optionCards = [ { type: 'Économique', option: bestOptions?.eco, colors: { border: 'border-green-200', bg: 'bg-green-50', text: 'text-green-800', button: 'bg-green-600 hover:bg-green-700', }, icon: '💰', badge: 'Le moins cher', }, { type: 'Standard', option: bestOptions?.standard, colors: { border: 'border-blue-200', bg: 'bg-blue-50', text: 'text-blue-800', button: 'bg-blue-600 hover:bg-blue-700', }, icon: '⚖️', badge: 'Équilibré', }, { type: 'Rapide', option: bestOptions?.fast, colors: { border: 'border-purple-200', bg: 'bg-purple-50', text: 'text-purple-800', button: 'bg-purple-600 hover:bg-purple-700', }, icon: '⚡', badge: 'Le plus rapide', }, ]; return (
{/* Header */}

Résultats de recherche

{origin}{destination}{' '} • {volumeCBM} CBM • {weightKG} kg {palletCount > 0 && ` • ${palletCount} palette${palletCount > 1 ? 's' : ''}`}

Tarifs trouvés

{results.length}

{/* Best Options */} {bestOptions && (

🏆 Meilleurs choix pour votre recherche

{optionCards.map(card => { if (!card.option) return null; return (
{card.icon}

{card.type}

{card.badge}

Prix total

{formatPrice(card.option.priceEUR)}

Transporteur : {card.option.companyName}
Transit : {card.option.transitDays} jours
Type : {card.option.containerType}
); })}
)} {/* All Results */}

Tous les tarifs disponibles ({results.length})

{results.map((result, index) => (

{result.companyName}

{result.origin} → {result.destination} • {result.containerType}

{formatPrice(result.priceEUR)}

Prix total

Prix de base

{formatPrice(result.priceBreakdown.basePrice)}

Frais volume

{formatPrice(result.priceBreakdown.volumeCharge)}

Frais poids

{formatPrice(result.priceBreakdown.weightCharge)}

Délai transit

{result.transitDays} jours

✓ Valide jusqu'au {new Date(result.validUntil).toLocaleDateString('fr-FR')} {result.hasSurcharges && ⚠️ Surcharges applicables}
))}
); }