Frontend

The LinguaAI frontend is a Flutter application targeting Android, iOS, and Web from a single codebase. Flutter 3.9 (Dart) is required.

Project Structure

frontend/lib/
├── main.dart                        # App entry point
├── screens/
│   ├── auth/
│   │   ├── welcome_screen.dart      # Animated landing page
│   │   ├── login_screen.dart        # Email/password + Google login
│   │   └── signup_screen.dart       # Registration form
│   ├── onboarding/
│   │   ├── onboarding_level_screen.dart
│   │   ├── onboarding_goals_screen.dart
│   │   ├── onboarding_focus_screen.dart
│   │   └── onboarding_complete_screen.dart
│   ├── home/
│   │   └── home_screen.dart         # Main dashboard
│   ├── tutor/
│   │   └── tutor_screen.dart        # AI conversational tutor
│   ├── ocr/
│   │   ├── ocr_scanner_screen.dart  # Camera capture
│   │   └── ocr_result_screen.dart   # Extracted text display
│   ├── stats/
│   │   ├── stats_screen.dart
│   │   ├── detailed_analytics_screen.dart
│   │   └── weak_areas_screen.dart
│   ├── study_tools/
│   │   └── study_tools_screen.dart
│   ├── profile/
│   │   ├── profile_screen.dart
│   │   ├── settings_screen.dart
│   │   └── help_support_screen.dart
│   └── main_navigation_shell.dart   # Bottom-nav scaffold
├── services/
│   ├── api_config.dart              # Endpoint constants
│   ├── auth_service.dart            # HTTP-based auth service
│   ├── supabase_auth_service.dart   # Direct Supabase auth service
│   ├── dictionary_service.dart      # Remote dictionary API client
│   ├── dictionary_sync_service.dart # Local/remote synchronization
│   ├── gamification_service.dart    # Fluency points and badges
│   ├── lesson_service.dart          # Lessons and submissions
│   ├── text_action_service.dart     # Tooling for text highlighting
│   ├── translation_service.dart     # Word translations
│   ├── tts_service.dart             # Text-to-speech module
│   └── user_service.dart            # User profile data
├── local_db/
│   ├── local_dictionary_store.dart  # SQLite repository
│   └── local_dictionary_word.dart   # SQLite data model
└── widgets/
    ├── background_decoration.dart
    ├── bottom_nav_bar.dart
    ├── custom_text_field.dart
    ├── expandable_fab.dart
    ├── onboarding_widgets.dart
    ├── primary_button.dart
    └── secondary_button.dart

Entry Point (main.dart)

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await dotenv.load(fileName: ".env");
  await SupabaseAuthService.initialize();
  runApp(const LinguaAIApp());
}
  • Loads .env with flutter_dotenv before any widget is built.

  • Initialises the Supabase client via SupabaseAuthService.initialize().

  • Applies a Material 3 theme with primary colour #1B3A5F (dark blue) and the RobotoSlab Google Font.

  • Sets WelcomeScreen as the home route.

Theme

Property

Value

Primary colour

#1B3A5F (dark navy blue)

Font family

Google Fonts RobotoSlab

Design system

Material Design 3

Scaffold background

White

Input field border radius

12 pt (rounded)

Services

api_config.dart

Centralises all backend endpoint strings.

class ApiConfig {
  static const String baseUrl = 'http://192.168.1.2:8000';

  // Auth
  static const String authSignup    = '/api/auth/signup';
  static const String authLogin     = '/api/auth/login';
  static const String authGoogleUrl = '/api/auth/google/url';
  static const String authGoogleCallback = '/api/auth/google/callback';
  static const String authGoogleToken    = '/api/auth/google/token';
  static const String authRefresh   = '/api/auth/refresh';
  static const String authLogout    = '/api/auth/logout';
  static const String authMe        = '/api/auth/me';
  static const String authOnboarding = '/api/auth/onboarding';
}

Note

Change baseUrl to match your backend host before running on a real device. The loopback address 127.0.0.1 only works on the same machine (e.g. web browser or desktop runner).

auth_service.dart

HTTP-based authentication client built with the http package. Tokens are persisted locally in SharedPreferences.

Key methods:

Method

Description

signUp({email, password, fullName, ...})

POST /api/auth/signup; stores tokens on success

login({email, password})

POST /api/auth/login; stores tokens on success

updateOnboarding({accessToken, ...})

PUT /api/auth/onboarding

getGoogleAuthUrl({redirectUri})

POST /api/auth/google/url

googleCallback({code})

POST /api/auth/google/callback

googleSignInWithToken({idToken})

POST /api/auth/google/token

refreshToken()

POST /api/auth/refresh using stored refresh token

getCurrentUser()

GET /api/auth/me with stored access token

logout()

POST /api/auth/logout; clears local tokens

isAuthenticated()

Returns true if an access token exists in storage

getAccessToken() / getRefreshToken()

Read tokens from SharedPreferences

clearTokens()

Removes all stored tokens and user data

Token storage keys:

  • _accessTokenKey — JWT access token

  • _refreshTokenKey — Refresh token

  • _userKey — Serialised UserResponse JSON

