Skip to content

feat: add autocomplete/typeahead to place search#542

Closed
ben-haas wants to merge 7 commits intomauriceboe:devfrom
ben-haas:search-auto-complete
Closed

feat: add autocomplete/typeahead to place search#542
ben-haas wants to merge 7 commits intomauriceboe:devfrom
ben-haas:search-auto-complete

Conversation

@ben-haas
Copy link
Copy Markdown

@ben-haas ben-haas commented Apr 9, 2026

Description

Add real-time autocomplete/typeahead suggestions to the place search field in PlaceFormModal. When users type in the search box, they now see a dropdown of place suggestions powered by Google Places Autocomplete API (with Nominatim fallback for users without a Google API key). Selecting a suggestion fetches full place details and populates the form.

Key changes:

  • New POST /api/maps/autocomplete backend route and autocompletePlaces service function
  • Debounced autocomplete dropdown in PlaceFormModal with full keyboard navigation (arrow keys, enter, escape) and mouse support
  • Location bias derived from existing trip places for more relevant suggestions

Related Issue or Discussion

Type of Change

  • Bug fix
  • New feature
  • Breaking change
  • Documentation update

Checklist

  • I have read the Contributing Guidelines
  • My branch is up to date with dev
  • This PR targets the dev branch, not main
  • I have tested my changes locally
  • I have added/updated tests that prove my fix is effective or that my feature works
  • I have updated documentation if needed

  field, with Google Places Autocomplete API and Nominatim fallback.

  - Add POST /api/maps/autocomplete route and autocompletePlaces service
  - Add mapsApi.autocomplete client method
  - Add debounced autocomplete dropdown to PlaceFormModal with keyboard
    navigation (arrow keys, enter, escape) and mouse selection
  - Use place details API to populate form fields on suggestion selection
  - Derive location bias from existing trip places for better results
  - Extract Google Maps URL regex to shared constant
@jubnl jubnl added the approved on discord Discussed and greenlit on discord label Apr 9, 2026
website: string
}

const GOOGLE_MAPS_URL_RE = /^https?:\/\/(www\.)?(google\.[a-z.]+\/maps|maps\.google\.[a-z.]+|maps\.app\.goo\.gl|goo\.gl)/i
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This regex is flawed: https://regexr.com/8ljek

@ben-haas
Copy link
Copy Markdown
Author

ben-haas commented Apr 9, 2026

I forgot to push up the tests. I'll look into the regex as well.

@ben-haas ben-haas requested a review from jubnl April 9, 2026 23:11
@jubnl
Copy link
Copy Markdown
Collaborator

jubnl commented Apr 9, 2026

oof.. The failing test has nothing to do with your pr, don't worry. I'll fix it when I have some time.

Regarding the regex, it still has some issues. By checking https://google.[2-3 chars].[2 chars]/maps, this work : https://google[.]aaa[.]ch/maps

I've updated the test case: https://regexr.com/8ljek

An idea you can explore is instead to URL(urlString.trim()), then use the hostname prop from the URL object

@ben-haas
Copy link
Copy Markdown
Author

oof.. The failing test has nothing to do with your pr, don't worry. I'll fix it when I have some time.

Regarding the regex, it still has some issues. By checking https://google.[2-3 chars].[2 chars]/maps, this work : https://google[.]aaa[.]ch/maps

I've updated the test case: https://regexr.com/8ljek

An idea you can explore is instead to URL(urlString.trim()), then use the hostname prop from the URL object

Ya, that seems cleaner. Just pushed an update.

@solarssk
Copy link
Copy Markdown

Hey! One question about the location bias logic - currently I understand, it picks the first place with coordinates from the trip:

What happens if the trip spans multiple countries (e.g. Japan + China)? The bias will always point to whichever country was added first, which could result in poor suggestions when searching for places in the other country.

@ben-haas
Copy link
Copy Markdown
Author

Hey! One question about the location bias logic - currently I understand, it picks the first place with coordinates from the trip:

What happens if the trip spans multiple countries (e.g. Japan + China)? The bias will always point to whichever country was added first, which could result in poor suggestions when searching for places in the other country.

That's a good point! It looks like a bounding box can be used in the locationBias parameter, which would be an improvement, however I'm re-thinking this feature now. There is a lot of nuance to trips that influences how the bias would be useful. For example, if I was planning a road trip, a search bias that included a corridor around my route would be nice, but if I was flying across a country or continent, obviously there is no use in having a search bias along the route.

I think the bias parameter should be removed entirely for now and possibly revisited later. There is more complexity than I originally considered and I'm not sure that it adds that much value.

What do you think @solarssk?

…h functionality

- Integrate a loading spinner for "Name" input field during place search.
- Enhance OpenStreetMap place detail retrieval with Nominatim lookup.
- Update `authStore` to track Google Maps API key presence.
@ben-haas
Copy link
Copy Markdown
Author

I caught a bug and made some changes to help with the searchBias. I also merged in dev and resolved all conflicts. Here is a summary:

Autocomplete search with location bias

  • Location bias uses a bounding box derived from the trip's existing places (or the map viewport) to improve suggestion relevance, with validation to reject degenerate/zero-area bounds

OSM place details fix

  • Bug fix: When no Google Places API key is present, selecting an autocomplete suggestion would not populate the modal fields (name, address, coordinates, website). Root cause: the Overpass API detail lookup only returned metadata (phone, website, hours) but not core fields. Added a Nominatim /lookup call (run in parallel with Overpass) to fetch name, address, lat, and lng for OSM places.

Loading UI

  • When a suggestion is selected, the place name is populated in the Name field immediately from the suggestion text
  • An inline spinner appears beside the name while the remaining details (address, coordinates, website) are fetched
  • hasMapsKey now updates reactively when the API key is saved or removed, so the "Search via OpenStreetMap" hint appears/disappears without a page refresh

Other

  • Added places.loadingDetails translation key across all 14 locales
  • Added tests for mapsApi.autocomplete and autocompletePlaces service interactions

jubnl added a commit that referenced this pull request Apr 15, 2026
- Fix race condition: AbortController cancels in-flight autocomplete
  requests on each keystroke; stale responses no longer overwrite fresh ones
- Remove acTrigger state hack; onFocus calls fetchSuggestions directly
- Cap autocomplete input at 200 chars server-side (400 on violation)
- Filter Nominatim suggestions with empty osm_id segments
- Revert getPlaceDetails OSM branch from unconditional parallel fetch to
  conditional serial: Nominatim called only when Overpass lacks coords/address
- Wire places.loadingDetails i18n key to Loader2 spinner via aria-label/role
- Add tests: MAPS-017, MAPS-040c, MAPS-093, FE-MAPS-004
@jubnl
Copy link
Copy Markdown
Collaborator

jubnl commented Apr 15, 2026

Closed in favor of #661

@jubnl jubnl closed this Apr 15, 2026
jubnl added a commit that referenced this pull request Apr 15, 2026
fix(search-autocomplete): address PR #542 review issues
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved on discord Discussed and greenlit on discord

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants