Skip to content

A production-ready React Native Expo mobile application demonstrating advanced mobile development practices, native features integration, and comprehensive security implementation.

Notifications You must be signed in to change notification settings

adarsh47-bug/Mini-LMS

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

10 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

MLMS - Mini Learning Management System

A production-ready React Native Expo mobile application demonstrating advanced mobile development practices, native features integration, and comprehensive security implementation.

Built for the React Native Developer Assignment - showcasing expertise in authentication, WebView integration, state management, native features, and real-world mobile app challenges.


🎬 Demo Video

Watch the complete app walkthrough (3-5 minutes):

MLMS - Mobile App Walkthrough

πŸ“Ί Click to watch on YouTube

What's covered:

  • Authentication & User Registration
  • Course Discovery & Browsing
  • Bookmarks & Enrollment
  • User Profile Management
  • Dark Mode & Real-time Features

πŸ“± Screenshots

Welcome & Authentication

Intro Screen Register Screen Login Screen

Intro Screen β€’ Registration β€’ Login

Main Features

Home Screen Courses List Bookmarks

Home β€’ Course Catalog β€’ Bookmarks

Course Management & Profile

Profile Screen Course Preview Course Details

User Profile β€’ Course Preview β€’ Course Details


πŸ“² Download APK

Ready to test? Download the production APK:

πŸ“² Download mini_lms.apk

Note: You may need to enable "Install from Unknown Sources" in your Android settings to install the APK.


πŸš€ Setup Instructions

Prerequisites

  • Node.js 18+ and npm
  • Expo CLI - Install globally: npm install -g expo-cli
  • iOS Simulator (macOS only) or Android Studio with emulator
  • Git for version control

Installation Steps

  1. Clone the repository

    git clone <repository-url>
    cd mlms
  2. Install dependencies

    npm install
  3. Configure environment variables

    # Copy the example environment file
    cp .env.example .env
    
    # Edit .env with your configuration (see Environment Variables section below)
  4. Start the development server

    npm start
  5. Run on device/emulator

    # iOS (macOS only)
    npm run ios
    
    # Android
    npm run android
    
    # Web (limited native features)
    npm run web

Building APK

# Install EAS CLI
npm install -g eas-cli

# Login to Expo account
eas login

# Configure build
eas build:configure

# Build development APK
eas build --platform android --profile development

# Build production APK
eas build --platform android --profile production

Running Tests

# Run all tests
npm test

# Run tests with coverage report
npm run test:coverage

# Run TypeScript type checking
npm run typecheck

# Run linter
npm run lint

πŸ”§ Environment Variables

Create a .env file in the project root with the following variables:

# API Configuration
EXPO_PUBLIC_API_BASE_URL=https://api.freeapi.app/api/v1
EXPO_PUBLIC_API_TIMEOUT=60000

# Environment
EXPO_PUBLIC_ENV=development

Environment Variables Explained

Variable Description Default Required
EXPO_PUBLIC_API_BASE_URL Base URL for FreeAPI backend https://api.freeapi.app/api/v1 βœ… Yes
EXPO_PUBLIC_API_TIMEOUT API request timeout in milliseconds 60000 (60s) βœ… Yes
EXPO_PUBLIC_ENV Environment mode (development, staging, production) development βœ… Yes

Note: All environment variables must be prefixed with EXPO_PUBLIC_ to be accessible in the Expo app.


πŸ—οΈ Key Architectural Decisions

1. State Management Strategy

Choice: Zustand + Expo SecureStore + AsyncStorage

  • Zustand: Lightweight global state management with TypeScript support and minimal boilerplate
  • Expo SecureStore: Platform-encrypted storage for sensitive data (auth tokens) using iOS Keychain and Android Keystore
  • AsyncStorage: Non-sensitive data persistence (bookmarks, preferences, cache)

