Skip to main content

Documentation 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.

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: a 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 location
  • bias=proximity:${lon},${lat} — boosts results closest to the search centre
  • lang=es — response labels in Spanish
  • limit=100 — maximum 100 results per page; the client paginates with offset
Community-submitted pins (places added by WayFy users) are served separately by 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 a SearchAutocomplete 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.
Selecting a suggestion fires the module’s search function (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 shared FilterPanel component renders two sub-components side by side on the right edge of each discovery page:

FilterAccessibility

Toggles the activeFilters array in global state. Three values are available:
ValueLabelColour
yesTotalSuccess (green)
limitedParcialWarning (amber)
noNoDanger (red)
At least one filter is always active (the toggle is a no-op if it would deselect the last active value).

FilterCategories

Toggles the activeCategories 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:
accommodation.hotel
accommodation.hostel
accommodation.motel
accommodation.guest_house
accommodation.apartment
accommodation.chalet
accommodation.hut

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:
catering.restaurant
catering.cafe
catering.fast_food
catering.bar
catering.pub
catering.ice_cream
catering.food_court
catering.biergarten

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:
public_transport.train
public_transport.subway
public_transport.bus
public_transport.tram
public_transport.ferry
railway
airport
service.taxi
rental.car
parking

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:
entertainment
tourism.attraction
tourism.sights
tourism.information
leisure.park
leisure.picnic
leisure.spa
leisure.playground

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 shared usePagination hook and PaginationControls component.
// usePagination signature
const {
  currentPage,   // number — current page (from ?page URL param)
  totalPages,    // number
  pageItems,     // T[] — slice of items for the current page
  setPage,       // (n: number) => void
  nextPage,      // () => void
  prevPage,      // () => void
  hasPrev,       // boolean
  hasNext,       // boolean
} = usePagination(items, itemsPerPage);
Page state is stored in the URL (?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:
1

Optimistic selection

setSelectedHotel (or equivalent) updates component state immediately, opening the detail panel with whatever data is already in the card.
2

Detail fetch

getPlaceDetails(place_id, signal) calls https://api.geoapify.com/v2/place-details?id=<place_id>&apiKey=<key> to fetch the enriched feature with full tag set, contact info, and geometry. The panel updates once the response arrives.
The detail panel for each module shows:
  • Name and category — from Geoapify feature properties
  • Addressaddress_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/review if an osm_id is 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.

Build docs developers (and LLMs) love