create-gufran-expo-app 2.0.0 → 2.0.1

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 (266) hide show
  1. package/lib/createApp.js +7 -2
  2. package/package.json +1 -1
  3. package/template/App.tsx +118 -0
  4. package/template/ReactotronConfig.js +5 -0
  5. package/template/android/app/build.gradle +184 -0
  6. package/template/android/app/debug.keystore +0 -0
  7. package/template/android/app/google-services.json +29 -0
  8. package/template/android/app/proguard-rules.pro +14 -0
  9. package/template/android/app/src/debug/AndroidManifest.xml +7 -0
  10. package/template/android/app/src/debugOptimized/AndroidManifest.xml +7 -0
  11. package/template/android/app/src/main/AndroidManifest.xml +28 -0
  12. package/template/android/app/src/main/assets/fonts/Outfit-Bold.ttf +0 -0
  13. package/template/android/app/src/main/assets/fonts/Outfit-Light.ttf +0 -0
  14. package/template/android/app/src/main/assets/fonts/Outfit-Medium.ttf +0 -0
  15. package/template/android/app/src/main/assets/fonts/Outfit-Regular.ttf +0 -0
  16. package/template/android/app/src/main/assets/fonts/Outfit-SemiBold.ttf +0 -0
  17. package/template/android/app/src/main/java/com/club/yakka/MainActivity.kt +61 -0
  18. package/template/android/app/src/main/java/com/club/yakka/MainApplication.kt +60 -0
  19. package/template/android/app/src/main/res/drawable/ic_launcher_background.xml +6 -0
  20. package/template/android/app/src/main/res/drawable/rn_edit_text_material.xml +37 -0
  21. package/template/android/app/src/main/res/drawable-hdpi/splashscreen_logo.png +0 -0
  22. package/template/android/app/src/main/res/drawable-mdpi/splashscreen_logo.png +0 -0
  23. package/template/android/app/src/main/res/drawable-xhdpi/splashscreen_logo.png +0 -0
  24. package/template/android/app/src/main/res/drawable-xxhdpi/splashscreen_logo.png +0 -0
  25. package/template/android/app/src/main/res/drawable-xxxhdpi/splashscreen_logo.png +0 -0
  26. package/template/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml +5 -0
  27. package/template/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml +5 -0
  28. package/template/android/app/src/main/res/mipmap-hdpi/ic_launcher.webp +0 -0
  29. package/template/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.webp +0 -0
  30. package/template/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp +0 -0
  31. package/template/android/app/src/main/res/mipmap-mdpi/ic_launcher.webp +0 -0
  32. package/template/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.webp +0 -0
  33. package/template/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp +0 -0
  34. package/template/android/app/src/main/res/mipmap-xhdpi/ic_launcher.webp +0 -0
  35. package/template/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.webp +0 -0
  36. package/template/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp +0 -0
  37. package/template/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp +0 -0
  38. package/template/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.webp +0 -0
  39. package/template/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp +0 -0
  40. package/template/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp +0 -0
  41. package/template/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.webp +0 -0
  42. package/template/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp +0 -0
  43. package/template/android/app/src/main/res/values/colors.xml +6 -0
  44. package/template/android/app/src/main/res/values/strings.xml +5 -0
  45. package/template/android/app/src/main/res/values/styles.xml +14 -0
  46. package/template/android/app/src/main/res/values-night/colors.xml +1 -0
  47. package/template/android/build.gradle +33 -0
  48. package/template/android/gradle/wrapper/gradle-wrapper.jar +0 -0
  49. package/template/android/gradle/wrapper/gradle-wrapper.properties +7 -0
  50. package/template/android/gradle.properties +65 -0
  51. package/template/android/gradlew +251 -0
  52. package/template/android/gradlew.bat +94 -0
  53. package/template/android/settings.gradle +39 -0
  54. package/template/app.json +69 -0
  55. package/template/assets/adaptive-icon.png +0 -0
  56. package/template/assets/adaptive-icon1.png +0 -0
  57. package/template/assets/app_icon.png +0 -0
  58. package/template/assets/favicon.png +0 -0
  59. package/template/assets/icon.png +0 -0
  60. package/template/assets/splash-icon.png +0 -0
  61. package/template/babel-plugin-disable-font-scaling.js +41 -0
  62. package/template/babel.config.js +28 -0
  63. package/template/firebase.json +5 -0
  64. package/template/index.ts +24 -0
  65. package/template/ios/.xcode.env +11 -0
  66. package/template/ios/ClubYakka/AppDelegate.swift +74 -0
  67. package/template/ios/ClubYakka/ClubYakka-Bridging-Header.h +3 -0
  68. package/template/ios/ClubYakka/ClubYakka.entitlements +8 -0
  69. package/template/ios/ClubYakka/GoogleService-Info.plist +30 -0
  70. package/template/ios/ClubYakka/Images.xcassets/AppIcon.appiconset/App-Icon-1024x1024@1x.png +0 -0
  71. package/template/ios/ClubYakka/Images.xcassets/AppIcon.appiconset/Contents.json +14 -0
  72. package/template/ios/ClubYakka/Images.xcassets/Contents.json +6 -0
  73. package/template/ios/ClubYakka/Images.xcassets/SplashScreenBackground.colorset/Contents.json +20 -0
  74. package/template/ios/ClubYakka/Images.xcassets/SplashScreenLegacy.imageset/Contents.json +23 -0
  75. package/template/ios/ClubYakka/Images.xcassets/SplashScreenLegacy.imageset/image.png +0 -0
  76. package/template/ios/ClubYakka/Images.xcassets/SplashScreenLegacy.imageset/image@2x.png +0 -0
  77. package/template/ios/ClubYakka/Images.xcassets/SplashScreenLegacy.imageset/image@3x.png +0 -0
  78. package/template/ios/ClubYakka/Info.plist +101 -0
  79. package/template/ios/ClubYakka/PrivacyInfo.xcprivacy +50 -0
  80. package/template/ios/ClubYakka/SplashScreen.storyboard +48 -0
  81. package/template/ios/ClubYakka/Supporting/Expo.plist +12 -0
  82. package/template/ios/ClubYakka.xcodeproj/project.pbxproj +669 -0
  83. package/template/ios/ClubYakka.xcodeproj/xcshareddata/xcschemes/ClubYakka.xcscheme +88 -0
  84. package/template/ios/ClubYakka.xcworkspace/contents.xcworkspacedata +10 -0
  85. package/template/ios/ClubYakka.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings +5 -0
  86. package/template/ios/Podfile +84 -0
  87. package/template/ios/Podfile.lock +2698 -0
  88. package/template/ios/Podfile.properties.json +8 -0
  89. package/template/metro.config.js +17 -0
  90. package/template/package.json +70 -0
  91. package/template/patches/react-native-background-upload+6.6.0.patch +704 -0
  92. package/template/react-native.config.js +7 -0
  93. package/template/src/assets/fonts/Outfit-Bold.ttf +0 -0
  94. package/template/src/assets/fonts/Outfit-Light.ttf +0 -0
  95. package/template/src/assets/fonts/Outfit-Medium.ttf +0 -0
  96. package/template/src/assets/fonts/Outfit-Regular.ttf +0 -0
  97. package/template/src/assets/fonts/Outfit-SemiBold.ttf +0 -0
  98. package/template/src/assets/icons/BG.svg +33 -0
  99. package/template/src/assets/icons/Ic_Users.svg +6 -0
  100. package/template/src/assets/icons/arrow-left-white.svg +4 -0
  101. package/template/src/assets/icons/arrow-left.svg +4 -0
  102. package/template/src/assets/icons/bell.svg +4 -0
  103. package/template/src/assets/icons/bottomSheetIcone.svg +3 -0
  104. package/template/src/assets/icons/call.svg +4 -0
  105. package/template/src/assets/icons/camera.svg +0 -0
  106. package/template/src/assets/icons/chatAppleGreenBG.svg +22 -0
  107. package/template/src/assets/icons/check.svg +4 -0
  108. package/template/src/assets/icons/check_Radio.svg +4 -0
  109. package/template/src/assets/icons/chevron-right.svg +3 -0
  110. package/template/src/assets/icons/clubDefauldImage.png +0 -0
  111. package/template/src/assets/icons/curvBackgroundView.svg +3 -0
  112. package/template/src/assets/icons/defaultClub.png +0 -0
  113. package/template/src/assets/icons/email.svg +3 -0
  114. package/template/src/assets/icons/emptyUser.svg +5 -0
  115. package/template/src/assets/icons/eye-Hide.svg +8 -0
  116. package/template/src/assets/icons/eye.svg +4 -0
  117. package/template/src/assets/icons/gallery.svg +4 -0
  118. package/template/src/assets/icons/home.svg +4 -0
  119. package/template/src/assets/icons/ic_Calendar.svg +14 -0
  120. package/template/src/assets/icons/ic_Calendar_blue.svg +12 -0
  121. package/template/src/assets/icons/ic_Calendar_white.svg +12 -0
  122. package/template/src/assets/icons/ic_Chat.svg +14 -0
  123. package/template/src/assets/icons/ic_ChatAppleGreen.svg +21 -0
  124. package/template/src/assets/icons/ic_ChatAppleWhite.svg +21 -0
  125. package/template/src/assets/icons/ic_Download.svg +6 -0
  126. package/template/src/assets/icons/ic_Events.svg +6 -0
  127. package/template/src/assets/icons/ic_HeadCoachIcon.svg +3 -0
  128. package/template/src/assets/icons/ic_Membership.svg +10 -0
  129. package/template/src/assets/icons/ic_Notification.svg +6 -0
  130. package/template/src/assets/icons/ic_Raffles.svg +14 -0
  131. package/template/src/assets/icons/ic_Referral_Members.svg +12 -0
  132. package/template/src/assets/icons/ic_Shop.svg +13 -0
  133. package/template/src/assets/icons/ic_Teams.svg +8 -0
  134. package/template/src/assets/icons/ic_Volunteer.svg +9 -0
  135. package/template/src/assets/icons/ic_add.svg +3 -0
  136. package/template/src/assets/icons/ic_addCircle.svg +5 -0
  137. package/template/src/assets/icons/ic_chatSend.svg +4 -0
  138. package/template/src/assets/icons/ic_chat_blue_bg.svg +22 -0
  139. package/template/src/assets/icons/ic_clock_blue.svg +4 -0
  140. package/template/src/assets/icons/ic_delete.svg +8 -0
  141. package/template/src/assets/icons/ic_more.svg +5 -0
  142. package/template/src/assets/icons/ic_mute.svg +10 -0
  143. package/template/src/assets/icons/ic_pdf.svg +3 -0
  144. package/template/src/assets/icons/ic_pending_AppleGreen.svg +11 -0
  145. package/template/src/assets/icons/ic_right_appleGreen.svg +11 -0
  146. package/template/src/assets/icons/ic_unread_chat_blue_bg.svg +23 -0
  147. package/template/src/assets/icons/ic_volunteer_Member.svg +8 -0
  148. package/template/src/assets/icons/index.ts +144 -0
  149. package/template/src/assets/icons/location-blue.svg +4 -0
  150. package/template/src/assets/icons/location-white.svg +4 -0
  151. package/template/src/assets/icons/location.svg +4 -0
  152. package/template/src/assets/icons/lock.svg +5 -0
  153. package/template/src/assets/icons/log-out.svg +5 -0
  154. package/template/src/assets/icons/login_logo.svg +9 -0
  155. package/template/src/assets/icons/mail.svg +4 -0
  156. package/template/src/assets/icons/or_saprater.svg +5 -0
  157. package/template/src/assets/icons/password.svg +4 -0
  158. package/template/src/assets/icons/profile-appleGreen.svg +6 -0
  159. package/template/src/assets/icons/search.svg +3 -0
  160. package/template/src/assets/icons/settings.svg +4 -0
  161. package/template/src/assets/icons/success.svg +4 -0
  162. package/template/src/assets/icons/unCheck_Radio.svg +3 -0
  163. package/template/src/assets/icons/uncheck.svg +3 -0
  164. package/template/src/assets/icons/upload_Image.svg +6 -0
  165. package/template/src/assets/icons/upload_Image_Member.svg +6 -0
  166. package/template/src/assets/icons/user.svg +4 -0
  167. package/template/src/assets/icons/wifi.svg +1 -0
  168. package/template/src/assets/images/Splash.png +0 -0
  169. package/template/src/assets/images/SplashLogo.png +0 -0
  170. package/template/src/assets/images/background.png +0 -0
  171. package/template/src/assets/images/clubDefauldImage.png +0 -0
  172. package/template/src/assets/images/index.tsx +9 -0
  173. package/template/src/assets/index.ts +1 -0
  174. package/template/src/components/common/AddMemberModal.tsx +543 -0
  175. package/template/src/components/common/AppLoader.tsx +91 -0
  176. package/template/src/components/common/Button.tsx +173 -0
  177. package/template/src/components/common/ClubCard.tsx +248 -0
  178. package/template/src/components/common/Icon.tsx +93 -0
  179. package/template/src/components/common/IconAlt.tsx +65 -0
  180. package/template/src/components/common/IconButton.tsx +92 -0
  181. package/template/src/components/common/ImagePicker.tsx +451 -0
  182. package/template/src/components/common/LoadingSpinner.tsx +30 -0
  183. package/template/src/components/common/OTPInput.tsx +128 -0
  184. package/template/src/components/common/ReminderCalendar.tsx +129 -0
  185. package/template/src/components/common/ReminderCardItem.tsx +91 -0
  186. package/template/src/components/common/SafeAreaWrapper.tsx +27 -0
  187. package/template/src/components/common/SetReminderModal.tsx +308 -0
  188. package/template/src/components/common/SlowInternet.js +57 -0
  189. package/template/src/components/common/TeamCard.tsx +297 -0
  190. package/template/src/components/common/TextInput.tsx +227 -0
  191. package/template/src/components/common/ToastConfig.tsx +103 -0
  192. package/template/src/components/common/ToastManager.ts +86 -0
  193. package/template/src/components/common/UploadProgressModal.tsx +284 -0
  194. package/template/src/components/common/WrapperContainer.tsx +39 -0
  195. package/template/src/components/common/index.ts +19 -0
  196. package/template/src/constants/Constants.tsx +7 -0
  197. package/template/src/constants/Fonts.tsx +30 -0
  198. package/template/src/constants/index.ts +45 -0
  199. package/template/src/constants/strings.ts +211 -0
  200. package/template/src/constants/theme.ts +72 -0
  201. package/template/src/contexts/AuthContext.tsx +268 -0
  202. package/template/src/contexts/index.ts +2 -0
  203. package/template/src/hooks/index.ts +3 -0
  204. package/template/src/hooks/useImageUpload.ts +199 -0
  205. package/template/src/index.ts +8 -0
  206. package/template/src/navigation/AuthStack.tsx +67 -0
  207. package/template/src/navigation/MainStack.tsx +183 -0
  208. package/template/src/navigation/MiddleStack.tsx +35 -0
  209. package/template/src/navigation/RootNavigator.tsx +101 -0
  210. package/template/src/navigation/index.ts +5 -0
  211. package/template/src/navigation/navigationRef.ts +5 -0
  212. package/template/src/providers/QueryProvider.tsx +30 -0
  213. package/template/src/screens/DetailsScreen.tsx +271 -0
  214. package/template/src/screens/HomeScreen.tsx +736 -0
  215. package/template/src/screens/ProfileScreen.tsx +202 -0
  216. package/template/src/screens/SettingsScreen.tsx +253 -0
  217. package/template/src/screens/SportHubScreen.tsx +280 -0
  218. package/template/src/screens/auth/AddMamber.tsx +428 -0
  219. package/template/src/screens/auth/ForgotPasswordScreen.tsx +176 -0
  220. package/template/src/screens/auth/LoginScreen.tsx +286 -0
  221. package/template/src/screens/auth/OTPVerifyScreen.tsx +359 -0
  222. package/template/src/screens/auth/RegisterScreen.tsx +430 -0
  223. package/template/src/screens/auth/SuccessScreen.tsx +201 -0
  224. package/template/src/screens/auth/WalcomeScreen.tsx +274 -0
  225. package/template/src/screens/auth/index.ts +8 -0
  226. package/template/src/screens/chat/ChatScreen.tsx +1819 -0
  227. package/template/src/screens/chat/ChatThreadsScreen.tsx +360 -0
  228. package/template/src/screens/chat/ReportMessageScreen.tsx +238 -0
  229. package/template/src/screens/clubs/Announcements.tsx +426 -0
  230. package/template/src/screens/clubs/BuyRaffleTicketsScreen.tsx +568 -0
  231. package/template/src/screens/clubs/ClubDeteils.tsx +497 -0
  232. package/template/src/screens/clubs/JoinClub.tsx +841 -0
  233. package/template/src/screens/events/EventScreen.tsx +460 -0
  234. package/template/src/screens/index.ts +42 -0
  235. package/template/src/screens/raffles/MyReferralMembersScreen.tsx +758 -0
  236. package/template/src/screens/raffles/RaffleDetailsScreen.tsx +762 -0
  237. package/template/src/screens/raffles/RafflesScreen.tsx +495 -0
  238. package/template/src/screens/raffles/SetRaffleReminderScreen.tsx +390 -0
  239. package/template/src/screens/teams/JoinTeamScreen.tsx +464 -0
  240. package/template/src/screens/teams/MyTeamDetailsScreen.tsx +979 -0
  241. package/template/src/screens/teams/MyTeamScreen.tsx +568 -0
  242. package/template/src/screens/teams/PendingRequestsScreen.tsx +426 -0
  243. package/template/src/screens/volunteerOpportunities/SetReminderScreen.tsx +631 -0
  244. package/template/src/screens/volunteerOpportunities/VolunteerOpportunitiesDetailsScreen.tsx +1049 -0
  245. package/template/src/screens/volunteerOpportunities/VolunteerOpportunitiesScreen.tsx +608 -0
  246. package/template/src/services/api.ts +167 -0
  247. package/template/src/services/authService.ts +422 -0
  248. package/template/src/services/index.ts +5 -0
  249. package/template/src/services/mainServices.ts +1963 -0
  250. package/template/src/stores/authStore.ts +159 -0
  251. package/template/src/stores/index.ts +2 -0
  252. package/template/src/types/index.ts +85 -0
  253. package/template/src/types/navigation.ts +206 -0
  254. package/template/src/utils/AzureUploaderService.ts +371 -0
  255. package/template/src/utils/ClubSearchManager.ts +222 -0
  256. package/template/src/utils/NotificationManager.ts +503 -0
  257. package/template/src/utils/UploadDebugUtil.ts +107 -0
  258. package/template/src/utils/imagePicker.ts +321 -0
  259. package/template/src/utils/index.ts +111 -0
  260. package/template/src/utils/permissions.ts +277 -0
  261. package/template/src/utils/scaling.ts +14 -0
  262. package/template/src/utils/storage.ts +247 -0
  263. package/template/src/utils/usePermissions.ts +275 -0
  264. package/template/src/utils/validation.ts +340 -0
  265. package/template/tsconfig.json +50 -0
  266. package/template/types/svg.d.ts +6 -0