Why not Redux? Zustand offers better TypeScript inference, smaller bundle size, and simpler API while maintaining powerful features like middleware and DevTools integration.

2. API Architecture

Centralized Axios Client with Interceptors

// Request Interceptor: Auto token injection
apiClient.interceptors.request.use(async (config) => {
  const token = await getAccessToken();
  if (token) config.headers.Authorization = `Bearer ${token}`;
  return config;
});

// Response Interceptor: Auto token refresh on 401
apiClient.interceptors.response.use(
  (response) => response,
  async (error) => {
    if (error.response?.status === 401) {
      // Attempt token refresh and retry request
    }
    return Promise.reject(error);
  }
);

Features:

  • Automatic auth token injection on every request
  • Token refresh handling on 401 responses
  • Exponential backoff retry logic (3 attempts) for network/5xx errors
  • Request deduplication to prevent duplicate concurrent requests
  • 60-second timeout with graceful error handling

3. Navigation Architecture

File-based Routing with Expo Router

app/
β”œβ”€β”€ _layout.tsx              # Root layout with providers
β”œβ”€β”€ (auth)/                  # Unauthenticated routes
β”‚   β”œβ”€β”€ index.tsx            # Welcome screen
β”‚   β”œβ”€β”€ login.tsx            # Login
β”‚   └── register.tsx         # Register
└── (app)/                   # Authenticated routes (protected)
    β”œβ”€β”€ (tabs)/              # Bottom tab navigation
    β”‚   β”œβ”€β”€ index.tsx        # Courses
    β”‚   β”œβ”€β”€ bookmarks.tsx    # Bookmarks
    β”‚   └── profile.tsx      # Profile
    β”œβ”€β”€ course/[id].tsx      # Dynamic course details
    └── webview.tsx          # WebView content viewer

Benefits:

  • Type-safe navigation with automatic TypeScript types
  • Automatic deep linking support
  • Cleaner code organization with convention over configuration
  • Built-in authentication guards via layout groups

4. Performance Optimizations

List Rendering:

  • FlashList (drop-in FlatList replacement) for 10x better performance
  • React.memo on CourseCard components to prevent unnecessary re-renders
  • keyExtractor using stable IDs
  • removeClippedSubviews for off-screen view recycling
  • Pagination with infinite scroll (20 items per page)

Component Optimization:

  • useCallback for stable function references in props
  • useMemo for expensive computations (search filtering, sorting)
  • Expo Image with built-in caching and progressive loading
  • Code splitting with dynamic imports where applicable

5. Security Implementation

Multi-layered Security Approach:

  1. Secure Token Storage

    • iOS: Keychain Services (hardware-encrypted)
    • Android: Keystore System (hardware-backed if available)
    • Web: Encrypted localStorage with fallback
  2. Data Encryption

    • AES-256 encryption for sensitive user data
    • SHA-256 hashing for password validation
    • Secure random key generation using Expo Crypto
  3. Input Validation

    • Zod schemas for runtime type validation
    • XSS protection via input sanitization
    • Email format validation and normalization
  4. Network Security

    • HTTPS-only API communication
    • Certificate pinning support (configurable)
    • Request timeout and retry limits
  5. Device Security

    • Jailbreak/root detection (iOS/Android)
    • Secure flag for screenshots (Android)

6. Error Handling Strategy

Resilient Error Management:

// Error Boundary for React crashes
<ErrorBoundary fallback={<ErrorFallbackUI />}>
  <App />
</ErrorBoundary>

// Network error handling with retry
try {
  await fetchCourses();
} catch (error) {
  if (isNetworkError(error)) {
    showRetryOption();
  } else {
    showGenericError();
  }
}

// Offline mode detection
useNetworkMonitor((isConnected) => {
  if (!isConnected) {
    showOfflineBanner();
  }
});

Features:

  • React Error Boundary to catch component crashes
  • Offline mode banner with real-time network monitoring
  • Axios retry interceptor with exponential backoff
  • User-friendly error messages mapped from API codes
  • Graceful degradation for missing native features

