diff --git a/package-lock.json b/package-lock.json index 8fe6710..c3b0ca1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6,6 +6,7 @@ "": { "dependencies": { "leaflet": "^1.9.4", + "nanoid": "^5.0.3", "preact": "^10.13.1" }, "devDependencies": { @@ -4209,10 +4210,9 @@ "dev": true }, "node_modules/nanoid": { - "version": "3.3.7", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", - "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", - "dev": true, + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-5.0.3.tgz", + "integrity": "sha512-I7X2b22cxA4LIHXPSqbBCEQSL+1wv8TuoefejsX4HFWyC6jc5JG7CEaxOltiKjc1M+YCS2YkrZZcj4+dytw9GA==", "funding": [ { "type": "github", @@ -4220,10 +4220,10 @@ } ], "bin": { - "nanoid": "bin/nanoid.cjs" + "nanoid": "bin/nanoid.js" }, "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + "node": "^18 || >=20" } }, "node_modules/natural-compare": { @@ -4590,6 +4590,24 @@ "node": "^10 || ^12 || >=14" } }, + "node_modules/postcss/node_modules/nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, "node_modules/preact": { "version": "10.19.2", "resolved": "https://registry.npmjs.org/preact/-/preact-10.19.2.tgz", diff --git a/package.json b/package.json index 0535662..5547f33 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ }, "dependencies": { "leaflet": "^1.9.4", + "nanoid": "^5.0.3", "preact": "^10.13.1" }, "devDependencies": { diff --git a/src/index.tsx b/src/index.tsx index 915b47b..2bf453a 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -1,9 +1,10 @@ import { render } from 'preact'; -import './style.css'; import { RoutePlanner } from './routePlanner'; +import './style.css'; + export function App() { - return (); + return ; } const app = document.getElementById('app'); diff --git a/src/routePlanner/index.tsx b/src/routePlanner/index.tsx index da859cf..9edde40 100644 --- a/src/routePlanner/index.tsx +++ b/src/routePlanner/index.tsx @@ -1,9 +1,30 @@ +import { useMemo, useState } from 'preact/hooks'; +import { MapComponent } from './map'; +import { Coordinates, Marker } from './types'; + import './style.css'; -import { MapComponent } from "./map" +import { MarkersComponent } from './markers'; +import { nanoid } from 'nanoid'; export const RoutePlanner = () => { - return
-
Markers
-
-
-} \ No newline at end of file + const [markers, setMarkers] = useState([]); + const onMapClick = useMemo( + () => (coordinates: Coordinates) => + setMarkers((markers) => [ + ...markers, + { coordinates, key: nanoid(10) }, + ]), + [], + ); + + return ( +
+
+ +
+
+ +
+
+ ); +}; diff --git a/src/routePlanner/map.tsx b/src/routePlanner/map.tsx index 428cd32..594fb39 100644 --- a/src/routePlanner/map.tsx +++ b/src/routePlanner/map.tsx @@ -1,8 +1,10 @@ -import 'leaflet/dist/leaflet.css'; import leaflet from 'leaflet'; import { useEffect, useRef } from 'preact/hooks'; +import { InternalMapProps } from './types'; + +import 'leaflet/dist/leaflet.css'; -export const MapComponent = () => { +export const MapComponent = ({ onMapClick }: InternalMapProps) => { const mapContainerRef = useRef(null); const mapRef = useRef(undefined); @@ -16,7 +18,7 @@ export const MapComponent = () => { } const map = leaflet.map(mapContainerRef.current); - map.setView([51.505, -0.09], 13); + map.setView([47.42111, 10.98528], 13); leaflet .tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', { @@ -29,5 +31,20 @@ export const MapComponent = () => { mapRef.current = map; }); + useEffect(() => { + const map = mapRef.current; + if (!map) { + return; + } + + const handler: leaflet.LeafletMouseEventHandlerFn = ({ latlng }) => + onMapClick(latlng); + map.on('click', handler); + + return () => { + map.removeEventListener('click', handler); + }; + }, [mapRef, onMapClick]); + return
; }; diff --git a/src/routePlanner/markers.tsx b/src/routePlanner/markers.tsx new file mode 100644 index 0000000..27e2a46 --- /dev/null +++ b/src/routePlanner/markers.tsx @@ -0,0 +1,18 @@ +import { InternalProps } from './types'; + +import 'leaflet/dist/leaflet.css'; + +export const MarkersComponent = ({ markers }: InternalProps) => { + return ( + <> +

Markers

+
    + {markers.map(({ key, coordinates }) => ( +
  1. + {coordinates.lat}, {coordinates.lng} +
  2. + ))} +
+ + ); +}; diff --git a/src/routePlanner/types.ts b/src/routePlanner/types.ts new file mode 100644 index 0000000..eab1cd0 --- /dev/null +++ b/src/routePlanner/types.ts @@ -0,0 +1,16 @@ +import type { LatLng } from 'leaflet'; + +export type Coordinates = LatLng; + +export type Marker = { + key: string; + coordinates: Coordinates; +}; + +export type InternalProps = { + markers: Marker[]; +}; + +export type InternalMapProps = InternalProps & { + onMapClick: (coordinates: Coordinates) => void; +};