Feature: Intelligent zoom and fix dropdown z-index
1. Fixed dropdown z-index - Set .map-overlay-top z-index to 500 - Now dropdown appears above filter buttons (z-index: 300) 2. Intelligent zoom when searching - 1 result: Zoom to that post (zoom level 14) - Multiple results: Calculate bounding box and fitBounds() - Shows all matching posts together on map - Padding of 100px on all sides - MaxZoom 15 to avoid zooming too close When you search and press Enter, the map automatically adjusts to show all matching results optimally. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
b013a71ea6
commit
964a133f5b
|
|
@ -247,6 +247,58 @@ export default function MapView({
|
|||
setSearchQuery(query);
|
||||
};
|
||||
|
||||
// Zoom intelligent: quand on cherche, zoom pour voir tous les résultats
|
||||
useEffect(() => {
|
||||
if (!searchQuery || !visiblePosts.length) return;
|
||||
|
||||
const map = mapRef.current;
|
||||
if (!map) return;
|
||||
|
||||
// Attendre un peu que les markers soient créés
|
||||
const timer = setTimeout(() => {
|
||||
const postsWithCoords = visiblePosts.filter(p => {
|
||||
const lat = typeof p.lat === 'number' ? p.lat : p.latitude;
|
||||
const lon = typeof p.lon === 'number' ? p.lon : p.lng;
|
||||
return lat != null && lon != null;
|
||||
});
|
||||
|
||||
if (postsWithCoords.length === 0) return;
|
||||
|
||||
if (postsWithCoords.length === 1) {
|
||||
// Un seul résultat: zoom dessus
|
||||
const p = postsWithCoords[0];
|
||||
const lat = typeof p.lat === 'number' ? p.lat : p.latitude;
|
||||
const lon = typeof p.lon === 'number' ? p.lon : p.lng;
|
||||
map.flyTo({
|
||||
center: [lon, lat],
|
||||
zoom: 14,
|
||||
speed: 1.2,
|
||||
essential: true
|
||||
});
|
||||
} else {
|
||||
// Plusieurs résultats: calculer bounds et fitter
|
||||
const lats = postsWithCoords.map(p => typeof p.lat === 'number' ? p.lat : p.latitude);
|
||||
const lons = postsWithCoords.map(p => typeof p.lon === 'number' ? p.lon : p.lng);
|
||||
|
||||
const minLat = Math.min(...lats);
|
||||
const maxLat = Math.max(...lats);
|
||||
const minLon = Math.min(...lons);
|
||||
const maxLon = Math.max(...lons);
|
||||
|
||||
map.fitBounds(
|
||||
[[minLon, minLat], [maxLon, maxLat]],
|
||||
{
|
||||
padding: { top: 100, bottom: 100, left: 100, right: 100 },
|
||||
maxZoom: 15,
|
||||
duration: 1000
|
||||
}
|
||||
);
|
||||
}
|
||||
}, 300); // Délai pour laisser les markers se créer
|
||||
|
||||
return () => clearTimeout(timer);
|
||||
}, [searchQuery, visiblePosts, mapRef]);
|
||||
|
||||
const handleOpenCreate = () => {
|
||||
if (!authenticated) {
|
||||
alert("You must be logged in to place a wire.");
|
||||
|
|
|
|||
|
|
@ -77,6 +77,7 @@
|
|||
transform:translateX(-50%);
|
||||
max-width: min(980px, calc(100vw - 24px));
|
||||
width:100%;
|
||||
z-index: 500; /* Au-dessus des filtres (z-index: 300) */
|
||||
}
|
||||
|
||||
/* Left / right: filtres */
|
||||
|
|
|
|||
Loading…
Reference in New Issue