Never miss another exam date.
A beautifully minimal mobile app to track upcoming exams, set smart reminders, and keep all your resources in one place.
Platform Expo SDK Supabase License
| Feature | Description |
|---|---|
| π Watchlist | Pin exams you care about and see a "Next Up" hero card with a live countdown |
| π Explore All Exams | Browse, search, and filter exams by category (UPSC, SSC, Banking, Railways, etc.) |
| β° Smart Reminders | Schedule notifications at customizable offsets β 1 week, 1 day, 1 hour before, or any custom value |
| π Resource Links | One-tap access to syllabus PDFs, previous year papers, and official websites |
| π Dark & Light Themes | A pure black/white theme system with persistent preference |
| π Onboarding Flow | Smooth first-launch experience β enter your name, pick exams, and get started |
| π± Skeleton Loading | Polished loading states with animated skeletons while data loads |
| π Analytics Sync | Anonymous device-level usage synced to Supabase for growth insights |
| Layer | Technology |
|---|---|
| Framework | React Native via Expo (SDK 54) |
| Navigation | React Navigation (Bottom Tabs) |
| Database | Supabase (PostgreSQL + Row Level Security) |
| Local Storage | AsyncStorage for watchlist, preferences, and offline state |
| Notifications | expo-notifications with custom scheduling |
| Fonts | Google Fonts β Instrument Sans & DM Mono |
| Animations | React Native Reanimated + Gesture Handler |
ExamTracker/
βββ App.js # Root β fonts, providers, tab navigation
βββ src/
β βββ components/
β β βββ ExamDetailSheet.js # Full-screen exam detail modal
β β βββ RichText.js # Markdown-style content renderer
β β βββ SkeletonCard.js # Loading skeleton for exam cards
β β βββ SkeletonWatchCard.js # Loading skeleton for watchlist cards
β β βββ ThemeSwitch.js # Dark/light mode toggle switch
β β βββ TimerBlocks.js # Countdown timer UI (block layout)
β β βββ TimerInline.js # Countdown timer UI (inline layout)
β βββ context/
β β βββ AppContext.js # Global state β exams, watchlist, user
β β βββ ThemeContext.js # Theme provider (dark/light colors)
β βββ lib/
β β βββ supabase.js # Supabase client initialization
β βββ screens/
β β βββ AllExamsScreen.js # Browse & search all exams
β β βββ CalendarScreen.js # Calendar view of exams
β β βββ OnboardingScreen.js # First-launch onboarding flow
β β βββ SettingsScreen.js # Notification & theme preferences
β β βββ WatchlistScreen.js # Pinned exams with "Next Up" hero
β βββ utils/
β βββ notifications.js # Notification scheduling & management
β βββ time.js # Date/time formatting helpers
β βββ urlUtils.js # URL validation & linking helpers
βββ supabase/
β βββ schema.sql # Full database schema with RLS policies
β βββ migration.sql # Incremental migration scripts
β βββ seedingdata.sql # Sample exam data for development
βββ assets/ # App icons, splash screens, animations
βββ android/ # Android native project (EAS Build)
- Node.js 18+ (LTS recommended)
- npm or yarn
- Expo Go on your phone, or an Android/iOS emulator
git clone https://github.com/ipmen-in/ExamTracker.git
cd ExamTracker
npm installCreate a .env file in the project root:
EXPO_PUBLIC_SUPABASE_URL=https://your-project.supabase.co EXPO_PUBLIC_SUPABASE_ANON_KEY=your-anon-key-here
- Create a new project at supabase.com
- Open the SQL Editor and run
supabase/schema.sqlto create tables with RLS policies - (Optional) Run
supabase/seedingdata.sqlto populate sample exam data
npx expo start
Scan the QR code with Expo Go or press a for Android emulator / i for iOS simulator.
npx expo run:android
Note: Full notification scheduling with channels requires a custom dev client or standalone build β Expo Go has limitations.
Security model:
categoriesandexamsare read-only for all app users β onlyservice_rolecan modify datauserscan only read/update their own row (matched bydevice_idheader)- Exam images stored in a public read-only Supabase Storage bucket
| Package | Purpose |
|---|---|
@supabase/supabase-js |
Database client |
@react-navigation/bottom-tabs |
Tab-based navigation |
react-native-reanimated |
Smooth animations |
react-native-gesture-handler |
Swipe & gesture support |
react-native-safe-area-context |
Safe area inset handling |
@react-native-async-storage/async-storage |
Persistent local storage |
expo-notifications |
Local push notifications |
expo-image-picker |
Image selection |
| Key | Type | Description |
|---|---|---|
watchlist |
string[] |
Array of pinned exam IDs |
notification_prefs |
number[] |
Minutes-before values, e.g. [10080, 1440, 60] |
notification_ids |
object |
Scheduled notification IDs keyed by exam ID |
userName |
string |
User's display name from onboarding |
onboardingComplete |
"true" |
Whether onboarding has been completed |
theme |
"dark" | "light" |
Preferred color scheme |
deviceId |
string |
Persistent UUID for analytics |
Contributions are welcome! Here's how to get started:
- Fork the repository
- Create a branch β
git checkout -b feat/your-feature - Make your changes β test on both Android and iOS
- Add migrations β any DB changes go in
supabase/migration.sql - Open a PR with a clear description
- GitHub Actions CI (lint, typecheck, build)
- End-to-end tests for onboarding & notification flows
- Exam sharing via deep links
- Study timer / Pomodoro integration
- Push notification support via Supabase Edge Functions
This project is licensed under the MIT License β see the LICENSE file for details.
Built with β€οΈ by Team IPMen