# Feature Spec: GPS-liknande uppdragsnavigering **Status:** Backlog **Prioritet:** Hög **Tilldelad:** Johan **Skapad:** 2026-06-16 **Källa:** Erik UX-prompt --- ## Översikt När en Zoomer accepterar eller öppnar ett uppdrag ska kartan växla till ett navigeringsläge som efterliknar premium fordons-GPS (VW/Audi/BMW) kombinerat med Uber/Bolt-känsla för uppdragskort. --- ## Flöde ``` Uppdragslista → Klick på uppdrag → Uppdragskort (flytande) ↓ [Lås upp uppdrag] [Starta navigation] [Visa alternativa rutter] ↓ Navigeringsläge (turn-by-turn) ``` --- ## Steg 1 — Uppdragskort (flytande overlay) Visas när användaren klickar på ett uppdrag på kartan. ### Innehåll - Titel - Adress - Avstånd från användaren (beräknat från GPS) - Beräknad restid - Beräknad ankomsttid (ETA) ### Exempel ``` 📍 Fasadfotografering — Storgatan 12 14,2 km · 18 min · ETA 14:37 ``` ### Knappar | Knapp | Funktion | |-------|----------| | **Lås upp uppdrag** | Reserverar uppdraget, drar kredit/visar pris | | **Starta navigation** | Startar turn-by-turn | | **Visa alternativa rutter** | Expanderar ruttval på kartan | --- ## Steg 2 — Kartbeteende vid öppnat uppdrag ### Auto-zoom & centrering - Hämta GPS-position i realtid (`navigator.geolocation.watchPosition`) - Zooma automatiskt till nivå där **både** Zoomer och destination syns - Centrera kartan så hela rutten ryms med padding (~15% marginal) - Använd `fitBounds()` med koordinater för [user_pos, destination] ### Markörer - **Zoomer:** Blå pulsande cirkel (standard Mapbox user location dot) - **Destination:** Uppdragets ikon/logotyp (custom marker) ### Rutt-ritning - Hämta rutt från routing-API (se nedan) - Rita primär rutt: solid linje, blå (#0066FF), 4px - Rita alternativa rutter: grå, 2px, klickbar - Visa avstånd + tid på varje ruttlinje --- ## Steg 3 — Navigeringsläge (turn-by-turn) Aktiveras via "Starta navigation". ### Kartbeteende - Rotera kartan i färdriktningen (heading-lock) - 3D-perspektiv (pitch: ~45°) - Zooma in till ~200m framförhållning - Kontinuerlig positions-uppdatering ### UI-overlay (top bar) ``` ┌─────────────────────────────────────────┐ │ ↰ Sväng vänster om 180 m │ │ Kungsgatan │ ├──────────────┬──────────────┬───────────┤ │ 12 min │ 2,4 km │ ETA 14:37│ └──────────────┴──────────────┴───────────┘ ``` ### Funktioner - Next maneuver (ikon + text + avstånd) - Återstående tid, avstånd, ETA — uppdateras live - **Auto-reroute** om avvikelse > 50m från rutten - "Anlänt" när Zoomer är inom ~30m av destination --- ## Tech Stack ### Routing API — rekommendation: **Mapbox Directions API** Anledning: Appen kör redan troligen Mapbox för 3D-kartan. Unified billing. ``` GET https://api.mapbox.com/directions/v5/mapbox/walking/{lon1},{lat1};{lon2},{lat2} ?alternatives=true &geometries=geojson &steps=true &language=sv &access_token={MAPBOX_TOKEN} ``` Returvärden vi använder: - `routes[].duration` → restid (sekunder) - `routes[].distance` → avstånd (meter) - `routes[].geometry` → GeoJSON för ritning - `routes[].legs[].steps[]` → turn-by-turn instruktioner **Alternativ om Mapbox ej används:** - Google Routes API (dyrare, men bättre ETA i Sverige) - OSRM self-hosted (gratis, kräver infra) ### Kostnad Mapbox Directions - Gratis: 100,000 requests/mån - Sedan: $1/1,000 requests - Zoomer gör ~1 request per uppdrag → vid 10,000 uppdrag/mån = $10 ### Turn-by-turn Mapbox Navigation SDK (iOS/Android) ger turn-by-turn gratis ovanpå Directions API. --- ## Visuell design ### Uppdragskort - Mörkt tema (#0a0a0a bakgrund, vit text) - Bottom sheet / sliding panel (60% skärmhöjd) - Mjuk spring-animation vid öppning (300ms) - Samma designspråk som nuvarande uppdragskort i appen ### Navigeringsläge - Mörkt tema - Top bar: svart, frostad glaseffekt - Manöverikoner: vita, Mapbox standard set - 3D-perspektiv: pitch 45°, bearing = heading - Smooth rotation vid svängar ### Animationer - `fitBounds()` med `animate: true, duration: 800ms` vid öppning - Smooth heading-rotation: interpolera bearing varje GPS-tick - Flytande transition uppdragsvy → navigation: 400ms --- ## Implementation — prioriterad ordning 1. **Routing API-integration** — hämta rutt + rita på karta 2. **Uppdragskort** — avstånd, restid, ETA 3. **Auto-zoom/fitBounds** — när uppdrag öppnas 4. **Alternativa rutter** — visa + väljbart 5. **Turn-by-turn UI** — top bar med manöver + stats 6. **Heading-rotation** — karta roterar med färdriktning 7. **Auto-reroute** — vid avvikelse --- ## Öppna frågor till Johan - [ ] Vilken kart-lib använder appen? (Mapbox GL, MapLibre, Google Maps?) - [ ] Finns det redan ett Mapbox-konto/token? - [ ] iOS, Android, eller React Native/Flutter? - [ ] Ska navigation köras in-app eller via deep link till Google Maps/Apple Maps? --- ## Acceptanskriterier - [ ] Uppdragskort visar korrekt avstånd, restid och ETA - [ ] Rutt ritas upp inom 2s efter uppdrag öppnas - [ ] Alternativa rutter visas och är klickbara - [ ] Navigeringsläge roterar kartan i färdriktning - [ ] Auto-reroute fungerar vid avvikelse - [ ] ETA uppdateras live under navigation - [ ] "Anlänt"-signal vid ~30m från destination - [ ] Fungerar offline (cached tiles) för basic kartvisning