This repository contains the source code for the Reme mobile application, a transparent group payments platform built with React Native and Expo. It allows users to create contribution wallets, track payments in real-time, and manage group goals directly from their mobile devices.
- Overview
- Key Features
- Project Structure
- Technology Stack
- Requirements
- Getting Started
- Configuration
- Testing
- Data Flow
The Reme mobile app serves as the user interface for the Reme platform. Built using React Native and Expo Router, it provides a native experience for both iOS and Android. Users can:
- Register & Login: Secure authentication flow with email/phone verification.
- Create Wallets: Set up contribution goals with targets and deadlines.
- Transact: Make payments using Paystack integration.
- Verify Identity: Link bank accounts securely for withdrawals.
- Track Progress: View detailed contribution history and group progress.
- Expo Router: File-based routing for intuitive navigation structure.
- Authentication Flow: Login, Register, OTP Verification, and Forgot Password screens.
- Wallet Detail View: Comprehensive dashboard for viewing contributions, progress bars, and contributors.
- Payment Integration: Seamless webview integration with Paystack for secure transactions.
- Profile Management: Update user details, manage bank accounts, and view personal transaction history.
- State Management: Zustand for global state management (auth, user preferences).
- Data Fetching: React Query (TanStack Query) for API caching, loading states, and mutations.
- UI Architecture: TailwindCSS (NativeWind/Uniwind) for rapid, consistent styling.
- Wallet Search: Ability to discover public or private wallets using unique codes.
- Contribution Tracking: Real-time progress bars showing amount raised vs. goal target.
- Monthly Insights: Visual breakdown of user spending and contributions month-over-month.
- Multiple Wallets: Interface to easily switch between and manage multiple active contribution groups.
- Archive System: Manual archiving of completed or expired wallets for cleaner organization.
This project is organized as a monorepo setup (using Turborepo concepts) but primarily focuses on the apps/native directory:
-
apps/native/app/: Expo Router pages and layouts.(auth): Authentication screens (login, register, welcome).(tabs): Main tab navigation (home, create wallet, profile).screens/: Additional independent screens (transactions, verify-otp).
components/: Reusable UI components (buttons, inputs, modals).utils/: API clients, helper functions, and constants.stores/: Global state stores (zustand).assets/: Images, fonts, and static resources.
-
packages/config/: Shared configuration files (TypeScript, ESLint).
- Framework: React Native (0.76+) via Expo (SDK 52+)
- Language: TypeScript 5.x
- Navigation: Expo Router (v4)
- Styling: TailwindCSS (v3) with NativeWind/Uniwind
- State Management: Zustand
- Data Fetching: React Query (TanStack Query v5)
- HTTP Client: Axios
- Secure Storage: Expo Secure Store (for JWT tokens)
- UI Components: Radix UI primitives inspiration, customised for mobile.
- Node.js (LTS recommended)
- Bun (Package Manager)
- Android Studio / Xcode (for running on simulators)
- Expo Go App (for running on physical devices)
Navigate to the root directory and install dependencies using Bun:
bun installCreate a .env file in apps/native if needed (see Configuration).
Start the project:
bun run dev:nativeOr specifically from the apps/native directory:
cd apps/native
bun run dev- Android: Press
ain the terminal to open in Android Emulator. - iOS: Press
iin the terminal to open in iOS Simulator (macOS only). - Physical Device: Scan the QR code with your Expo Go app.
The application requires connection to the backend API. Update the API base URL in apps/native/utils/api.ts or set it via environment variables if configured:
```typescript
export const API_URL = "http://YOUR_LOCAL_IP:8080/api/v1";Note: When using an emulator, use the specific IP 10.0.2.2 for Android or localhost for iOS. For physical devices, use your machine's local IP address.
If you are using ngrok to tunnel your backend, replace the API_URL with your public HTTPS URL:
export const API_URL = "https://your-tunnel-url.ngrok-free.app/api/v1";This is the most reliable way to connect a physical device to your local server.
Run linting and type checking across the project:
bun run check-types- User Action: User interacts with a component (e.g., "Create Wallet").
- Mutation: A React Query mutation is triggered.
- API Call: Axios sends a request to the configured backend endpoint, attaching the Bearer token from Secure Store.
- State Update: On success, the local cache is invalidated/updated, reflecting changes immediately in the UI.
- Feedback: Toast messages or UI updates inform the user of the result.