Add 8 proposed changes and old trails analysis

Proposed changes (all with proposal, design, specs, tasks):
- app-navigation (9 tasks) — nav bars for both apps
- planner-landing-page (7 tasks) — standalone landing page
- planner-multiplayer-awareness (13 tasks) — participants, cursors, names
- changelog (13 tasks) — public changelog with "what's new"
- transactional-emails (15 tasks) — magic link + welcome emails
- planner-features (18 tasks) — no-go areas, notes, recovery, rate limits
- komoot-import (23 tasks) — Komoot tour import
- route-features (37 tasks) — sharing, multi-day, spatial, photos

Also adds docs/old-trails-analysis.md with feature analysis from the
older trails project.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Ullrich Schäfer 2026-03-25 03:57:20 +01:00
parent 57141cdfab
commit c7c1c275df
No known key found for this signature in database
GPG key ID: A32FF691A0F752D9
55 changed files with 1704 additions and 0 deletions

View file

@ -0,0 +1,2 @@
schema: spec-driven
created: 2026-03-25

View file

@ -0,0 +1,46 @@
## Context
Yjs awareness already tracks users with `{ color, name }` state and renders
map cursors via `CursorTracker` in `PlannerMap.tsx`. The current implementation
has issues: random names can't be changed, cursor labels are unstyled, and
there's no participant list showing who's in the session.
## Goals / Non-Goals
**Goals:**
- See all participants in the session (name, color, host/participant role)
- Edit your own name (saved to localStorage, synced via awareness)
- Polished cursor rendering on the map
- Visual feedback when someone joins or leaves
**Non-Goals:**
- Chat or messaging between participants
- Cursor position sharing outside the map (e.g., in the sidebar)
- Participant permissions or kicking (admin-only debug feature already exists)
## Decisions
### D1: Participant list in session header
Show colored dots + names in the header bar (already has space between profile
selector and connection status). Clicking your own name opens an inline edit.
Keeps the sidebar free for waypoints.
### D2: Name persisted in localStorage, synced via awareness
Current approach: random name from a list, stored in localStorage as
`trails:user`. Enhancement: let users edit it. On change, update localStorage
AND call `awareness.setLocalStateField("user", { color, name })`. All other
clients see the update immediately.
### D3: Cursor as SVG pointer with name tag
Replace the current `divIcon` cursor label with: a small SVG arrow in the
user's color + a name tag with background, shadow, and rounded corners.
Position offset so the pointer tip is at the actual lat/lng.
### D4: Join/leave toasts
When awareness detects a new client or a client leaving, show a brief toast
("Alice joined" / "Bob left") that auto-dismisses after 3 seconds. Use a
simple absolute-positioned div, no toast library.

View file

@ -0,0 +1,35 @@
## Why
The Planner supports collaborative editing but the multiplayer experience is
bare. Users can't see who else is in the session. Cursor labels are small
floating divs that look broken (no proper styling, overlap with map controls).
Users get randomly assigned names like "Hiker" or "Explorer" with no way to
change them. This makes collaboration confusing — you can't tell who is who.
## What Changes
- **Participant list**: Show who's in the session (name, color, host badge)
in the sidebar or header
- **Name editing**: Let users set their name after joining (persisted in
localStorage, synced via Yjs awareness)
- **Cursor styling**: Fix cursor labels — proper pointer icon, name tag with
shadow, avoid overlap with map controls
- **Connection indicators**: Show when participants join/leave
## Capabilities
### New Capabilities
(None — this enhances existing Yjs awareness features.)
### Modified Capabilities
- `planner-session`: Session view gains participant list and name editing
- `map-display`: Map cursor rendering improved
## Impact
- **Files**: `PlannerMap.tsx` (cursor styling), `SessionView.tsx` (participant
list), `use-yjs.ts` (name editing), new `ParticipantList` component
- **Dependencies**: None
- **i18n**: New keys for participant labels and name editing

View file

@ -0,0 +1,12 @@
## MODIFIED Requirements
### Requirement: Map cursor rendering
Other participants' cursors on the map SHALL be clearly visible with proper styling.
#### Scenario: Cursor appearance
- **WHEN** another participant moves their mouse on the map
- **THEN** a colored pointer icon with their name tag appears at the cursor position
#### Scenario: Cursor does not obscure map controls
- **WHEN** cursors are rendered
- **THEN** they appear below map controls (zoom, layer switcher) in z-index

View file

@ -0,0 +1,28 @@
## MODIFIED Requirements
### Requirement: Session participant awareness
Users in a planning session SHALL see who else is present and be able to identify themselves.
#### Scenario: Participant list visible
- **WHEN** multiple users are in a session
- **THEN** the header shows each participant's name and color
#### Scenario: Host badge
- **WHEN** a participant is the routing host
- **THEN** their entry in the participant list shows a host indicator
#### Scenario: Edit own name
- **WHEN** a user clicks their own name in the participant list
- **THEN** an inline text input appears to change their display name
#### Scenario: Name persisted
- **WHEN** a user changes their name
- **THEN** the name is saved to localStorage and immediately visible to all other participants via awareness
#### Scenario: Join notification
- **WHEN** a new participant joins the session
- **THEN** a brief toast shows "[name] joined"
#### Scenario: Leave notification
- **WHEN** a participant leaves the session
- **THEN** a brief toast shows "[name] left"

View file

@ -0,0 +1,27 @@
## 1. Name Editing
- [ ] 1.1 Update use-yjs.ts: allow updating user name via a returned setter function
- [ ] 1.2 Save updated name to localStorage and sync via awareness.setLocalStateField
- [ ] 1.3 Add i18n keys for participant UI (en + de)
## 2. Participant List
- [ ] 2.1 Create ParticipantList component showing all awareness states (name, color dot, host badge)
- [ ] 2.2 Add inline name edit when clicking own name in the list
- [ ] 2.3 Integrate ParticipantList into SessionView header
## 3. Cursor Styling
- [ ] 3.1 Replace current divIcon cursor with SVG pointer arrow + styled name tag (background, shadow, rounded)
- [ ] 3.2 Set cursor z-index below map controls to avoid overlap
## 4. Join/Leave Toasts
- [ ] 4.1 Track awareness changes (added/removed clients) in SessionView
- [ ] 4.2 Show auto-dismissing toast when participant joins or leaves (3 second duration)
## 5. Verify
- [ ] 5.1 Test with two browser windows: verify participant list, name editing, cursor rendering
- [ ] 5.2 Verify join/leave toasts appear correctly
- [ ] 5.3 Verify name persists across page refresh (localStorage)