new-react-native-boilerplate 0.0.0-stage → 1.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 (227) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +329 -2
  3. package/package.json +49 -4
  4. package/run.sh +36 -0
  5. package/setup.js +141 -0
  6. package/template/.bundle/config +2 -0
  7. package/template/.editorconfig +14 -0
  8. package/template/.eslintrc.js +49 -0
  9. package/template/.husky/commit-msg +4 -0
  10. package/template/.husky/pre-commit +1 -0
  11. package/template/.prettierrc.js +6 -0
  12. package/template/.watchmanconfig +1 -0
  13. package/template/Gemfile +17 -0
  14. package/template/Gemfile.lock +114 -0
  15. package/template/README.md +101 -0
  16. package/template/__tests__/App.test.tsx +13 -0
  17. package/template/__tests__/CustomTextInput.test.jsx +29 -0
  18. package/template/android/app/build.gradle +119 -0
  19. package/template/android/app/debug.keystore +0 -0
  20. package/template/android/app/proguard-rules.pro +10 -0
  21. package/template/android/app/src/main/AndroidManifest.xml +27 -0
  22. package/template/android/app/src/main/assets/fonts/Poppins-Bold.ttf +0 -0
  23. package/template/android/app/src/main/assets/fonts/Poppins-Medium.ttf +0 -0
  24. package/template/android/app/src/main/assets/fonts/Poppins-Regular.ttf +0 -0
  25. package/template/android/app/src/main/assets/fonts/Poppins-SemiBold.ttf +0 -0
  26. package/template/android/app/src/main/assets/fonts/futura_book.otf +0 -0
  27. package/template/android/app/src/main/assets/fonts/futura_medium.otf +0 -0
  28. package/template/android/app/src/main/java/com/boilerplatereactnative/MainActivity.kt +22 -0
  29. package/template/android/app/src/main/java/com/boilerplatereactnative/MainApplication.kt +27 -0
  30. package/template/android/app/src/main/res/drawable/rn_edit_text_material.xml +37 -0
  31. package/template/android/app/src/main/res/mipmap-hdpi/ic_launcher.png +0 -0
  32. package/template/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png +0 -0
  33. package/template/android/app/src/main/res/mipmap-mdpi/ic_launcher.png +0 -0
  34. package/template/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png +0 -0
  35. package/template/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png +0 -0
  36. package/template/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png +0 -0
  37. package/template/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png +0 -0
  38. package/template/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png +0 -0
  39. package/template/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png +0 -0
  40. package/template/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png +0 -0
  41. package/template/android/app/src/main/res/values/strings.xml +3 -0
  42. package/template/android/app/src/main/res/values/styles.xml +9 -0
  43. package/template/android/build.gradle +21 -0
  44. package/template/android/gradle/wrapper/gradle-wrapper.jar +0 -0
  45. package/template/android/gradle/wrapper/gradle-wrapper.properties +7 -0
  46. package/template/android/gradle.properties +49 -0
  47. package/template/android/gradlew +248 -0
  48. package/template/android/gradlew.bat +98 -0
  49. package/template/android/link-assets-manifest.json +29 -0
  50. package/template/android/settings.gradle +6 -0
  51. package/template/app.json +4 -0
  52. package/template/babel.config.js +43 -0
  53. package/template/eslint.config.mjs +175 -0
  54. package/template/index.d.ts +1 -0
  55. package/template/index.js +10 -0
  56. package/template/ios/.xcode.env +11 -0
  57. package/template/ios/BoilerPlateReactNative/AppDelegate.swift +11 -0
  58. package/template/ios/BoilerPlateReactNative/Images.xcassets/AppIcon.appiconset/Contents.json +53 -0
  59. package/template/ios/BoilerPlateReactNative/Images.xcassets/Contents.json +6 -0
  60. package/template/ios/BoilerPlateReactNative/Info.plist +102 -0
  61. package/template/ios/BoilerPlateReactNative/LaunchScreen.storyboard +47 -0
  62. package/template/ios/BoilerPlateReactNative/PrivacyInfo.xcprivacy +37 -0
  63. package/template/ios/BoilerPlateReactNative/SceneDelegate.swift +54 -0
  64. package/template/ios/BoilerPlateReactNative.xcodeproj/project.pbxproj +531 -0
  65. package/template/ios/BoilerPlateReactNative.xcodeproj/xcshareddata/xcschemes/BoilerPlateReactNative.xcscheme +88 -0
  66. package/template/ios/BoilerPlateReactNative.xcworkspace/contents.xcworkspacedata +10 -0
  67. package/template/ios/BoilerPlateReactNative.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -0
  68. package/template/ios/Podfile +34 -0
  69. package/template/ios/Podfile.lock +2552 -0
  70. package/template/ios/link-assets-manifest.json +29 -0
  71. package/template/jest.config.js +13 -0
  72. package/template/jest.setup.js +30 -0
  73. package/template/metro.config.js +15 -0
  74. package/template/package.json +88 -0
  75. package/template/plugins/compile-js/_prompts.js +6 -0
  76. package/template/plugins/compile-js/index.js +9 -0
  77. package/template/plugins/compile-js/plugin.js +103 -0
  78. package/template/plugins/compile-js/tsconfig.build.json +20 -0
  79. package/template/plugins/index.js +46 -0
  80. package/template/plugins/printSuccess/_prompts.js +1 -0
  81. package/template/plugins/printSuccess/index.js +9 -0
  82. package/template/plugins/printSuccess/plugin.js +40 -0
  83. package/template/react-native.config.js +7 -0
  84. package/template/src/App.tsx +27 -0
  85. package/template/src/assets/fonts/Poppins-Bold.ttf +0 -0
  86. package/template/src/assets/fonts/Poppins-Medium.ttf +0 -0
  87. package/template/src/assets/fonts/Poppins-Regular.ttf +0 -0
  88. package/template/src/assets/fonts/Poppins-SemiBold.ttf +0 -0
  89. package/template/src/assets/fonts/futura_book.otf +0 -0
  90. package/template/src/assets/fonts/futura_medium.otf +0 -0
  91. package/template/src/assets/images/check.png +0 -0
  92. package/template/src/assets/images/check@2x.png +0 -0
  93. package/template/src/assets/images/check@3x.png +0 -0
  94. package/template/src/assets/images/email.png +0 -0
  95. package/template/src/assets/images/email@2x.png +0 -0
  96. package/template/src/assets/images/email@3x.png +0 -0
  97. package/template/src/assets/images/icBack.png +0 -0
  98. package/template/src/assets/images/icBack@2x.png +0 -0
  99. package/template/src/assets/images/icBack@3x.png +0 -0
  100. package/template/src/assets/images/icClose.png +0 -0
  101. package/template/src/assets/images/icClose@2x.png +0 -0
  102. package/template/src/assets/images/icClose@3x.png +0 -0
  103. package/template/src/assets/images/icComment.png +0 -0
  104. package/template/src/assets/images/icComment@2x.png +0 -0
  105. package/template/src/assets/images/icComment@3x.png +0 -0
  106. package/template/src/assets/images/icLike.png +0 -0
  107. package/template/src/assets/images/icLike@2x.png +0 -0
  108. package/template/src/assets/images/icLike@3x.png +0 -0
  109. package/template/src/assets/images/icSearch.png +0 -0
  110. package/template/src/assets/images/icSearch@2x.png +0 -0
  111. package/template/src/assets/images/icSearch@3x.png +0 -0
  112. package/template/src/assets/images/icSetting.png +0 -0
  113. package/template/src/assets/images/icSetting@2x.png +0 -0
  114. package/template/src/assets/images/icSetting@3x.png +0 -0
  115. package/template/src/assets/images/icShare.png +0 -0
  116. package/template/src/assets/images/icShare@2x.png +0 -0
  117. package/template/src/assets/images/icShare@3x.png +0 -0
  118. package/template/src/assets/images/line.png +0 -0
  119. package/template/src/assets/images/line@2x.png +0 -0
  120. package/template/src/assets/images/line@3x.png +0 -0
  121. package/template/src/assets/images/lock.png +0 -0
  122. package/template/src/assets/images/lock@2x.png +0 -0
  123. package/template/src/assets/images/lock@3x.png +0 -0
  124. package/template/src/assets/images/notification.png +0 -0
  125. package/template/src/assets/images/notification@2x.png +0 -0
  126. package/template/src/assets/images/notification@3x.png +0 -0
  127. package/template/src/assets/images/oct_dark.png +0 -0
  128. package/template/src/assets/images/oct_light.png +0 -0
  129. package/template/src/assets/images/onboard.png +0 -0
  130. package/template/src/assets/images/password_hide.png +0 -0
  131. package/template/src/assets/images/password_hide@2x.png +0 -0
  132. package/template/src/assets/images/password_hide@3x.png +0 -0
  133. package/template/src/assets/images/password_show.png +0 -0
  134. package/template/src/assets/images/password_show@2x.png +0 -0
  135. package/template/src/assets/images/password_show@3x.png +0 -0
  136. package/template/src/assets/images/right_arrow.png +0 -0
  137. package/template/src/assets/images/right_arrow@2x.png +0 -0
  138. package/template/src/assets/images/right_arrow@3x.png +0 -0
  139. package/template/src/assets/images/star.png +0 -0
  140. package/template/src/assets/images/star@2x.png +0 -0
  141. package/template/src/assets/images/star@3x.png +0 -0
  142. package/template/src/assets/images/uncheck.png +0 -0
  143. package/template/src/assets/images/uncheck@2x.png +0 -0
  144. package/template/src/assets/images/uncheck@3x.png +0 -0
  145. package/template/src/assets/images/user.png +0 -0
  146. package/template/src/assets/images/user@2x.png +0 -0
  147. package/template/src/assets/images/user@3x.png +0 -0
  148. package/template/src/components/atoms/ButtonContainer.tsx +52 -0
  149. package/template/src/components/atoms/ImageContainer.tsx +10 -0
  150. package/template/src/components/atoms/RemoteImage.tsx +8 -0
  151. package/template/src/components/atoms/RoundImageBorder.tsx +35 -0
  152. package/template/src/components/atoms/TextContainer.tsx +38 -0
  153. package/template/src/components/atoms/WrapperContainer.tsx +43 -0
  154. package/template/src/components/atoms/index.ts +6 -0
  155. package/template/src/components/molecules/AuthHeader.tsx +55 -0
  156. package/template/src/components/molecules/CustomTextInput.tsx +102 -0
  157. package/template/src/components/molecules/EmptyComp.tsx +16 -0
  158. package/template/src/components/molecules/ErrorComp.tsx +25 -0
  159. package/template/src/components/molecules/FooterView.tsx +41 -0
  160. package/template/src/components/molecules/HeaderComp.tsx +51 -0
  161. package/template/src/components/molecules/HomeHeader.tsx +63 -0
  162. package/template/src/components/molecules/HomeListHeader.tsx +48 -0
  163. package/template/src/components/molecules/HomeListItems.tsx +86 -0
  164. package/template/src/components/molecules/Loader.tsx +25 -0
  165. package/template/src/components/molecules/ModalSheet.tsx +146 -0
  166. package/template/src/components/molecules/RememberMe.tsx +58 -0
  167. package/template/src/components/molecules/SearchBar.tsx +46 -0
  168. package/template/src/components/molecules/index.ts +12 -0
  169. package/template/src/constants/apiConstant.ts +12 -0
  170. package/template/src/constants/fontFamily.ts +8 -0
  171. package/template/src/constants/imagePath.ts +25 -0
  172. package/template/src/constants/index.ts +3 -0
  173. package/template/src/constants/storageKeys.ts +5 -0
  174. package/template/src/models/ApiErrorResponse.ts +19 -0
  175. package/template/src/models/HomeData.ts +17 -0
  176. package/template/src/models/User.ts +11 -0
  177. package/template/src/navigations/AuthStack.tsx +20 -0
  178. package/template/src/navigations/MainStack.tsx +19 -0
  179. package/template/src/navigations/Routes.tsx +22 -0
  180. package/template/src/navigations/navigationProps.ts +8 -0
  181. package/template/src/redux/hooks.ts +10 -0
  182. package/template/src/redux/reducers/auth.ts +43 -0
  183. package/template/src/redux/reducers/common.ts +24 -0
  184. package/template/src/redux/reducers/index.ts +31 -0
  185. package/template/src/redux/reducers/product.ts +37 -0
  186. package/template/src/redux/reducers/settings.ts +55 -0
  187. package/template/src/redux/store.ts +19 -0
  188. package/template/src/redux/types.ts +6 -0
  189. package/template/src/screens/Home/Home.tsx +65 -0
  190. package/template/src/screens/Login/Login.tsx +35 -0
  191. package/template/src/screens/Login/components/LoginForm.tsx +88 -0
  192. package/template/src/screens/Login/hooks/useLogin.ts +38 -0
  193. package/template/src/screens/Login/styles.ts +17 -0
  194. package/template/src/screens/Login/types.ts +10 -0
  195. package/template/src/screens/Onboarding/Onboarding.tsx +87 -0
  196. package/template/src/screens/Onboarding/styles.ts +25 -0
  197. package/template/src/screens/PostDetails/PostDetails.tsx +168 -0
  198. package/template/src/screens/PostDetails/styles.ts +82 -0
  199. package/template/src/screens/Signup/Signup.tsx +32 -0
  200. package/template/src/screens/Signup/components/SignupForm.tsx +113 -0
  201. package/template/src/screens/Signup/hooks/useSignup.ts +38 -0
  202. package/template/src/screens/Signup/styles.ts +18 -0
  203. package/template/src/screens/Signup/type.ts +12 -0
  204. package/template/src/screens/index.ts +5 -0
  205. package/template/src/services/apiService.ts +144 -0
  206. package/template/src/services/authService.ts +79 -0
  207. package/template/src/services/productService.ts +45 -0
  208. package/template/src/services/statusHandler.ts +17 -0
  209. package/template/src/styles/breakpoints.ts +11 -0
  210. package/template/src/styles/themes.ts +45 -0
  211. package/template/src/styles/unistyles.ts +25 -0
  212. package/template/src/translations/ar.json +47 -0
  213. package/template/src/translations/en.json +47 -0
  214. package/template/src/translations/fr.json +47 -0
  215. package/template/src/translations/index.ts +32 -0
  216. package/template/src/typings/env.d.ts +5 -0
  217. package/template/src/typings/global.d.ts +3 -0
  218. package/template/src/utils/handleLocalStorage.ts +31 -0
  219. package/template/src/utils/i18nHelpers.ts +20 -0
  220. package/template/src/utils/index.ts +66 -0
  221. package/template/src/utils/scaling.ts +13 -0
  222. package/template/src/utils/themeHelpers.ts +10 -0
  223. package/template/src/utils/validationForm.ts +23 -0
  224. package/template/src/utils/validations.ts +69 -0
  225. package/template/tsconfig.json +22 -0
  226. package/template/yarn.lock +7728 -0
  227. package/template.config.js +6 -0
