diff --git a/frontend/src/components/Map/BaseMapLayers.tsx b/frontend/src/components/Map/BaseMapLayers.tsx new file mode 100644 index 0000000..9f56a97 --- /dev/null +++ b/frontend/src/components/Map/BaseMapLayers.tsx @@ -0,0 +1,17 @@ +// src/components/map/MapLayer.tsx +import { TileLayer, Marker } from "react-leaflet"; + +interface MapLayerProps { + initialPosition: [number, number]; +} + +const BaseMapLayers = ({ initialPosition }: MapLayerProps) => { + return ( + <> + + + + ); +}; + +export default BaseMapLayers; diff --git a/frontend/src/components/Map/CurrentLocationMarker.tsx b/frontend/src/components/Map/CurrentLocationMarker.tsx new file mode 100644 index 0000000..c5ce58e --- /dev/null +++ b/frontend/src/components/Map/CurrentLocationMarker.tsx @@ -0,0 +1,31 @@ +import { useEffect, useRef } from "react"; +import { useMap } from "react-leaflet"; +import L from "leaflet"; +import { useGeolocationContext } from "../../providers/GeolocationContext"; + +const CurrentLocationMarker = () => { + const map = useMap(); + const { location, error } = useGeolocationContext(); + const markerRef = useRef(); + + useEffect(() => { + if (location) { + const lat = location.coords.latitude; + const lng = location.coords.longitude; + + if (markerRef.current) { + markerRef.current.setLatLng([lat, lng]); + } else { + markerRef.current = L.marker([lat, lng]).addTo(map); + } + } + }, [location, map]); + + if (error) { + console.error(`Geolocation error (${error.code}): ${error.message}`); + } + + return null; +}; + +export default CurrentLocationMarker; diff --git a/frontend/src/components/Map/Map.tsx b/frontend/src/components/Map/Map.tsx deleted file mode 100644 index 42ee6e9..0000000 --- a/frontend/src/components/Map/Map.tsx +++ /dev/null @@ -1,60 +0,0 @@ -import React, { useEffect, useRef } from "react"; -import { MapContainer, Marker, TileLayer, useMap } from "react-leaflet"; -import L from "leaflet"; -import { useGeolocationContext } from "./../../providers/GeolocationContext"; -import "./style.css"; - -const Map = () => { - const map = useMap(); - const { location, error } = useGeolocationContext(); - - const markerRef = useRef(); - const circleRef = useRef(); - - useEffect(() => { - if (location) { - const lat = location.coords.latitude; - const lng = location.coords.longitude; - const accuracy = location.coords.accuracy; - - if (markerRef.current) map.removeLayer(markerRef.current); - if (circleRef.current) map.removeLayer(circleRef.current); - - circleRef.current = new L.Circle([lat, lng], { radius: accuracy }).addTo( - map - ); - markerRef.current = L.marker([lat, lng]).addTo(map); - - map.fitBounds(circleRef.current.getBounds()); - } - }, [location, map]); - - if (error) { - console.error(`Geolocation error (${error.code}): ${error.message}`); - } - - return null; -}; - -const MapComponent = () => { - const params = new URLSearchParams(window.location.search); - const lat = parseFloat(params.get("lat") || "50.740717"); - const lng = parseFloat(params.get("lng") || "2.258634"); - - // need to setView after the return to the map page - - return ( - - - {} - - - - ); -}; - -export default MapComponent; diff --git a/frontend/src/components/Map/MapContainerWrapper.tsx b/frontend/src/components/Map/MapContainerWrapper.tsx new file mode 100644 index 0000000..a3acb44 --- /dev/null +++ b/frontend/src/components/Map/MapContainerWrapper.tsx @@ -0,0 +1,38 @@ +// src/components/map/MapComponent.tsx +import React from "react"; +import { MapContainer } from "react-leaflet"; +import { useGeolocationContext } from "../../providers/GeolocationContext"; +import ChangeView from "../../utils/ChangeView"; +import CurrentLocationMarker from "./CurrentLocationMarker"; +import BaseMapLayers from "./BaseMapLayers"; +import { getMapZoom, getInitialCoords } from "./functions"; +import "./style.css"; + +const MapContainerWrapper = () => { + const params = new URLSearchParams(window.location.search); + const paramLat = params.get("lat"); + const paramLng = params.get("lng"); + + const { location } = useGeolocationContext(); + + const coords = getInitialCoords({ + paramLat, + paramLng, + userLocation: location, + }); + const zoom = getMapZoom(paramLat, paramLng); + + return ( + + + + + + ); +}; + +export default MapContainerWrapper; diff --git a/frontend/src/components/Map/functions.tsx b/frontend/src/components/Map/functions.tsx new file mode 100644 index 0000000..00be4ad --- /dev/null +++ b/frontend/src/components/Map/functions.tsx @@ -0,0 +1,33 @@ +export const getMapZoom = ( + paramLat: string | null, + paramLng: string | null +): number => { + if (paramLat === null && paramLng === null) { + return 20; + } + return 16; +}; + +interface InitialCoordsParams { + paramLat: string | null; + paramLng: string | null; + userLocation: GeolocationPosition | null; +} + +export const getInitialCoords = ({ + paramLat, + paramLng, + userLocation, +}: InitialCoordsParams): [number, number] => { + const defaultLat = 50.740717; // Coordonnées par défaut + const defaultLng = 2.258634; + + const lat = paramLat + ? parseFloat(paramLat) + : userLocation?.coords.latitude || defaultLat; + const lng = paramLng + ? parseFloat(paramLng) + : userLocation?.coords.longitude || defaultLng; + + return [lat, lng]; +}; diff --git a/frontend/src/components/index.js b/frontend/src/components/index.js index d7d3321..019ed66 100644 --- a/frontend/src/components/index.js +++ b/frontend/src/components/index.js @@ -1,6 +1,6 @@ -import MapComponent from "./Map/Map"; +import MapContainerWrapper from "./Map/MapContainerWrapper"; import Navbar from "./NavBar/NavBar"; import Card from "./Card/Card"; import ListCards from "./ListCards/ListCards"; -export { Navbar, Card, ListCards, MapComponent }; +export { Navbar, Card, ListCards, MapContainerWrapper }; diff --git a/frontend/src/hooks/useGeolocation.tsx b/frontend/src/hooks/useGeolocation.tsx index e1f7003..18f450d 100644 --- a/frontend/src/hooks/useGeolocation.tsx +++ b/frontend/src/hooks/useGeolocation.tsx @@ -1,29 +1,29 @@ import { useEffect, useState } from "react"; const useGeolocation = () => { - interface LocationPosition { - coords: { - latitude: number; - longitude: number; - accuracy: number; - }; - } + // interface LocationPosition { + // coords: { + // latitude: number; + // longitude: number; + // accuracy: number; + // }; + // } - interface LocationPositionError { - code: number; - message: string; - } + // interface LocationPositionError { + // code: number; + // message: string; + // } - const [location, setLocation] = useState(null); - const [error, setError] = useState(null); + const [location, setLocation] = useState(null); + const [error, setError] = useState(null); useEffect(() => { const watchPosition = navigator.geolocation.watchPosition( - (position: LocationPosition) => { + (position: GeolocationPosition) => { setLocation(position); console.log("Geolocation position:", position); }, - (error: LocationPositionError) => { + (error: GeolocationPositionError) => { setError(error); console.error(`Geolocation error (${error.code}): ${error.message}`); } diff --git a/frontend/src/pages/Homepage/HomePage.tsx b/frontend/src/pages/Homepage/HomePage.tsx index b87ec07..e709559 100644 --- a/frontend/src/pages/Homepage/HomePage.tsx +++ b/frontend/src/pages/Homepage/HomePage.tsx @@ -1,10 +1,10 @@ import React from "react"; -import { MapComponent } from "src/components"; +import { MapContainerWrapper } from "src/components"; const HomePage = () => { return (
- +
); }; diff --git a/frontend/src/utils/ChangeView.tsx b/frontend/src/utils/ChangeView.tsx new file mode 100644 index 0000000..9588610 --- /dev/null +++ b/frontend/src/utils/ChangeView.tsx @@ -0,0 +1,19 @@ +import { useEffect } from "react"; +import { useMap } from "react-leaflet"; + +interface ChangeViewProps { + coords: [number, number]; + zoom: number; +} + +const ChangeView = ({ coords, zoom }: ChangeViewProps) => { + const map = useMap(); + + useEffect(() => { + map.setView(coords, zoom); + }, [coords, zoom, map]); + + return null; +}; + +export default ChangeView;