7. Testing Strategy

Comprehensive Test Coverage (>70%)

__tests__/
β”œβ”€β”€ components/        # Component behavior tests
β”œβ”€β”€ services/          # API service tests
β”œβ”€β”€ stores/            # State management tests
β”œβ”€β”€ hooks/             # Custom hook tests
└── utils/             # Utility function tests

Stack:

  • Jest + React Native Testing Library
  • Mock implementation for Expo modules
  • Coverage enforcement via jest.config.js
  • CI/CD integration ready

πŸ“ Project Structure

mlms/
β”œβ”€β”€ app/                          # Expo Router file-based routing
β”‚   β”œβ”€β”€ _layout.tsx               # Root layout (providers, theme)
β”‚   β”œβ”€β”€ global.css                # NativeWind global styles
β”‚   β”œβ”€β”€ (app)/                    # Authenticated routes
β”‚   β”‚   β”œβ”€β”€ _layout.tsx           # App layout with tab navigation
β”‚   β”‚   β”œβ”€β”€ (tabs)/               # Bottom tabs
β”‚   β”‚   β”‚   β”œβ”€β”€ index.tsx         # Courses home
β”‚   β”‚   β”‚   β”œβ”€β”€ bookmarks.tsx     # Bookmarks
β”‚   β”‚   β”‚   └── profile.tsx       # Profile
β”‚   β”‚   β”œβ”€β”€ course/[id].tsx       # Course detail (dynamic route)
β”‚   β”‚   β”œβ”€β”€ webview.tsx           # WebView content viewer
β”‚   β”‚   β”œβ”€β”€ enrolled.tsx          # Enrolled courses
β”‚   β”‚   └── change-password.tsx   # Password change
β”‚   └── (auth)/                   # Public routes
β”‚       β”œβ”€β”€ index.tsx             # Welcome/Intro
β”‚       β”œβ”€β”€ login.tsx             # Login
β”‚       β”œβ”€β”€ register.tsx          # Registration
β”‚       └── forgot-password.tsx   # Password recovery
β”‚
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ components/               # Reusable UI components
β”‚   β”‚   β”œβ”€β”€ ThemedButton.tsx
β”‚   β”‚   β”œβ”€β”€ ThemedInput.tsx
β”‚   β”‚   β”œβ”€β”€ CourseCard.tsx
β”‚   β”‚   β”œβ”€β”€ ErrorBoundary.tsx
β”‚   β”‚   β”œβ”€β”€ AppNotify/            # Notification system
β”‚   β”‚   └── NetworkStatus/        # Network indicators
β”‚   β”‚
β”‚   β”œβ”€β”€ screens/                  # Screen components
β”‚   β”‚   β”œβ”€β”€ LoginScreen.tsx
β”‚   β”‚   β”œβ”€β”€ CourseListScreen.tsx
β”‚   β”‚   β”œβ”€β”€ CourseDetailScreen.tsx
β”‚   β”‚   └── ...
β”‚   β”‚
β”‚   β”œβ”€β”€ services/                 # API and business logic
β”‚   β”‚   β”œβ”€β”€ api.ts                # Axios client + interceptors
β”‚   β”‚   β”œβ”€β”€ auth.service.ts       # Auth API calls
β”‚   β”‚   β”œβ”€β”€ course.service.ts     # Course API calls
β”‚   β”‚   └── notification.service.ts
β”‚   β”‚
β”‚   β”œβ”€β”€ stores/                   # Zustand state stores
β”‚   β”‚   β”œβ”€β”€ bookmarkStore.ts      # Bookmarks management
β”‚   β”‚   β”œβ”€β”€ courseStore.ts        # Courses cache
β”‚   β”‚   └── networkStore.ts       # Network state
β”‚   β”‚
β”‚   β”œβ”€β”€ context/                  # React Context providers
β”‚   β”‚   β”œβ”€β”€ auth-context.tsx      # Auth state
β”‚   β”‚   β”œβ”€β”€ theme-context.tsx     # Dark/light theme
β”‚   β”‚   └── notification-context.tsx
β”‚   β”‚
β”‚   β”œβ”€β”€ hooks/                    # Custom React hooks
β”‚   β”‚   β”œβ”€β”€ useNetworkMonitor.ts
β”‚   β”‚   β”œβ”€β”€ useStorageState.ts
β”‚   β”‚   └── useNotificationHandler.ts
β”‚   β”‚
β”‚   β”œβ”€β”€ types/                    # TypeScript definitions
β”‚   β”‚   β”œβ”€β”€ auth.types.ts         # Auth + validation schemas
β”‚   β”‚   β”œβ”€β”€ course.types.ts       # Course/product types
β”‚   β”‚   └── api.types.ts          # API request/response
β”‚   β”‚
β”‚   β”œβ”€β”€ utils/                    # Utility functions
β”‚   β”‚   β”œβ”€β”€ logger.utils.ts       # Centralized logging
β”‚   β”‚   β”œβ”€β”€ storage.utils.ts      # Secure storage helpers
β”‚   β”‚   β”œβ”€β”€ security.utils.ts     # Encryption, validation
β”‚   β”‚   β”œβ”€β”€ error.utils.ts        # Error mapping
β”‚   β”‚   └── date.utils.ts         # Date formatting
β”‚   β”‚
β”‚   └── constants/                # App-wide constants
β”‚       β”œβ”€β”€ app.constants.ts      # App metadata, API config
β”‚       β”œβ”€β”€ colors.constants.ts   # Theme colors
β”‚       └── tabs.constants.ts     # Tab configuration
β”‚
β”œβ”€β”€ assets/                       # Static assets
β”‚   └── images/                   # Icons, splash screens
β”‚
β”œβ”€β”€ documentation/                # Project documentation
β”‚   β”œβ”€β”€ tasks.md                  # Assignment requirements
β”‚   β”œβ”€β”€ FreeAPI_*.md              # API documentation
β”‚   β”œβ”€β”€ TESTING.md                # Testing guide
β”‚   β”œβ”€β”€ SECURITY.md               # Security practices
β”‚   └── QUICK_REFERENCE.md        # Quick commands
β”‚
β”œβ”€β”€ .env.example                  # Environment template
β”œβ”€β”€ app.config.js                 # Expo configuration
β”œβ”€β”€ jest.config.js                # Jest testing config
β”œβ”€β”€ tailwind.config.js            # NativeWind config
└── tsconfig.json                 # TypeScript config