@@ -0,0 +1,72 @@
1
+ import { Theme } from '../types';
2
+ import { moderateScale } from '../utils/scaling';
3
+
4
+ export const lightTheme: Theme = {
5
+ colors: {
6
+ primary: '#007AFF',
7
+ secondary: '#5856D6',
8
+ background: '#FFFFFF',
9
+ surface: '#F2F2F7',
10
+ text: '#000000',
11
+ textSecondary: '#8E8E93',
12
+ border: '#C6C6C8',
13
+ error: '#FF3B30',
14
+ success: '#34C759',
15
+ warning: '#FF9500',
16
+ blue: '#0047AB',
17
+ appleGreen: '#A7D129',
18
+ DarkGray: '#484848',
19
+ green: '#34C759',
20
+ white: '#FFFFFF',
21
+ black: '#000000',
22
+ lightLavenderGray: '#F4F7FB',
23
+ imageBorder: '#F1E9F9',
24
+ paraText: '#3E3E3E',
25
+ cancelButton: '#FB6A57',
26
+ red: '#ED0000',
27
+ },
28
+ spacing: {
29
+ xs: moderateScale(4),
30
+ sm: moderateScale(8),
31
+ md: moderateScale(16),
32
+ lg: moderateScale(24),
33
+ xl: moderateScale(32),
34
+ },
35
+ borderRadius: {
36
+ sm: moderateScale(4),
37
+ md: moderateScale(8),
38
+ lg: moderateScale(12),
39
+ xl: moderateScale(16),
40
+ xxl: moderateScale(30),
41
+ },
42
+ typography: {
43
+ fontSize: {
44
+ xs: moderateScale(12),
45
+ sm: moderateScale(14),
46
+ md: moderateScale(16),
47
+ lg: moderateScale(18),
48
+ xl: moderateScale(24),
49
+ xxl: moderateScale(32) ,
50
+ },
51
+ fontWeight: {
52
+ normal: '400',
53
+ medium: '500',
54
+ semibold: '600',
55
+ bold: '700',
56
+ },
57
+ },
58
+ };
59
+
60
+ export const darkTheme: Theme = {
61
+ ...lightTheme,
62
+ colors: {
63
+ ...lightTheme.colors,
64
+ background: '#000000',
65
+ surface: '#1C1C1E',
66
+ text: '#FFFFFF',
67
+ textSecondary: '#8E8E93',
68
+ border: '#38383A',
69
+ },
70
+ };
71
+
72
+ export const theme = lightTheme; // Default theme
@@ -0,0 +1,268 @@
1
+ import React, { createContext, useContext, useReducer, useEffect, ReactNode } from 'react';
2
+ import { User } from '../types';
3
+ import { StorageService } from '../utils';
4
+
5
+ // Auth State
6
+ interface AuthState {
7
+ isLoading: boolean;
8
+ isAuthenticated: boolean;
9
+ user: User | null;
10
+ token: string | null;
11
+ }
12
+
13
+ // Auth Actions
14
+ type AuthAction =
15
+ | { type: 'RESTORE_TOKEN'; token: string | null; user: User | null }
16
+ | { type: 'SIGN_IN'; token: string; user: User }
17
+ | { type: 'SIGN_OUT' }
18
+ | { type: 'SET_LOADING'; isLoading: boolean };
19
+
20
+ // Auth Context Type
21
+ interface AuthContextType extends AuthState {
22
+ login: (email: string, password: string) => Promise<boolean>;
23
+ register: (userData: RegisterData) => Promise<boolean>;
24
+ logout: () => Promise<void>;
25
+ updateUser: (userData: Partial<User>) => Promise<void>;
26
+ }
27
+
28
+ interface RegisterData {
29
+ firstName: string;
30
+ lastName: string;
31
+ email: string;
32
+ password: string;
33
+ }
34
+
35
+ // Initial state
36
+ const initialState: AuthState = {
37
+ isLoading: true,
38
+ isAuthenticated: false,
39
+ user: null,
40
+ token: null,
41
+ };
42
+
43
+ // Auth reducer
44
+ function authReducer(prevState: AuthState, action: AuthAction): AuthState {
45
+ switch (action.type) {
46
+ case 'RESTORE_TOKEN':
47
+ return {
48
+ ...prevState,
49
+ token: action.token,
50
+ user: action.user,
51
+ isAuthenticated: !!action.token,
52
+ isLoading: false,
53
+ };
54
+ case 'SIGN_IN':
55
+ return {
56
+ ...prevState,
57
+ isAuthenticated: true,
58
+ token: action.token,
59
+ user: action.user,
60
+ isLoading: false,
61
+ };
62
+ case 'SIGN_OUT':
63
+ return {
64
+ ...prevState,
65
+ isAuthenticated: false,
66
+ token: null,
67
+ user: null,
68
+ isLoading: false,
69
+ };
70
+ case 'SET_LOADING':
71
+ return {
72
+ ...prevState,
73
+ isLoading: action.isLoading,
74
+ };
75
+ default:
76
+ return prevState;
77
+ }
78
+ }
79
+
80
+ // Create context
81
+ const AuthContext = createContext<AuthContextType | undefined>(undefined);
82
+
83
+ // Auth Provider Component
84
+ interface AuthProviderProps {
85
+ children: ReactNode;
86
+ }
87
+
88
+ export const AuthProvider: React.FC<AuthProviderProps> = ({ children }) => {
89
+ const [state, dispatch] = useReducer(authReducer, initialState);
90
+
91
+ // Restore authentication state on app startup
92
+ useEffect(() => {
93
+ const restoreAuthState = () => {
94
+ try {
95
+ const token = StorageService.auth.getToken();
96
+ const user = StorageService.auth.getUser();
97
+
98
+ dispatch({ type: 'RESTORE_TOKEN', token: token || null, user: user || null });
99
+ } catch (error) {
100
+ console.error('Failed to restore auth state:', error);
101
+ dispatch({ type: 'RESTORE_TOKEN', token: null, user: null });
102
+ }
103
+ };
104
+
105
+ restoreAuthState();
106
+ }, []);
107
+
108
+ // Login function
109
+ const login = async (email: string, password: string): Promise<boolean> => {
110
+ try {
111
+ dispatch({ type: 'SET_LOADING', isLoading: true });
112
+
113
+ // Mock API call - replace with actual authentication API
114
+ const response = await mockAuthAPI.login(email, password);
115
+
116
+ if (response.success && response.data) {
117
+ const { token, user } = response.data;
118
+
119
+ // Store authentication data
120
+ StorageService.auth.setToken(token);
121
+ StorageService.auth.setUser(user);
122
+
123
+ dispatch({ type: 'SIGN_IN', token, user });
124
+ return true;
125
+ }
126
+
127
+ return false;
128
+ } catch (error) {
129
+ console.error('Login error:', error);
130
+ return false;
131
+ } finally {
132
+ dispatch({ type: 'SET_LOADING', isLoading: false });
133
+ }
134
+ };
135
+
136
+ // Register function
137
+ const register = async (userData: RegisterData): Promise<boolean> => {
138
+ try {
139
+ dispatch({ type: 'SET_LOADING', isLoading: true });
140
+
141
+ // Mock API call - replace with actual registration API
142
+ const response = await mockAuthAPI.register(userData);
143
+
144
+ if (response.success && response.data) {
145
+ const { token, user } = response.data;
146
+
147
+ // Store authentication data
148
+ StorageService.auth.setToken(token);
149
+ StorageService.auth.setUser(user);
150
+
151
+ dispatch({ type: 'SIGN_IN', token, user });
152
+ return true;
153
+ }
154
+
155
+ return false;
156
+ } catch (error) {
157
+ console.error('Registration error:', error);
158
+ return false;
159
+ } finally {
160
+ dispatch({ type: 'SET_LOADING', isLoading: false });
161
+ }
162
+ };
163
+
164
+ // Logout function
165
+ const logout = async (): Promise<void> => {
166
+ try {
167
+ // Clear stored authentication data
168
+ StorageService.auth.clearAuthData();
169
+
170
+ dispatch({ type: 'SIGN_OUT' });
171
+ } catch (error) {
172
+ console.error('Logout error:', error);
173
+ }
174
+ };
175
+
176
+ // Update user function
177
+ const updateUser = async (userData: Partial<User>): Promise<void> => {
178
+ try {
179
+ if (!state.user) return;
180
+
181
+ const updatedUser = { ...state.user, ...userData };
182
+
183
+ // Update stored user data
184
+ StorageService.auth.setUser(updatedUser);
185
+
186
+ // Update context state
187
+ dispatch({
188
+ type: 'SIGN_IN',
189
+ token: state.token!,
190
+ user: updatedUser
191
+ });
192
+ } catch (error) {
193
+ console.error('Update user error:', error);
194
+ }
195
+ };
196
+
197
+ const contextValue: AuthContextType = {
198
+ ...state,
199
+ login,
200
+ register,
201
+ logout,
202
+ updateUser,
203
+ };
204
+
205
+ return (
206
+ <AuthContext.Provider value={contextValue}>
207
+ {children}
208
+ </AuthContext.Provider>
209
+ );
210
+ };
211
+
212
+ // Custom hook to use auth context
213
+ export const useAuth = (): AuthContextType => {
214
+ const context = useContext(AuthContext);
215
+ if (context === undefined) {
216
+ throw new Error('useAuth must be used within an AuthProvider');
217
+ }
218
+ return context;
219
+ };
220
+
221
+ // Mock API for demonstration - replace with actual API calls
222
+ const mockAuthAPI = {
223
+ login: async (email: string, password: string) => {
224
+ // Simulate network delay
225
+ await new Promise(resolve => setTimeout(resolve, 1000));
226
+
227
+ // Mock successful login - in real app, validate against server
228
+ if (email === 'demo@example.com' && password === 'password123') {
229
+ return {
230
+ success: true,
231
+ data: {
232
+ token: 'mock-jwt-token-' + Date.now(),
233
+ user: {
234
+ id: '1',
235
+ name: 'Demo User',
236
+ email: email,
237
+ avatar: 'https://via.placeholder.com/100x100/007AFF/FFFFFF?text=DU',
238
+ createdAt: new Date('2023-01-01'),
239
+ updatedAt: new Date(),
240
+ },
241
+ },
242
+ };
243
+ }
244
+
245
+ return { success: false };
246
+ },
247
+
248
+ register: async (userData: RegisterData) => {
249
+ // Simulate network delay
250
+ await new Promise(resolve => setTimeout(resolve, 1000));
251
+
252
+ // Mock successful registration
253
+ return {
254
+ success: true,
255
+ data: {
256
+ token: 'mock-jwt-token-' + Date.now(),
257
+ user: {
258
+ id: Date.now().toString(),
259
+ name: `${userData.firstName} ${userData.lastName}`,
260
+ email: userData.email,
261
+ avatar: `https://via.placeholder.com/100x100/007AFF/FFFFFF?text=${userData.firstName[0]}${userData.lastName[0]}`,
262
+ createdAt: new Date(),
263
+ updatedAt: new Date(),
264
+ },
265
+ },
266
+ };
267
+ },
268
+ };
@@ -0,0 +1,2 @@
1
+ // AuthContext has been replaced with Zustand store
2
+ // export * from './AuthContext';
@@ -0,0 +1,3 @@
1
+ export { useImageUpload } from './useImageUpload';
2
+ export type { UploadState, UseImageUploadOptions } from './useImageUpload';
3
+
@@ -0,0 +1,199 @@
1
+ import { useState, useCallback } from 'react';
2
+ import { AzureUploadService, UploadResult } from '../utils/AzureUploaderService';
3
+ import { ImagePickerResult } from '../utils/imagePicker';
4
+ import { apiClient, API_ENDPOINTS } from '../services/api';
5
+
6
+ export interface UploadState {
7
+ isUploading: boolean;
8
+ progress: number;
9
+ error: string | null;
10
+ uploadedUrl: string | null;
11
+ isRetrying: boolean;
12
+ retryCount: number;
13
+ }
14
+
15
+ export interface UseImageUploadOptions {
16
+ containerName?: string;
17
+ maxRetries?: number;
18
+ retryDelay?: number;
19
+ onUploadStart?: () => void;
20
+ onUploadProgress?: (progress: number) => void;
21
+ onUploadSuccess?: (url: string) => void;
22
+ onUploadError?: (error: string) => void;
23
+ onUploadComplete?: () => void;
24
+ }
25
+
26
+ export const useImageUpload = (options: UseImageUploadOptions = {}) => {
27
+ const {
28
+ containerName = 'profile',
29
+ maxRetries = 3,
30
+ retryDelay = 1000,
31
+ onUploadStart,
32
+ onUploadProgress,
33
+ onUploadSuccess,
34
+ onUploadError,
35
+ onUploadComplete,
36
+ } = options;
37
+
38
+ const [uploadState, setUploadState] = useState<UploadState>({
39
+ isUploading: false,
40
+ progress: 0,
41
+ error: null,
42
+ uploadedUrl: null,
43
+ isRetrying: false,
44
+ retryCount: 0,
45
+ });
46
+
47
+ const resetUploadState = useCallback(() => {
48
+ setUploadState({
49
+ isUploading: false,
50
+ progress: 0,
51
+ error: null,
52
+ uploadedUrl: null,
53
+ isRetrying: false,
54
+ retryCount: 0,
55
+ });
56
+ }, []);
57
+
58
+ const uploadImage = useCallback(async (imageResult: ImagePickerResult): Promise<UploadResult> => {
59
+ try {
60
+ setUploadState(prev => ({
61
+ ...prev,
62
+ isUploading: true,
63
+ progress: 0,
64
+ error: null,
65
+ retryCount: 0,
66
+ }));
67
+
68
+ onUploadStart?.();
69
+
70
+ // Step 1: Get SAS token
71
+ console.log('Getting SAS token for image upload...',imageResult?.fileName );
72
+ const response = await apiClient.post(API_ENDPOINTS.AUTH.UPLOAD_SAS, {
73
+ containerName,
74
+ blobName: imageResult?.fileName || `image_${Date.now()}.jpg`,
75
+ });
76
+
77
+ if (response?.status !== 200) {
78
+ throw new Error(response?.data?.message || 'Failed to get upload token');
79
+ }
80
+
81
+ const sasToken = response?.data?.data?.sasUrl;
82
+ const blobUrl = response?.data?.data?.blobUrl;
83
+
84
+ if (!sasToken) {
85
+ throw new Error('Invalid response from upload token API');
86
+ }
87
+
88
+ // If blobUrl is not provided, derive it from sasUrl
89
+ const finalBlobUrl = blobUrl || sasToken.split('?')[0];
90
+
91
+ console.log('SAS token received, starting upload...');
92
+
93
+ // Step 2: Upload file with retry mechanism
94
+ const uploadResult = await AzureUploadService.uploadFileWithRetry({
95
+ fileUri: imageResult.uri,
96
+ sasUrl: sasToken,
97
+ blobUrl: finalBlobUrl,
98
+ options: {
99
+ maxRetries,
100
+ retryDelay,
101
+ },
102
+ onProgress: (progress) => {
103
+ setUploadState(prev => ({ ...prev, progress }));
104
+ onUploadProgress?.(progress);
105
+ },
106
+ onComplete: (url) => {
107
+ setUploadState(prev => ({
108
+ ...prev,
109
+ uploadedUrl: url,
110
+ isUploading: false,
111
+ progress: 100,
112
+ }));
113
+ onUploadSuccess?.(url);
114
+ },
115
+ onError: (error) => {
116
+ setUploadState(prev => ({
117
+ ...prev,
118
+ error: error.message,
119
+ isUploading: false,
120
+ }));
121
+ onUploadError?.(error.message);
122
+ },
123
+ onCancelled: () => {
124
+ setUploadState(prev => ({
125
+ ...prev,
126
+ isUploading: false,
127
+ error: 'Upload was cancelled',
128
+ }));
129
+ onUploadError?.('Upload was cancelled');
130
+ },
131
+ });
132
+
133
+ onUploadComplete?.();
134
+ return uploadResult;
135
+
136
+ } catch (error: any) {
137
+ console.error('Image upload error:', error);
138
+ const errorMessage = error?.message || 'Upload failed';
139
+
140
+ setUploadState(prev => ({
141
+ ...prev,
142
+ isUploading: false,
143
+ error: errorMessage,
144
+ }));
145
+
146
+ onUploadError?.(errorMessage);
147
+ onUploadComplete?.();
148
+
149
+ return {
150
+ success: false,
151
+ error: errorMessage,
152
+ };
153
+ }
154
+ }, [
155
+ containerName,
156
+ maxRetries,
157
+ retryDelay,
158
+ onUploadStart,
159
+ onUploadProgress,
160
+ onUploadSuccess,
161
+ onUploadError,
162
+ onUploadComplete,
163
+ ]);
164
+
165
+ const retryUpload = useCallback(async (imageResult: ImagePickerResult): Promise<UploadResult> => {
166
+ setUploadState(prev => ({
167
+ ...prev,
168
+ isRetrying: true,
169
+ retryCount: prev.retryCount + 1,
170
+ error: null,
171
+ }));
172
+
173
+ const result = await uploadImage(imageResult);
174
+
175
+ setUploadState(prev => ({
176
+ ...prev,
177
+ isRetrying: false,
178
+ }));
179
+
180
+ return result;
181
+ }, [uploadImage]);
182
+
183
+ const cancelUpload = useCallback(() => {
184
+ setUploadState(prev => ({
185
+ ...prev,
186
+ isUploading: false,
187
+ error: 'Upload cancelled by user',
188
+ }));
189
+ onUploadError?.('Upload cancelled by user');
190
+ }, [onUploadError]);
191
+
192
+ return {
193
+ uploadState,
194
+ uploadImage,
195
+ retryUpload,
196
+ cancelUpload,
197
+ resetUploadState,
198
+ };
199
+ };
@@ -0,0 +1,8 @@
1
+ // Main entry point for the src folder
2
+ export * from './components/common';
3
+ export * from './constants';
4
+ export * from './contexts';
5
+ export * from './navigation';
6
+ export * from './screens';
7
+ export * from './types';
8
+ export * from './utils';
@@ -0,0 +1,67 @@
1
+ import React from 'react';
2
+ import { createNativeStackNavigator } from '@react-navigation/native-stack';
3
+ import { AuthStackParamList } from '../types';
4
+ import { LoginScreen, RegisterScreen, ForgotPasswordScreen, OTPVerifyScreen, WelcomeScreen } from '../screens/auth';
5
+ import { theme } from '../constants';
6
+ import { StorageService } from '../utils/storage';
7
+ import SuccessScreen from '../screens/auth/SuccessScreen';
8
+
9
+ const Stack = createNativeStackNavigator<AuthStackParamList>();
10
+
11
+ export const AuthStack: React.FC = () => {
12
+ // Check if welcome screen has been shown before
13
+ const hasWelcomeScreenBeenShown = StorageService.preferences.getWelcomeScreenShown();
14
+
15
+ // Set initial route based on whether welcome screen has been shown
16
+ const initialRouteName = hasWelcomeScreenBeenShown ? 'Login' : 'Welcome';
17
+
18
+ return (
19
+ <Stack.Navigator
20
+ id={undefined}
21
+ initialRouteName={initialRouteName}
22
+ screenOptions={{
23
+ headerShown: false,
24
+ headerStyle: {
25
+ backgroundColor: theme.colors.background,
26
+ },
27
+ headerTintColor: theme.colors.text,
28
+ headerTitleStyle: {
29
+ fontWeight: theme.typography.fontWeight.semibold,
30
+ fontSize: theme.typography.fontSize.lg,
31
+ },
32
+ headerBackTitle: '',
33
+ animation: 'fade',
34
+ headerShadowVisible: false,
35
+ }}
36
+ >
37
+ <Stack.Screen
38
+ name="Welcome"
39
+ component={WelcomeScreen}
40
+
41
+ />
42
+ <Stack.Screen
43
+ name="Login"
44
+ component={LoginScreen}
45
+
46
+ />
47
+ <Stack.Screen
48
+ name="Register"
49
+ component={RegisterScreen}
50
+
51
+ />
52
+ <Stack.Screen
53
+ name="ForgotPassword"
54
+ component={ForgotPasswordScreen}
55
+
56
+ />
57
+ <Stack.Screen
58
+ name="OTPVerify"
59
+ component={OTPVerifyScreen}
60
+ />
61
+ <Stack.Screen
62
+ name="Success"
63
+ component={SuccessScreen}
64
+ />
65
+ </Stack.Navigator>
66
+ );
67
+ };