/** * Commission Payment Page * * 2-column layout: * - Left: payment method selector + action * - Right: booking summary */ 'use client'; import { useState, useEffect } from 'react'; import { useRouter, useParams } from 'next/navigation'; import { CreditCard, Building2, ArrowLeft, Loader2, AlertTriangle, CheckCircle, Copy, Clock, } from 'lucide-react'; import { getCsvBooking, payBookingCommission, declareBankTransfer } from '@/lib/api/bookings'; interface BookingData { id: string; bookingNumber?: string; carrierName: string; carrierEmail: string; origin: string; destination: string; volumeCBM: number; weightKG: number; palletCount: number; priceEUR: number; priceUSD: number; primaryCurrency: string; transitDays: number; containerType: string; status: string; commissionRate?: number; commissionAmountEur?: number; } type PaymentMethod = 'card' | 'transfer' | null; const BANK_DETAILS = { beneficiary: 'XPEDITIS SAS', iban: 'FR76 XXXX XXXX XXXX XXXX XXXX XXX', bic: 'XXXXXXXX', }; export default function PayCommissionPage() { const router = useRouter(); const params = useParams(); const bookingId = params.id as string; const [booking, setBooking] = useState(null); const [loading, setLoading] = useState(true); const [paying, setPaying] = useState(false); const [declaring, setDeclaring] = useState(false); const [error, setError] = useState(null); const [selectedMethod, setSelectedMethod] = useState(null); const [copied, setCopied] = useState(null); useEffect(() => { async function fetchBooking() { try { const data = await getCsvBooking(bookingId); setBooking(data as any); if (data.status !== 'PENDING_PAYMENT') { router.replace('/dashboard/bookings'); } } catch (err) { setError('Impossible de charger les détails du booking'); } finally { setLoading(false); } } if (bookingId) fetchBooking(); }, [bookingId, router]); const handlePayByCard = async () => { setPaying(true); setError(null); try { const result = await payBookingCommission(bookingId); window.location.href = result.sessionUrl; } catch (err) { setError(err instanceof Error ? err.message : 'Erreur lors de la création du paiement'); setPaying(false); } }; const handleDeclareTransfer = async () => { setDeclaring(true); setError(null); try { await declareBankTransfer(bookingId); router.push('/dashboard/bookings?transfer=declared'); } catch (err) { setError(err instanceof Error ? err.message : 'Erreur lors de la déclaration du virement'); setDeclaring(false); } }; const copyToClipboard = (value: string, key: string) => { navigator.clipboard.writeText(value); setCopied(key); setTimeout(() => setCopied(null), 2000); }; const formatPrice = (price: number, currency: string) => new Intl.NumberFormat('fr-FR', { style: 'currency', currency }).format(price); if (loading) { return (
Chargement...
); } if (error && !booking) { return (

{error}

); } if (!booking) return null; const commissionAmount = booking.commissionAmountEur || 0; const commissionRate = booking.commissionRate || 0; const reference = booking.bookingNumber || booking.id.slice(0, 8).toUpperCase(); return (
{/* Back button */}

Paiement de la commission

Finalisez votre booking en réglant la commission de service

{error && (

{error}

)}
{/* LEFT — Payment method selector */}

Choisir le mode de paiement

{/* Card option */} {/* Transfer option */} {/* Card action */} {selectedMethod === 'card' && (

Vous serez redirigé vers Stripe pour finaliser votre paiement en toute sécurité.

)} {/* Transfer action */} {selectedMethod === 'transfer' && (

Effectuez le virement avec les coordonnées ci-dessous, puis cliquez sur “J'ai effectué le virement”.

{/* Bank details */}
{[ { label: 'Bénéficiaire', value: BANK_DETAILS.beneficiary, key: 'beneficiary' }, { label: 'IBAN', value: BANK_DETAILS.iban, key: 'iban', mono: true }, { label: 'BIC / SWIFT', value: BANK_DETAILS.bic, key: 'bic', mono: true }, { label: 'Montant', value: formatPrice(commissionAmount, 'EUR'), key: 'amount', bold: true, }, { label: 'Référence', value: reference, key: 'ref', mono: true }, ].map(({ label, value, key, mono, bold }) => (
{label}
{value} {key !== 'amount' && ( )}
))}
Mentionnez impérativement la référence {reference} dans le libellé du virement.
)} {/* Placeholder when no method selected */} {selectedMethod === null && (
Sélectionnez un mode de paiement ci-dessus
)}
{/* RIGHT — Booking summary */}

Récapitulatif

{booking.bookingNumber && (
Numéro {booking.bookingNumber}
)}
Transporteur {booking.carrierName}
Trajet {booking.origin} → {booking.destination}
Volume / Poids {booking.volumeCBM} CBM · {booking.weightKG} kg
Transit {booking.transitDays} jours
Prix transport {formatPrice(booking.priceEUR, 'EUR')}
{/* Commission box */}

Commission ({commissionRate}% du prix transport)

{formatPrice(commissionAmount, 'EUR')}

{formatPrice(booking.priceEUR, 'EUR')} × {commissionRate}%

Après validation du paiement, votre demande est envoyée au transporteur ( {booking.carrierEmail}). Vous serez notifié de sa réponse.

); }