|
1 | 1 | import { useTranslations } from 'next-intl';
|
2 | 2 | import Image from 'next/image';
|
3 |
| -import React, { useEffect, useState, useCallback, useContext } from 'react'; |
| 3 | +import React, { useEffect, useState, useCallback, useContext, useRef } from 'react'; |
4 | 4 | import { MapContainer, Marker, Popup, TileLayer, useMapEvents } from 'react-leaflet';
|
5 | 5 | import L, { LatLngExpression, LatLngBounds, LatLngTuple } from 'leaflet';
|
6 | 6 | import _ from 'lodash';
|
@@ -132,34 +132,54 @@ const Map = ({
|
132 | 132 | logger.debug('Sellers Array:', { sellers });
|
133 | 133 | }, [sellers]);
|
134 | 134 |
|
135 |
| - // Function to handle marker click |
136 |
| - const handleMarkerClick = (sellerCoordinates: LatLngTuple) => { |
137 |
| - if (!mapRef.current) return; |
138 |
| - |
139 |
| - const map = mapRef.current; |
140 |
| - const currentZoom = map.getZoom(); |
141 |
| - |
142 |
| - // Set the view to the seller's coordinates |
143 |
| - map.setView(sellerCoordinates, currentZoom, { animate: true }); |
144 |
| - // Get the position of the clicked marker |
145 |
| - const markerPoint = map.latLngToContainerPoint(sellerCoordinates); |
146 |
| - // Get the width and height of the map container |
147 |
| - const mapSize = map.getSize(); |
148 |
| - const mapWidth = mapSize.x; |
149 |
| - const mapHeight = mapSize.y; |
150 |
| - // Calculate the offsets to center the marker in the map view |
151 |
| - const panOffset = L.point(mapWidth / 2 - markerPoint.x, mapHeight / 2 - markerPoint.y); |
152 |
| - |
153 |
| - // Pan the map by the calculated offset |
154 |
| - map.panBy(panOffset, { animate: false }); // Disable animation to make the movement instant |
| 135 | + const useMarkerZoomHandler = (mapRef: React.RefObject<L.Map>) => { |
| 136 | + const lastClickedMarker = useRef<string | null>(null); |
| 137 | + |
| 138 | + // Function to handle marker click |
| 139 | + const handleMarkerClick = (sellerCoordinates: LatLngTuple) => { |
| 140 | + if (!mapRef.current) return; |
| 141 | + |
| 142 | + const map = mapRef.current; |
| 143 | + const currentZoom = map.getZoom(); |
| 144 | + const maxZoom = map.getMaxZoom(); |
| 145 | + |
| 146 | + const coordKey = sellerCoordinates.join(','); |
| 147 | + |
| 148 | + // Prevent zooming again on the same marker |
| 149 | + if (lastClickedMarker.current === coordKey) return; |
| 150 | + |
| 151 | + // Update the last clicked marker |
| 152 | + lastClickedMarker.current = coordKey; |
| 153 | + |
| 154 | + // Calculate target zoom |
| 155 | + const targetZoom = Math.min(currentZoom + 3, maxZoom); |
| 156 | + |
| 157 | + // Convert lat/lng to pixel position |
| 158 | + const markerPoint = map.latLngToContainerPoint(sellerCoordinates); |
| 159 | + |
| 160 | + // Offset to move popup up and left |
| 161 | + const OFFSET_X = -3; |
| 162 | + const OFFSET_Y = 28; |
| 163 | + const panOffset = L.point(OFFSET_X, OFFSET_Y); |
| 164 | + |
| 165 | + // New center for map |
| 166 | + const newCenter = map.containerPointToLatLng(markerPoint.subtract(panOffset)); |
| 167 | + |
| 168 | + // Zoom and pan with animation |
| 169 | + map.setView(newCenter, targetZoom, { animate: true }); |
| 170 | + }; |
| 171 | + |
| 172 | + return handleMarkerClick; |
155 | 173 | };
|
156 |
| - |
| 174 | + |
157 | 175 | useEffect(() => {
|
158 | 176 | if (mapRef.current) {
|
159 | 177 | fetchInitialCoordinates(); // Fetch sellers when map is ready
|
160 | 178 | }
|
161 | 179 | }, [mapRef.current]);
|
162 | 180 |
|
| 181 | + const handleMarkerClick = useMarkerZoomHandler(mapRef); |
| 182 | + |
163 | 183 | const saveMapState = () => {
|
164 | 184 | try{
|
165 | 185 | if (!mapRef.current) {
|
|
0 commit comments