πŸ› οΈ Tech Stack

Category Technology Purpose
Framework React Native Expo SDK 54 Cross-platform mobile development
Language TypeScript (strict mode) Type safety and developer experience
Navigation Expo Router File-based routing with type safety
Styling NativeWind (Tailwind CSS) Utility-first responsive styling
State Management Zustand Lightweight global state
Data Fetching Axios HTTP client with interceptors
Forms React Hook Form Performant form handling
Validation Zod Runtime schema validation
Testing Jest + Testing Library Unit and integration testing
Secure Storage Expo SecureStore Encrypted token storage
Persistence AsyncStorage Non-sensitive data cache
Notifications Expo Notifications Push notifications
Images Expo Image Optimized image loading
Network Expo Network Connectivity monitoring
Encryption Expo Crypto AES encryption, SHA hashing

✨ Features Implemented

βœ… Part 1: Authentication & User Management

  • Login/Register with FreeAPI /api/v1/users endpoints
  • Secure token storage using Expo SecureStore (Keychain/Keystore)
  • Auto-login on app restart with token validation
  • Logout with complete token cleanup
  • Token refresh handling on 401 responses
  • Profile screen with user info and stats
  • Profile picture update (camera + gallery)
  • User statistics (courses enrolled, bookmarks count)
  • Password change functionality

