Data Flow
How data moves from user input → UI → API → database and back.
Application State Machine
┌──────────┐ onStart() ┌─────────────┐ onComplete(data) ┌─────────────┐
│ HERO │ ────────────► │ SETUP │ ──────────────────► │ PLANNER │
│ Landing │ │ Wizard │ │ Map View │
└──────────┘ └─────────────┘ └─────────────┘
▲ │ ▲ │
└───── onBack() ────────────┘ └──────── onBack() ────────────┘State managed in Index.tsx as AppState = 'hero' | 'setup' | 'planner'.
Trip Generation
User submits header search bar
AirbnbSearchBar / MobileLandingSearchBar produces a TripSetupData object (location, dates, units, currency, fuel).
generateTrip(setup) called
tripEngine.ts calculates total days, distributes distance, computes fuel/cost per day.
Trip object created
Contains setup + days[] + totals. Stored in React state.
MapPlanner renders
GoogleMapView geocodes start/end. ItinerarySidebar (desktop) / MobileItineraryBottomSheet (mobile) shows the day-by-day plan.
Adding a Stop
User searches location User taps "Add stop" in itinerary
│ │
▼ ▼
GoogleSearchBar (Places API) ItinerarySidebar / BottomSheet button
│ │
▼ │
handlePlaceSelected() handleAddStop(dayIndex)
• setSelectedLocation() │
• setAddStopDay(0) │
• setAddStopOpen(true) │
│ │
└──────────┬─────────────────────┘
▼
AddStopDialog opens
(pre-filled location or empty)
│
▼
User fills: type, day, name, cost
│
▼
handleStopAdded(dayIndex, stop)
• Immutably updates trip.days[dayIndex].stops
• Recalculates totalStops
• Calls onUpdateTrip(newTrip)
│
▼
Trip state updated → UI re-rendersGoogle Maps API Flow
API Key Loading
useGoogleMaps() hook
→ supabase.functions.invoke('google-maps-key')
→ Edge function reads GOOGLE_MAPS_API_KEY secret
→ Returns { key: "..." }
→ Injects <script> tag with key
→ Sets ready = truePlaces Autocomplete
usePlacesAutocomplete(inputRef, onSelect) → Waits for useGoogleMaps().ready → Creates google.maps.places.Autocomplete on input → User types → Google suggests places → User selects → onSelect(PlaceResult) fires → PlaceResult has: name, geometry, place_id, address_components
Persistence Flow (Phase 2 — Planned)
User generates trip
│
├─── If signed in ──► INSERT into trips, trip_days, trip_stops
│ │
│ Auto-save on every stop add/remove
│
└─── If guest ──────► Trip lives in React state only
│
"Save" button → triggers auth modal
│
After sign-in → save trip to DBAuthentication Flow (Phase 2 — Planned)
User clicks "Sign up"
Email + password form. supabase.auth.signUp() called.
Email verification sent
User must click link in email (auto-confirm OFF).
User confirms email
Account activated. Trigger creates profiles row.
User signs in
supabase.auth.signInWithPassword(). Session stored in localStorage.
Auth state propagates
onAuthStateChange() updates UI: avatar in header, save enabled.