.. _frontend: 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 ----------------- .. code-block:: text 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``) ---------------------------- .. code-block:: 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 ----- .. list-table:: :header-rows: 1 :widths: 30 70 * - 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. .. code-block:: dart 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:** .. list-table:: :header-rows: 1 :widths: 40 60 * - 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:** .. code-block:: dart await SupabaseAuthService.initialize(); // Reads SUPABASE_URL and SUPABASE_KEY from .env **Key methods:** .. list-table:: :header-rows: 1 :widths: 40 60 * - 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`` for reactive UI updates **Google Sign-In configuration:** .. code-block:: dart 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. .. code-block:: dart class OcrService { static Future 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 ~~~~~~~~~~~~~~ .. list-table:: :header-rows: 1 :widths: 35 65 * - 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 ~~~~~~~~~~~~~~~~ .. list-table:: :header-rows: 1 :widths: 35 65 * - 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 ~~~ .. list-table:: :header-rows: 1 :widths: 35 65 * - 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 ~~~~~~~~~ .. list-table:: :header-rows: 1 :widths: 35 65 * - 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 ~~~~~~~~~~~~~~~~~~ .. list-table:: :header-rows: 1 :widths: 35 65 * - 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 ---------------- .. list-table:: :header-rows: 1 :widths: 35 65 * - 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 ---------------- .. list-table:: :header-rows: 1 :widths: 30 15 55 * - 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