xpeditis2.0/apps/frontend/app/dashboard/search-advanced/page.tsx
2026-02-03 22:14:03 +01:00

755 lines
29 KiB
TypeScript

/**
* Advanced Rate Search Page
*
* Complete search form with all filters and best options display
* Uses only ports available in CSV rates for origin/destination selection
*/
'use client';
import { useState, useEffect } from 'react';
import { useRouter } from 'next/navigation';
import { Search, Loader2 } from 'lucide-react';
import { useQuery } from '@tanstack/react-query';
import {
getAvailableOrigins,
getAvailableDestinations,
RoutePortInfo,
} from '@/lib/api/rates';
import dynamic from 'next/dynamic';
// Import dynamique pour éviter les erreurs SSR avec Leaflet
const PortRouteMap = dynamic(() => import('@/components/PortRouteMap'), {
ssr: false,
loading: () => <div className="h-80 bg-gray-100 rounded-lg flex items-center justify-center">Chargement de la carte...</div>,
});
interface Package {
type: 'caisse' | 'colis' | 'palette' | 'autre';
quantity: number;
length: number;
width: number;
height: number;
weight: number;
stackable: boolean;
}
interface SearchForm {
// General
origin: string;
destination: string;
// Conditionnement
packages: Package[];
// Douane
eurDocument: boolean;
customsStop: boolean;
exportAssistance: boolean;
// Marchandise
dangerousGoods: boolean;
specialHandling: boolean;
// Manutention
tailgate: boolean;
straps: boolean;
thermalCover: boolean;
// Autres
regulatedProducts: boolean;
appointment: boolean;
insurance: boolean;
t1Document: boolean;
}
export default function AdvancedSearchPage() {
const router = useRouter();
const [searchForm, setSearchForm] = useState<SearchForm>({
origin: '',
destination: '',
packages: [
{
type: 'palette',
quantity: 1,
length: 120,
width: 80,
height: 100,
weight: 500,
stackable: true,
},
],
eurDocument: false,
customsStop: false,
exportAssistance: false,
dangerousGoods: false,
specialHandling: false,
tailgate: false,
straps: false,
thermalCover: false,
regulatedProducts: false,
appointment: false,
insurance: false,
t1Document: false,
});
const [currentStep, setCurrentStep] = useState(1);
const [originSearch, setOriginSearch] = useState('');
const [destinationSearch, setDestinationSearch] = useState('');
const [showOriginDropdown, setShowOriginDropdown] = useState(false);
const [showDestinationDropdown, setShowDestinationDropdown] = useState(false);
const [selectedOriginPort, setSelectedOriginPort] = useState<RoutePortInfo | null>(null);
const [selectedDestinationPort, setSelectedDestinationPort] = useState<RoutePortInfo | null>(null);
// Fetch available origins from CSV rates
const { data: originsData, isLoading: isLoadingOrigins } = useQuery({
queryKey: ['available-origins'],
queryFn: getAvailableOrigins,
});
// Fetch available destinations based on selected origin
const { data: destinationsData, isLoading: isLoadingDestinations } = useQuery({
queryKey: ['available-destinations', searchForm.origin],
queryFn: () => getAvailableDestinations(searchForm.origin),
enabled: !!searchForm.origin,
});
// Filter origins based on search input
const filteredOrigins = (originsData?.origins || []).filter(port => {
if (!originSearch || originSearch.length < 1) return true;
const searchLower = originSearch.toLowerCase();
return (
port.code.toLowerCase().includes(searchLower) ||
port.name.toLowerCase().includes(searchLower) ||
port.city.toLowerCase().includes(searchLower) ||
port.countryName.toLowerCase().includes(searchLower)
);
});
// Filter destinations based on search input
const filteredDestinations = (destinationsData?.destinations || []).filter(port => {
if (!destinationSearch || destinationSearch.length < 1) return true;
const searchLower = destinationSearch.toLowerCase();
return (
port.code.toLowerCase().includes(searchLower) ||
port.name.toLowerCase().includes(searchLower) ||
port.city.toLowerCase().includes(searchLower) ||
port.countryName.toLowerCase().includes(searchLower)
);
});
// Reset destination when origin changes
useEffect(() => {
if (searchForm.origin && selectedDestinationPort) {
// Check if current destination is still valid for new origin
const isValidDestination = destinationsData?.destinations?.some(
d => d.code === searchForm.destination
);
if (!isValidDestination) {
setSearchForm(prev => ({ ...prev, destination: '' }));
setSelectedDestinationPort(null);
setDestinationSearch('');
}
}
}, [searchForm.origin, destinationsData]);
// Calculate total volume and weight
const calculateTotals = () => {
let totalVolumeCBM = 0;
let totalWeightKG = 0;
let totalPallets = 0;
searchForm.packages.forEach(pkg => {
const volumeM3 = (pkg.length * pkg.width * pkg.height) / 1000000;
totalVolumeCBM += volumeM3 * pkg.quantity;
totalWeightKG += pkg.weight * pkg.quantity;
if (pkg.type === 'palette') {
totalPallets += pkg.quantity;
}
});
return { totalVolumeCBM, totalWeightKG, totalPallets };
};
const handleSearch = () => {
const { totalVolumeCBM, totalWeightKG, totalPallets } = calculateTotals();
// Build query parameters
const params = new URLSearchParams({
origin: searchForm.origin,
destination: searchForm.destination,
volumeCBM: totalVolumeCBM.toString(),
weightKG: totalWeightKG.toString(),
palletCount: totalPallets.toString(),
hasDangerousGoods: searchForm.dangerousGoods.toString(),
requiresSpecialHandling: searchForm.specialHandling.toString(),
requiresTailgate: searchForm.tailgate.toString(),
requiresStraps: searchForm.straps.toString(),
requiresThermalCover: searchForm.thermalCover.toString(),
hasRegulatedProducts: searchForm.regulatedProducts.toString(),
requiresAppointment: searchForm.appointment.toString(),
});
// Redirect to results page
router.push(`/dashboard/search-advanced/results?${params.toString()}`);
};
const addPackage = () => {
setSearchForm({
...searchForm,
packages: [
...searchForm.packages,
{
type: 'palette',
quantity: 1,
length: 120,
width: 80,
height: 100,
weight: 500,
stackable: true,
},
],
});
};
const removePackage = (index: number) => {
setSearchForm({
...searchForm,
packages: searchForm.packages.filter((_, i) => i !== index),
});
};
const updatePackage = (index: number, field: keyof Package, value: any) => {
const newPackages = [...searchForm.packages];
newPackages[index] = { ...newPackages[index], [field]: value };
setSearchForm({ ...searchForm, packages: newPackages });
};
const renderStep1 = () => (
<div className="space-y-6">
<h2 className="text-xl font-semibold text-gray-900">1. Informations Générales</h2>
{/* Info banner about available routes */}
<div className="bg-blue-50 border border-blue-200 rounded-md p-3">
<p className="text-sm text-blue-800">
Seuls les ports ayant des tarifs disponibles dans notre système sont proposés.
{originsData?.total && (
<span className="font-medium"> ({originsData.total} ports d'origine disponibles)</span>
)}
</p>
</div>
<div className="grid grid-cols-2 gap-4">
{/* Origin Port with Autocomplete - Limited to CSV routes */}
<div className="relative">
<label className="block text-sm font-medium text-gray-700 mb-2">
Port d'origine * {searchForm.origin && <span className="text-green-600 text-xs"> Sélectionné</span>}
</label>
<div className="relative">
<input
type="text"
value={originSearch}
onChange={e => {
setOriginSearch(e.target.value);
setShowOriginDropdown(true);
// Clear selection if user modifies the input
if (selectedOriginPort && e.target.value !== selectedOriginPort.displayName) {
setSearchForm({ ...searchForm, origin: '', destination: '' });
setSelectedOriginPort(null);
setSelectedDestinationPort(null);
setDestinationSearch('');
}
}}
onFocus={() => setShowOriginDropdown(true)}
onBlur={() => setTimeout(() => setShowOriginDropdown(false), 200)}
placeholder="Rechercher un port d'origine..."
className={`w-full px-3 py-2 border rounded-md focus:ring-blue-500 focus:border-blue-500 ${
searchForm.origin ? 'border-green-500 bg-green-50' : 'border-gray-300'
}`}
/>
{isLoadingOrigins && (
<div className="absolute right-3 top-1/2 -translate-y-1/2">
<Loader2 className="h-4 w-4 animate-spin text-gray-400" />
</div>
)}
</div>
{showOriginDropdown && filteredOrigins.length > 0 && (
<div className="absolute left-0 right-0 mt-2 bg-white border border-gray-200 rounded-md shadow-lg max-h-60 overflow-y-auto z-50">
{filteredOrigins.slice(0, 15).map((port: RoutePortInfo) => (
<button
key={port.code}
type="button"
onClick={() => {
setSearchForm({ ...searchForm, origin: port.code, destination: '' });
setOriginSearch(port.displayName);
setSelectedOriginPort(port);
setSelectedDestinationPort(null);
setDestinationSearch('');
setShowOriginDropdown(false);
}}
className="w-full text-left px-4 py-3 hover:bg-blue-50 border-b border-gray-100 last:border-b-0"
>
<div className="font-medium text-gray-900">{port.name}</div>
<div className="text-gray-500 text-xs mt-1">
{port.code} - {port.city}, {port.countryName}
</div>
</button>
))}
{filteredOrigins.length > 15 && (
<div className="px-4 py-2 text-xs text-gray-500 bg-gray-50">
+{filteredOrigins.length - 15} autres résultats. Affinez votre recherche.
</div>
)}
</div>
)}
{showOriginDropdown && filteredOrigins.length === 0 && !isLoadingOrigins && originsData && (
<div className="absolute left-0 right-0 mt-2 bg-white border border-gray-200 rounded-md shadow-lg p-4 z-50">
<p className="text-sm text-gray-500">Aucun port d'origine trouvé pour "{originSearch}"</p>
</div>
)}
</div>
{/* Destination Port with Autocomplete - Limited to routes from selected origin */}
<div className="relative">
<label className="block text-sm font-medium text-gray-700 mb-2">
Port de destination * {searchForm.destination && <span className="text-green-600 text-xs">✓ Sélectionné</span>}
</label>
<div className="relative">
<input
type="text"
value={destinationSearch}
onChange={e => {
setDestinationSearch(e.target.value);
setShowDestinationDropdown(true);
// Clear selection if user modifies the input
if (selectedDestinationPort && e.target.value !== selectedDestinationPort.displayName) {
setSearchForm({ ...searchForm, destination: '' });
setSelectedDestinationPort(null);
}
}}
onFocus={() => setShowDestinationDropdown(true)}
onBlur={() => setTimeout(() => setShowDestinationDropdown(false), 200)}
disabled={!searchForm.origin}
placeholder={searchForm.origin ? 'Rechercher une destination...' : 'Sélectionnez d\'abord un port d\'origine'}
className={`w-full px-3 py-2 border rounded-md focus:ring-blue-500 focus:border-blue-500 ${
searchForm.destination ? 'border-green-500 bg-green-50' : 'border-gray-300'
} ${!searchForm.origin ? 'bg-gray-100 cursor-not-allowed' : ''}`}
/>
{isLoadingDestinations && searchForm.origin && (
<div className="absolute right-3 top-1/2 -translate-y-1/2">
<Loader2 className="h-4 w-4 animate-spin text-gray-400" />
</div>
)}
</div>
{searchForm.origin && destinationsData?.total !== undefined && (
<p className="text-xs text-gray-500 mt-1">
{destinationsData.total} destination{destinationsData.total > 1 ? 's' : ''} disponible{destinationsData.total > 1 ? 's' : ''} depuis {selectedOriginPort?.name || searchForm.origin}
</p>
)}
{showDestinationDropdown && filteredDestinations.length > 0 && (
<div className="absolute left-0 right-0 mt-2 bg-white border border-gray-200 rounded-md shadow-lg max-h-60 overflow-y-auto z-50">
{filteredDestinations.slice(0, 15).map((port: RoutePortInfo) => (
<button
key={port.code}
type="button"
onClick={() => {
setSearchForm({ ...searchForm, destination: port.code });
setDestinationSearch(port.displayName);
setSelectedDestinationPort(port);
setShowDestinationDropdown(false);
}}
className="w-full text-left px-4 py-3 hover:bg-blue-50 border-b border-gray-100 last:border-b-0"
>
<div className="font-medium text-gray-900">{port.name}</div>
<div className="text-gray-500 text-xs mt-1">
{port.code} - {port.city}, {port.countryName}
</div>
</button>
))}
{filteredDestinations.length > 15 && (
<div className="px-4 py-2 text-xs text-gray-500 bg-gray-50">
+{filteredDestinations.length - 15} autres résultats. Affinez votre recherche.
</div>
)}
</div>
)}
{showDestinationDropdown && filteredDestinations.length === 0 && !isLoadingDestinations && searchForm.origin && destinationsData && (
<div className="absolute left-0 right-0 mt-2 bg-white border border-gray-200 rounded-md shadow-lg p-4 z-50">
<p className="text-sm text-gray-500">Aucune destination trouvée pour "{destinationSearch}"</p>
</div>
)}
</div>
</div>
{/* Carte interactive de la route maritime */}
{selectedOriginPort && selectedDestinationPort && selectedOriginPort.latitude && selectedDestinationPort.latitude && (
<div className="mt-6 border border-gray-200 rounded-lg overflow-hidden">
<div className="bg-gray-50 px-4 py-3 border-b border-gray-200">
<h3 className="text-sm font-semibold text-gray-900">
Route maritime : {selectedOriginPort.name} {selectedDestinationPort.name}
</h3>
<p className="text-xs text-gray-500 mt-1">
Distance approximative et visualisation de la route
</p>
</div>
<PortRouteMap
portA={{
lat: selectedOriginPort.latitude,
lng: selectedOriginPort.longitude!,
}}
portB={{
lat: selectedDestinationPort.latitude,
lng: selectedDestinationPort.longitude!,
}}
height="400px"
/>
</div>
)}
</div>
);
const renderStep2 = () => (
<div className="space-y-6">
<div className="flex items-center justify-between">
<h2 className="text-xl font-semibold text-gray-900">2. Conditionnement</h2>
<button
type="button"
onClick={addPackage}
className="px-4 py-2 text-sm font-medium text-blue-700 bg-blue-50 rounded-md hover:bg-blue-100"
>
+ Ajouter un colis
</button>
</div>
{searchForm.packages.map((pkg, index) => (
<div key={index} className="border border-gray-200 rounded-lg p-4 space-y-4">
<div className="flex items-center justify-between">
<h3 className="font-medium text-gray-900">Colis #{index + 1}</h3>
{searchForm.packages.length > 1 && (
<button
type="button"
onClick={() => removePackage(index)}
className="text-sm text-red-600 hover:text-red-700"
>
Supprimer
</button>
)}
</div>
<div className="grid grid-cols-5 gap-3">
<div>
<label className="block text-xs font-medium text-gray-700 mb-1">Type</label>
<select
value={pkg.type}
onChange={e => updatePackage(index, 'type', e.target.value)}
className="w-full px-2 py-1.5 text-sm border border-gray-300 rounded-md"
>
<option value="caisse">Caisse</option>
<option value="colis">Colis</option>
<option value="palette">Palette</option>
<option value="autre">Autre</option>
</select>
</div>
<div>
<label className="block text-xs font-medium text-gray-700 mb-1">Quantité</label>
<input
type="number"
min="1"
value={pkg.quantity}
onChange={e => updatePackage(index, 'quantity', parseInt(e.target.value) || 1)}
className="w-full px-2 py-1.5 text-sm border border-gray-300 rounded-md"
/>
</div>
<div>
<label className="block text-xs font-medium text-gray-700 mb-1">L (cm)</label>
<input
type="number"
min="1"
value={pkg.length}
onChange={e => updatePackage(index, 'length', parseInt(e.target.value) || 0)}
className="w-full px-2 py-1.5 text-sm border border-gray-300 rounded-md"
/>
</div>
<div>
<label className="block text-xs font-medium text-gray-700 mb-1">l (cm)</label>
<input
type="number"
min="1"
value={pkg.width}
onChange={e => updatePackage(index, 'width', parseInt(e.target.value) || 0)}
className="w-full px-2 py-1.5 text-sm border border-gray-300 rounded-md"
/>
</div>
<div>
<label className="block text-xs font-medium text-gray-700 mb-1">H (cm)</label>
<input
type="number"
min="1"
value={pkg.height}
onChange={e => updatePackage(index, 'height', parseInt(e.target.value) || 0)}
className="w-full px-2 py-1.5 text-sm border border-gray-300 rounded-md"
/>
</div>
</div>
<div className="grid grid-cols-2 gap-3">
<div>
<label className="block text-xs font-medium text-gray-700 mb-1">Poids (kg)</label>
<input
type="number"
min="1"
value={pkg.weight}
onChange={e => updatePackage(index, 'weight', parseInt(e.target.value) || 0)}
className="w-full px-2 py-1.5 text-sm border border-gray-300 rounded-md"
/>
</div>
<div className="flex items-center pt-6">
<input
type="checkbox"
checked={pkg.stackable}
onChange={e => updatePackage(index, 'stackable', e.target.checked)}
className="h-4 w-4 text-blue-600 border-gray-300 rounded"
/>
<label className="ml-2 text-sm text-gray-700">Gerbable</label>
</div>
</div>
</div>
))}
<div className="bg-blue-50 border border-blue-200 rounded-md p-4">
<h3 className="text-sm font-medium text-blue-900 mb-2">Récapitulatif</h3>
<div className="text-sm text-blue-800 space-y-1">
<div>Volume total: {calculateTotals().totalVolumeCBM.toFixed(2)} m³</div>
<div>Poids total: {calculateTotals().totalWeightKG} kg</div>
<div>Palettes: {calculateTotals().totalPallets}</div>
</div>
</div>
</div>
);
const renderStep3 = () => (
<div className="space-y-6">
<h2 className="text-xl font-semibold text-gray-900">3. Options & Services</h2>
<div className="space-y-4">
<div className="border-b pb-4">
<h3 className="text-sm font-semibold text-gray-900 mb-3">Douane Import / Export</h3>
<div className="space-y-2">
<label className="flex items-center">
<input
type="checkbox"
checked={searchForm.eurDocument}
onChange={e => setSearchForm({ ...searchForm, eurDocument: e.target.checked })}
className="h-4 w-4 text-blue-600 border-gray-300 rounded"
/>
<span className="ml-2 text-sm text-gray-700">EUR 1</span>
</label>
<label className="flex items-center">
<input
type="checkbox"
checked={searchForm.t1Document}
onChange={e => setSearchForm({ ...searchForm, t1Document: e.target.checked })}
className="h-4 w-4 text-blue-600 border-gray-300 rounded"
/>
<span className="ml-2 text-sm text-gray-700">T1</span>
</label>
<label className="flex items-center">
<input
type="checkbox"
checked={searchForm.customsStop}
onChange={e => setSearchForm({ ...searchForm, customsStop: e.target.checked })}
className="h-4 w-4 text-blue-600 border-gray-300 rounded"
/>
<span className="ml-2 text-sm text-gray-700">Stop douane</span>
</label>
<label className="flex items-center">
<input
type="checkbox"
checked={searchForm.exportAssistance}
onChange={e =>
setSearchForm({ ...searchForm, exportAssistance: e.target.checked })
}
className="h-4 w-4 text-blue-600 border-gray-300 rounded"
/>
<span className="ml-2 text-sm text-gray-700">Assistance export</span>
</label>
</div>
</div>
<div className="border-b pb-4">
<h3 className="text-sm font-semibold text-gray-900 mb-3">Marchandise</h3>
<div className="space-y-2">
<label className="flex items-center">
<input
type="checkbox"
checked={searchForm.dangerousGoods}
onChange={e => setSearchForm({ ...searchForm, dangerousGoods: e.target.checked })}
className="h-4 w-4 text-blue-600 border-gray-300 rounded"
/>
<span className="ml-2 text-sm text-gray-700">Marchandise Dangereuse</span>
</label>
<label className="flex items-center">
<input
type="checkbox"
checked={searchForm.regulatedProducts}
onChange={e =>
setSearchForm({ ...searchForm, regulatedProducts: e.target.checked })
}
className="h-4 w-4 text-blue-600 border-gray-300 rounded"
/>
<span className="ml-2 text-sm text-gray-700">Produits règlementés</span>
</label>
</div>
</div>
<div className="border-b pb-4">
<h3 className="text-sm font-semibold text-gray-900 mb-3">Manutention particulière</h3>
<div className="space-y-2">
<label className="flex items-center">
<input
type="checkbox"
checked={searchForm.specialHandling}
onChange={e =>
setSearchForm({ ...searchForm, specialHandling: e.target.checked })
}
className="h-4 w-4 text-blue-600 border-gray-300 rounded"
/>
<span className="ml-2 text-sm text-gray-700">Manutention spéciale</span>
</label>
<label className="flex items-center">
<input
type="checkbox"
checked={searchForm.tailgate}
onChange={e => setSearchForm({ ...searchForm, tailgate: e.target.checked })}
className="h-4 w-4 text-blue-600 border-gray-300 rounded"
/>
<span className="ml-2 text-sm text-gray-700">Hayon</span>
</label>
<label className="flex items-center">
<input
type="checkbox"
checked={searchForm.straps}
onChange={e => setSearchForm({ ...searchForm, straps: e.target.checked })}
className="h-4 w-4 text-blue-600 border-gray-300 rounded"
/>
<span className="ml-2 text-sm text-gray-700">Sangles</span>
</label>
<label className="flex items-center">
<input
type="checkbox"
checked={searchForm.thermalCover}
onChange={e => setSearchForm({ ...searchForm, thermalCover: e.target.checked })}
className="h-4 w-4 text-blue-600 border-gray-300 rounded"
/>
<span className="ml-2 text-sm text-gray-700">Couverture thermique</span>
</label>
</div>
</div>
<div>
<h3 className="text-sm font-semibold text-gray-900 mb-3">Autres options</h3>
<div className="space-y-2">
<label className="flex items-center">
<input
type="checkbox"
checked={searchForm.appointment}
onChange={e => setSearchForm({ ...searchForm, appointment: e.target.checked })}
className="h-4 w-4 text-blue-600 border-gray-300 rounded"
/>
<span className="ml-2 text-sm text-gray-700">Rendez-vous livraison</span>
</label>
<label className="flex items-center">
<input
type="checkbox"
checked={searchForm.insurance}
onChange={e => setSearchForm({ ...searchForm, insurance: e.target.checked })}
className="h-4 w-4 text-blue-600 border-gray-300 rounded"
/>
<span className="ml-2 text-sm text-gray-700">Assurance</span>
</label>
</div>
</div>
</div>
</div>
);
return (
<div className="max-w-7xl mx-auto space-y-6">
{/* Header */}
<div>
<h1 className="text-3xl font-bold text-gray-900">Recherche Avancée de Tarifs</h1>
<p className="text-sm text-gray-500 mt-1">
Formulaire complet avec toutes les options de transport
</p>
</div>
{/* Progress Steps */}
<div className="flex items-center justify-center space-x-4">
{[1, 2, 3].map(step => (
<div key={step} className="flex items-center">
<div
className={`flex items-center justify-center w-10 h-10 rounded-full ${
currentStep >= step ? 'bg-blue-600 text-white' : 'bg-gray-200 text-gray-600'
}`}
>
{step}
</div>
{step < 3 && (
<div
className={`w-20 h-1 mx-2 ${
currentStep > step ? 'bg-blue-600' : 'bg-gray-200'
}`}
/>
)}
</div>
))}
</div>
{/* Form */}
<div className="bg-white rounded-lg shadow p-8">
{currentStep === 1 && renderStep1()}
{currentStep === 2 && renderStep2()}
{currentStep === 3 && renderStep3()}
{/* Navigation */}
<div className="mt-8 flex items-center justify-between pt-6 border-t">
<button
type="button"
onClick={() => setCurrentStep(Math.max(1, currentStep - 1))}
disabled={currentStep === 1}
className="px-6 py-2 text-sm font-medium text-gray-700 bg-gray-100 rounded-md hover:bg-gray-200 disabled:opacity-50 disabled:cursor-not-allowed"
>
Précédent
</button>
{currentStep < 3 ? (
<button
type="button"
onClick={() => setCurrentStep(currentStep + 1)}
disabled={!searchForm.origin || !searchForm.destination}
className="px-6 py-2 text-sm font-medium text-white bg-blue-600 rounded-md hover:bg-blue-700 disabled:opacity-50 disabled:cursor-not-allowed"
>
Suivant
</button>
) : (
<button
type="button"
onClick={handleSearch}
disabled={!searchForm.origin || !searchForm.destination}
className="px-6 py-3 text-base font-medium text-white bg-green-600 rounded-md hover:bg-green-700 disabled:opacity-50 disabled:cursor-not-allowed flex items-center"
>
<Search className="h-5 w-5 mr-2" /> Rechercher les tarifs
</button>
)}
</div>
</div>
</div>
);
}