feat: improve directions panel with route legend and place card below

- Add route legend showing wilderness (dashed orange) vs road (solid blue)
- Show place card below directions panel when clicking map during routing
- Clean up error messages to be user-friendly (no offroute text)
- Legend only appears when route has wilderness segments

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Matt 2026-05-09 03:37:05 +00:00
commit 19a96cba5e
2 changed files with 316 additions and 267 deletions

View file

@ -74,13 +74,15 @@ export default function DirectionsPanel({ onClose }) {
} }
const handleAddStop = () => { const handleAddStop = () => {
// Insert a stop between origin and destination // For now, show a message - multi-stop UI is complex
// For now, this adds to the stops array // TODO: Implement full multi-stop UI
// The UI will show intermediate stops
} }
// Check if route has wilderness segments
const hasWilderness = routeResult?.summary?.wilderness_distance_km > 0
// Multi-stop support: show intermediate stops from the stops array // Multi-stop support: show intermediate stops from the stops array
const intermediateStops = stops.slice(1, -1) // Everything except first and last const intermediateStops = stops.slice(1, -1)
return ( return (
<div className="flex flex-col gap-3"> <div className="flex flex-col gap-3">
@ -154,7 +156,7 @@ export default function DirectionsPanel({ onClose }) {
autoFocus={routeStart && !routeEnd} autoFocus={routeStart && !routeEnd}
/> />
{/* Add stop button */} {/* Add stop button - only show when route exists */}
{routeStart && routeEnd && stops.length < 10 && ( {routeStart && routeEnd && stops.length < 10 && (
<button <button
onClick={handleAddStop} onClick={handleAddStop}
@ -230,7 +232,7 @@ export default function DirectionsPanel({ onClose }) {
</div> </div>
)} )}
{/* Error message */} {/* Error message - friendly text, no "offroute" */}
{routeError && ( {routeError && (
<div <div
className="px-3 py-2 rounded-lg text-sm" className="px-3 py-2 rounded-lg text-sm"
@ -239,7 +241,41 @@ export default function DirectionsPanel({ onClose }) {
color: "var(--error, #ef4444)", color: "var(--error, #ef4444)",
}} }}
> >
{routeError} {routeError.includes("No route") || routeError.includes("not found")
? "No route found. Try a different start point or mode."
: routeError.includes("entry point")
? "No roads found nearby — try Foot mode for trails."
: routeError}
</div>
)}
{/* Route legend - only shown when route has wilderness segment */}
{routeResult && hasWilderness && !routeLoading && (
<div
className="flex items-center gap-4 px-3 py-2 rounded-lg text-xs"
style={{ background: "var(--bg-overlay)" }}
>
<div className="flex items-center gap-1.5">
<svg width="24" height="2" style={{ overflow: "visible" }}>
<line
x1="0" y1="1" x2="24" y2="1"
stroke="#f97316"
strokeWidth="3"
strokeDasharray="4,3"
/>
</svg>
<span style={{ color: "var(--text-secondary)" }}>Wilderness (on foot)</span>
</div>
<div className="flex items-center gap-1.5">
<svg width="24" height="2" style={{ overflow: "visible" }}>
<line
x1="0" y1="1" x2="24" y2="1"
stroke="#3b82f6"
strokeWidth="3"
/>
</svg>
<span style={{ color: "var(--text-secondary)" }}>Road/Trail</span>
</div>
</div> </div>
)} )}

View file

@ -90,10 +90,23 @@ export default function Panel({ onClearRoute }) {
const showEmptyState = panelState === 'IDLE' && !hasRoutePoints const showEmptyState = panelState === 'IDLE' && !hasRoutePoints
const routesContent = directionsMode ? ( const routesContent = directionsMode ? (
<>
<DirectionsPanel onClose={() => { <DirectionsPanel onClose={() => {
setDirectionsMode(false) setDirectionsMode(false)
onClearRoute?.() onClearRoute?.()
}} /> }} />
{/* Show place card below directions when clicking map during routing */}
{selectedPlace && (
<div className="mt-3 border-t pt-3" style={{ borderColor: "var(--border)" }}>
<PlaceCard
place={selectedPlace}
variant="preview"
expanded={true}
onClose={clearSelectedPlace}
/>
</div>
)}
</>
) : ( ) : (
<> <>
<SearchBar /> <SearchBar />