This repository contains the source code for the GetPayIn 3-page store application, built with React Native and Expo. The application is designed with a modern, scalable architecture and a focus on code quality, user experience, and robustness.
Latest Build: Download APK
Install this APK on your Android device to test the app.
- Authentication: Secure login using DummyJSON API (
/auth/login). Session is persisted and restored on app launch, validated via/auth/me. - Biometric Unlock: Biometric authentication (Face ID/Touch ID) with a password fallback (demo password: "1234"). If a valid session is detected on app launch, the biometric unlock is prompted immediately.
- Auto-Lock: Automatically locks after 10 seconds of user inactivity and when the app goes to the background.
- All Products Screen: Displays a list of products with pull-to-refresh.
- Specific Category Screen: Shows products filtered by the smartphones category with pull-to-refresh.
- Superadmin Role: The designated user (
emilys) has superadmin privileges, enabling a delete button on products.
- Offline Support: Product data is cached using React Query and persisted to the device with MMKV. Cached lists render instantly on relaunch and remain available offline. An offline banner is displayed on the Products and Category screens when disconnected.
- Modern UI & Design System: A custom, theme-based design system was built from scratch using styled-components to ensure a polished and consistent user interface.
- Advanced Feedback:
- Global offline indicator
- User-friendly toast notifications for API errors
- Loading states and error boundaries
- Comprehensive Testing: The project includes a full suite of unit and component tests using Jest and React Native Testing Library, achieving high coverage of critical logic.
- Continuous Integration: Automated testing pipeline using GitHub Actions that runs on every push and pull request, ensuring code quality and preventing regressions.
- Specific Category:
smartphones - Superadmin User:
emilys
- Framework: React Native with Expo (Managed Workflow + Dev Client)
- Language: TypeScript
- Navigation: Expo Router (file-based routing)
- Client State: Redux Toolkit (for auth session, lock state)
- Server State: TanStack React Query (for all API interactions and caching)
- Styling: Styled-Components with a custom Design System
- Theme: Dark/Light mode support with custom color schemes
- Data Persistence: MMKV for high-performance React Query cache persistence
- API Client: Axios
- Offline Support: React Query + MMKV + NetInfo
- Testing Framework: Jest & React Native Testing Library
- Coverage: Targeted tests (Redux slices, basic render). Additional tests can be added for hooks and screens.
- CI/CD: GitHub Actions workflow for automated testing on every push and PR
The architecture strictly separates client and server state, a modern best practice that improves maintainability and performance. The use of MMKV with React Native's New Architecture (JSI) ensures near-instantaneous cache rehydration for an excellent offline-first user experience.
GetPayInStore/
├── src/
│ ├── app/ # Expo Router screens & pages
│ │ ├── (tabs)/ # Tab-based navigation screens
│ │ │ ├── products.tsx # Products list screen
│ │ │ ├── account.tsx # Account/profile screen
│ │ │ └── category.tsx # Categories screen
│ │ ├── _layout.tsx # Root layout with theme provider
│ │ ├── index.tsx # Login screen
│ │ └── modal.tsx # Modal screens
│ ├── api/ # API client configuration
│ ├── components/ # Reusable UI components
│ ├── contexts/ # React contexts (Theme, etc.)
│ ├── hooks/ # Custom React hooks
│ ├── services/ # Business logic & services
│ ├── store/ # Redux store & slices
│ ├── theme/ # Design system & theme definitions
│ ├── types/ # TypeScript type definitions
│ └── utils/ # Utility functions
├── android/ # Native Android code
├── ios/ # Native iOS code
├── docs/ # Documentation
└── README.md # This file
- Node.js (LTS version 18.x or higher)
- npm or yarn
- iOS Simulator (macOS only) or Android Emulator, or a physical device
- Expo CLI (optional, but recommended):
npm install -g expo-cli - Xcode (for iOS development on macOS)
- Android Studio (for Android development)
-
Clone the repository:
git clone <repository-url> cd GetPayInStore
-
Install dependencies:
npm install
Or with yarn:
yarn install
-
Install iOS pods (macOS only):
cd ios && pod install && cd ..
Important: This project uses native modules (
react-native-mmkv,expo-local-authentication) and requires a development build. You cannot use the standard Expo Go app.
npm run ios
# or
npx expo run:iosnpm run android
# or
npx expo run:androidnpm start
# or
npx expo startThe project includes comprehensive automated testing with Jest and React Native Testing Library.
npm testnpm run test:watchnpm run test:coverageThe project uses GitHub Actions for automated testing. Tests run automatically on:
- Every push to any branch
- Every pull request
The CI pipeline ensures:
- All tests pass before merging
- Consistent test results across environments
- Early detection of breaking changes
You can view the test results in the "Actions" tab of the GitHub repository.
Use any user from DummyJSON Users, for example:
Regular User:
- Username:
emilys - Password:
emilyspass
Superadmin User (can delete products):
- Username:
emilys - Password:
emilyspass
Note: DummyJSON demo credentials can change over time. If a login fails, try another user from https://dummyjson.com/users and update SUPERADMIN_USERNAME in src/hooks/useLoginMutation.ts and src/hooks/useSession.ts accordingly.
Example regular user:
- Username:
averyp - Password:
averyppass
- JWT token-based authentication with DummyJSON API
- Secure token storage using Expo SecureStore
- Biometric authentication (Face ID/Touch ID) for app unlock
- Password fallback for devices without biometric support
- Session persistence across app restarts
- Automatically locks after 10 seconds of inactivity
- Locks when app goes to background
- Uses React hooks to track user interactions
- Smooth lock/unlock transitions
- All product data cached with React Query
- Persistent cache using MMKV (high-performance key-value storage)
- Network status indicator
- Graceful degradation when offline
- Instant data availability on app launch
- All Products: List with pull-to-refresh
- Smartphones Category: Filtered product view with pull-to-refresh
- Delete Functionality: Available only to superadmin user
- Error Handling: Toast notifications for API operations
- Custom theme built with styled-components
- Consistent spacing, typography, and color system
- Dark/Light mode support
- Reusable component library
- Type-safe theming with TypeScript
- Unit tests for Redux slices
- Component tests for UI components
- Basic component smoke test
- Jest setup mocks MMKV, SecureStore, LocalAuth, NetInfo, and Expo Router
- Automated CI/CD pipeline with GitHub Actions
React Query provides powerful caching, background updates, and offline support out of the box. It eliminates the need to manage server state in Redux, keeping our global store lean and focused on client-only state.
MMKV is a high-performance key-value storage library built by WeChat. It leverages React Native's New Architecture (JSI) for synchronous, fast operations. This ensures instant cache rehydration on app launch, crucial for a great offline experience.
Styled-components provides a powerful, type-safe way to style React Native components. It enables us to build a comprehensive design system with theming support while keeping styles co-located with components.
Expo Router brings Next.js-style file-based routing to React Native, providing deep linking, type-safe navigation, and better code organization out of the box.
While React Query handles server state, Redux Toolkit is perfect for app-wide client state (auth session, lock status) that needs to be accessible across the entire app with minimal boilerplate.
iOS Build Fails:
- Ensure you're running on macOS
- Try cleaning the build:
cd ios && rm -rf build && pod install && cd .. - Clear cache:
npx expo start -c
Android Build Fails:
- Ensure Android Studio and SDK are properly installed
- Check that
ANDROID_HOMEenvironment variable is set - Clear Gradle cache:
cd android && ./gradlew clean && cd ..
App crashes on launch:
- Clear app data and cache
- Rebuild the app:
npm run iosornpm run android
Biometric authentication not working:
- Ensure biometric authentication is set up on your device/simulator
- Check app permissions in device settings
Network requests failing:
- Verify internet connection
- Check that DummyJSON API is accessible: https://dummyjson.com
- Infinite scrolling / pagination
- Product search and filtering
- Shopping cart functionality
- Order history
- Push notifications
- Analytics integration
- Performance monitoring
- E2E testing with Detox
This project is part of a coding challenge for GetPayIn.
For any questions or issues, please contact the development team.
Built with ❤️ using React Native, Expo, and TypeScript