From 3af6aee32c383410ecad4db169839d2c1347098e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ullrich=20Sch=C3=A4fer?= Date: Sat, 11 Apr 2026 01:56:10 +0200 Subject: [PATCH] Add "Add as waypoint" button to POI popups Clicking the button in a POI popup adds the POI's location and name as a new waypoint at the end of the route. Uses event delegation on the map container to handle clicks on dynamically created popup buttons. Co-Authored-By: Claude Opus 4.6 (1M context) --- apps/planner/app/components/PlannerMap.tsx | 5 +++-- apps/planner/app/components/PoiPanel.tsx | 22 +++++++++++++++++++++- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/apps/planner/app/components/PlannerMap.tsx b/apps/planner/app/components/PlannerMap.tsx index ce969ec..cf6afa8 100644 --- a/apps/planner/app/components/PlannerMap.tsx +++ b/apps/planner/app/components/PlannerMap.tsx @@ -361,11 +361,12 @@ export function PlannerMap({ yjs, onRouteRequest, highlightPosition, highlighted }, [yjs.routeData]); const addWaypoint = useCallback( - (lat: number, lng: number) => { + (lat: number, lng: number, name?: string) => { yjs.doc.transact(() => { const yMap = new Y.Map(); yMap.set("lat", lat); yMap.set("lon", lng); + if (name) yMap.set("name", name); yjs.waypoints.push([yMap]); }, "local"); }, @@ -512,7 +513,7 @@ export function PlannerMap({ yjs, onRouteRequest, highlightPosition, highlighted - + {waypoints.map((wp, i) => ( diff --git a/apps/planner/app/components/PoiPanel.tsx b/apps/planner/app/components/PoiPanel.tsx index ca3eb64..e2f04bb 100644 --- a/apps/planner/app/components/PoiPanel.tsx +++ b/apps/planner/app/components/PoiPanel.tsx @@ -8,6 +8,7 @@ import { Z_POI_MARKER } from "~/lib/z-index"; interface PoiPanelProps { poiState: PoiState; + onAddWaypoint?: (lat: number, lon: number, name?: string) => void; } export function PoiPanel({ poiState }: PoiPanelProps) { @@ -79,7 +80,7 @@ export function PoiPanel({ poiState }: PoiPanelProps) { ); } -export function PoiMarkers({ poiState }: PoiPanelProps) { +export function PoiMarkers({ poiState, onAddWaypoint }: PoiPanelProps) { const map = useMap(); const layerRef = useRef(L.layerGroup()); @@ -88,6 +89,22 @@ export function PoiMarkers({ poiState }: PoiPanelProps) { return () => { layerRef.current.remove(); }; }, [map]); + // Event delegation for "Add as waypoint" buttons in popups + useEffect(() => { + const container = map.getContainer(); + const handler = (e: MouseEvent) => { + const btn = (e.target as HTMLElement).closest(".poi-add-wp") as HTMLElement | null; + if (!btn || !onAddWaypoint) return; + const lat = parseFloat(btn.dataset.lat!); + const lon = parseFloat(btn.dataset.lon!); + const name = btn.dataset.name || undefined; + onAddWaypoint(lat, lon, name); + map.closePopup(); + }; + container.addEventListener("click", handler); + return () => container.removeEventListener("click", handler); + }, [map, onAddWaypoint]); + useEffect(() => { const group = layerRef.current; group.clearLayers(); @@ -126,6 +143,9 @@ export function PoiMarkers({ poiState }: PoiPanelProps) { if (poi.tags.opening_hours) popupLines.push(`🕐 ${poi.tags.opening_hours}`); if (poi.tags.website) popupLines.push(`Website`); popupLines.push(`OSM`); + if (onAddWaypoint) { + popupLines.push(``); + } marker.bindPopup(popupLines.join("
"), { maxWidth: 200 }); group.addLayer(marker);