App.js loads fonts and the splash screen, wraps everything in AuthContextProvider, and renders UnauthStack or AuthStack depending on isAuthenticated. AuthStack wraps BottomTabsNavigator in VersionsProvider.
Auth (stacks/UnauthStack.js)
| Screen | File | Calls |
|---|
| Login | screens/loginScreen.js | rest/api/token/; Google button; language picker; Terms and Privacy. Unverified accounts go to VerifyEmail |
| SignUp | screens/SignupScreen.js | rest/signup/ or Google |
| ResetPassword | screens/ResetPasswordScreen.js | rest/request-password-reset/, rest/confirm-password-reset/ |
| VerifyEmail | screens/VerifyEmailScreen.js | rest/verify-code/, rest/resend-verification/, rest/change-unverified-email/; logs in automatically on success |
Home (hidden tab)
| Screen | What |
|---|
| HomeScreen | Cards: W.A.R. Prayer, Getting Started Right, Videos & Training, Get Books, Giving (hidden on iOS) |
| WarPrayerScreen | Static guide: Worship, Admit, Request |
| GettingStartedRightScreen | Link to emaw.churchcenter.com/registrations |
| VideosAndTrainingScreen | Link to the EMAW Vimeo channel |
| GetBooksScreen | Link to everymanawarrior.com/purchase.html |
| DonateScreen | Link to everymanawarrior.com/emaw-donations.html (Android only) |
Quiet Time
| Screen | Calls |
|---|
| QTScreen ("Journal") | rest/qt/fetchQT/ |
QtEntryScreen (components/QuietTimeEntryForm.js) | rest/qt/submitQT/, rest/qt/updateQT/<id>/; sections: passage, Major Themes, questions, Best Verse |
| HistoricQTScreen | rest/fetch-quiet-time-entry/<id>/, rest/qt/deleteQT/<id>/; share or copy with or without W.A.R. sections |
Verse Memory
| Screen | Calls |
|---|
| VerseMemoryScreen | menu |
| AllVersesScreen | rest/get-user-verses/, rest/mark-verse-memorized/, rest/remove-verse/<id>/, rest/manage-verse-in-collection/, audio via rest/generate-audio-file/ |
| AddVerseScreen | reference picker; text from local SQLite; rest/add-memory-verse/ |
| CollectionsScreen | rest/get-user-collections/, rest/create-collection/, rest/delete-collection/<id>/, rest/get-collection-verse-count/ |
| PracticeScreen | five modes: FlashcardMode, InitialsMode, FillInTheBlankMode, WordScrambleMode, AudioPracticeMode (rest/analyze-verse-audio/) |
| VerseFinderScreen | rest/ai/find-verse/; verse text from SQLite; add to collections |
Bible
| Screen | Calls |
|---|
| BibleScreen | Offline reader; highlights, notes, tags (rest/notes/*), memorize, similar (rest/bibles/similar/), compare versions, start a Quiet Time; remembers last position |
| BibleSearchScreen | rest/bibles/search/ (semantic), local FTS5 fallback offline |
| BibleLibraryScreen | All highlights, notes and tags with filters |
Books
| Screen | Calls |
|---|
| BooksScreen | four covers |
| BookSubScreen | weeks with progress (rest/get-user-progress/<book>/), from locales/<lang>/book_info.json |
| DiscussionQuestionsScreen | rest/get-answers/, rest/get-submission-dates/, rest/submit-discussion-questions/; drafts in AsyncStorage |
| WeeklyQTScreen | assigned passages with completion; opens QtEntryScreen |
Settings (screens/SettingsScreen.js)
Language, default Bible version, stats (rest/user-stats/), sign-in methods (rest/auth/identities/, link/unlink Google), Change Password (hidden for password-less accounts), Logout (rest/api/token/logout/), Delete Account (rest/delete-user/, confirm with password or Google).
API layer
store/AxiosInstance.js: 30 s timeout; setupInterceptors(logout, refreshTokenFn); retries a network error once; on 401 refreshes (rest/api/token/refresh/ with rotate: true, concurrent 401s share one refresh) and retries; 429 passes through. Session bootstrap checks GET rest/validate/token. Every API call is a standalone function in utils/ importing the shared instance.