Bagisto Open Source eCommerce Mobile App

repository·main·Indexed 12 days ago

https://github.com/bagisto/opensource-ecommerce-mobile-app

An open-source mobile eCommerce application built with Flutter that synchronizes in real-time with a Bagisto (Laravel-based) store via GraphQL. Requires Bagisto v2.0.0 or higher and the Bagisto API module. Documentation covers installation, GraphQL API configuration, theme customization, and Firebase Cloud Messaging (FCM) setup for Android and iOS.

Tokens
25K
Snippets
64
Records
105
Agent score
95%

What's inside Bagisto Mobile App

  1. Handle different notification states

    main

    You must implement logic to handle how the app responds when a notification is received or tapped in different states:

    1. Foreground (App Open): Use the onForegroundMessage callback. Since the app is already open, you typically display a local notification or update the UI.
    2. Background (App Minimized): Use onMessageOpenedApp. This is triggered when the user taps a notification while the app is in the background.
    3. Terminated (App Killed): Use getInitialMessage() to check if the app was launched via a notification tap.
    // Handle Foreground
    Future<void> _handleForegroundNotification(RemoteMessage message) async {
      debugPrint('📬 Foreground notification');
    }
    
    // Handle Background/Tapped
    Future<void> _handleMessageOpenedApp(RemoteMessage message) async {
      debugPrint('📲 App opened from notification');
    }
    
    // Handle Terminated
    final initialMessage = await _messaging.getInitialMessage();
    if (initialMessage != null) {
      // Handle the message
    }
  2. Implement RTL (Right-to-Left) support

    main

    Flutter handles text direction automatically based on the locale. If adding an RTL language (e.g., he for Hebrew or fa for Persian), ensure your custom UI components do not use hardcoded LTR values:

    • Avoid: EdgeInsets.only(left: ...) or Alignment.centerLeft.
    • Use: EdgeInsetsDirectional and AlignmentDirectional to ensure layouts flip correctly for RTL users.
  3. Understand the Bagisto color architecture

    main

    The app's color system is organized into several semantic categories to ensure consistency across the UI. Colors are consumed either directly via the AppColors class, through Material 3 ThemeData, or via predefined TextStyles.

    Color Categories:

    • Primary: Main brand colors (primary500, primary600).
    • Neutral: Grayscale palette (neutral50 to neutral900) used for backgrounds, text, and borders.
    • Status: Success colors (green shades) for feedback states.
    • Process: Info/blue colors (process600, process700).
    • Static: Basic colors like white and black.
  4. How image placeholders work

    main

    The app uses code-based placeholders instead of static images to handle loading states. When an image is loading, the app displays a colored Container that adapts to the current theme.

    • Light Mode: Uses AppColors.neutral100 (light gray).
    • Dark Mode: Uses AppColors.neutral800 (dark gray).

    These colors are defined in lib/core/theme/app_theme.dart. The implementation relies on the cached_network_image package's placeholder callback.

    CachedNetworkImage(
      imageUrl: 'https://example.com/image.jpg',
      placeholder: (context, url) => Container(
        color: isDark ? AppColors.neutral800 : AppColors.neutral100,
      ),
      errorWidget: (context, url, error) => Icon(Icons.error),
    )
  5. Follow Maestro testing quality rules

    main

    When creating or reviewing Maestro test cases, ensure they adhere to these industry-standard quality rules:

    • Valid Syntax: Must be valid Maestro YAML.
    • Avoid Hard Sleeps: Use waitFor instead of fixed sleep commands to improve test stability.
    • Assertions: Always include assertions like assertVisible or assertNotVisible to validate state.
    • Selectors: Use accessibility IDs or test tags for element selection.
    • Structure: Maintain a clear structure with descriptive comments.
    • Coverage: Include positive, negative, and edge-case scenarios.
    • Modularity: Design tests to be modular and scalable.
  6. How localization and language selection works

    main

    The app uses Flutter localization and synchronizes the selected language with the Bagisto backend.

    Workflow

    1. Bootstrap: On startup, ChannelBootstrapService fetches available locales and the default locale from Bagisto.
    2. Storage: The selected locale is persisted using LocaleCubit (via shared preferences).
    3. UI Application: MaterialApp uses the stored locale along with AppLocalizations delegates.
    4. Backend Sync: Every GraphQL request includes the selected locale in the X-LOCALE header so Bagisto returns translated content.

    Key Files

    • lib/l10n/: Contains ARB files for base translations.
    • lib/core/graphql/graphql_client.dart: Handles the injection of the X-LOCALE header.
    • lib/features/account/presentation/pages/preferences_bottom_sheet.dart: The UI component for changing languages.

    Note: The system currently expects simple language codes (e.g., en, fr). Region-specific codes like pt_BR may require manual code changes in the locale storage and comparison logic.

  7. Understand GraphQL client and network configuration

    main

    The app's GraphQL client is implemented in lib/core/graphql/graphql_client.dart and follows these specifications:

    Headers

    Every request includes:

    • Content-Type: application/json
    • X-STOREFRONT-KEY: {storefrontKey}

    Network Settings

    • Timeouts: The app uses a custom TimeoutHttpClient with a 30-second timeout for both connection and receiving data.
    • Logging: Detailed request and response logging is enabled during debug mode.
    • Caching: The app uses HiveStore for offline data persistence of GraphQL responses.
  8. How language selection and localization work

    main

    The Bagisto Flutter app uses a dual-layer localization system. To achieve full localization, you must configure both the Flutter app and the Bagisto backend:

    1. Flutter App (UI Text): Uses Flutter's gen_l10n system with ARB files in lib/l10n/. This localizes static UI elements like buttons, labels, and titles.
    2. Bagisto Backend (Storefront Data): The app sends the selected locale via the X-LOCALE header in GraphQL requests using GraphQLClient. This tells the backend to return localized dynamic content such as categories, CMS pages, and product descriptions.

    The Lifecycle of a Language Change:

    • ChannelBootstrapService fetches available locales from the Bagisto channel at startup.
    • LocaleCubit manages the currently selected locale and persists it to shared preferences.
    • MaterialApp applies the locale to the UI using localizationsDelegates and supportedLocales.
    • When a user selects a new language, the X-LOCALE header is updated for all subsequent GraphQL calls.
  9. Change App Icons (Launcher Icons)

    main

    To change the application icon for Android and iOS, follow these platform-specific steps:

    Android

    Android adaptive icons are stored in various mipmap directories within android/app/src/main/res/ (e.g., mipmap-hdpi, mipmap-xhdpi). Recommended Method: Use Android Studio's Image Asset tool:

    1. Right-click on the app folder.
    2. Select NewImage Asset.
    3. Select Launcher Icons as the icon type and choose your custom image.

    iOS

    Icons are located in ios/Runner/Assets.xcassets/AppIcon.appiconset/.

    1. Replace the existing icon images in this folder with your custom icons.
    2. Ensure you provide all required sizes (20, 29, 40, 60, 76, 83.5 points at @1x, @2x, and @3x).
  10. Use label-based selectors in Maestro flows

    main

    When writing Maestro flows for this project, prioritize using visible text and accessibility labels for navigation and actions instead of coordinate-based selectors. This approach ensures that flows remain readable and easier to maintain when the UI undergoes changes.

    Rules for Maestro flows:

    • DO NOT use point: selectors.
    • PREFER visible text and accessibility labels.
    • APPLY these rules to all attached Android flows, such as maestro/flows/android/full_app_flow_attached.yaml.
  11. Configure API Endpoints and GraphQL Client

    main

    To connect the mobile app to your Bagisto backend, you must configure the API endpoint and the GraphQL client settings.

    • API Endpoint: Modify lib/core/constants/api_constants.dart to point to your server URL.
    • GraphQL Client: Configuration for the GraphQL client is located in lib/core/graphql/graphql_client.dart.
  12. Customize Application Identity (Title and Icon)

    main

    Change Application Title

    • Android: Edit android/app/src/main/AndroidManifest.xml and update the android:label attribute.
    • iOS: In Xcode, go to the General tab and change the Display Name.

    Change App Icon

    • Android: Open the android folder in Android Studio, right-click the app module, and select New > Image Asset.
    • iOS: Replace the icons located at ios/Runner/Assets.xcassets/AppIcon.appiconset.

    Change Splash Screen

    Replace the image at assets/images/splash.png. The splash screen is loaded directly from lib/features/splash/presentation/splash_screen.dart and does not require additional constant updates.