diff --git a/src/components/Map/MapView.jsx b/src/components/Map/MapView.jsx index 2b0d323..a7eabfb 100644 --- a/src/components/Map/MapView.jsx +++ b/src/components/Map/MapView.jsx @@ -17,6 +17,7 @@ import { usePostsEngine } from "./usePostsEngine"; import { useAuth } from "../../auth/AuthContext"; import FilterButtons from "../Filters/FilterButtons"; import TimeFilterButtons from "../Filters/TimeFilterButtons"; +import SmartSearchBar from "../Search/SmartSearchBar"; export default function MapView({ theme = "dark", @@ -208,6 +209,35 @@ export default function MapView({ map.flyTo({ center: userPosition, zoom: 9, speed: 1.2 }); }; + const handlePickSuggestion = (item, { zoom }) => { + const map = mapRef.current; + if (!map) return; + + // Extract coords from item + let coords = null; + if (Array.isArray(item.coords) && item.coords.length === 2) { + coords = item.coords; // [lon, lat] + } else if (typeof item.lon === 'number' && typeof item.lat === 'number') { + coords = [item.lon, item.lat]; + } + + if (!coords) { + console.warn('[MapView] No coords for suggestion:', item); + return; + } + + console.log('[MapView] Flying to:', item.title, coords, 'zoom:', zoom); + map.flyTo({ + center: coords, + zoom: zoom || 12, + speed: 1.4, + essential: true + }); + + // Clear search query after navigation + setSearchQuery(""); + }; + const handleOpenCreate = () => { if (!authenticated) { alert("You must be logged in to place a wire."); @@ -413,38 +443,15 @@ export default function MapView({
{status &&
{status}
} - {/* TOP: Search à gauche, 2 icônes à droite, sur une seule ligne */} + {/* TOP: Search avec suggestions intelligentes */}
-
- - setSearchQuery(e.target.value)} - autoCapitalize="none" - autoCorrect="off" - spellCheck={false} - /> - {searchQuery ? ( - - ) : null} - +
${escapeHtml(post?.title || "Untitled")} @@ -576,7 +597,7 @@ export function createSimpleMarkerForPost(post, mapRef, markersRef, expandedElRe const marker = new maplibregl.Marker({ element: root, - anchor: "center", + anchor: "bottom", // La pointe du pin est à la position exacte }) .setLngLat(lngLat) .addTo(map); diff --git a/src/components/Search/SmartSearchBar.jsx b/src/components/Search/SmartSearchBar.jsx index 55b07f7..6b47423 100644 --- a/src/components/Search/SmartSearchBar.jsx +++ b/src/components/Search/SmartSearchBar.jsx @@ -67,6 +67,7 @@ export default function SmartSearchBar({ const [items, setItems] = useState([]); const [active, setActive] = useState(-1); const [err, setErr] = useState(""); + const [hasSearched, setHasSearched] = useState(false); const abortRef = useRef(null); const boxRef = useRef(null); @@ -80,45 +81,45 @@ export default function SmartSearchBar({ return () => document.removeEventListener("mousedown", onDocDown); }, []); - useEffect(() => { - const query = q.trim(); - setErr(""); - + // Fonction pour déclencher une recherche + const triggerSearch = async (searchQuery) => { if (abortRef.current) abortRef.current.abort(); - // Allow empty query to get popular suggestions - // if (!query) { - // setItems([]); - // setLoading(false); - // setActive(-1); - // return; - // } - const ctrl = new AbortController(); abortRef.current = ctrl; setLoading(true); + setErr(""); - const t = setTimeout(async () => { - try { - console.log('[SmartSearchBar] Searching for:', query); - const res = await recoSearch(query, { signal: ctrl.signal, limit: 12 }); - console.log('[SmartSearchBar] Got results:', res?.length || 0, res); - setItems(res); - setOpen(true); - setActive(res.length ? 0 : -1); - } catch (e) { - if (ctrl.signal.aborted) return; - console.error('[SmartSearchBar] Search error:', e); - setErr((e && e.message) ? e.message : "Search error"); - setItems([]); - } finally { - if (!ctrl.signal.aborted) setLoading(false); - } - }, 150); // Réduit de 220ms à 150ms pour réactivité accrue + try { + console.log('[SmartSearchBar] Searching for:', searchQuery); + const res = await recoSearch(searchQuery, { signal: ctrl.signal, limit: 12 }); + console.log('[SmartSearchBar] Got results:', res?.length || 0, res); + setItems(res); + setOpen(true); + setActive(res.length ? 0 : -1); + setHasSearched(true); + } catch (e) { + if (ctrl.signal.aborted) return; + console.error('[SmartSearchBar] Search error:', e); + setErr((e && e.message) ? e.message : "Search error"); + setItems([]); + } finally { + if (!ctrl.signal.aborted) setLoading(false); + } + }; + + useEffect(() => { + const query = q.trim(); + + if (abortRef.current) abortRef.current.abort(); + + const t = setTimeout(() => { + triggerSearch(query); + }, 150); // Debounce 150ms return () => { clearTimeout(t); - ctrl.abort(); + if (abortRef.current) abortRef.current.abort(); }; }, [q]); @@ -164,7 +165,13 @@ export default function SmartSearchBar({ className="sw-search__input" value={q} onChange={(e) => setQ(e.target.value)} - onFocus={() => setOpen(true)} + onFocus={() => { + setOpen(true); + // Si pas encore cherché et query vide, charger suggestions populaires + if (!hasSearched && !q.trim()) { + triggerSearch(""); + } + }} onKeyDown={onKeyDown} placeholder={placeholder} aria-label="Search"