Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/viet2811/uk-travel-recommendation/llms.txt

Use this file to discover all available pages before exploring further.

The UK Travel Recommendation app is organised into four distinct screen groups that a user encounters in order: the auth screens for account creation and sign-in, a three-step onboarding flow that tailors the recommendation engine to their interests, the main discovery and liked-attractions experience, and a settings area for updating ongoing preferences. Each group maps to a specific navigator in the root NativeStackNavigator, ensuring clean transition animations and type-safe route parameters throughout.

Route Parameter Reference

All screen names and their associated parameters are declared in a single type in types/navigation.tsx. This is the canonical reference for any navigation.navigate() call in the codebase:
export type RootStackParamList = {
  Landing: undefined;
  Register: undefined;
  Login: undefined;
  PreferenceStack: undefined;
  PreferenceCat: undefined;
  PreferenceArea: undefined;
  PreferenceImport: undefined;
  Main: undefined;
  Discovery: undefined;
  Liked: undefined;
  LikedMain: undefined;
  LikedAreaScreen: { items: Attraction[]; areaName: string };
  Profile: undefined;
  Settings: undefined;
  UpdateGeoFilter: undefined;
  AttractionImport: undefined;
};
LikedAreaScreen is the only route that carries params. The items array is passed directly from the liked-attractions list to avoid a redundant network request when opening the map view.

Auth Screens

These three screens are accessible to unauthenticated users and form the gateway to the rest of the app.

WelcomeScreen (Landing)

The app’s entry point. Displays the app name and two call-to-action buttons: Log In and Register. No network requests are made here — it is a purely presentational screen.

RegisterScreen

A form with username and password fields. On submit it calls registerUser({ username, password }) (POST user/register/) and, on success, immediately calls login() so the user lands directly in the onboarding flow without a separate sign-in step.

LoginScreen

Collects credentials and calls login(username, password) from AuthContext. Displays inline error messages returned in result.message on failure. On success, React Navigation automatically redirects to Main (returning users) or PreferenceStack (first-time users).

Onboarding Flow

New users are routed through a three-screen preference-gathering flow immediately after registration. Completing the flow populates the backend’s user-preference vector, which powers the initial personalised recommendations.
1

PreferenceCat — Choose Categories

Displays the attraction categories as selectable tiles. The user taps the categories they are interested in, and the screen builds two parallel arrays:
  • preferences: (0 | 1)[] — a binary vector (1 = interested, 0 = not interested) with one element per category.
  • labels: string[] — the human-readable names of the selected categories.
These are sent to POST user/preferences/ via setUserPreferences() when the user proceeds to the next step.
Category selection screen
2

PreferenceArea — Pick a Geographic Area

An optional step that lets the user restrict recommendations to a specific geographical area of the UK in three levels: County, Region and Country.
  • The Map Picker UI is displayed with interactive SVG specifically for Region and Country whereas the areas are sufficiently big.
  • For County, it is displayed as a searchable list instead due to its small size.
The selection is stored as a query-string fragment in AsyncStorage under the key geoFilter (e.g. ?area=Scotland).Users can skip this step; in that case recommendations are drawn from the full UK dataset.
Geographic area selection screen
3

PreferenceImport — Import Visited Attractions

Allows the user to search for attractions they have already visited and bulk-import them as liked items. This seeds the recommendation engine with real historical signal before the user has made any in-app swipes.
  • A search field calls searchAttractions(name) (GET /recommendations/search?q=<name>) to find matching attractions.
  • Selected attractions are submitted via addVisitedAttractions(ids) (POST /recommendations/like/bulk/).
  • This screen is also accessible from Settings via the AttractionImport route for users who want to add more visited places later.
Import visited attractions screen

Discovery Screen

The DiscoveryScreen is the heart of the app — a continuously refreshing swipeable deck of personalised UK attraction cards.

Swipe Deck

Custom swipe animation from scratch, tailored from Rakha Wibowo’s. Each card shows the attraction image, name, category, and a short description. Swipe right to like, swipe left to dislike. The deck never empties thanks to automatic background pre-fetching.

Auto-Pagination

The useRecommendations hook monitors currentIndex. When five or fewer cards remain in the local cache, it automatically fetches the next page from /recommendations (with the current geoFilter appended) and appends the new items to the deck.

Swipe Actions

  • Swipe rightonSwipeRight(id)likeMutation.mutate(id) → calls likeAttraction(id) (POST /recommendations/like/<id>) → on success, invalidates the likedHistory query so the Liked tab reflects the change immediately.
  • Swipe leftonSwipeLeft(id) → calls dislikeAttraction(id) directly (POST /recommendations/dislike/<id>).

Attraction Detail Sheet

Tapping a card (rather than swiping) opens a @gorhom/bottom-sheet panel with extended details: full description, address, opening hours, and a link to an external website if available.
The geo filter in Settings applies to future recommendation fetches only. Cards already loaded into the deck are not discarded when you change the filter — swipe through the remaining cards and the next fetch will honour the new area.

Liked Screens

The Liked tab shows every attraction the user has swiped right on, organised for easy browsing and geographic exploration.
1

LikedMain — Liked Attractions Grid

Fetches the full liked history via getLikedAttraction() (GET /recommendations/history/liked) and renders a scrollable grid of attraction cards. Cards are grouped by geographic area, and each group header is a tappable button that navigates to LikedAreaScreen.
2

LikedAreaScreen — Map View

Receives { items: Attraction[], areaName: string } as route params and renders a react-native-maps full-screen map with a marker for each liked attraction in that area. Tapping a marker opens a callout with the attraction name and a shortcut to the detail bottom sheet.

Settings Screens

The SettingsScreen (accessible from the Profile tab) contains two sub-screens for updating persistent user preferences:
Lets the user change their geographic recommendation area after onboarding. Selecting a new area writes the updated query-string fragment to AsyncStorage (geoFilter). The next getRecommendations() call will use the new value. The current in-memory deck is not invalidated immediately — the change takes effect on the next page fetch.
The same search-and-bulk-import screen used during onboarding (PreferenceImport), but accessible at any time from Settings. Useful for users who have visited new places and want to keep the recommendation model up to date. Submits selections via addVisitedAttractions(ids) (POST /recommendations/like/bulk/).
Changing your geo filter via UpdateGeoFilter does not reset your preference vector or liked history. It only changes the geographic scope of future recommendation API calls.

Build docs developers (and LLMs) love