supabase_auth_service.dart

Alternative authentication service that communicates directly with the Supabase client SDK. Used primarily for Google Sign-In on mobile.

Initialisation:

await SupabaseAuthService.initialize();
// Reads SUPABASE_URL and SUPABASE_KEY from .env

Key methods:

Method

Description

signInWithGoogle()

Full native Google Sign-In flow; returns SupabaseAuthResult

signUpWithEmail({email, password, fullName})

Email registration via Supabase SDK

signInWithEmail({email, password})

Email login via Supabase SDK

signOut()

Signs out of both Google and Supabase

currentUser

Current User? object

currentSession

Current Session? object

isSignedIn

bool

authStateChanges

Stream<AuthState> for reactive UI updates

Google Sign-In configuration:

GoogleSignIn(
  clientId:       dotenv.env['CLIENT_ANDROID'],
  serverClientId: dotenv.env['CLIENT_WEB'],
  scopes: ['email', 'profile'],
)

ocr_service.dart

Wraps Google ML Kit Text Recognition for on-device OCR.

class OcrService {
  static Future<String> extractText(String imagePath) async { ... }
}
  • Accepts a local image file path.

  • Returns all recognised text lines joined by \n.

  • Returns an empty string if no text is found.

  • Always closes the TextRecognizer in a finally block.

Other Key Services

  • `dictionary_service.dart` / `dictionary_sync_service.dart` — Manages dictionary words and syncs local SQLite cache with Supabase backend.

  • `gamification_service.dart` — Retrieves fluency points, badges, and the leaderboard.

  • `lesson_service.dart` — Requests available lessons by field, fetches questions, and submits answers.

  • `user_service.dart` — Manages user profile data and streak notifications.

Local Storage (SQLite)

The app uses sqflite inside lib/local_db/local_dictionary_store.dart to cache the user’s dictionary. This allows rapid lookups and offline capability. The dictionary_sync_service.dart regularly checks for a delta between the remote Supabase truth and the local table, effectively mirroring them.

Screens

Authentication

Screen

Description

WelcomeScreen

Animated landing page with fade/scale/slide animations; navigates to Login or Signup.

LoginScreen

Email + password fields, Google Sign-In button, forgot password link.

SignupScreen

Full name, email, password fields with form validation.

Onboarding

After registration, users complete a four-step onboarding flow:

  1. onboarding_level_screen — Select proficiency level (Beginner … Fluent).

  2. onboarding_goals_screen — Select learning goals (multi-select).

  3. onboarding_focus_screen — Select focus areas (multi-select).

  4. onboarding_complete_screen — Confirmation and navigation to home.

Selections are submitted to PUT /api/auth/onboarding.

Core Application

Screen

Description

MainNavigationShell

Scaffold with a bottom navigation bar giving access to Home, Tutor, Stats, Study Tools, and Profile.

HomeScreen

Personalised dashboard with animated greeting. Entry point to all major features.

TutorScreen

Conversational AI tutor interface (planned backend integration).

StudyToolsScreen

Curated learning resources and exercises.

OCR

Screen

Description

OcrScannerScreen

Opens the camera or image picker; passes the selected image to OcrService.extractText().

OcrResultScreen

Displays extracted text; allows the user to copy, save, or interact with the content.

Analytics

Screen

Description

StatsScreen

High-level learning statistics (XP, streak, session count).

DetailedAnalyticsScreen

In-depth charts and breakdowns.

WeakAreasScreen

Lists skill areas where the user consistently underperforms.

Profile & Settings

Screen

Description

ProfileScreen

View and edit display name, avatar, and learning preferences.

SettingsScreen

App-level settings (notifications, theme, language).

HelpSupportScreen

FAQ and support contact information.

Reusable Widgets

Widget

Description

BackgroundDecoration

Gradient or pattern background applied to screen scaffolds.

BottomNavBar

Custom bottom navigation bar with active-state styling.

CustomTextField

Styled TextFormField with consistent border radius and colours.

ExpandableFab

Floating action button that expands to reveal multiple actions.

OnboardingWidgets

Cards and selection chips used across onboarding screens.

PrimaryButton

Main CTA button with filled background.

SecondaryButton

Outlined or text-style secondary action button.

TranslationPanel

Bottom sheet for displaying word definitions, synonyms, and translations.

WordLookupDialog

Popup dialog showing details and allowing users to save words to their personal dictionary.

Key Dependencies

Package

Version

Purpose

supabase_flutter

^2.3.0

Supabase SDK (auth, realtime, storage)

google_sign_in

^6.2.1

Native Google Sign-In on Android/iOS

http

^1.2.0

REST HTTP client

shared_preferences

^2.2.2

Local token and user-data persistence

flutter_dotenv

^5.1.0

.env file loading

google_fonts

^6.1.0

RobotoSlab and other Google Fonts

google_mlkit_text_recognition

^0.14.0

On-device OCR

camera

^0.11.0+2

Camera preview and capture

image_picker

^1.1.2

Photo library access

permission_handler

^11.3.1

Camera and storage permissions

path_provider

^2.1.2

Access to device file paths