@fadyshawky/react-native-magic 2.2.1 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (138) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +90 -56
  3. package/index.js +4 -0
  4. package/package.json +8 -2
  5. package/scripts/askPackageName.js +10 -5
  6. package/template/.env.development +8 -6
  7. package/template/.env.example +15 -5
  8. package/template/.env.production +8 -6
  9. package/template/.env.staging +8 -6
  10. package/template/.eslintrc.js +14 -0
  11. package/template/.husky/pre-commit +1 -0
  12. package/template/App.tsx +47 -16
  13. package/template/__tests__/App.test.tsx +28 -10
  14. package/template/babel.config.js +20 -1
  15. package/template/docs/ARCHITECTURE.md +40 -10
  16. package/template/docs/BEST_PRACTICES.md +10 -1
  17. package/template/docs/CUSTOMIZATION.md +118 -5
  18. package/template/docs/design-system.html +1164 -0
  19. package/template/docs/wireframes.html +411 -0
  20. package/template/index.js +10 -0
  21. package/template/jest.config.js +16 -1
  22. package/template/jest.setup.js +61 -0
  23. package/template/package-lock.json +12178 -8293
  24. package/template/package.json +53 -20
  25. package/template/react-native.config.js +3 -0
  26. package/template/resources/fonts/.gitkeep +0 -0
  27. package/template/scripts/ci-sync-env.cjs +71 -0
  28. package/template/src/assets/brand/logo-mark.svg +8 -0
  29. package/template/src/assets/brand/logo-mono.svg +9 -0
  30. package/template/src/assets/brand/logo-primary.svg +15 -0
  31. package/template/src/assets/brand/wordmark-dark.svg +18 -0
  32. package/template/src/common/components/AppBottomSheet.tsx +87 -0
  33. package/template/src/common/components/AppSwitch.tsx +75 -0
  34. package/template/src/common/components/AppTextInput.tsx +161 -0
  35. package/template/src/common/components/Avatar.tsx +75 -0
  36. package/template/src/common/components/Badge.tsx +66 -0
  37. package/template/src/common/components/CardScroller.tsx +58 -0
  38. package/template/src/common/components/Cards.tsx +13 -7
  39. package/template/src/common/components/Carousel.tsx +196 -0
  40. package/template/src/common/components/Checkbox.tsx +85 -0
  41. package/template/src/common/components/Chip.tsx +55 -0
  42. package/template/src/common/components/Dropdown.tsx +202 -0
  43. package/template/src/common/components/ErrorBoundary.tsx +82 -0
  44. package/template/src/common/components/FlatListWrapper.tsx +4 -5
  45. package/template/src/common/components/ListItem.tsx +90 -0
  46. package/template/src/common/components/LoadingComponent.tsx +8 -2
  47. package/template/src/common/components/Logo.tsx +77 -0
  48. package/template/src/common/components/ModalDialog.tsx +141 -0
  49. package/template/src/common/components/NetworkBanner.tsx +47 -0
  50. package/template/src/common/components/OTPInput.tsx +0 -1
  51. package/template/src/common/components/PrimaryButton.tsx +0 -14
  52. package/template/src/common/components/PrimaryTextInput.tsx +66 -130
  53. package/template/src/common/components/RadioGroup.tsx +95 -0
  54. package/template/src/common/components/SafeText.tsx +4 -3
  55. package/template/src/common/components/SearchBar.tsx +7 -5
  56. package/template/src/common/components/SegmentedControl.tsx +77 -0
  57. package/template/src/common/components/Skeleton.tsx +47 -0
  58. package/template/src/common/components/TryAgain.tsx +4 -2
  59. package/template/src/common/helpers/arrayHelpers.ts +2 -2
  60. package/template/src/common/helpers/defaultKeyIdExtractor.ts +1 -1
  61. package/template/src/common/helpers/regexHelpers.ts +1 -2
  62. package/template/src/common/helpers/stringsHelpers.ts +0 -1
  63. package/template/src/common/hooks/useBackHandler.ts +5 -2
  64. package/template/src/common/hooks/useEventRegister.ts +1 -1
  65. package/template/src/common/hooks/useFlatListActions.ts +1 -1
  66. package/template/src/common/hooks/useWhyDidYouUpdate.ts +1 -1
  67. package/template/src/common/localization/LocalizationProvider.tsx +1 -1
  68. package/template/src/common/localization/RTLInitializer.tsx +1 -1
  69. package/template/src/common/localization/dateFormatter.ts +0 -1
  70. package/template/src/common/localization/intlFormatter.ts +0 -1
  71. package/template/src/common/localization/localization.ts +2 -2
  72. package/template/src/common/localization/translations/homeLocalization.ts +14 -0
  73. package/template/src/common/localization/translations/loginLocalization.ts +8 -0
  74. package/template/src/common/localization/translations/mainNavigationLocalization.ts +2 -0
  75. package/template/src/common/localization/translations/profileLocalization.ts +16 -0
  76. package/template/src/common/utils/index.tsx +0 -6
  77. package/template/src/common/validations/commonValidations.ts +2 -2
  78. package/template/src/core/api/errorHandler.ts +1 -1
  79. package/template/src/core/api/responseHandlers.ts +1 -3
  80. package/template/src/core/api/serverHeaders.ts +61 -12
  81. package/template/src/core/notifications/notificationAuth.ts +6 -0
  82. package/template/src/core/notifications/notificationService.ts +125 -0
  83. package/template/src/core/notifications/routeFromNotificationData.ts +32 -0
  84. package/template/src/core/store/categories/categoriesActions.ts +25 -0
  85. package/template/src/core/store/categories/categoriesSlice.ts +51 -0
  86. package/template/src/core/store/categories/categoriesState.ts +19 -0
  87. package/template/src/core/store/rootReducer.ts +2 -0
  88. package/template/src/core/store/store.tsx +6 -1
  89. package/template/src/core/store/user/userActions.ts +75 -14
  90. package/template/src/core/store/user/userSlice.ts +49 -26
  91. package/template/src/core/store/user/userState.ts +6 -4
  92. package/template/src/core/theme/ThemeProvider.tsx +5 -3
  93. package/template/src/core/theme/brand.ts +50 -0
  94. package/template/src/core/theme/colors.ts +113 -99
  95. package/template/src/core/theme/commonConsts.ts +2 -2
  96. package/template/src/core/theme/commonStyles.ts +1 -1
  97. package/template/src/core/theme/themes.ts +2 -0
  98. package/template/src/core/theme/types.ts +4 -2
  99. package/template/src/core/utils/stringUtils.ts +1 -1
  100. package/template/src/design-system/index.ts +2 -0
  101. package/template/src/design-system/tokens/brand.ts +6 -0
  102. package/template/src/design-system/tokens/index.ts +3 -0
  103. package/template/src/design-system/tokens/palette.ts +4 -0
  104. package/template/src/design-system/tokens/typography-spacing.ts +2 -0
  105. package/template/src/navigation/AuthStack.tsx +1 -4
  106. package/template/src/navigation/HeaderComponents.tsx +6 -3
  107. package/template/src/navigation/MainStack.tsx +18 -6
  108. package/template/src/navigation/RootNavigation.tsx +4 -7
  109. package/template/src/navigation/TabBar.tsx +7 -6
  110. package/template/src/navigation/types.ts +10 -31
  111. package/template/src/screens/Login/Login.tsx +47 -47
  112. package/template/src/screens/OTP/OTPScreen.tsx +6 -9
  113. package/template/src/screens/components/ComponentsScreen.tsx +301 -0
  114. package/template/src/screens/home/HomeScreen.tsx +143 -1
  115. package/template/src/screens/home/hooks/useHomeData.ts +19 -5
  116. package/template/src/screens/index.tsx +1 -0
  117. package/template/src/screens/profile/Profile.tsx +139 -2
  118. package/template/src/screens/splash/Splash.tsx +44 -11
  119. package/template/src/sheetManager/sheets.tsx +1 -1
  120. package/template/tsconfig.json +14 -2
  121. package/template/types/globals.d.ts +43 -0
  122. package/template/types/index.ts +2 -6
  123. package/template/types/modules.d.ts +9 -0
  124. package/template/types/react-native-config.d.ts +0 -2
  125. package/.vscode/settings.json +0 -8
  126. package/CHANGELOG.md +0 -119
  127. package/CODE_OF_CONDUCT.md +0 -83
  128. package/CONTRIBUTING.md +0 -60
  129. package/local.properties +0 -1
  130. package/template/src/common/components/ImageCropPickerButton.tsx +0 -107
  131. package/template/src/common/components/PhotoTakingButton.tsx +0 -94
  132. package/template/src/common/helpers/imageHelpers.ts +0 -5
  133. package/template/src/common/helpers/inAppReviewHelper.ts +0 -30
  134. package/template/src/common/helpers/orientationHelpers.ts +0 -25
  135. package/template/src/common/helpers/shareHelpers.ts +0 -47
  136. package/template/src/common/utils/FeesCaalculation.tsx +0 -37
  137. package/template/src/common/utils/printData.tsx +0 -161
  138. package/template/src/common/validations/examples/TextInputWithValidation.tsx +0 -229