@@ -0,0 +1,82 @@
1
+ import fontFamily from "@constants/fontFamily";
2
+ import {
3
+ height,
4
+ moderateScale,
5
+ scale,
6
+ verticalScale,
7
+ width
8
+ } from "@utils/scaling";
9
+ import { createStyleSheet } from "react-native-unistyles";
10
+
11
+ const stylesheet = createStyleSheet((theme) => ({
12
+ btnStyle: {
13
+ backgroundColor: theme.colors.white,
14
+ borderRadius: moderateScale(10),
15
+ height: moderateScale(34),
16
+ minWidth: moderateScale(96)
17
+ },
18
+ btnTextStyle: {
19
+ color: theme.colors.black,
20
+ fontFamily: fontFamily.medium,
21
+ fontSize: scale(14)
22
+ },
23
+ commentBtn: {
24
+ borderRadius: moderateScale(10),
25
+ height: moderateScale(34),
26
+ minWidth: moderateScale(96)
27
+ },
28
+ containerView: {
29
+ borderTopLeftRadius: moderateScale(34),
30
+ borderTopRightRadius: moderateScale(34),
31
+ marginTop: verticalScale(-26),
32
+ paddingHorizontal: moderateScale(16)
33
+ },
34
+ descTextStyle: {
35
+ color: theme.colors.opacity50,
36
+ fontSize: scale(14)
37
+ },
38
+ flexView: {
39
+ alignItems: "center",
40
+ flex: 0.3,
41
+ flexDirection: "row"
42
+ },
43
+ followUs: {
44
+ color: theme.colors.white,
45
+ fontFamily: fontFamily.semiBold,
46
+ fontSize: scale(18)
47
+ },
48
+ headerLine: {
49
+ alignSelf: "center",
50
+ borderRadius: moderateScale(12),
51
+ height: moderateScale(2),
52
+ marginVertical: verticalScale(14),
53
+ width: moderateScale(42)
54
+ },
55
+
56
+ headerTextStyle: {
57
+ fontFamily: fontFamily.semiBold,
58
+ fontSize: scale(20)
59
+ },
60
+ imageStyle: {
61
+ justifyContent: "space-between",
62
+ minHeight: height / 2.5,
63
+ paddingBottom: verticalScale(40),
64
+ paddingHorizontal: moderateScale(28),
65
+ width
66
+ },
67
+ likeCommentView: {
68
+ alignItems: "center",
69
+ flexDirection: "row",
70
+ justifyContent: "space-between",
71
+ marginTop: verticalScale(14)
72
+ },
73
+ rectangleBox: {
74
+ backgroundColor: "#B3C680",
75
+ borderRadius: moderateScale(18),
76
+ flexDirection: "row",
77
+ minHeight: moderateScale(85),
78
+ paddingHorizontal: moderateScale(30),
79
+ paddingVertical: verticalScale(18)
80
+ }
81
+ }));
82
+ export default stylesheet;
@@ -0,0 +1,32 @@
1
+ import {WrapperContainer} from '@components/atoms';
2
+ import AuthHeader from '@components/molecules/AuthHeader';
3
+ import React from 'react';
4
+ import {View} from 'react-native';
5
+ import {KeyboardAwareScrollView} from 'react-native-keyboard-aware-scroll-view';
6
+ import {useStyles} from 'react-native-unistyles';
7
+ import SignupForm from './components/SignupForm';
8
+ import useSignup from './hooks/useSignup';
9
+ import stylesheet from './styles';
10
+ import {FooterView} from '@components/molecules';
11
+
12
+ function Signup(): React.JSX.Element {
13
+ // Signup hidden action and effect implementation from the screen
14
+ const {onGoBack} = useSignup();
15
+
16
+ // Stylesheet declaration
17
+ const {styles} = useStyles(stylesheet);
18
+
19
+ return (
20
+ <WrapperContainer>
21
+ <KeyboardAwareScrollView>
22
+ <View style={styles.container}>
23
+ <AuthHeader description="WELCOME_PLEASE_ENTER_YOUR_DETAILS" title="CREATE_AN_ACCOUNT" />
24
+ <SignupForm />
25
+ </View>
26
+ </KeyboardAwareScrollView>
27
+ <FooterView linkPress={onGoBack} linkText="LOGIN" simpleText="ALREADY_HAVE_ACCOUNT" />
28
+ </WrapperContainer>
29
+ );
30
+ }
31
+
32
+ export default Signup;
@@ -0,0 +1,113 @@
1
+ import CustomButton from '@components/atoms/ButtonContainer';
2
+ import {CustomTextInput} from '@components/molecules';
3
+ import RememberMe from '@components/molecules/RememberMe';
4
+ import imagePath from '@constants/imagePath';
5
+ import {useDispatch, useSelector} from '@redux/hooks';
6
+ import {alertFunction} from '@utils/index';
7
+ import {verticalScale} from '@utils/scaling';
8
+ import validationForm from '@utils/validationForm';
9
+ import {Formik} from 'formik';
10
+ import React, {createRef, Fragment, useCallback, useRef, useState} from 'react';
11
+ import type {TextInputInstance} from 'react-native';
12
+ import {Keyboard} from 'react-native';
13
+ import {signup} from 'src/services/authService';
14
+
15
+ // Form field reference declaration
16
+ const inputRef = {
17
+ email: createRef<TextInputInstance>(),
18
+ password: createRef<TextInputInstance>(),
19
+ };
20
+
21
+ const SignupForm = (): React.JSX.Element => {
22
+ // Redux variables
23
+ const dispatch = useDispatch();
24
+ const isLoading = useSelector(state => state.common.isLoading);
25
+
26
+ // Reference Variableș
27
+ const signupFormRef = useRef(null);
28
+
29
+ // Local state declaration
30
+ const [secureTextEntry, setSecureTextEntry] = useState(true);
31
+
32
+ // Signup button callback
33
+ const onSignup = useCallback(
34
+ async ({email, name, password}: {email: string; name: string; password: string}) => {
35
+ dispatch(signup({email, name, password}));
36
+ },
37
+ [dispatch],
38
+ );
39
+
40
+ return (
41
+ <Formik
42
+ initialValues={{
43
+ email: '',
44
+ name: '',
45
+ password: '',
46
+ }}
47
+ innerRef={signupFormRef}
48
+ onSubmit={onSignup}
49
+ validationSchema={validationForm.signup}>
50
+ {({...params}) => {
51
+ return (
52
+ <Fragment>
53
+ <CustomTextInput
54
+ error={params.touched.name ? params.errors.name : null}
55
+ id="name"
56
+ label="NAME"
57
+ leftImage={imagePath.icUser}
58
+ onBlur={params.handleBlur('name')}
59
+ onChangeText={params.handleChange('name')}
60
+ onSubmitEditing={() => inputRef.email.current?.focus()}
61
+ placeholder="ENTER_YOUR_NAME"
62
+ returnKeyType="next"
63
+ style={{marginBottom: verticalScale(24)}}
64
+ value={params.values.name}
65
+ />
66
+ <CustomTextInput
67
+ autoCapitalize="none"
68
+ autoCorrect={false}
69
+ error={params.touched.email ? params.errors.email : null}
70
+ id="email"
71
+ keyboardType="email-address"
72
+ label="EMAIL"
73
+ leftImage={imagePath.icEmail}
74
+ onBlur={params.handleBlur('email')}
75
+ onChangeText={params.handleChange('email')}
76
+ onSubmitEditing={() => inputRef.password.current?.focus()}
77
+ placeholder="ENTER_YOUR_EMAIL"
78
+ ref={inputRef.email}
79
+ returnKeyType="next"
80
+ style={{marginBottom: verticalScale(24)}}
81
+ value={params.values.email}
82
+ />
83
+ <CustomTextInput
84
+ error={params.touched.password ? params.errors.password : null}
85
+ id="password"
86
+ label="PASSWORD"
87
+ leftImage={imagePath.icLock}
88
+ onBlur={params.handleBlur('password')}
89
+ onChangeText={params.handleChange('password')}
90
+ onPressRight={() => setSecureTextEntry(!secureTextEntry)}
91
+ onSubmitEditing={() => Keyboard.dismiss()}
92
+ placeholder="ENTER_YOUR_PASSWORD"
93
+ ref={inputRef.password}
94
+ returnKeyType="done"
95
+ rightImage={secureTextEntry ? imagePath.icPassword : imagePath.icPasswordShow}
96
+ secureTextEntry={secureTextEntry}
97
+ style={{marginBottom: verticalScale(24)}}
98
+ value={params.values.password}
99
+ />
100
+ <RememberMe onPressForgot={() => alertFunction('Password', 'Forgot Password')} />
101
+ <CustomButton
102
+ isLoading={isLoading}
103
+ label="SIGNUP"
104
+ onPress={() => params.handleSubmit()}
105
+ />
106
+ </Fragment>
107
+ );
108
+ }}
109
+ </Formik>
110
+ );
111
+ };
112
+
113
+ export default SignupForm;
@@ -0,0 +1,38 @@
1
+ import type { AuthStackParamList } from '@navigations/AuthStack';
2
+ import type { NavigationProp} from '@react-navigation/native';
3
+ import { useNavigation } from '@react-navigation/native';
4
+ import { useDispatch, useSelector } from '@redux/hooks';
5
+ import { hasError } from '@redux/reducers/auth';
6
+ import { alertFunction } from '@utils/index';
7
+ import { useCallback, useEffect } from 'react';
8
+ import { Platform, ToastAndroid } from 'react-native';
9
+
10
+ // Custom Signup hook
11
+ const useSignup = () => {
12
+ // Navigation variable declaration
13
+ const navigation = useNavigation<NavigationProp<AuthStackParamList>>();
14
+
15
+ // Redux variables
16
+ const dispatch = useDispatch();
17
+ const error = useSelector(state => state.auth.error);
18
+
19
+ const onGoBack = useCallback(() => {
20
+ navigation.goBack();
21
+ }, [navigation]);
22
+
23
+ // Effects
24
+ useEffect(() => {
25
+ if (error?.message) {
26
+ if (Platform.OS === 'android') {
27
+ ToastAndroid.show(error.message, ToastAndroid.SHORT);
28
+ } else {
29
+ alertFunction(error.message, '', false, onGoBack);
30
+ }
31
+ dispatch(hasError(new Error('')));
32
+ }
33
+ }, [dispatch, error, onGoBack]);
34
+
35
+ return {onGoBack};
36
+ };
37
+
38
+ export default useSignup;
@@ -0,0 +1,18 @@
1
+ import { moderateScale } from "@utils/scaling";
2
+ import { createStyleSheet } from "react-native-unistyles";
3
+
4
+ // no user before defined
5
+ const stylesheet = createStyleSheet(() => ({
6
+ container: {
7
+ flex: 1,
8
+ marginHorizontal: moderateScale(16),
9
+ },
10
+ flexRow: {
11
+ alignItems: 'center',
12
+ flexDirection: 'row',
13
+ justifyContent: 'space-between',
14
+ marginBottom: moderateScale(24),
15
+ },
16
+ }));
17
+
18
+ export default stylesheet;
@@ -0,0 +1,12 @@
1
+ import type { User } from "@models/User";
2
+
3
+ export interface SignupRequestData {
4
+ email: string,
5
+ name: string;
6
+ password: string;
7
+ username: string
8
+ }
9
+
10
+ export default interface SignupResponse {
11
+ data: User;
12
+ }
@@ -0,0 +1,5 @@
1
+ export { default as Home } from './Home/Home';
2
+ export { default as Login } from './Login/Login';
3
+ export { default as Onboarding } from './Onboarding/Onboarding';
4
+ export { default as PostDetails } from './PostDetails/PostDetails';
5
+ export { default as Signup } from './Signup/Signup';
@@ -0,0 +1,144 @@
1
+ /* eslint-disable @typescript-eslint/no-explicit-any, no-console */
2
+ import API_CONSTANT, { BASE_URL } from "@constants/apiConstant";
3
+ import storageKeys from "@constants/storageKeys";
4
+ import type { ExtendedApiErrorResponse } from "@models/ApiErrorResponse";
5
+ import type { User } from "@models/User";
6
+ import type { LocalStorage } from "@typings/global";
7
+ import axios from "axios";
8
+ import { MMKV } from "react-native-mmkv";
9
+ import { refreshToken } from "./authService";
10
+ import { isTokenExpired } from "@utils/index";
11
+
12
+ export const storage = new MMKV();
13
+
14
+ interface PostOptions {
15
+ cancelToken?: any; // Adjust the type as per your requirements
16
+ }
17
+
18
+ const api = axios.create({
19
+ baseURL: BASE_URL, // Replace with your API base URL,
20
+ headers: {
21
+ Accept: 'Application/json',
22
+ 'Content-Type': 'application/json',
23
+ },
24
+ timeout: 10_000 // Set a timeout for requests (in milliseconds)
25
+ });
26
+
27
+ const handleApiError = (error: ExtendedApiErrorResponse) => {
28
+ console.log("here error", error);
29
+ if (error.response) {
30
+ switch (error.axiosError?.status) {
31
+ case 401: {
32
+ // handle your unauthorized error here
33
+ return { ...error.response, error: error.message };
34
+ }
35
+ default: {
36
+ if (!error) {
37
+ return { error: "Unknown error" };
38
+ }
39
+
40
+ if (error.response && error.response.data.error && !error.message) {
41
+ return {
42
+ ...error.response,
43
+ error: error.response.data.error || "Network Error"
44
+ };
45
+ }
46
+
47
+ if (error.response && error.response.data) {
48
+ return error.response.data;
49
+ }
50
+
51
+ return { error: `${error.message}` };
52
+ }
53
+ }
54
+ }
55
+ return { error: error.message }
56
+ }
57
+
58
+ // Axios interceptor to add Authorization header before each request
59
+ api.interceptors.request.use(async config => {
60
+ // Add the Authorization header if a token is present
61
+ const userData = getItem(storageKeys.USER_DATA);
62
+ let token = userData?.accessToken;
63
+ if (userData) {
64
+ const isExpired = isTokenExpired(token || null);
65
+ console.log("isExpired.....", isExpired);
66
+ if (
67
+ isExpired &&
68
+ !config.url?.includes(API_CONSTANT.refreshToken)
69
+ ) {
70
+ await refreshToken();
71
+ token = getItem(storageKeys.USER_DATA)?.accessToken || '';
72
+ }
73
+ if(token){
74
+ config.headers.Authorization = `Bearer ${token}`;
75
+ }else{
76
+ throw new Error("Authorization failed");
77
+ }
78
+ }
79
+ return config;
80
+ }, (error) => {
81
+ return Promise.reject(error);
82
+ });
83
+
84
+ export const get = async (endpoint: string, params = {}) => {
85
+ try {
86
+ const response = await api.get(endpoint, { params });
87
+ return response.data;
88
+ } catch (error: any) {
89
+ throw handleApiError(error);
90
+ }
91
+ };
92
+
93
+ export const post = async (
94
+ endpoint: string,
95
+ data = {},
96
+ options?: PostOptions
97
+ ) => {
98
+ try {
99
+ const response = await api.post(endpoint, data, options);
100
+ return response.data;
101
+ } catch (error: any) {
102
+ throw handleApiError(error);
103
+ }
104
+ };
105
+
106
+ export const put = async (endpoint: string, data = {}, options?: PostOptions) => {
107
+ try {
108
+ const response = await api.put(endpoint, data, options);
109
+ return response.data;
110
+ } catch (error: any) {
111
+ throw handleApiError(error);
112
+ }
113
+ };
114
+
115
+ export const remove = async (endpoint: string) => {
116
+ try {
117
+ const response = await api.delete(endpoint);
118
+ return response.data;
119
+ } catch (error: any) {
120
+ throw handleApiError(error);
121
+ }
122
+ };
123
+
124
+ export const setItem = (key: LocalStorage, value: any) => {
125
+ storage.set(key, JSON.stringify(value));
126
+ };
127
+
128
+ export const getItem = <T = User>(key: LocalStorage): null | T => {
129
+ const jsonUser = storage.getString(key);
130
+ if (jsonUser) {
131
+ try {
132
+ const userObject = JSON.parse(jsonUser) as T;
133
+ return userObject;
134
+ } catch (error) {
135
+ console.log("Error parsing user data:", error);
136
+ return null;
137
+ }
138
+ } else {
139
+ console.log("No data found for the key:", key);
140
+ return null;
141
+ }
142
+ };
143
+
144
+ export const clearAllItem = () => storage.clearAll();
@@ -0,0 +1,79 @@
1
+ /* eslint-disable no-console */
2
+ import API_CONSTANT from "@constants/apiConstant";
3
+ import storageKeys from "@constants/storageKeys";
4
+ import { hasError, saveUserData } from "@redux/reducers/auth";
5
+ import { setLoading } from "@redux/reducers/common";
6
+ import type { AppDispatch } from "@redux/store";
7
+ import store from "@redux/store";
8
+ import { getItem, post, setItem } from "./apiService";
9
+
10
+ // Login authentication API
11
+ const login = (authCred: {password: string; username: string,}) => async (dispatch: AppDispatch) => {
12
+ try {
13
+ dispatch(setLoading(true));
14
+ const response = await post(API_CONSTANT.login, authCred);
15
+ if (response) {
16
+ dispatch(saveUserData(response));
17
+ setItem(storageKeys.USER_DATA, response);
18
+ } else {
19
+ console.info(response.data.message);
20
+ dispatch(hasError(new Error(response.data.message)));
21
+ }
22
+ } catch (error) {
23
+ console.error(error);
24
+ dispatch(hasError(error as Error));
25
+ } finally {
26
+ dispatch(setLoading(false));
27
+ }
28
+ };
29
+
30
+
31
+ // Signup authentication API
32
+ const signup = (details: {email: string, name: string, password: string}) => async (dispatch: AppDispatch) => {
33
+ try {
34
+ dispatch(setLoading(true));
35
+ const response = await post(API_CONSTANT.register, details);
36
+ if (response.status == 200) {
37
+ if (response.success) {
38
+ dispatch(saveUserData(response));
39
+ } else {
40
+ console.info(response.message);
41
+ dispatch(hasError(new Error(response?.message)));
42
+ }
43
+ } else {
44
+ console.info(response?.message);
45
+ dispatch(hasError(new Error(response?.message)));
46
+ }
47
+ } catch (error) {
48
+ console.error(error);
49
+ dispatch(hasError(error as Error));
50
+ } finally {
51
+ dispatch(setLoading(false));
52
+ }
53
+ };
54
+
55
+
56
+ // Refresh Token API
57
+ const refreshToken = async () => {
58
+ const dispatch = store.dispatch;
59
+ try {
60
+ const userData = getItem(storageKeys.USER_DATA);
61
+ const currentRefreshToken = userData?.refreshToken;
62
+ dispatch(setLoading(true));
63
+ const response = await post(API_CONSTANT.refreshToken, {
64
+ refreshToken: currentRefreshToken,
65
+ });
66
+ if (response.success) {
67
+ setItem(storageKeys.USER_DATA, response);
68
+ dispatch(saveUserData(response));
69
+ } else {
70
+ dispatch(hasError(response.message));
71
+ }
72
+ } catch (error) {
73
+ dispatch(hasError(error as Error));
74
+ } finally {
75
+ dispatch(setLoading(false));
76
+ }
77
+ };
78
+
79
+ export { login, refreshToken, signup };
@@ -0,0 +1,45 @@
1
+ /* eslint-disable no-console */
2
+ import API_CONSTANT from "@constants/apiConstant";
3
+ import { hasError } from "@redux/reducers/auth";
4
+ import { setLoading } from "@redux/reducers/common";
5
+ import { setProductDetail, setProducts } from "@redux/reducers/product";
6
+ import type { AppDispatch } from "@redux/store";
7
+ import { get } from "./apiService";
8
+
9
+ // Products get API
10
+ const getProduct = (limit: number) => async (dispatch: AppDispatch) => {
11
+ try {
12
+ dispatch(setLoading(true));
13
+ const response = await get(`${API_CONSTANT.product}?limit=${limit}`);
14
+ if (response.products) {
15
+ dispatch(setProducts(response.products));
16
+ } else {
17
+ console.info(response?.message);
18
+ }
19
+ } catch (error) {
20
+ console.error(error);
21
+ dispatch(hasError(error as Error));
22
+ } finally {
23
+ dispatch(setLoading(false));
24
+ }
25
+ };
26
+
27
+ // Products details get API
28
+ const getProductDetails = (productId: number) => async (dispatch: AppDispatch) => {
29
+ try {
30
+ dispatch(setLoading(true));
31
+ const response = await get(`${API_CONSTANT.product}/${productId}`);
32
+ if (response) {
33
+ dispatch(setProductDetail(response));
34
+ } else {
35
+ console.info(response?.message);
36
+ }
37
+ } catch (error) {
38
+ console.error(error);
39
+ dispatch(hasError(error as Error));
40
+ } finally {
41
+ dispatch(setLoading(false));
42
+ }
43
+ };
44
+
45
+ export { getProduct, getProductDetails };
@@ -0,0 +1,17 @@
1
+
2
+ import type { AxiosError } from "axios";
3
+
4
+ const statusHandler = (err: AxiosError) => {
5
+ if (err.response) {
6
+ switch (err.response.status) {
7
+ case 401: {
8
+ // handle your unauthorized error here
9
+ break;
10
+ }
11
+ default: {
12
+ }
13
+ }
14
+ }
15
+ };
16
+
17
+ export default statusHandler;
@@ -0,0 +1,11 @@
1
+ const breakpoints = {
2
+ lg: 992,
3
+ md: 768,
4
+ sm: 576,
5
+ superLarge: 2000,
6
+ tvLike: 4000,
7
+ xl: 1200,
8
+ xs: 0,
9
+ } as const;
10
+
11
+ export default breakpoints;
@@ -0,0 +1,45 @@
1
+ const constantsColors = {
2
+ black: "#000000",
3
+ blue: "#001EB9",
4
+ danger: "#dc3545",
5
+ grey: "#B0B0B0",
6
+ light: "#f8f9fa",
7
+ white: "#ffffff",
8
+ };
9
+ export const lightTheme = {
10
+ colors: {
11
+ ...constantsColors,
12
+ background: "#ffffff",
13
+ barStyle: "dark-content",
14
+ darkwhite: "#000000",
15
+ opacity50: "rgba(1,1,1,0.5)",
16
+ placeholder: "rgba(1,1,1,0.52)",
17
+ textInputColor: "rgba(217, 217, 217,0.2)",
18
+ typography: "#000000",
19
+ },
20
+ margins: {
21
+ lg: 8,
22
+ md: 4,
23
+ sm: 2,
24
+ xl: 12,
25
+ },
26
+ } as const;
27
+
28
+ export const darkTheme = {
29
+ colors: {
30
+ ...constantsColors,
31
+ background: "#000000",
32
+ barStyle: "light-content",
33
+ darkwhite: "#ffffff",
34
+ opacity50: "rgba(201, 201, 201,0.5)",
35
+ placeholder: "#f8f9fa",
36
+ textInputColor: "#000000",
37
+ typography: "#ffffff",
38
+ },
39
+ margins: {
40
+ lg: 8,
41
+ md: 4,
42
+ sm: 2,
43
+ xl: 12,
44
+ },
45
+ } as const;
@@ -0,0 +1,25 @@
1
+ import { UnistylesRegistry } from "react-native-unistyles";
2
+ import breakpoints from "./breakpoints";
3
+ import { darkTheme, lightTheme } from "./themes";
4
+
5
+ type AppBreakpoints = typeof breakpoints;
6
+ type AppThemes = {
7
+ dark: typeof darkTheme;
8
+ light: typeof lightTheme;
9
+ };
10
+
11
+ declare module "react-native-unistyles" {
12
+ /* eslint-disable @typescript-eslint/no-empty-object-type -- official unistyles v2 module augmentation pattern */
13
+ export interface UnistylesBreakpoints extends AppBreakpoints {}
14
+ export interface UnistylesThemes extends AppThemes {}
15
+ /* eslint-enable @typescript-eslint/no-empty-object-type */
16
+ }
17
+
18
+ UnistylesRegistry.addBreakpoints(breakpoints)
19
+ .addThemes({
20
+ dark: darkTheme,
21
+ light: lightTheme,
22
+ })
23
+ .addConfig({
24
+ adaptiveThemes: true,
25
+ });