Commit graph

8 commits

Author SHA1 Message Date
Ullrich Schäfer
c2abb64ee0
Add per-waypoint notes and nearby POI snap to Planner
- `note` field on Waypoint type, stored in Yjs Y.Map and exported as
  `<desc>` inside `<wpt>` in GPX
- Inline textarea note editing in WaypointSidebar with auto-resize,
  character counter (500 max), save-on-blur, Escape cancel
- Note indicator dot on map markers; note tooltip on hover
- `useNearbyPois` hook: fetches POIs within 500m of selected waypoint
  via Overpass proxy, 500ms debounce, AbortController, 60s rate-limit
  suppression
- NearbyPoiMarkers component: renders POI markers on map for selected
  waypoint with snap-to-POI on click
- Nearby section in WaypointSidebar: list with snap buttons, spinner,
  empty/rate-limited states, "Show more" toggle (5 → all)
- Unit tests for fetchNearbyPois bbox geometry and snap-to-POI Yjs
  transaction behaviour

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-17 23:58:21 +02:00
Ullrich Schäfer
861701e881
Show POI details (phone, website, opening hours) on Journal route detail page
Waypoints snapped to OSM POIs in the Planner now carry their metadata all
the way through to the Journal:

- Extend Waypoint type with osmId and poiTags fields
- Extract osmId/poiTags from Yjs Y.Map in ExportButton and SaveToJournalButton
- Encode POI metadata as <trails:poi> extensions in GPX <wpt> elements
- Parse <trails:poi> extensions back in the GPX parser
- Display phone, website, opening hours, address on Journal route detail
- E2E test for the full roundtrip; seed endpoint now defaults to public visibility

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-17 23:32:38 +02:00
Ullrich Schäfer
08070cdd90
Sync notes through GPX, Journal, and Planner roundtrip
Full notes lifecycle:
- GPX: description field in GpxData, <metadata><desc> in generate/parse
- Export: Plan GPX and Save to Journal include notes as description
- Journal: updateRoute extracts description from GPX, stores on route
- Reimport: Edit in Planner passes notes via URL params → Yjs Y.Text
- Drop import: GPX with <desc> restores notes in session

Spec updated: session-notes gains GPX export, Journal sync, and
reimport requirements.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 03:35:40 +02:00
Ullrich Schäfer
774e2b1ae3
Add multi-track GPX export option (splitByDay)
generateGpx() gains a splitByDay option that splits the track into
separate <trk> elements per day, each named "Day N: Start - End".
Track points are split at the closest points to overnight waypoints.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 00:04:48 +02:00
Ullrich Schäfer
efdb3c1973
Add multi-day data model, computeDays, and GPX roundtrip
- overnight.ts: Yjs helpers to set/clear/check overnight flag on waypoints
- compute-days.ts: Pure function splitting routes into DayStage[] at day breaks
- use-days.ts: Reactive hook mapping Yjs state into computeDays() input
- GPX generate: emit <type>overnight</type> for isDayBreak waypoints
- GPX parse: recognize <type>overnight</type> and set isDayBreak on waypoints

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 23:51:31 +02:00
Ullrich Schäfer
4b711abaec
Add split export: Export Route vs Export Plan
Split button with default "Export GPX" (track only) and dropdown:
- Export Route: clean track for use in any app
- Export Plan: track + waypoints + no-go areas in GPX extensions
  (trails:planning namespace) for reimporting into the planner

Also:
- Add no-go area serialization to generateGpx (GPX extensions)
- Parse no-go areas from GPX extensions on import
- Initialize no-go areas in Yjs session from imported GPX
- Save to Journal now exports track only (consistent with Export Route)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 10:52:39 +01:00
Ullrich Schäfer
62b5fb998e
Fix planner production server + use .ts extensions everywhere
- Fix createRequestHandler → createRequestListener (@react-router/node
  removed the old API)
- Move noEmit + allowImportingTsExtensions to tsconfig.base.json so all
  packages and apps inherit them consistently
- Add explicit .ts extensions to all remaining relative imports across
  packages and apps

Verified locally: node --experimental-strip-types server.ts starts and
responds 200.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 01:41:33 +01:00
Ullrich Schäfer
2cfa5e54e7
Implement shared packages (tasks 2.1-2.6)
- @trails-cool/types: Route, Activity, Waypoint, RouteVersion, RouteMetadata
- @trails-cool/gpx: GPX parser (XML→waypoints/tracks/elevation) and generator
  with round-trip test, haversine distance, elevation gain/loss computation
- @trails-cool/map: MapView (Leaflet + OSM/OpenTopoMap/CyclOSM layer switcher),
  RouteLayer (GeoJSON polyline rendering)
- @trails-cool/ui: Button (primary/secondary/ghost), Input (with label/error),
  Card components with Tailwind styling
- @trails-cool/i18n: react-i18next config with English + German translations,
  browser language detection, fallback to English

All 13 unit tests pass. Both apps build successfully.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 13:09:35 +01:00