- MapView.jsx: extract addBoundaryLayer function, use getComputedStyle
for accent color (MapLibre rejects CSS vars in paint properties)
- PlaceCard.jsx: gate fetchNearbyContacts on auth.authenticated
- PlaceDetail.jsx: gate fetchNearbyContacts on auth.authenticated
- api.js: replace invalid timeout option with AbortSignal.timeout()
- RadialMenu.jsx: remove user-select from SVG style (Firefox rejects)
- Panel.jsx: add Cancel button for pending directions state
- Add /api/auth/whoami endpoint check on app load
- Store auth state in Zustand (authenticated, username, loaded)
- Hide Contacts tab when unauthenticated
- Gate fetchNearbyContacts calls on auth.authenticated
- Replace Save button with Log in affordance when unauthenticated
- Add Login/Logout buttons to panel header
- Prevent any /api/contacts/* requests from firing when unauthenticated
Public functionality (search, routing, place details) remains
fully functional for unauthenticated users.
Symptom: HAR capture showed /api/geocode requests with NO lat/lon/zoom
params despite map being centered on Twin Falls. Results returned
out-of-state addresses (Illinois, Iowa, Arkansas).
Root cause: SearchBar subscribed to mapCenter via React hook, but the
value was stale at search time due to render timing.
Fix: api.js searchGeocode now reads mapCenter directly from the store
via useStore.getState() at call time. This is the correct pattern for
non-component code. SearchBar no longer passes mapCenter as a param.
- Snap selection to feature geometry when clicking labeled places
- Add wikidata enrichment for basemap labels (population, description)
- Differentiate visual feedback: reticle marker vs pulsing highlight
- Clear previous feature highlight when selection changes
- Store selection mode (reticle/feature) and feature info in state
Frontend: MapView click handler, PlaceDetail wikidata fetch, CSS
Backend: /api/place/wikidata/<id> route for Wikidata API lookups
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add mapCenter state to store (lat/lon/zoom)
- Track map center on moveend in MapView
- Pass mapCenter to searchGeocode from SearchBar
- Update searchGeocode API call to include viewport params
Search results now prioritize locations near the current map view.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Shows PAD-US land ownership data (unit name, agency hierarchy, access
status) when clicking on map areas. Upgrades "Dropped pin" name to
land unit summary on public land. Private land gets a muted indicator.
- api.js: fetchLandclass() for /api/landclass endpoint
- PlaceDetail.jsx: LandclassSection, PrivateLandIndicator components
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replaces Share button with Copy dropdown (Address / Coordinates).
Map single-click drops preview pin, opens PlaceDetail with
"Dropped pin" placeholder, reverse geocodes via /api/reverse to
fill in address. Stop-pin clicks preserved via flag ref. Escape
key closes PlaceDetail. Double-click zoom unaffected.
Phase 3 Step 5 C1.5 of Navi.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adds synthetic "Your location" stop A when GPS granted; place
detail panel slides in on search result click with Directions /
Add stop / Save (stub) / Share actions; elevation via Valhalla
/height; react-hot-toast for feedback; pendingDestination state
for GPS-denied Directions flow.
Phase 3 Step 5 C1 of Navi.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Full navigation UI with:
- Search bar with 150ms debounced autocomplete from /api/geocode
- Keyboard navigation (arrow keys, Enter, Escape)
- Exact match badge for verified address results
- Multi-stop list with drag-to-reorder (dnd-kit)
- 10-stop cap with disabled state
- Mode selector (drive/walk/bike)
- Valhalla route display with per-leg color polyline
- Maneuver list with instructions, distance, time remaining
- Click maneuver to fly map to that point
- Optimize stops button (3+ stops, uses /optimized_route)
- Responsive: side panel (desktop ≥768px), bottom sheet (mobile)
- Stop pins: green origin, red destination, blue intermediate
- Pin popup with remove button
- Geolocation permission requested on first route, not on load
- Error handling for unroutable pairs
- nginx proxy for /api/ and /valhalla/ endpoints
Dependencies added: zustand, @dnd-kit/core, @dnd-kit/sortable,
@dnd-kit/utilities
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>