L o a d i n g
Back to Portfolio Mobile App · Mental Health

Nonu — Student Mental Health App

A cross-platform (iOS + Android) React Native app for the "Live for a Cause" mental-health initiative — students sign in with a phone number and SMS OTP, browse wellness events, and book counselling sessions through an in-app calendar.

React Native 0.70 React Navigation v6 Firebase Auth AsyncStorage react-native-calendars

iOS + Android

One React Native Codebase

Firebase OTP

Phone Authentication

Custom Client

Token-Authenticated REST

ESLint + Husky

Enforced Code Quality
Walkthrough

App Screens

Key Features

What The App Does

Firebase Phone OTP Auth

6-digit SMS OTP with a 45-second resend cooldown and invalid-code handling.

Token-Aware Session Client

ID token persisted in AsyncStorage, auto-attached as a Bearer header on every call.

Session Booking Calendar

Custom month calendar plus a horizontal time-slot selector for assessments.

Home Dashboard

Profile-completion progress bar and a state-driven contextual banner system.

Session History & Reports

Monthly-grouped history with Intake/Cancelled/Missed rows and a scored report card.

Enforced Code Quality

ESLint, Prettier and a Husky pre-commit hook running lint-staged on every commit.

Technology

Stack & Integrations

Frontend
React Native 0.70 (bare) React 18.2 React Navigation v6 react-native-calendars
Auth & Data
Firebase Authentication AsyncStorage Custom REST client
Tooling
ESLint / Prettier Husky + lint-staged Jest
Platforms
Gradle (Android) CocoaPods (iOS) Metro Bundler
Architecture

How It's Built

Authentication drives navigation: Login/Register capture a phone number and route to an OTP screen, which calls Firebase's signInWithPhoneNumber, confirms the SMS code, force-refreshes the ID token, and stores it in AsyncStorage before moving into onboarding. Home re-reads that token on every focus and redirects back to Login when it's absent — a lightweight, client-side route guard rather than a server-enforced session.

All network calls run through one centralized client (src/api/api.js): a single apiRequest() helper attaches the stored Bearer token, performs the fetch, and normalizes error handling, so screens never touch fetch directly. The UI layer is built from reusable, parametrized components — an EventCard, five interchangeable state-selected banner components, and per-status history rows — wired into a native-stack-over-bottom-tabs navigation structure.