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,86 @@
1
+
2
+
3
+ import { TextContainer } from "@components/atoms";
4
+ import RemoteImage from "@components/atoms/RemoteImage";
5
+ import fontFamily from "@constants/fontFamily";
6
+ import type { ProductsData } from "@models/HomeData";
7
+ import type { HomeStackParamList } from "@navigations/MainStack";
8
+ import type { NavigationProp } from "@react-navigation/native";
9
+ import { moderateScale, scale, verticalScale } from "@utils/scaling";
10
+ import React, { memo } from "react";
11
+ import { Pressable, View } from "react-native";
12
+ import { createStyleSheet, useStyles } from "react-native-unistyles";
13
+
14
+ const stylesheet = createStyleSheet((theme) => ({
15
+ container: {
16
+ alignItems: "center",
17
+ flexDirection: "row",
18
+ marginHorizontal: moderateScale(16),
19
+ },
20
+ flexRow: {
21
+ alignItems: "center",
22
+ flexDirection: "row",
23
+ justifyContent: "space-between",
24
+ },
25
+ imageStyle: {
26
+ borderRadius: moderateScale(10),
27
+ height: moderateScale(20),
28
+ marginRight: moderateScale(4),
29
+ width: moderateScale(20),
30
+ },
31
+ profileImage: {
32
+ backgroundColor: theme.colors.grey,
33
+ borderRadius: moderateScale(24),
34
+ height: moderateScale(134),
35
+ marginRight: moderateScale(16),
36
+ width: moderateScale(134),
37
+ },
38
+ textStyle: {
39
+ color: theme.colors.opacity50,
40
+ fontSize: scale(12),
41
+ },
42
+ }));
43
+
44
+ interface HomeListItemsProps {
45
+ item: ProductsData;
46
+ navigation: NavigationProp<HomeStackParamList>;
47
+ }
48
+
49
+ const HomeListItems: React.FC<HomeListItemsProps> = memo(({ item, navigation }) => {
50
+ const { styles } = useStyles(stylesheet);
51
+ return (
52
+ <Pressable
53
+ onPress={() => navigation.navigate("PostDetails", { productId: item.id })}
54
+ style={styles.container}
55
+ >
56
+ <RemoteImage source={{ uri: item.thumbnail }} style={styles.profileImage} />
57
+
58
+ <View style={{ flex: 1 }}>
59
+ <TextContainer isDynamicText style={{ fontSize: scale(12) }} text={item.title} />
60
+ <TextContainer
61
+ isDynamicText
62
+ numberOfLines={2}
63
+ style={{
64
+ fontFamily: fontFamily.medium,
65
+ marginVertical: verticalScale(6),
66
+ }}
67
+ text={item.description}
68
+ />
69
+ <View style={styles.flexRow}>
70
+ <View style={{ alignItems: "center", flex: 1, flexDirection: "row" }}>
71
+ <RemoteImage
72
+ source={{
73
+ uri: "https://www.profilebakery.com/wp-content/uploads/2023/03/AI-Profile-Picture.jpg",
74
+ }}
75
+ style={styles.imageStyle}
76
+ />
77
+ <TextContainer isDynamicText style={styles.textStyle} text="Regulators" />
78
+ </View>
79
+ <TextContainer isDynamicText style={styles.textStyle} text="June 14 2023" />
80
+ </View>
81
+ </View>
82
+ </Pressable>
83
+ );
84
+ });
85
+
86
+ export default HomeListItems;
@@ -0,0 +1,25 @@
1
+ import { WrapperContainer } from "@components/atoms";
2
+ import React from "react";
3
+ import { ActivityIndicator, View } from "react-native";
4
+ import { createStyleSheet, useStyles } from "react-native-unistyles";
5
+
6
+ const stylesheet = createStyleSheet(() => ({
7
+ container: {
8
+ alignItems: "center",
9
+ flex: 1,
10
+ justifyContent: "center",
11
+ },
12
+ }));
13
+
14
+ const Loader = (): React.JSX.Element => {
15
+ const { styles } = useStyles(stylesheet);
16
+ return (
17
+ <WrapperContainer isSafeAreaView={false}>
18
+ <View style={styles.container}>
19
+ <ActivityIndicator size="large" />
20
+ </View>
21
+ </WrapperContainer>
22
+ );
23
+ };
24
+
25
+ export default React.memo(Loader);
@@ -0,0 +1,146 @@
1
+ import {ImageContainer, TextContainer} from '@components/atoms';
2
+ import fontFamily from '@constants/fontFamily';
3
+ import imagePath from '@constants/imagePath';
4
+ import {useDispatch, useSelector} from '@redux/hooks';
5
+ import types from '@redux/types';
6
+ import changeLanguage from '@utils/i18nHelpers';
7
+ import {moderateScale, verticalScale} from '@utils/scaling';
8
+ import changeTheme from '@utils/themeHelpers';
9
+ import type {ReactNode} from 'react';
10
+ import React, { forwardRef, useImperativeHandle, useState} from 'react';
11
+ import type { ModalProps} from 'react-native';
12
+ import {Modal, Pressable, Switch, View} from 'react-native';
13
+ import {createStyleSheet, UnistylesRuntime, useStyles} from 'react-native-unistyles';
14
+ import {storage} from 'src/services/apiService';
15
+
16
+ const stylesheet = createStyleSheet(theme => ({
17
+ container: {
18
+ backgroundColor: theme.colors.background,
19
+ borderTopLeftRadius: moderateScale(24),
20
+ borderTopRightRadius: moderateScale(24),
21
+ elevation: 5,
22
+ marginTop: 'auto',
23
+ minHeight: '25%',
24
+ paddingHorizontal: moderateScale(16),
25
+ paddingVertical: moderateScale(8),
26
+ shadowColor: theme.colors.background,
27
+ shadowOffset: {
28
+ height: 2,
29
+ width: 0,
30
+ },
31
+ shadowOpacity: 0.25,
32
+ shadowRadius: 3.84,
33
+ },
34
+ headerView: {
35
+ flexDirection: 'row',
36
+ justifyContent: 'space-between',
37
+ },
38
+ horizontalLine: {
39
+ alignSelf: 'center',
40
+ backgroundColor: theme.colors.opacity50,
41
+ borderRadius: moderateScale(8),
42
+ height: moderateScale(6),
43
+ width: moderateScale(80),
44
+ },
45
+ logoutText: {
46
+ color: theme.colors.danger,
47
+ fontFamily: fontFamily.semiBold,
48
+ },
49
+ modalView: {
50
+ flexDirection: 'row',
51
+ justifyContent: 'space-between',
52
+ marginTop: verticalScale(8),
53
+ },
54
+ textStyle: (isSelected: boolean) => ({
55
+ color: isSelected ? theme.colors.danger : theme.colors.typography,
56
+ fontFamily: isSelected ? fontFamily.semiBold : fontFamily.regular,
57
+ }),
58
+ }));
59
+
60
+ interface ModalSheetProps extends ModalProps {
61
+ children?: ReactNode;
62
+ }
63
+
64
+ export interface ModalSheetRef {
65
+ toggleSheet: () => void;
66
+ }
67
+
68
+ const ModalSheet = forwardRef<ModalSheetRef, ModalSheetProps>((props, ref) => {
69
+ const [isVisible, setVisible] = useState(false);
70
+ const {defaultLanguage, languages} = useSelector(state => state.settings);
71
+
72
+ const isDarkMode = UnistylesRuntime.themeName === 'dark';
73
+ const dispatch = useDispatch();
74
+ const {styles} = useStyles(stylesheet);
75
+
76
+ useImperativeHandle(ref, () => ({
77
+ toggleSheet: () => {
78
+ setVisible(!isVisible);
79
+ },
80
+ }));
81
+
82
+ const onPressLogout = () => {
83
+ setVisible(!isVisible);
84
+ setTimeout(() => {
85
+ // need time to close modal
86
+ storage.clearAll();
87
+ dispatch({type: types.CLEAR_REDUX_STATE});
88
+ }, 800);
89
+ };
90
+
91
+ return (
92
+ <Modal animationType="slide" transparent visible={isVisible} {...props}>
93
+ <View style={styles.container}>
94
+ <View style={styles.headerView}>
95
+ <View />
96
+ <View style={styles.horizontalLine} />
97
+ <Pressable onPress={() => setVisible(!isVisible)}>
98
+ <ImageContainer source={imagePath.icClose} />
99
+ </Pressable>
100
+ </View>
101
+ <>
102
+ <View style={styles.modalView}>
103
+ <View>
104
+ <TextContainer
105
+ style={{
106
+ fontFamily: fontFamily.semiBold,
107
+ }}
108
+ text="CHANGE_LANGUAGE"
109
+ />
110
+ {languages.map(val => (
111
+ <Pressable
112
+ key={String(val.sortName)}
113
+ onPress={() => changeLanguage(val)}
114
+ style={{
115
+ marginTop: verticalScale(8),
116
+ }}>
117
+ <TextContainer
118
+ isDynamicText
119
+ style={styles.textStyle(defaultLanguage.sortName === val.sortName)}
120
+ text={val.name}
121
+ />
122
+ </Pressable>
123
+ ))}
124
+ </View>
125
+ <View>
126
+ <TextContainer style={{fontFamily: fontFamily.semiBold}} text="CHANGE_THEME" />
127
+ <Switch
128
+ onChange={() => changeTheme(isDarkMode ? 'light' : 'dark')}
129
+ style={{
130
+ alignSelf: 'flex-end',
131
+ marginVertical: verticalScale(8),
132
+ }}
133
+ value={isDarkMode}
134
+ />
135
+ </View>
136
+ </View>
137
+ <Pressable style={{alignSelf: 'center', marginVertical: verticalScale(16)}}>
138
+ <TextContainer onPress={onPressLogout} style={styles.logoutText} text="LOGOUT" />
139
+ </Pressable>
140
+ </>
141
+ </View>
142
+ </Modal>
143
+ );
144
+ });
145
+
146
+ export default React.memo(ModalSheet);
@@ -0,0 +1,58 @@
1
+ import { ImageContainer, TextContainer } from "@components/atoms";
2
+ import fontFamily from "@constants/fontFamily";
3
+ import imagePath from "@constants/imagePath";
4
+ import { moderateScale, scale, verticalScale } from "@utils/scaling";
5
+ import React, { useState } from "react";
6
+ import type { PropsWithChildren } from "react";
7
+ import { Pressable, View } from "react-native";
8
+ import { createStyleSheet, useStyles } from "react-native-unistyles";
9
+
10
+ const stylesheet = createStyleSheet(() => ({
11
+ flexRow: {
12
+ alignItems: "center",
13
+ flexDirection: "row",
14
+ justifyContent: "space-between",
15
+ marginBottom: verticalScale(24),
16
+ },
17
+
18
+ headerStyle: {
19
+ alignItems: "center",
20
+ flexDirection: "row",
21
+ marginBottom: verticalScale(32),
22
+ },
23
+ textStyle: {
24
+ fontFamily: fontFamily.medium,
25
+ fontSize: scale(12),
26
+ opacity: 0.6,
27
+ },
28
+ }));
29
+
30
+ type SectionProps = PropsWithChildren<{
31
+ onPressForgot: () => void;
32
+ }>;
33
+
34
+ const RememberMe = ({ onPressForgot }: SectionProps): React.JSX.Element => {
35
+ const [rememberMe, setRememberMe] = useState<boolean>(false);
36
+ const { styles } = useStyles(stylesheet);
37
+ return (
38
+ <View style={styles.flexRow}>
39
+ <Pressable
40
+ onPress={() => setRememberMe(!rememberMe)}
41
+ style={{ alignItems: "center", flexDirection: "row" }}
42
+ >
43
+ <ImageContainer
44
+ resizeMode="contain"
45
+ source={rememberMe ? imagePath.icCheck : imagePath.icUnchek}
46
+ style={{
47
+ height: moderateScale(14),
48
+ marginRight: moderateScale(12),
49
+ width: moderateScale(14),
50
+ }}
51
+ />
52
+ <TextContainer style={styles.textStyle} text="REMEBER_ME" />
53
+ </Pressable>
54
+ <TextContainer onPress={onPressForgot} style={styles.textStyle} text="FORGOT_PASSWORD" />
55
+ </View>
56
+ );
57
+ };
58
+ export default React.memo(RememberMe);
@@ -0,0 +1,46 @@
1
+ import { ImageContainer, TextContainer } from "@components/atoms";
2
+ import fontFamily from "@constants/fontFamily";
3
+ import imagePath from "@constants/imagePath";
4
+ import { moderateScale, scale } from "@utils/scaling";
5
+ import type { PropsWithChildren } from "react";
6
+ import React from "react";
7
+ import type { TextStyle, ViewStyle } from "react-native";
8
+ import { View } from "react-native";
9
+ import { createStyleSheet, useStyles } from "react-native-unistyles";
10
+
11
+ const stylesheet = createStyleSheet((theme) => ({
12
+ container: {
13
+ alignItems: "center",
14
+ borderColor: theme.colors.opacity50,
15
+ borderRadius: moderateScale(36),
16
+ borderWidth: moderateScale(1.2),
17
+ flexDirection: "row",
18
+ height: moderateScale(56),
19
+ paddingHorizontal: moderateScale(12),
20
+ },
21
+ titleStyle: {
22
+ color: theme.colors.opacity50,
23
+ fontFamily: fontFamily.regular,
24
+ fontSize: scale(14),
25
+ marginLeft: moderateScale(16),
26
+ },
27
+ }));
28
+
29
+ type SectionProps = PropsWithChildren<{
30
+ style?: ViewStyle;
31
+ textStyle?: TextStyle;
32
+ title: string;
33
+ }>;
34
+
35
+ const SearchBar = ({ style, textStyle, title }: SectionProps): React.JSX.Element => {
36
+ const { styles } = useStyles(stylesheet);
37
+
38
+ return (
39
+ <View style={[styles.container, style]}>
40
+ <ImageContainer source={imagePath.icSearch} />
41
+ <TextContainer style={[styles.titleStyle, textStyle]} text={title} />
42
+ </View>
43
+ );
44
+ };
45
+
46
+ export default React.memo(SearchBar);
@@ -0,0 +1,12 @@
1
+ export { default as AuthHeader } from "./AuthHeader";
2
+ export { default as CustomTextInput } from "./CustomTextInput";
3
+ export { default as EmptyComp } from "./EmptyComp";
4
+ export { default as ErrorComp } from "./ErrorComp";
5
+ export { default as FooterView } from "./FooterView";
6
+ export { default as HeaderComp } from "./HeaderComp";
7
+ export { default as HomeHeader } from "./HomeHeader";
8
+ export { default as HomeListItems } from "./HomeListItems";
9
+ export { default as Loader } from "./Loader";
10
+ export { default as ModalSheet } from "./ModalSheet";
11
+ export { default as RememberMe } from "./RememberMe";
12
+ export { default as SearchBar } from "./SearchBar";
@@ -0,0 +1,12 @@
1
+ import {BASE_API_URL} from "@env";
2
+
3
+ export const BASE_URL = BASE_API_URL;
4
+
5
+ const API_CONSTANT = {
6
+ login: "auth/login",
7
+ product: "/products",
8
+ refreshToken: "auth/refreshToken",
9
+ register: "users/add",
10
+ };
11
+
12
+ export default API_CONSTANT;
@@ -0,0 +1,8 @@
1
+ export default {
2
+ bold: "Poppins-Bold",
3
+ futuraBook: "Futura-Book",
4
+ futuraRegular: "Futura",
5
+ medium: "Poppins-Medium",
6
+ regular: "Poppins-Regular",
7
+ semiBold: "Poppins-SemiBold",
8
+ };
@@ -0,0 +1,25 @@
1
+ /* eslint-disable @typescript-eslint/no-require-imports -- require() is the idiomatic way to load static image assets in React Native */
2
+ export default {
3
+ icBack: require("@assets/images/icBack.png"),
4
+ icCheck: require("@assets/images/check.png"),
5
+ icClose: require("@assets/images/icClose.png"),
6
+ icComment: require("@assets/images/icComment.png"),
7
+ icDarkOct: require("@assets/images/oct_dark.png"),
8
+ icEmail: require("@assets/images/email.png"),
9
+ icLightOct: require("@assets/images/oct_light.png"),
10
+ icLike: require("@assets/images/icLike.png"),
11
+ icLine: require("@assets/images/line.png"),
12
+ icLock: require("@assets/images/lock.png"),
13
+ icNotification: require("@assets/images/notification.png"),
14
+ icOnboard: require("@assets/images/onboard.png"),
15
+ icPassword: require("@assets/images/password_hide.png"),
16
+
17
+ icPasswordShow: require("@assets/images/password_show.png"),
18
+ icRightArrow: require("@assets/images/right_arrow.png"),
19
+ icSearch: require("@assets/images/icSearch.png"),
20
+ icSetting: require("@assets/images/icSetting.png"),
21
+ icShare: require("@assets/images/icShare.png"),
22
+ icStar: require("@assets/images/star.png"),
23
+ icUnchek: require("@assets/images/uncheck.png"),
24
+ icUser: require("@assets/images/user.png"),
25
+ };
@@ -0,0 +1,3 @@
1
+ export default {
2
+ DATA_LIMIT: 150
3
+ };
@@ -0,0 +1,5 @@
1
+ export default {
2
+ DEFAULT_LANGUAGE: "@defaultLanguage",
3
+ DEFAULT_THEME: "@defaultTheme",
4
+ USER_DATA: '@userInfo'
5
+ };
@@ -0,0 +1,19 @@
1
+ import type { AxiosError } from "axios";
2
+
3
+ type ResponseStatus = {
4
+ data: {
5
+ error: string;
6
+ status: boolean;
7
+ };
8
+ };
9
+
10
+ export interface ApiErrorResponse {
11
+ error?: Error;
12
+ message?: string;
13
+ response?: ResponseStatus;
14
+ status?: boolean;
15
+ }
16
+
17
+ export interface ExtendedApiErrorResponse extends ApiErrorResponse {
18
+ axiosError?: AxiosError;
19
+ }
@@ -0,0 +1,17 @@
1
+ export interface ProductsData {
2
+ brand: string;
3
+ category: string;
4
+ description: string;
5
+ discountPercentage: number;
6
+ id: number;
7
+ images: [];
8
+ price: number;
9
+ rating: number;
10
+ stock: number;
11
+ thumbnail: string | undefined;
12
+ title: string;
13
+ }
14
+
15
+ export interface HomeData extends ProductsData {
16
+ products: Array<HomeData>;
17
+ }
@@ -0,0 +1,11 @@
1
+ export type User = {
2
+ accessToken: string;
3
+ email: string;
4
+ firstName: string;
5
+ gender: string;
6
+ id: number;
7
+ image: string;
8
+ lastName: string;
9
+ refreshToken: string;
10
+ username: string;
11
+ };
@@ -0,0 +1,20 @@
1
+ import {createNativeStackNavigator} from '@react-navigation/native-stack';
2
+ import React from 'react';
3
+ import * as Screens from '../screens';
4
+
5
+ export type AuthStackParamList = {
6
+ Login: undefined;
7
+ Onboarding: undefined;
8
+ Signup: undefined;
9
+ };
10
+
11
+ export const Stack = createNativeStackNavigator<AuthStackParamList>();
12
+ const AuthStack = () => (
13
+ <>
14
+ <Stack.Screen component={Screens.Onboarding} name="Onboarding" />
15
+ <Stack.Screen component={Screens.Login} name="Login" />
16
+ <Stack.Screen component={Screens.Signup} name="Signup" />
17
+ </>
18
+ );
19
+
20
+ export default AuthStack;
@@ -0,0 +1,19 @@
1
+ import { createNativeStackNavigator } from "@react-navigation/native-stack";
2
+ import React from "react";
3
+ import * as Screens from "../screens";
4
+
5
+ export type HomeStackParamList = {
6
+ Home: undefined;
7
+ PostDetails: { productId: number };
8
+ Settings: undefined;
9
+ };
10
+ const Stack = createNativeStackNavigator<HomeStackParamList>();
11
+
12
+ const MainStack = () => (
13
+ <>
14
+ <Stack.Screen component={Screens.Home} name="Home" />
15
+ <Stack.Screen component={Screens.PostDetails} name="PostDetails" />
16
+ </>
17
+ );
18
+
19
+ export default MainStack;
@@ -0,0 +1,22 @@
1
+ import type {RootState} from '@redux/store';
2
+ import {NavigationContainer} from '@react-navigation/native';
3
+ import {createNativeStackNavigator} from '@react-navigation/native-stack';
4
+ import {useSelector} from '@redux/hooks';
5
+ import React from 'react';
6
+ import AuthStack from './AuthStack';
7
+ import MainStack from './MainStack';
8
+
9
+ const Stack = createNativeStackNavigator();
10
+
11
+ const Routes = () => {
12
+ const {userData} = useSelector((state: RootState) => state.auth);
13
+ return (
14
+ <NavigationContainer>
15
+ <Stack.Navigator screenOptions={{headerShown: false}}>
16
+ {userData?.accessToken ? MainStack() : AuthStack()}
17
+ </Stack.Navigator>
18
+ </NavigationContainer>
19
+ );
20
+ };
21
+
22
+ export default Routes;
@@ -0,0 +1,8 @@
1
+ import type { NativeStackScreenProps } from "@react-navigation/native-stack";
2
+
3
+ export type ApplicationStackParamList = {
4
+ Example: undefined;
5
+ Startup: undefined;
6
+ };
7
+
8
+ export type ApplicationScreenProps = NativeStackScreenProps<ApplicationStackParamList>;
@@ -0,0 +1,10 @@
1
+
2
+ import type { AppDispatch, RootState } from "./store";
3
+
4
+ import type { TypedUseSelectorHook } from "react-redux";
5
+ import { useDispatch as useReduxDispatch, useSelector as useReduxSelector } from "react-redux";
6
+
7
+ // Type safe hooks
8
+ export const useSelector: TypedUseSelectorHook<RootState> = useReduxSelector;
9
+
10
+ export const useDispatch: () => AppDispatch = useReduxDispatch;
@@ -0,0 +1,43 @@
1
+
2
+ import type { User } from "@models/User";
3
+ import type { PayloadAction } from "@reduxjs/toolkit";
4
+ import { createSlice } from "@reduxjs/toolkit";
5
+
6
+ export interface AuthState {
7
+ error: Error | null;
8
+ isLoading: boolean;
9
+ userData: User;
10
+ }
11
+
12
+ const initialState: AuthState = {
13
+ error: null,
14
+ isLoading: false,
15
+ userData: {
16
+ accessToken: "",
17
+ email: "",
18
+ firstName: "",
19
+ gender: "",
20
+ id: 0,
21
+ image: "",
22
+ lastName: "",
23
+ refreshToken: "",
24
+ username: ""
25
+ },
26
+ };
27
+
28
+ const authSlice = createSlice({
29
+ initialState,
30
+ name: "auth",
31
+ reducers: {
32
+ hasError: (state, action: PayloadAction<Error>) => {
33
+ state.error = action.payload;
34
+ },
35
+ saveUserData: (state, action: PayloadAction<User>) => {
36
+ state.userData = action.payload;
37
+ },
38
+ },
39
+ });
40
+
41
+ export const { hasError, saveUserData } = authSlice.actions;
42
+
43
+ export default authSlice.reducer;
@@ -0,0 +1,24 @@
1
+ import type { PayloadAction } from "@reduxjs/toolkit";
2
+ import { createSlice } from "@reduxjs/toolkit";
3
+
4
+ export interface CommonState {
5
+ isLoading: boolean;
6
+ }
7
+
8
+ const initialState: CommonState = {
9
+ isLoading: false,
10
+ };
11
+
12
+ const commonSlice = createSlice({
13
+ initialState,
14
+ name: "common",
15
+ reducers: {
16
+ setLoading: (state, action: PayloadAction<boolean>) => {
17
+ state.isLoading = action.payload;
18
+ },
19
+ },
20
+ });
21
+
22
+ export const { setLoading } = commonSlice.actions;
23
+
24
+ export default commonSlice.reducer;
@@ -0,0 +1,31 @@
1
+ import type { UnknownAction } from "@reduxjs/toolkit";
2
+ import { combineReducers } from "@reduxjs/toolkit";
3
+ import types from "../types";
4
+ import type { AuthState } from "./auth";
5
+ import auth from "./auth";
6
+ import type { CommonState } from "./common";
7
+ import common from "./common";
8
+ import type { ProductState } from "./product";
9
+ import product from "./product";
10
+ import type { SettingsState } from "./settings";
11
+ import settings from "./settings";
12
+
13
+ export interface RootState {
14
+ auth: AuthState;
15
+ common: CommonState;
16
+ product: ProductState;
17
+ settings: SettingsState; // Update with the type of settings state
18
+ }
19
+ const appReducer = combineReducers({
20
+ auth,
21
+ common,
22
+ product,
23
+ settings
24
+ });
25
+ const rootReducer = (state: RootState | undefined, action: UnknownAction) => {
26
+ if (action.type === types.CLEAR_REDUX_STATE) {
27
+ state = undefined;
28
+ }
29
+ return appReducer(state, action);
30
+ };
31
+ export default rootReducer;