first commit
This commit is contained in:
@@ -0,0 +1,96 @@
|
||||
import React, { useEffect, useRef } from "react";
|
||||
import L, { Map } from "leaflet";
|
||||
import "leaflet/dist/leaflet.css";
|
||||
|
||||
export type LocationCoordinates = { latitude: number; longitude: number };
|
||||
|
||||
interface SelectLocationMapProps {
|
||||
initialCoordinates?: LocationCoordinates;
|
||||
onChange?: (coordinates: LocationCoordinates) => void;
|
||||
height?: string;
|
||||
}
|
||||
|
||||
export default function SelectLocationMap(props: SelectLocationMapProps) {
|
||||
const { initialCoordinates = { latitude: -30.86239, longitude: -64.49569 }, onChange, height = "150px" } = props;
|
||||
const mapRef = useRef<Map | null>(null);
|
||||
const mapContainerRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (!mapContainerRef.current) return;
|
||||
|
||||
if (!mapRef.current) {
|
||||
// Inicializar el mapa solo una vez
|
||||
mapRef.current = L.map(mapContainerRef.current).setView(
|
||||
[initialCoordinates.latitude, initialCoordinates.longitude],
|
||||
14
|
||||
);
|
||||
|
||||
// Añadir la capa de OpenStreetMap
|
||||
L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", {
|
||||
attribution:
|
||||
'© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',
|
||||
}).addTo(mapRef.current);
|
||||
|
||||
// Evento para capturar el movimiento del mapa y actualizar las coordenadas
|
||||
mapRef.current.on("moveend", () => {
|
||||
if (mapRef.current) {
|
||||
const center = mapRef.current.getCenter();
|
||||
if (onChange) {
|
||||
onChange({ latitude: center.lat, longitude: center.lng });
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// Si el mapa ya existe, solo actualizamos la vista manteniendo el zoom actual
|
||||
const currentZoom = mapRef.current.getZoom();
|
||||
mapRef.current.setView(
|
||||
[initialCoordinates.latitude, initialCoordinates.longitude],
|
||||
currentZoom
|
||||
);
|
||||
}
|
||||
|
||||
// Cleanup al desmontar el componente por completo
|
||||
return () => {
|
||||
// No hacemos remove() aquí en cada cambio de coordenadas, solo dejamos que React
|
||||
// destruya el div. Leaflet puede tener problemas si se borra el contenedor pero no la ref.
|
||||
};
|
||||
}, [initialCoordinates.latitude, initialCoordinates.longitude]);
|
||||
|
||||
// Use a separate effect to cleanup the map strictly when component unmounts
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
if (mapRef.current) {
|
||||
mapRef.current.remove();
|
||||
mapRef.current = null;
|
||||
}
|
||||
};
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
position: "relative",
|
||||
border: "solid 1px var(--black)",
|
||||
borderRadius: "5px",
|
||||
marginTop: "20px",
|
||||
}}
|
||||
>
|
||||
{/* Contenedor del mapa */}
|
||||
<div ref={mapContainerRef} style={{ height: height, width: "100%" }} />
|
||||
|
||||
{/* Marcador fijo en el centro del mapa */}
|
||||
<div
|
||||
style={{
|
||||
position: "absolute",
|
||||
top: "50%",
|
||||
left: "50%",
|
||||
transform: "translate(-50%, -50%)",
|
||||
pointerEvents: "none",
|
||||
zIndex: 1000,
|
||||
}}
|
||||
>
|
||||
<img src="/location.png" alt="Marker" style={{ width: "32px", height: "48px" }} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user