Skip to content

Mobile app

The React Native app in apps/mobile — its screens, how it reaches the API, sign-in, payments and how to build it.

The Mobile app brings the shop to iOS and Android. Customers browse, search by text, voice or photo, pay with Stripe or SSLCommerz and track their orders. The same app also gives admin and employee users management screens and gives vendors a dashboard. It is a bare React Native 0.88 app (no Expo) in apps/mobile. It talks to the same API as the Storefront.

Built with

React Native 0.88, React 19.3, React Navigation 7, Zustand + AsyncStorage, Stripe React Native. See Tech stack.

Screens

28 screens: 4 bottom tabs and 24 stack screens.

Installed separately

Outside the pnpm workspace (!apps/mobile). Install it with npm and its own package-lock.json.

Entry

apps/mobile/App.tsx → apps/mobile/src/navigation/AppNavigator.tsx

Home
  1. 1
    Navbar

    HomeNavbar: logo and quick actions

  2. 2
    Banner

    Hero banners from the API

  3. 3
    Categories

    Horizontal category chips

  4. 4
    Product-type rows

    One horizontal row per product type, with an ads banner after the second

  5. 5
    Become a vendor

    Call-out that opens the vendor flow

  6. 6
    Best Deals + All Products

    Deals row, then an infinite product grid with pull-to-refresh

apps/mobile/src/screens/HomeScreen.tsx

App.tsx wraps everything in StripeProvider, gesture and safe-area providers, a toast provider and the NavigationContainer. A stack navigator holds a MainTabs route with four tabs: Home, Shop, Search and Profile. If you tap Profile while signed out, the app opens Login.

Group Screens
Tabs Home, Shop (category and brand filters), Search (text, voice, image), Profile
Shopping SingleProduct, ProductList, Cart, PlaceOrder, Checkout, Wishlist
Account Login, Signup, EditProfile (avatar via image picker), Orders, SingleOrder
Journal Blog (all guides), BlogPost (one article, rendered natively from the post’s HTML)
Admin and employee Dashboard, OrderManagement, ProductManagement, UserManagement, CategoryManagement, BrandManagement, ReviewManagement, AnalyticsScreen
Vendor BecomeVendor, VendorGuide, VendorDashboard

Route types live in apps/mobile/types.ts. Which roles see which screens is set in apps/mobile/src/utils/rolePermissions.ts.

The app uses the same theme as the storefront: the cream page, chocolate text and buttons, peach washes and the brown accent from packages/ui/src/styles/tokens.css, plus the storefront’s font, DM Sans.

Piece Where it lives
Colours apps/mobile/src/constants/colors.ts. Semantic tokens (background, primary, accent, secondary, muted, border…) plus the legacy names (babyshopSky → #8c4e32), using the same values as apps/web/app/globals.css.
Font DM Sans TTFs in ios/userapp/Fonts (listed under UIAppFonts) and android/app/src/main/assets/fonts. apps/mobile/src/theme/fonts.ts wraps StyleSheet.create at startup, so every text style gets the DM Sans face that matches its fontWeight. index.js imports it first.
Logo apps/mobile/src/components/common/BrandLogo.tsx, the same Little Bear mark as BrandLogo in @babyshop/ui.
Bottom navigation apps/mobile/src/navigation/AppTabBar.tsx, used as the tab navigator’s tabBar.
Home sections The same order as the storefront home: hero (Banner, with the bundled hero.jpg, toys.png and backpack.png from apps/web/public/home), DailyBestSells, categories, product-type rows, Mom Care, the journal (HomeBlogStrip), BecomeVendor, then all products. Section headings use SectionHeader (Hugeicons icon chip + title + “View all”).
  • iPhone: a floating capsule of real iOS 26 Liquid Glass (@callstack/liquid-glass), tinted cream. A highlight springs to the selected tab. On iOS older than 26 it falls back to a frosted, translucent capsule. The bar floats over the content, so tab screens add useTabBarClearance() as bottom padding on their main list.
  • Android: a Material 3 navigation bar: white surface, a peach “active indicator” pill behind the selected icon, ripple feedback, and bottom padding for the edge-to-edge system bar.

apps/mobile/src/config/environment.ts› getApiBaseUrl picks the base URL:

Build Platform Base URL
Debug (__DEV__) Android emulator http://10.0.2.2:8000/api
Debug (__DEV__) iOS simulator http://localhost:8000/api
Release both https://api.babymart.reactbd.com/api

10.0.2.2 is how the Android emulator reaches your computer’s localhost. All calls go through one fetch wrapper, apps/mobile/src/services/api.ts. It is split into modules for auth, products, categories, cart, orders, payments, reviews, wishlist, admin, analytics, vendors and more. Signed-in calls send Authorization: Bearer <token>.

  • Email: Login and Signup call POST/api/auth/login and POST/api/auth/register.
  • Google: apps/mobile/src/services/googleAuthService.ts signs in with @react-native-google-signin, then sends the ID token to POST/api/auth/oauth.
  • Session: the user object, including the token, is saved by Zustand persist (user-storage) in AsyncStorage. checkStoredAuth() restores it on launch. Cart, order and wishlist stores are saved the same way.

Token rules and roles are explained in Auth and roles.

  1. PlaceOrder creates the order with POST/api/ordersorderAPI.createOrder().
  2. On Checkout, the customer picks a method:
    • Stripe: the app asks for a PaymentIntent from POST/api/payments/create-intent, then shows Stripe’s native PaymentSheet (usePaymentSheet).
    • SSLCommerz: POST/api/payments/sslcommerz/init returns a gateway URL, which opens in a WebView (SSLCommerzWebView).
  3. The API confirms the payment and updates the order. See Payments.

Install and run the app from its own folder. Full steps, including the simulator setup, are in Installation.

Terminal window
cd apps/mobile
npm install # or, from the root: pnpm mobile:install
cd ios && pod install && cd ..
npm start # Metro
npm run ios # or: npm run android
  • React Native 0.88 template: iOS starts React Native from ios/userapp/SceneDelegate.swift (registered in Info.plist under UIApplicationSceneManifest); AppDelegate.swift only returns true. Android’s MainApplication.kt builds the ReactHost directly.
  • Patches: postinstall still runs patch-package, but no patches are needed on Stripe 0.85 (the old STPPaymentStatus fix ships upstream).
  • iOS: the Xcode target is userapp. The Gemfile pins CocoaPods >= 1.13 (not 1.15.0 or 1.15.1). Pods link as dynamic frameworks by default, because Stripe 0.85 pulls the Stripe iOS SDK through Swift Package Manager, which needs them (USE_FRAMEWORKS=static pod install overrides this). The Podfile also:
    • turns on modular headers for GoogleUtilities and RecaptchaInterop (needed by Google Sign-In 10),
    • links the system frameworks that react-native-voice-ts and react-native-image-picker use without declaring them,
    • raises every pod’s deployment target to the minimum Xcode accepts.
  • Android: applicationId is com.babymart.app, with minSdk 24, compileSdk 37 and targetSdk 36, on Gradle 9.4.1 and Kotlin 2.2. Edge-to-edge is on, as in the React Native 0.88 template.
  • Metro also watches the monorepo root, so it can resolve the root node_modules.
  • Tests: one Jest smoke test, __tests__/App.test.tsx. Native modules are mocked in jest.setup.js.