Primer prototipo

This commit is contained in:
2026-05-20 14:05:55 +02:00
parent c2ab9a46d4
commit c06300833b
22 changed files with 1115 additions and 2 deletions
+68
View File
@@ -0,0 +1,68 @@
import { MapContainer, TileLayer, Marker, useMapEvents } from "react-leaflet";
import L from "leaflet";
// Configuración del icono por defecto. Leaflet no encuentra sus iconos cuando
// se empaqueta con Vite; los referenciamos desde el CDN para no copiar
// archivos a public/.
const icon = new L.Icon({
iconUrl: "https://unpkg.com/leaflet@1.9.4/dist/images/marker-icon.png",
iconRetinaUrl: "https://unpkg.com/leaflet@1.9.4/dist/images/marker-icon-2x.png",
shadowUrl: "https://unpkg.com/leaflet@1.9.4/dist/images/marker-shadow.png",
iconSize: [25, 41],
iconAnchor: [12, 41],
});
const DEFAULT_CENTER = [40.4168, -3.7038];
const DEFAULT_ZOOM = 13;
function LocationPicker({ onPick }) {
useMapEvents({
click(e) {
onPick({ lat: e.latlng.lat, lng: e.latlng.lng });
},
});
return null;
}
export default function MapView({
businesses,
selectedId,
onSelect,
pickingLocation,
onPickLocation,
pickedLocation,
}) {
return (
<div className="map">
<MapContainer
center={DEFAULT_CENTER}
zoom={DEFAULT_ZOOM}
style={{ height: "100%", width: "100%" }}
>
<TileLayer
attribution='&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a>'
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
/>
{businesses.map((b) => (
<Marker
key={b.id}
position={[b.lat, b.lng]}
icon={icon}
eventHandlers={{ click: () => onSelect(b.id) }}
opacity={selectedId && selectedId !== b.id ? 0.6 : 1}
/>
))}
{pickingLocation && <LocationPicker onPick={onPickLocation} />}
{pickedLocation && (
<Marker
position={[pickedLocation.lat, pickedLocation.lng]}
icon={icon}
/>
)}
</MapContainer>
{pickingLocation && (
<div className="map-hint">Haz clic en el mapa para fijar la ubicación</div>
)}
</div>
);
}