@@ -2,26 +2,56 @@
2
2
 
3
3
  ## Overview
4
4
 
5
- This app uses a layered structure: **UI** (screens, components) → **navigation** → **core** (store, api, theme, config) and **common** (components, localization, helpers).
5
+ This app uses a layered structure: **UI** (screens, components) → **navigation** → **core** (store, api, theme, config, notifications) and **common** (components, localization, helpers). A **design-system** layer re-exports the theme tokens, the brand tokens (gradients/glow), and the theme provider as a single barrel.
6
+
7
+ > Imports in `src/` are **relative**. Path aliases (`@core/*`, `@common/*`, `@design-system`, …) are configured in `babel.config.js`, `tsconfig.json`, and `jest.config.js` and are available if you prefer them, but the shipped code reaches into `core/theme/*` directly rather than going through the barrel.
6
8
 
7
9
  ## Folder map
8
10
 
9
11
  | Folder | Purpose |
10
12
  |--------|--------|
11
- | `src/common/` | Shared UI components, localization (i18n), helpers, validations, hooks, urls, utils |
12
- | `src/core/` | Store (Redux + persist), API client, theme, config, services, hooks |
13
- | `src/navigation/` | Navigator setup, auth stack, main stack, tab bar, header components |
14
- | `src/screens/` | Feature screens (Login, Home, Profile, etc.); each may have local `components/` and `hooks/` |
13
+ | `src/common/` | Shared UI components (incl. `ErrorBoundary`, `NetworkBanner`, `SnackbarProvider`), localization (i18n), helpers, validations, hooks, urls, utils |
14
+ | `src/core/api/` | Single axios instance + interceptors (auth, refresh-token dedup, locale, 401/402 handling) |
15
+ | `src/core/store/` | Redux Toolkit slices (`app`, `user`, `categories`) + persist (AsyncStorage, selective whitelist transforms) |
16
+ | `src/core/theme/` | `colors.ts`, `fonts.ts`, `commonSizes.ts`, `brand.ts` (gradients/glow), `ThemeProvider.tsx`. Light/dark/system theming |
17
+ | `src/core/config/` | Env-driven config (`API_BASE_URL`, `ENV`, feature toggles) |
18
+ | `src/core/notifications/` | FCM listeners (`notificationService.ts`), tap-routing (`routeFromNotificationData.ts`), auth check |
19
+ | `src/design-system/` | Theme + brand token re-exports + theme provider re-export (barrel; `@design-system` alias available but unused) |
20
+ | `src/navigation/` | Navigator setup, auth stack, main stack, root navigation ref, header components |
21
+ | `src/screens/` | Feature screens (Splash, Login, OTP, Home, Profile); each may have local `components/` and `hooks/` |
22
+ | `src/assets/brand/` | Brand logo SVGs (`logo-primary`, `logo-mono`, `logo-mark`, `wordmark-dark`) |
15
23
  | `src/sheetManager/` | Action sheet registration |
