From 2345334bc71db886748213fce6dbfb0ad2776fca Mon Sep 17 00:00:00 2001 From: Matt Date: Sat, 9 May 2026 08:23:38 +0000 Subject: [PATCH] feat: wire up radial menu directions and multi-stop add button - Radial menu "From here" now sets origin and opens directions panel - Radial menu "To here" now sets destination, opens directions panel, and uses GPS as origin fallback when available - DirectionsPanel "Add stop" button now creates intermediate stops - Stops array initialized from routeStart/routeEnd when adding stops Co-Authored-By: Claude Opus 4.5 --- src/components/DirectionsPanel.jsx | 39 ++++++++++++++++++++++++++++-- src/components/MapView.jsx | 25 +++++++++++++------ 2 files changed, 55 insertions(+), 9 deletions(-) diff --git a/src/components/DirectionsPanel.jsx b/src/components/DirectionsPanel.jsx index 794cad6..b485636 100644 --- a/src/components/DirectionsPanel.jsx +++ b/src/components/DirectionsPanel.jsx @@ -74,8 +74,43 @@ export default function DirectionsPanel({ onClose }) { } const handleAddStop = () => { - // For now, show a message - multi-stop UI is complex - // TODO: Implement full multi-stop UI + // Build stops array from current route endpoints if not already populated + let newStops = [...stops] + + // If stops is empty but we have endpoints, initialize from routeStart/routeEnd + if (newStops.length === 0) { + if (routeStart) { + newStops.push({ + id: crypto.randomUUID(), + lat: routeStart.lat, + lon: routeStart.lon, + name: routeStart.name || "Start", + }) + } + if (routeEnd) { + newStops.push({ + id: crypto.randomUUID(), + lat: routeEnd.lat, + lon: routeEnd.lon, + name: routeEnd.name || "Destination", + }) + } + } + + // Create placeholder intermediate stop + const newStop = { + id: crypto.randomUUID(), + lat: null, + lon: null, + name: "", + } + + // Insert before destination (last position), or at end if no destination + const insertIdx = Math.max(0, newStops.length - 1) + newStops.splice(insertIdx, 0, newStop) + + // Update stops array - reorderStops triggers UI update + reorderStops(newStops) } // Check if route has wilderness segments diff --git a/src/components/MapView.jsx b/src/components/MapView.jsx index c77994b..0f13fd1 100644 --- a/src/components/MapView.jsx +++ b/src/components/MapView.jsx @@ -1672,13 +1672,24 @@ const MapView = forwardRef(function MapView(_, ref) { lon: radialMenu.lon, name: radialMenu.centerLabel || radialMenu.lat.toFixed(5) + ", " + radialMenu.lon.toFixed(5), } - const { routeStart, setRouteEnd, computeRoute } = useStore.getState() + const { routeStart, setRouteStart, setRouteEnd, computeRoute, setDirectionsMode, geoPermission, userLocation } = useStore.getState() + setRouteEnd(place) + setDirectionsMode(true) + if (routeStart) { computeRoute() - } else { - toast("Set starting point first") + } else if (geoPermission === "granted" && userLocation) { + // Use GPS as origin fallback + setRouteStart({ + lat: userLocation.lat, + lon: userLocation.lon, + name: "Your location", + source: "gps", + }) + computeRoute() } + // If no origin and no GPS, directions panel opens and origin field auto-focuses }, }, { @@ -1692,16 +1703,16 @@ const MapView = forwardRef(function MapView(_, ref) { lon: radialMenu.lon, name: radialMenu.centerLabel || radialMenu.lat.toFixed(5) + ", " + radialMenu.lon.toFixed(5), } - const { clearRoute, setRouteStart, routeEnd, computeRoute } = useStore.getState() + const { clearRoute, setRouteStart, routeEnd, computeRoute, setDirectionsMode } = useStore.getState() clearRoute() clearRouteDisplay(mapInstance.current) setRouteStart(place) - // If we already have a destination, compute route immediately + setDirectionsMode(true) + if (routeEnd) { computeRoute() - } else { - toast("Now tap destination") } + // If no destination, directions panel opens and destination field auto-focuses }, }, {