'use client'; import { useState, useEffect, useRef } from 'react'; interface AddressSuggestion { display_name: string; lat: string; lon: string; } interface AddressAutocompleteProps { value: string; onChange: (address: string) => void; placeholder?: string; required?: boolean; } export default function AddressAutocomplete({ value, onChange, placeholder = 'Rechercher une adresse...', required = false, }: AddressAutocompleteProps) { const [suggestions, setSuggestions] = useState([]); const [showSuggestions, setShowSuggestions] = useState(false); const [loading, setLoading] = useState(false); const wrapperRef = useRef(null); const timeoutRef = useRef(null); useEffect(() => { const handleClickOutside = (event: MouseEvent) => { if (wrapperRef.current && !wrapperRef.current.contains(event.target as Node)) { setShowSuggestions(false); } }; document.addEventListener('mousedown', handleClickOutside); return () => { document.removeEventListener('mousedown', handleClickOutside); if (timeoutRef.current) { clearTimeout(timeoutRef.current); } }; }, []); const searchAddresses = async (query: string) => { if (query.length < 3) { setSuggestions([]); return; } setLoading(true); try { // Annuler la requête précédente si elle existe if (timeoutRef.current) { clearTimeout(timeoutRef.current); } // Attendre un peu avant de faire la requête (debounce) timeoutRef.current = setTimeout(async () => { try { const response = await fetch( `https://nominatim.openstreetmap.org/search?format=json&q=${encodeURIComponent(query)}&limit=5&addressdetails=1&countrycodes=fr`, { headers: { 'User-Agent': 'MAD Platform', 'Accept-Language': 'fr-FR,fr;q=0.9', }, } ); if (response.ok) { const data = await response.json(); setSuggestions(data); setShowSuggestions(true); } } catch (error) { console.error('Erreur lors de la recherche d\'adresses:', error); } finally { setLoading(false); } }, 300); } catch (error) { console.error('Erreur:', error); setLoading(false); } }; const handleInputChange = (e: React.ChangeEvent) => { const newValue = e.target.value; onChange(newValue); searchAddresses(newValue); }; const handleSelectSuggestion = (suggestion: AddressSuggestion) => { onChange(suggestion.display_name); setShowSuggestions(false); setSuggestions([]); }; return (
{ if (suggestions.length > 0) { setShowSuggestions(true); } }} placeholder={placeholder} required={required} className="w-full px-4 py-2.5 border border-gray-300 rounded-lg text-gray-900 placeholder-gray-400 focus:outline-none focus:ring-2 focus:ring-lblue focus:border-transparent" /> {loading && (
)}
{showSuggestions && suggestions.length > 0 && (
{suggestions.map((suggestion, index) => ( ))}
)}
); }