Skip to content

NUS-MTechSE-DMSS/swipe2eat-ui

Repository files navigation

Swipe2Eat UI

A Flutter app for discovering, swiping, saving, and revisiting food recommendations. The app integrates with the shared backend for authentication, preferences, food discovery, favorites, chat recommendations, and profile management.

Contents

Features

Core App

  • Swipe-based food discovery with card gestures and like/dislike actions.
  • Favorites screen that reloads liked foods from the backend.
  • Food detail screen with image, rating, price, tags, description, and map location link.
  • Profile screen for user details, preferences, logout, and account deletion.
  • Onboarding flow for cuisine, budget, spice, dietary type, and allergens.
  • Chat recommendations backed by the LLM chat API.
  • Responsive Flutter UI for iOS, Android, web, and desktop-capable builds.

Authentication

  • AWS Cognito sign-up, confirmation, sign-in, forgot-password, token refresh, and delete-user flows.
  • ID token authentication for backend APIs.
  • Access token use where Cognito requires it.
  • SharedPreferences-backed local session storage.
  • Automatic session refresh through AuthenticatedHttpClient.

Backend And Local State

  • Food discovery fetches personalized results by Cognito user id first, then falls back to preference filters.
  • Preferences sync to the backend and are also saved locally.
  • Swipe preferences are queued through the backend swipe endpoint.
  • Favorites are synced from the backend and cached in FavoritesStore.
  • Backend image keys are expanded to public S3 image URLs.

Prerequisites

  • Flutter SDK with Dart SDK support for sdk: ^3.10.7.
  • Git.
  • Xcode and CocoaPods for iOS development on macOS.
  • Android Studio or Android SDK for Android development.

Useful checks:

flutter --version
dart --version
flutter doctor

Installation

git clone https://github.com/NUS-MTechSE-DMSS/swipe2eat-ui.git
cd swipe2eat-ui
flutter pub get

For iOS:

cd ios
pod install
cd ..

Configuration

The backend base URL is read from ApiConfig.baseUrl, which uses the API_BASE_URL Dart define.

Environment files live in config/env/:

config/env/dev.json
config/env/staging.json
config/env/prod.json

Example run using an environment file:

flutter run --dart-define-from-file=config/env/dev.json

Android builds also define product flavors in android/app/build.gradle.kts:

flutter run --flavor dev --dart-define-from-file=config/env/dev.json

Running The App

List devices:

flutter devices

iOS simulator:

flutter run -d <simulator_id> --dart-define-from-file=config/env/dev.json

Android emulator:

flutter run -d <emulator_id> --flavor dev --dart-define-from-file=config/env/dev.json

Web:

flutter run -d chrome --dart-define-from-file=config/env/dev.json

Project Structure

lib/
  app.dart
  main.dart
  core/
    config/api_config.dart
    navigation/
    services/
    state/favorites_store.dart
    theme/
    utils/
    widgets/
  features/
    auth/
    chat/
    discover/
    favorites/
    onboarding/
    profile/
  models/

test/
  core/
  features/
  models/
  test_helpers/

integration_test/
  app_smoke_test.dart
  favorites_location_link_test.dart

API Integration

The app uses authenticated backend calls through AuthenticatedHttpClient where a session is required.

Authentication

AWS Cognito endpoint:

https://cognito-idp.ap-southeast-1.amazonaws.com/

Implemented Cognito operations:

  • SignUp
  • ConfirmSignUp
  • ResendConfirmationCode
  • ForgotPassword
  • ConfirmForgotPassword
  • InitiateAuth for sign-in
  • InitiateAuth for refresh-token auth
  • DeleteUser

Food Discovery

Primary personalized request:

GET /food/?userId={cognitoUserId}

Fallback request when personalized results are empty:

GET /food/?budget=medium&cuisines=Thai&cuisines=Japanese&spiceLevel=3

The parser accepts list responses directly, or wrapped in data or foods.

Favorites

GET /preference/food/users/{cognitoUserId}

Favorites can be returned as food objects directly or nested under a food key. The favorites parser preserves address when the backend provides it.

Swipe Preferences

POST /preference/food/swipe

This records like/dislike actions for the authenticated user.

User Preferences

GET /preference/users/{cognitoUserId}
PUT /preference/users/{cognitoUserId}
GET /preference/dietary/options
GET /preference/dietary/users/{cognitoUserId}

Preferences are saved locally as a fallback when sync fails.

Profile And User

GET /user/{cognitoUserId}
GET /user/me
PUT /user/me
POST /user/create-user
POST /user/logout

Food Location Flow

Food details show two related location values:

  1. Static place label: the grey text under the dish title always shows item.restaurant, mapped from backend restaurantName.
  2. Map link: the blue underlined row uses item.address when present. If address is missing, it falls back to item.restaurant.

Sequence:

Backend food JSON
  -> FoodService or FavoritesScreen parser
  -> FoodItem(restaurant, address)
  -> FoodDetailScreen
  -> choose address if present, otherwise restaurant
  -> render blue map link
  -> tap opens Google Maps search via url_launcher

Google Maps URL format:

https://www.google.com/maps/search/?api=1&query=<encoded location>

This means a food item like Thai Fried Rice at Dunman Food Centre still gets a map link even if the backend did not send a full address.

Testing

Current local verification:

flutter analyze
flutter test
flutter test integration_test/favorites_location_link_test.dart

As of this update:

  • flutter test passes 298 unit/widget tests.
  • integration_test/favorites_location_link_test.dart has 2 passing integration tests for the food location link flow.
  • integration_test/app_smoke_test.dart covers basic app launch/auth navigation.

See test/TESTSUITE_README.md for the test layout and focused test commands.

Dependencies

Runtime dependencies:

  • flutter
  • http: ^1.2.2
  • shared_preferences: ^2.2.3
  • url_launcher: ^6.3.0
  • cupertino_icons: ^1.0.8

Development dependencies:

  • flutter_test
  • integration_test
  • flutter_lints: ^6.0.0
  • mockito: ^5.4.4
  • build_runner: ^2.4.9

For exact versions, see pubspec.yaml.

Troubleshooting

Flutter Command Not Found

Ensure Flutter is installed and on your PATH:

flutter --version

iOS Pods Or Build Issues

cd ios
pod install
cd ..
flutter clean
flutter pub get

Device Not Detected

flutter doctor
flutter devices

For Android, also check USB debugging and Android licenses:

flutter doctor --android-licenses

Backend Or Login Issues

  • Confirm API_BASE_URL points to the intended backend.
  • Confirm Cognito sign-in succeeds before testing authenticated screens.
  • Clear simulator app data when testing a fresh auth state.
  • Re-run with the expected environment file:
flutter run --dart-define-from-file=config/env/dev.json

Food Location Link Missing

Expected behavior:

  • If address is present, the blue map row shows the address.
  • If address is missing but restaurantName is present, the blue map row shows the restaurant/place name.
  • If both are missing or restaurant is Unknown, no map link is shown.

Run the regression test:

flutter test integration_test/favorites_location_link_test.dart

Test

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors