WayFy’s Place Discovery modules let travelers search for specific venue types around any location in the world. Four dedicated sections — Hotels, Restaurants, Transports, and Entertainment — each follow the same architecture: aDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/jhonyes04/new-wayfy/llms.txt
Use this file to discover all available pages before exploring further.
SearchAutocomplete bar geocodes any city or address into coordinates, the useGeoapify-backed hook fetches up to 100 venues per page from the Geoapify Places API within a 5 km radius, and results are filtered by accessibility level and sub-category before being paginated. Selecting a result opens a full detail panel with photos, OSM tags, and a save-to-favourites button.
Data Source
All four discovery modules source their venue data from the Geoapify Places API (https://api.geoapify.com/v2/places). The frontend calls this directly using VITE_GEOAPIFY_KEY from the Vite environment. Requests include:
categories— a comma-separated list of Geoapify category strings (see per-module lists below)filter=circle:${lon},${lat},${radius}— 5 km radius around the searched locationbias=proximity:${lon},${lat}— boosts results closest to the search centrelang=es— response labels in Spanishlimit=100— maximum 100 results per page; the client paginates withoffset
GET /api/places and appear on the Accessibility Map rather than in the discovery modules.
Place photos are resolved via the
usePlacePhoto hook. It checks, in priority order: a direct image URL on the OSM raw tags, a wikimedia_commons file, a Wikidata P18 image, a Google photo proxy (/api/utils/google-photo), and finally an OG image scraped from the place’s website. A concurrency limit of 4 simultaneous photo requests prevents overloading external services.Search Autocomplete
Every discovery section includes aSearchAutocomplete component at the top of the page. This component uses the Geoapify Geocoding API to suggest places as you type, with a 350 ms debounce. Key props:
onSelect(place)
Required callback. Receives
{ lat, lon, formatted, name, address_line1, address_line2, place_id, country_code }.bias
Pass
{ lat, lon } to prioritise suggestions near the user’s current location.filter
Geoapify filter string, e.g.
countrycode:es or circle:lon,lat,radius.type
Restrict suggestions to a Geoapify type:
amenity, city, street, etc.searchHotels, searchRestaurants, searchTransports, or searchEntertainment), which updates the URL query string (?q=...&lat=...&lon=...) so the search state survives page refresh.
Accessibility & Category Filters
The sharedFilterPanel component renders two sub-components side by side on the right edge of each discovery page:
FilterAccessibility
Toggles theactiveFilters array in global state. Three values are available:
| Value | Label | Colour |
|---|---|---|
yes | Total | Success (green) |
limited | Parcial | Warning (amber) |
no | No | Danger (red) |
FilterCategories
Toggles theactiveCategories array in global state for all 11 OSM category slugs (gastronomia, alojamiento, transporte, salud, cultura_turismo, recreacion, deporte, gobierno, baños, dinero, tiendas). A clear all button (red fa-circle-xmark icon) deselects all categories at once; clicking it again restores the previous selection via toggle state.
Filtering happens client-side: the full result set from Geoapify is stored in global state and the module’s filter hook (useHotelFilters, useRestaurantsFilters, useTransportsFilters, useEntertainmentFilters) derives the visible subset by matching each feature’s Geoapify category string against the active slugs.
Hotels
OSM category slug:alojamiento
The useHotels hook searches the following Geoapify categories:
Components
HotelsSearch
SearchAutocomplete wrapper that calls searchHotels(place) on selection and syncs ?q, ?lat, ?lon URL params.HotelsList
Paginated grid of
HotelCard components. Reads pageItems from usePagination and renders PaginationControls below.HotelCard
Summary card with photo (via
usePlacePhoto), name, address, and accessibility badge. Clicking selects the hotel.HotelDetail
Full detail panel (offcanvas) showing all OSM tags, contact info, photo, accessibility data from community reviews, and a favourite toggle.
Restaurants
OSM category slug:gastronomia
The useRestaurants hook searches:
Components
RestaurantsSearch
Autocomplete bar wired to
searchRestaurants. URL params: ?q, ?lat, ?lon.RestaurantsList
Paginated list of
RestaurantCard components.RestaurantCard
Card with cuisine type badge, photo, name, and accessibility indicator.
RestaurantDetail
Full OSM tag display including opening hours, cuisine, phone, website, and community accessibility review.
Transports
OSM category slug:transporte
The useTransports hook searches:
Components
TransportsSearch
Autocomplete bar wired to
searchTransports.TransportsList
Paginated list of
TransportCard components.TransportCard
Card showing transport type icon, name, and step-free / wheelchair-boarding badges.
TransportDetail
Detail panel with OSM
wheelchair:boarding, step_free, lift, and escalator tags prominently displayed.Entertainment
OSM category slug:recreacion / cultura_turismo
The useEntertainment hook searches:
Components
EntertainmentsSearch
Autocomplete bar wired to
searchEntertainment.EntertainmentsList
Paginated grid of
EntertainmentCard components.EntertainmentCard
Card with attraction category, photo, name, and accessibility badge.
EntertainmentDetail
Detail panel showing full OSM tags, Wikimedia photos, and community review data.
Pagination
All four modules use the sharedusePagination hook and PaginationControls component.
?page=N) so it survives navigation. When filters change and reduce totalPages, the hook resets to page 1 automatically via a useEffect.
Place Detail
Selecting any card in a discovery module triggers a two-step process:Optimistic selection
setSelectedHotel (or equivalent) updates component state immediately, opening the detail panel with whatever data is already in the card.- Name and category — from Geoapify feature properties
- Address —
address_line1+address_line2 - Photo — resolved by
usePlacePhoto(Wikidata → Google proxy → OG image fallback chain) - OSM accessibility tags — kerb, tactile paving, wheelchair, step_free, etc.
- Community review — pulled from
GET /api/accessibility/:osm_id/reviewif anosm_idis present - Favourite button — saves or removes the place via
useFavorites
The
osm_id on a Geoapify feature comes from feature.properties.datasource.raw.osm_id (prefixed with the OSM type, e.g. node/12345678). This is used to cross-reference community accessibility reviews stored in WayFy’s database.