16
24
 
17
25
  ## Data flow
18
26
 
19
- - **Auth**: Token is stored in Redux (`user.accessToken`). Navigation shows Auth stack when there is no token, Main stack when there is.
20
- - **API**: Single axios instance in `src/core/api/serverHeaders.ts`. Base URL comes from `src/core/config` (and `.env`). Request interceptor adds `Authorization: Bearer` and `locale`; response interceptor handles 401 (e.g. logout).
21
- - **Redux**: Slices live under `src/core/store/<domain>/` (e.g. `app`, `user`). Persist whitelist controls what is saved to AsyncStorage.
27
+ - **Auth**: Token is stored in Redux (`user.accessToken`). Navigation shows Auth stack when there is no token, Main stack when there is. `user.refreshToken` is persisted; the axios response interceptor dedups concurrent 401s via a single in-flight `refreshPromise`, then retries the original request. On refresh failure, `setLogout()` is dispatched.
28
+ - **API**: Single axios instance in `src/core/api/serverHeaders.ts`. Base URL comes from `src/core/config` (and `.env`). Request interceptor adds `Authorization: Bearer` and `locale`. Response interceptor handles 401 (refresh) and 402 (logout).
29
+ - **Redux**: Slices live under `src/core/store/<domain>/` (`app`, `user`, `categories`). Each follows the house pattern — a `newState` reducer helper, a `LoadState` enum for request status, and `createAsyncThunk` thunks that call the API helpers. `categories` is a worked example: its thunk GETs `/categories`, the slice tracks `LoadState`, and the Home screen's `useHomeData` hook renders the result through `FlatListWrapper` (a full data → thunk → slice → list demo). Persist whitelist (`store.tsx`) controls what survives a kill — `user`: `accessToken`, `refreshToken`, `fcmToken`, `user`; `app`: `language`, `isRTL`. The `app` slice defaults `language` to English (`Languages.en`); Arabic / RTL stay wired and switchable at runtime.
30
+ - **Notifications**: `index.js` registers the FCM background handler before app boot — it queues any incoming `data` payload into `pendingBackgroundNotificationData`. `App.tsx` mounts `startPushNotificationListeners()` which wires foreground/background/cold-start/token-refresh listeners, plus an `AppState` + store subscriber that flushes the pending route when the user is logged in and the navigator is ready.
31
+ - **Theming**: The "Indigo → Cyan" tokens live in `src/core/theme/colors.ts`; gradient and glow tokens (`BrandGradients`, `Glow`) live in `src/core/theme/brand.ts` and pair with `react-native-linear-gradient`. `ThemeProvider` exposes `useTheme()` and **follows the system color scheme by default** (`App.tsx` renders `<ThemeProvider>` with no forced theme). Light and dark are both supported; the Profile screen offers a manual toggle. The brand `Logo` (`src/common/components/Logo.tsx`) renders the "FS" monogram from `react-native-svg` in four variants (`gradient` / `mono` / `light` / `mark`).
32
+
33
+ ## Provider order in `App.tsx`
34
+
35
+ Outer → inner:
36
+
37
+ 1. `ErrorBoundary` (catches render errors with a retry fallback)
38
+ 2. `Provider` (Redux store)
39
+ 3. `PersistGate` (redux-persist)
40
+ 4. `GestureHandlerRootView`
41
+ 5. `SnackbarProvider`
42
+ 6. `ThemeProvider`
43
+ 7. `RTLInitializer` (must wrap `LocalizationProvider`)
44
+ 8. `LocalizationProvider`
45
+ 9. `SafeAreaProvider`
46
+ 10. `SheetProvider` (react-native-actions-sheet)
47
+ 11. `BottomSheetModalProvider` (@gorhom/bottom-sheet)
48
+ 12. `AppNavigator`
49
+ 13. `NetworkBanner` (sibling of navigator, fixed position)
50
+
51
+ Order is load-bearing: persist must be ready before redux-aware components mount; gesture-handler must wrap everything that uses gestures; RTL must initialize before localized text renders.
22
52
 
23
53
  ## SOLID mapping
24
54
 
25
55
  - **SRP**: One domain per store folder; one primary concern per component file; theme split into colors, fonts, sizes, consts, styles.
26
- - **OCP**: Extend by adding screens, slices, or routes without changing existing stack logic; extend theme by editing theme files.
27
- - **DIP**: Core (API, store) does not depend on UI; screens depend on core via hooks/selectors; config abstracts environment.
56
+ - **OCP**: Extend by adding screens, slices, or routes without changing existing stack logic; extend theme by editing theme files; extend notifications by editing `routeFromNotificationData.ts` only.
57
+ - **DIP**: Core (API, store, notifications) does not depend on UI; screens depend on core via hooks/selectors; config abstracts environment.
@@ -4,6 +4,8 @@
4
4
 
5
5
  - Use **TypeScript** strictly; avoid `any` where possible.
6
6
  - Use typed Redux: `useAppSelector`, `useAppDispatch`, and `createAppAsyncThunk` with `RootState` / `AppDispatch`.
7
+ - Follow the house slice pattern: a `newState` reducer helper, a `LoadState` enum for request status, and `createAsyncThunk` thunks that call the API helpers. The `categories` slice (`src/core/store/categories/`) is the reference.
8
+ - Use relative imports to match the existing code. Path aliases are configured but not used by the shipped `src/`.
7
9
  - Run `npm run lint` and fix issues.