βœ… Part 2: Course Catalog

  • Fetch courses from /api/v1/public/randomproducts
  • Fetch instructors from /api/v1/public/randomusers
  • Scrollable course list with FlashList optimization
  • Course thumbnail, instructor, title, description display
  • Bookmark icon with toggle functionality
  • Pull-to-refresh with smooth animations
  • Real-time search filtering (title, category, description, instructor)
  • Course detail screen with complete information
  • Enroll button with visual feedback
  • Bookmark persistence with AsyncStorage

βœ… Part 3: WebView Integration

  • WebView screen for course content display
  • HTML template for course details rendering
  • Native-to-WebView communication via headers
  • JavaScript injection for dynamic data
  • WebView error handling

βœ… Part 4: Native Features

  • Notification permission request on first app launch
  • Local notification on 5+ courses bookmarked
  • 24-hour inactivity reminder notification
  • Android notification channels configuration
  • Notification scheduling and cancellation

βœ… Part 5: State Management & Performance

  • Zustand stores for bookmarks, courses, network state
  • Expo SecureStore for auth tokens (encrypted)
  • AsyncStorage for bookmarks and preferences
  • FlashList with proper optimization (keyExtractor, memo)
  • Pull-to-refresh without jank
  • Component memoization and stable callbacks
  • Image caching with Expo Image

βœ… Part 6: Error Handling

  • API failure retry with exponential backoff (3 attempts)
  • User-friendly error messages
  • Request timeout handling (60s)
  • Offline mode banner with network monitoring
  • WebView load error handling
  • React Error Boundary for crash recovery

🌟 Bonus Features Implemented

  • Testing: Jest + Testing Library with >70% coverage
  • Security: AES encryption, jailbreak detection, input sanitization
  • Dark Mode: System-aware theme switching
  • Form Validation: Zod schemas with real-time feedback
  • Logging: Centralized logger with environment awareness
  • TypeScript: Strict mode with comprehensive types
  • Performance: Optimized lists, memoization, caching

πŸ”’ Security Features

  1. Token Security

    • iOS: Keychain Services (hardware-encrypted)
    • Android: Keystore (hardware-backed encryption when available)
    • Automatic token cleanup on logout/401
  2. Data Encryption

    • AES-256 encryption for sensitive data
    • SHA-256 hashing for integrity checks
    • Secure random key generation
  3. Input Protection

    • XSS prevention via sanitization
    • Email validation and normalization
    • Password strength requirements (min 6 chars)
  4. Network Security

    • HTTPS-only communication
    • Request/response timeout limits
    • Certificate pinning support (optional)
  5. Device Security

    • Jailbreak detection (iOS)
    • Root detection (Android)
    • Platform-specific security checks

πŸ§ͺ Testing

# Run all tests
npm test

# Run with coverage
npm run test:coverage

# Watch mode
npm run test:watch

Test Coverage:

  • Unit tests: Services, stores, utilities, hooks
  • Component tests: UI components behavior
  • Integration tests: API calls, state updates
  • Overall coverage: >70% (enforced)

Test Files:

src/
β”œβ”€β”€ components/__tests__/
β”œβ”€β”€ services/__tests__/
β”œβ”€β”€ stores/__tests__/
β”œβ”€β”€ hooks/__tests__/
└── utils/__tests__/

See TESTING.md for detailed testing guide.


πŸ“š API Documentation

Base URL: https://api.freeapi.app/api/v1

Authentication Endpoints

Method Endpoint Description
POST /users/register Register new user
POST /users/login Login user
POST /users/logout Logout current user
GET /users/current-user Get current user profile
POST /users/change-password Change user password
POST /users/refresh-token Refresh access token

Public Endpoints

