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);
|
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 = () => {
|
const handleOpenCreate = () => {
|
||||||
if (!authenticated) {
|
if (!authenticated) {
|
||||||
alert("You must be logged in to place a wire.");
|
alert("You must be logged in to place a wire.");
|
||||||
|
|
|
||||||
|
|
@ -77,6 +77,7 @@
|
||||||
transform:translateX(-50%);
|
transform:translateX(-50%);
|
||||||
max-width: min(980px, calc(100vw - 24px));
|
max-width: min(980px, calc(100vw - 24px));
|
||||||
width:100%;
|
width:100%;
|
||||||
|
z-index: 500; /* Au-dessus des filtres (z-index: 300) */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Left / right: filtres */
|
/* Left / right: filtres */
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue