Skip to content

M13 — Maps

Status: agreed · Last session: 2026-09-28

Sources: requirements.md M13, M9, M11 · decisions.md P25, P17, A13 · M1 day plan card (the right column on web is kept for this map).

Who and the job

  • Traveller: "Where are today's places, how far apart, and where do we sleep?" — on the day, on the phone.
  • Group leader: "Does the route make sense?" — the whole trip at a glance, to forward to the group.
  • Editor (P36): spots a stop in the wrong place or a day that zig-zags across town.

Value

A list of stops does not show distance or order on the ground. The map answers "how far is the hotel from the temple?" without leaving NepWalk, and one tap hands the day's route to Google Maps for real navigation. On web it fills the empty right column with something useful (the Visitacity pattern).

Placement — and why

Element Mobile Tablet / web Why
Day map "Map" button above the cards → full-screen map, close to return Right column, sticky while the cards scroll Phones have no room for both; on web the map sits beside the cards it explains
Pins Numbered like the cards (1, 2, 3…); 🏨 pin for tonight's hotel Same The number links a pin to its card
Route line Thin line joining the pins in visit order, ending at the hotel Same Shows the day's direction and back-tracking
Pin tap Closes the full-screen map, scrolls to that card and highlights it Scrolls the card into view and highlights it The card holds the detail; no second popup to read
Stops without coordinates Listed under the map as "Not on map: …" Same Honest: never a made-up position
"Open in Google Maps" — day Button on the map: the day as a route, stops as waypoints in order, tonight's hotel as the destination Same One tap = the day's route in the app travellers already navigate with
"Open in Google Maps" — stop Small link on each card with coordinates Same For "just take me to this one place"
Whole-trip map From the trip overview From the trip overview The whole trip at a glance for the leader (M4)

Wireframe

Mobile — day

┌──────────────────────────────┐
│ Day 2 · Wed 30 Dec           │
│ 🌙 Tonight: Hotel Barahi ·   │
│    Pokhara                   │
│ [ 🗺 Map ]                    │  opens full screen
│ ┌──────────────────────────┐ │
│ │ 1 · PHOTO / card …       │ │
│ │     📍 Google Maps        │ │  per-stop link
│ └──────────────────────────┘ │
└──────────────────────────────┘

Full screen:
┌──────────────────────────────┐
│ ✕  Day 2 map                 │
│   ①───②                      │
│         \                    │
│          ③────🏨             │
│                              │
│ Not on map: Free time        │
│ [ Open day in Google Maps ]  │
└──────────────────────────────┘

Web — day

┌──────────────┬──────────────────────────────┬──────────────────────┐
│ DAYS         │ Day 2 · Wed 30 Dec  [+ Add stop]│   DAY MAP (sticky)   │
│ …            │ 🌙 Tonight: Hotel Barahi      │    ①───②             │
│              │ ┌──────┬───────────────────┐ │          \            │
│              │ │PHOTO │ 1 · 09:00 · 2 h   │ │           ③───🏨      │
│              │ │      │ Phewa Lake        │ │                       │
│              │ └──────┴───────────────────┘ │ Not on map: Free time │
│              │   🚗 25 min                   │ [Open day in Google   │
│              │ ┌──────┬───────────────────┐ │  Maps]                │
│              │ │PHOTO │ 2 · 11:30 …       │ │                       │
└──────────────┴──────────────────────────────┴──────────────────────┘

Whole-trip map (overview)

┌───────────────────────────────────────────┐
│ Trip map                                  │
│   Kathmandu (3 nights) ●                  │
│                         \  ✈ (dashed)     │
│                          ● Pokhara (3)    │
│                         /  🚗             │
│   Chitwan (2) ●────────                   │
└───────────────────────────────────────────┘

One pin per overnight town with the number of nights; lines in day order; flights dashed, roads solid.

States

  • No stop has coordinates: no map; "No places on the map yet" (editor: "Link stops to library places to see them on the map" — M1 card).
  • Only some have coordinates: map with those; the rest under "Not on map".
  • One stop: a single pin, zoomed to the town.
  • Loading: grey block the size of the map. Tiles fail (offline): pins and lines still draw on a plain background; "Map tiles unavailable".
  • More than 9 stops: the Google Maps day route takes the first 9 in order (Google's waypoint limit) and says "first 9 stops".

Rules and edge cases

  • Positions come only from library places (place.latitude/longitude, M9) or a stay's linked place; never geocoded from free text.
  • Numbers match the card order of the day (the same order the Timeline shows).
  • Tiles: OpenStreetMap (P25), with the required "© OpenStreetMap contributors" attribution. Low traffic is fine under the OSM tile policy; a paid tile host only if usage grows.
  • Transport items (travel lines) are not pins; their ends are the stops around them.
  • Whole-trip map: a town = the city of the night's stay (nights.ts); a move is AIR if a FLIGHT covers it, else ROAD.
  • Maps are view-only for everyone; editing stays in the cards.

Decided (28 Sep)

  • Day map: web right column (sticky); mobile "Map" button → full screen.
  • Numbered pins + 🏨 tonight's hotel + route line in visit order; pin tap scrolls to and highlights the card; stops without coordinates listed as "Not on map".
  • "Open in Google Maps": both — the day as a route (waypoints, hotel as destination) on the map, and a per-stop link on each card.
  • Whole-trip map opens from a "Trip map" link in the sidebar's "Trip overview" box (full-width map view) until the M4 overview page exists; revisit then (28 Sep, "okay for now").
  • Whole-trip map: on the trip overview — one pin per overnight town with nights count, lines in day order, flights dashed.

TBD

  • None open.

Backlog (after launch)

  • Walking / driving time along the real road (routing API) instead of straight lines.
  • Offline map tiles for the day (PWA, M6).
  • Nearby suggestions on the map (cafés, ATMs).

Tasks

For build day 13 (Wed 30 Sep), [fe]:

  1. Map component on OpenStreetMap tiles (Leaflet, loaded client-side only), with attribution; pure helpers in src/lib/ (Vitest) for: pins from a day's stops (numbered, hotel last, "not on map" list), route order, map bounds.
  2. Day map: web right column (sticky), mobile "Map" button → full-screen view; pin tap scrolls to and highlights the card.
  3. "Open in Google Maps": day route URL (waypoints ≤ 9, hotel destination) + per-stop link on cards — URL builders in src/lib/ with tests.
  4. Whole-trip map: towns from nights, nights count, lines in day order (flights dashed) — helper with tests; opened from a "Trip map" link in the sidebar's "Trip overview" box.
  5. States: no coordinates, partial, one stop, loading, tiles unavailable.