Method Endpoint Description
GET /public/randomproducts Get random products (courses)
GET /public/randomproducts?page=1&limit=20 Paginated products
GET /public/randomusers Get random users (instructors)

See documentation/FreeAPI_*.md for detailed API documentation.


⚠️ Known Issues/Limitations

Platform Limitations

  1. Notifications on Simulators

    • Issue: Push notifications don't work on iOS Simulator or Android Emulator
    • Workaround: Test on physical device or use Expo Go
    • Impact: Local notifications for bookmarks and inactivity reminders
  2. Camera/Image Picker in Expo Go

    • Issue: Full camera access requires development build
    • Workaround: Use expo-dev-client or build custom APK with EAS
    • Impact: Profile picture upload from camera
  3. Web Platform

    • Issue: Limited native features (notifications, secure storage)
    • Workaround: Graceful degradation with fallbacks
    • Impact: Reduced functionality on web platform

API Limitations

  1. Random Product/User Data

    • Issue: FreeAPI returns random products/users, not real LMS data
    • Mapping: Products β†’ Courses, Users β†’ Instructors
    • Impact: No real course content, enrollment is local-only
  2. No Course Content Backend

    • Issue: WebView displays generated HTML, not real course videos/materials
    • Workaround: Local HTML template with course details
    • Impact: Limited WebView functionality demonstration
  3. Token Refresh Reliability

    • Issue: FreeAPI token refresh occasionally fails
    • Workaround: Automatic re-login prompt on failure
    • Impact: User may need to login again after extended session

Performance Considerations

  1. First Launch Delay

    • Issue: Initial API calls may be slow (~2-3s)
    • Cause: FreeAPI cold start time
    • Workaround: Loading indicators and skeleton screens
  2. Large Image Loading

    • Issue: Some product images are large (>1MB)
    • Workaround: Expo Image with progressive loading and caching
    • Impact: Minor delay on slow networks

Testing Limitations

  1. Expo Module Mocking
    • Issue: Some Expo modules (SecureStore, Notifications) need manual mocks
    • Workaround: Jest mock implementations in jest.setup.js
    • Impact: Some integration tests may not cover full native behavior

Future Improvements

  • Implement proper course video playback
  • Add biometric authentication (Face ID/Touch ID/Fingerprint)
  • Integrate real error tracking (Sentry)
  • Add analytics tracking (Expo Analytics)
  • Implement background fetch for course updates
  • Add offline course caching with sync
  • Implement deep linking for course sharing
  • Add accessibility features (screen reader support)

🎯 Assignment Compliance

This project fulfills all mandatory requirements:

βœ… Mandatory Technologies:

  • React Native Expo (SDK 54)
  • TypeScript (strict mode)
  • Expo SecureStore (auth tokens)
  • AsyncStorage (bookmarks)
  • Expo Router (navigation)
  • NativeWind (styling)

βœ… Bonus Technologies:

  • Jest + Testing Library (>70% coverage)
  • React Hook Form (forms)
  • Zod (validation)
  • Expo Image (caching)
  • Custom error tracking
  • Custom logging solution

βœ… All Parts Implemented:

  • Part 1: Authentication & User Management βœ…
  • Part 2: Course Catalog βœ…
  • Part 3: WebView Integration βœ…
  • Part 4: Native Features βœ…
  • Part 5: State Management & Performance βœ…
  • Part 6: Error Handling βœ…

πŸ“– Additional Documentation


πŸ“ License

This project is built as part of a developer assignment and is for demonstration purposes.


πŸ‘¨β€πŸ’» Author

Built with ❀️ for the React Native Expo Developer Assignment


πŸ™ Acknowledgments

  • FreeAPI for providing the backend API
  • Expo for the amazing development framework
  • React Native community for excellent documentation
  • NativeWind for Tailwind CSS in React Native

About

A production-ready React Native Expo mobile application demonstrating advanced mobile development practices, native features integration, and comprehensive security implementation.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published