# Task 02 — Location Autocomplete Component

A reusable React component that lets a captain search the location master,
and if not found, search Google Places to add a new location. Used in the
Vihar Create form (Task 03).

## File to create

```
apps/web/src/components/locations/location-picker.tsx
```

## Component contract

```tsx
interface LocationPickerProps {
  label: string;                 // "Departure" / "Arrival"
  value: number | null;          // selected location_id
  onChange: (id: number | null) => void;
  placeholder?: string;
}
```

## Behavior

1. **First, search the local master** at `GET /api/locations?q={query}`.
   Show results immediately (no debounce needed - it's local).
2. If the captain doesn't see what they want, show a "+ Add new from Google Maps"
   button at the bottom of the dropdown.
3. Tapping that button switches the dropdown to Google Places mode.
   Generate a session token (use `crypto.randomUUID()` — that's what Google
   recommends for session tokens).
4. As they type (debounced 300 ms), call `GET /api/places/autocomplete?q=...&sessionToken=...`.
5. When they pick a Google prediction:
   - Show a small modal: "Add this location to South Mumbai?"
   - Field: location type (dropdown: upashray / temple / residence / dharamshala / other)
   - Field: display name (pre-filled with Google's primary text, editable)
   - Field: locality (optional dropdown from `/api/localities`)
   - Submit button calls `POST /api/locations/from-place-id` with placeId, sessionToken, locationType, displayName, localityId.
   - On success, set the selected location_id and close.

## State machine

```
[empty] --type--> [searching local]
                       |
                       v
                [list of local matches] --pick--> done
                       |
                       +--no match, click "Add"--> [google search]
                                                       |
                                                       v
                                                [google predictions] --pick--> [add modal] --submit--> done
```

## UI notes

- Use the `Input` component from `apps/web/src/components/ui/input.tsx`.
- Use `Card` for the dropdown panel.
- Animate the dropdown open with `animate-fade-in`.
- Keyboard: arrow keys + enter should work for picking.
- Show a small Google logo / "Powered by Google" text below the predictions
  (Google requires attribution for Places usage).

## Acceptance

1. Type "walk" in the picker — see local matches like "Walkeshwar Jain Temple".
2. Pick one — `onChange(locationId)` fires, dropdown closes, picker shows the name.
3. Type "starbucks" (something not in master) — see "+ Add new from Google Maps".
4. Click it — predictions from Google appear.
5. Pick one — modal opens with prefilled name + type dropdown.
6. Submit — location persists, picker shows it as selected.
7. Reopen the picker — your newly added location now appears in local search.

## Gotchas

- **Session token reuse:** generate ONE token when the picker is opened in
  Google mode and reuse it for ALL keystrokes until terminated by a Place
  Details call (which `from-place-id` does server-side). New tokens per
  keystroke = lost free tier.
- **Debounce, but only in Google mode.** Local master search doesn't need
  debouncing; the result list is small and instant.
- **Conflict on dedup:** if `from-place-id` returns 409 with an existing
  location, pick that one transparently rather than showing an error.
- **Cleanup:** when the picker unmounts or the user picks a result, the
  session token is no longer needed (server side). No client cleanup needed.

## Out of scope

- Map preview / pin display — defer to Phase 2
- Editing existing locations — captain can only edit via a separate admin screen
- Bulk import of locations — separate one-time script