8
10
 
9
11
  ## Structure
@@ -21,6 +23,13 @@
21
23
 
22
24
  - Avoid creating new objects/functions in render when they are passed as props to children.
23
25
  - Use stable keys for list items.
26
+ - For heavy lists, use `src/common/components/FlatListWrapper.tsx` (FlashList-backed) and set `estimatedItemSize`; don't reintroduce a raw `FlatList`.
27
+
28
+ ## Theming
29
+
30
+ - Change brand colors, fonts, and sizes only in `src/core/theme/` — keep the token keys stable so the rest of the app keeps working.
31
+ - Reuse the gradient and glow tokens from `src/core/theme/brand.ts` (`BrandGradients`, `Glow`) for the futuristic surfaces rather than hardcoding shadows or gradient stops.
32
+ - The app follows the system color scheme by default; verify new screens in both light and dark.
24
33
 
25
34
  ## Security
26
35
 
@@ -29,5 +38,5 @@
29
38
 
30
39
  ## LTS / upgrades
31
40
 
32
- - The template targets **Node >= 20** and current stable **React Native** (e.g. 0.84.x).
41
+ - The template targets **Node >= 20** and **React Native 0.85.x** (React 19.2.x).
33
42
  - To upgrade React Native, use [React Native Upgrade Helper](https://react-native-community.github.io/upgrade-helper/): select your current version and the target version, then apply the suggested changes to `package.json`, `android/`, `ios/`, and config files.
@@ -17,17 +17,40 @@ If you omit `--package-name`, the template will **prompt you** after init to ent
17
17
 
18
18
  1. Copy `.env.example` to `.env`.
19
19
  2. Set `API_BASE_URL` (and any other keys) for your backend.
20
- 3. The app reads these via `react-native-config`; `src/core/config/index.ts` re-exports them for type-safe use.
20
+ 3. The app reads these via `react-native-config`; `src/core/config/index.ts` re-exports them for type-safe use as `API_BASE_URL` and `ENV` (the environment name; falls back to a legacy `ENVIRONMENT` var). Route all env access through this module.
21
21
 
22
22
  Optional: use multiple env files (e.g. `.env.development`, `.env.staging`, `.env.production`) and build variants so each build uses the right URL.
23
23
 
24
- ## Theme
24
+ ## Theme & branding
25
25
 
26
- Edit these files for your brand (no need to touch components):
26
+ The template ships a futuristic **"Indigo → Cyan"** system (primary indigo `#5B6CFF`, accent cyan `#22E0D6`, deep ink `#0B1020`). Edit these files for your brand — token *keys* are stable across the app, so changing the hex values rebrands everything (no need to touch components):
27
27
 
28
28
  - **Colors**: `src/core/theme/colors.ts`
29
29
  - **Fonts**: `src/core/theme/fonts.ts`
30
30
  - **Sizes / spacing**: `src/core/theme/commonSizes.ts`
31
+ - **Gradients & glow**: `src/core/theme/brand.ts` — `BrandColors`, `BrandGradients` (e.g. `BrandGradients.primary = ['#5B6CFF', '#22E0D6']`), `GradientDirection`, and `Glow` (ready-to-spread `ViewStyle` shadows). Gradient surfaces use `react-native-linear-gradient`.
32
+
33
+ These tokens are also re-exported from the `src/design-system` barrel.
34
+
35
+ ### Light / dark / system theming
36
+
37
+ `ThemeProvider` (`src/core/theme/ThemeProvider.tsx`) exposes `useTheme()` and **follows the OS color scheme by default** — `App.tsx` renders `<ThemeProvider>` with no forced theme. Both light and dark are supported, and the Profile screen includes a manual toggle. To force one theme, pass it to `<ThemeProvider>` in `App.tsx`.
38
+
39
+ ### Logo
40
+
41
+ The brand mark is a forward-leaning **"FS" monogram**:
42
+
43
+ - React component: `src/common/components/Logo.tsx` — `<Logo size={96} variant="gradient" />`, built on `react-native-svg`. Variants: `gradient` (default), `mono`, `light`, `mark`. It is wired into Splash, Login, Home, and Profile.
44
+ - Raw SVGs: `src/assets/brand/` (`logo-primary.svg`, `logo-mono.svg`, `logo-mark.svg`, `wordmark-dark.svg`).
45
+
46
+ To use your own mark, replace the paths in `Logo.tsx` (and the SVGs) — the rest of the app references the component, not the assets directly.
47
+
48
+ ### Visual references
49
+
50
+ Two static reference pages ship with the template:
51
+
52
+ - **[`docs/design-system.html`](./design-system.html)** — color ramps, gradients, glow, and logo variants.
53
+ - **[`docs/wireframes.html`](./wireframes.html)** — the screen flow.
31
54
 
32
55
  ## Adding a new language
33
56
 
@@ -38,9 +61,11 @@ Edit these files for your brand (no need to touch components):
38
61
 
39
62
  ## Adding a screen
40
63
 
64
+ The template ships real, branded screens: **Splash** (the Auth stack entry, which hands off to Login), **Login** (logo + phone/password), **OTP** (verifies via a `verifyOTP` thunk), **Home** (greeting + gradient hero card + a categories list), and **Profile** (user card + language toggle + theme toggle + logout). Use any of them as a starting point.
65
+
41
66
  1. Create a folder under `src/screens/<Feature>/` with `Feature.tsx` and optional `components/` and `hooks/`.
42
- 2. Register the screen in the right stack in `src/navigation/` (e.g. `AuthStack.tsx` or `MainStack.tsx`).
43
- 3. Add the route and component to the stacks screen list.
67
+ 2. Register the screen in the right stack in `src/navigation/` (the Auth stack or the Main stack).
68
+ 3. Add the route to `RootStackParamList` in `src/navigation/types.ts` (currently `Splash`, `Login`, `OTP`, `Main`, `Account`) and add the component to the stack's screen list.
44
69
 
45
70
  ## Adding a Redux slice
46
71
 
@@ -48,6 +73,94 @@ Edit these files for your brand (no need to touch components):
48
73
  2. Add the slice to `src/core/store/rootReducer.ts`.
49
74
  3. If the slice should persist, add a `createWhitelistFilter('<domain>', ['field1', 'field2'])` entry in `src/core/store/store.tsx` persist config.
50
75
 
76
+ The `categories` slice (`src/core/store/categories/`) is a complete, copyable example of the house pattern: a `newState` reducer helper, a `LoadState` enum for request status, and a `createAsyncThunk` that calls the `get()` API helper. The Home screen's `useHomeData` hook dispatches it and renders the result through `FlatListWrapper`.
77
+
51
78
  ## Feature flags / app config
52
79
 
53
80
  Toggle features or app-level constants in `src/core/config/index.ts` or via env vars read there (e.g. `enableRTL`).
81
+
82
+ ## Firebase / push notifications (FCM)
83
+
84
+ The template ships with `@react-native-firebase/{app,messaging,analytics}` wired into `src/core/notifications/`. Listeners are started from `App.tsx` and the background handler is registered in `index.js`. To make this work on a real device you need to add your Firebase project credentials.
85
+
86
+ ### iOS
87
+
88
+ 1. In the [Firebase console](https://console.firebase.google.com), add an iOS app using your `BUNDLE_ID`.
89
+ 2. Download `GoogleService-Info.plist` and drag it into `ios/<YourApp>/` in Xcode (Copy items if needed, target = your app).
90
+ 3. In `ios/Podfile`, ensure modular headers are enabled near the top:
91
+ ```ruby
92
+ use_modular_headers!
93
+ ```
94
+ 4. In `ios/<YourApp>/AppDelegate.swift`, configure Firebase at startup:
95
+ ```swift
96
+ import FirebaseCore
97
+ // …
98
+ func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
99
+ FirebaseApp.configure()
100
+ // …
101
+ }
102
+ ```
103
+ 5. Enable **Push Notifications** + **Background Modes → Remote notifications** in the target's Signing & Capabilities.
104
+ 6. Upload your APNs auth key in Firebase project settings → Cloud Messaging.
105
+ 7. Run `cd ios && pod install`.
106
+
107
+ ### Android
108
+
109
+ 1. In the Firebase console, add an Android app using your `ANDROID_APP_ID`.
110
+ 2. Download `google-services.json` and drop it into `android/app/`.
111
+ 3. In `android/build.gradle`, add the Google services classpath:
112
+ ```gradle
113
+ buildscript {
114
+ dependencies {
115
+ classpath("com.google.gms:google-services:4.4.2")
116
+ }
117
+ }
118
+ ```
119
+ 4. In `android/app/build.gradle`, apply the plugin at the very bottom:
120
+ ```gradle
121
+ apply plugin: "com.google.gms.google-services"
122
+ ```
123
+ 5. Rebuild: `cd android && ./gradlew clean`.
124
+
125
+ ### Routing taps
126
+
127
+ Notification taps route via `src/core/notifications/routeFromNotificationData.ts`. Send `data.screen` (and optionally `data.params` as a JSON string) in the FCM payload — the router calls `navigate(screen, params)`. Extend that file with `data.type`/`data.target` switches for richer flows.
128
+
129
+ ## React Native 0.85.x
130
+
131
+ The template is on RN 0.85.2. If you upgrade your generated app to a newer RN later, use the [Upgrade Helper](https://react-native-community.github.io/upgrade-helper/) — select your current RN version on the left and the target on the right, then apply the suggested diffs to `package.json`, `ios/`, `android/`, and config files.
132
+
133
+ `react-native-reanimated` 4.x requires `react-native-worklets` and the `react-native-worklets/plugin` babel plugin (already in `babel.config.js`). Do not also add `react-native-reanimated/plugin` — only one of the two.
134
+
135
+ ## Path aliases
136
+
137
+ The template wires these aliases through `babel.config.js`, `tsconfig.json`, and `jest.config.js`. **They are configured but not used by the shipped code** — `src/` imports relatively. They are here if you prefer aliases; opt in per file.
138
+
139
+ | Alias | Path |
140
+ |-------|------|
141
+ | `@core/*` | `src/core/*` |
142
+ | `@common/*` | `src/common/*` |
143
+ | `@navigation/*` | `src/navigation/*` |
144
+ | `@screens/*` | `src/screens/*` |
145
+ | `@sheetManager/*` | `src/sheetManager/*` |
146
+ | `@design-system` | `src/design-system` |
147
+ | `@types/*` | `src/types/*` |
148
+ | `@utils/*` | `src/utils/*` |
149
+
150
+ Add new aliases in all three files together — Babel rewrites imports at build time, TS resolves them for the editor, Jest resolves them for tests.
151
+
152
+ ## CI / version bumping
153
+
154
+ `scripts/ci-sync-env.cjs` writes/updates `KEY=value` pairs in an env file. Use it in CI to inject Play Store / App Store auto-incremented build numbers:
155
+
156
+ ```bash
157
+ node scripts/ci-sync-env.cjs .env.production \
158
+ ANDROID_VERSION_CODE=42 \
159
+ IOS_BUILD_NUMBER=42
160
+ ```
161
+
162
+ Then run your release build — Gradle and the iOS scheme pick up the values via `react-native-config`.
163
+
164
+ ## Git hooks
165
+
166
+ `husky` v9 + `lint-staged` are wired. Hooks live in `.husky/`. The pre-commit hook runs `lint-staged`, which applies `eslint --fix` and `prettier --write` to staged files only. To skip once (rare): `git commit --no-verify`.