@varunindiit/create-rn-starter 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 (243) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +93 -0
  3. package/bin/index.js +270 -0
  4. package/lib/prompt.js +63 -0
  5. package/lib/rename.js +239 -0
  6. package/lib/scaffold.js +110 -0
  7. package/lib/utils.js +122 -0
  8. package/package.json +38 -0
  9. package/template/.eslintrc.js +4 -0
  10. package/template/.prettierrc.js +5 -0
  11. package/template/.watchmanconfig +1 -0
  12. package/template/App.tsx +100 -0
  13. package/template/Gemfile +17 -0
  14. package/template/README.md +97 -0
  15. package/template/__tests__/App.test.tsx +13 -0
  16. package/template/_gitignore +75 -0
  17. package/template/android/app/build.gradle +119 -0
  18. package/template/android/app/debug.keystore +0 -0
  19. package/template/android/app/proguard-rules.pro +10 -0
  20. package/template/android/app/src/main/AndroidManifest.xml +45 -0
  21. package/template/android/app/src/main/assets/fonts/MonaSans-Black.ttf +0 -0
  22. package/template/android/app/src/main/assets/fonts/MonaSans-BlackItalic.ttf +0 -0
  23. package/template/android/app/src/main/assets/fonts/MonaSans-Bold.ttf +0 -0
  24. package/template/android/app/src/main/assets/fonts/MonaSans-BoldItalic.ttf +0 -0
  25. package/template/android/app/src/main/assets/fonts/MonaSans-ExtraBold.ttf +0 -0
  26. package/template/android/app/src/main/assets/fonts/MonaSans-ExtraBoldItalic.ttf +0 -0
  27. package/template/android/app/src/main/assets/fonts/MonaSans-ExtraLight.ttf +0 -0
  28. package/template/android/app/src/main/assets/fonts/MonaSans-ExtraLightItalic.ttf +0 -0
  29. package/template/android/app/src/main/assets/fonts/MonaSans-Italic.ttf +0 -0
  30. package/template/android/app/src/main/assets/fonts/MonaSans-Light.ttf +0 -0
  31. package/template/android/app/src/main/assets/fonts/MonaSans-LightItalic.ttf +0 -0
  32. package/template/android/app/src/main/assets/fonts/MonaSans-Medium.ttf +0 -0
  33. package/template/android/app/src/main/assets/fonts/MonaSans-MediumItalic.ttf +0 -0
  34. package/template/android/app/src/main/assets/fonts/MonaSans-Regular.ttf +0 -0
  35. package/template/android/app/src/main/assets/fonts/MonaSans-SemiBold.ttf +0 -0
  36. package/template/android/app/src/main/assets/fonts/MonaSans-SemiBoldItalic.ttf +0 -0
  37. package/template/android/app/src/main/java/com/awesomeproject/MainActivity.kt +22 -0
  38. package/template/android/app/src/main/java/com/awesomeproject/MainApplication.kt +27 -0
  39. package/template/android/app/src/main/res/drawable/launch_screen.png +0 -0
  40. package/template/android/app/src/main/res/drawable/rn_edit_text_material.xml +37 -0
  41. package/template/android/app/src/main/res/layout/launch_screen.xml +12 -0
  42. package/template/android/app/src/main/res/mipmap-hdpi/ic_launcher.png +0 -0
  43. package/template/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png +0 -0
  44. package/template/android/app/src/main/res/mipmap-mdpi/ic_launcher.png +0 -0
  45. package/template/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png +0 -0
  46. package/template/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png +0 -0
  47. package/template/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png +0 -0
  48. package/template/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png +0 -0
  49. package/template/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png +0 -0
  50. package/template/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png +0 -0
  51. package/template/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png +0 -0
  52. package/template/android/app/src/main/res/values/colors.xml +3 -0
  53. package/template/android/app/src/main/res/values/strings.xml +3 -0
  54. package/template/android/app/src/main/res/values/styles.xml +11 -0
  55. package/template/android/build.gradle +21 -0
  56. package/template/android/gradle/wrapper/gradle-wrapper.jar +0 -0
  57. package/template/android/gradle/wrapper/gradle-wrapper.properties +7 -0
  58. package/template/android/gradle.properties +44 -0
  59. package/template/android/gradlew +248 -0
  60. package/template/android/gradlew.bat +98 -0
  61. package/template/android/link-assets-manifest.json +69 -0
  62. package/template/android/settings.gradle +6 -0
  63. package/template/app.json +4 -0
  64. package/template/babel.config.js +4 -0
  65. package/template/declarations.d.ts +6 -0
  66. package/template/env.example +20 -0
  67. package/template/index.js +10 -0
  68. package/template/ios/.xcode.env +11 -0
  69. package/template/ios/.xcode.env.local +1 -0
  70. package/template/ios/AwesomeProject/AppDelegate.swift +60 -0
  71. package/template/ios/AwesomeProject/Images.xcassets/AppIcon.appiconset/Contents.json +53 -0
  72. package/template/ios/AwesomeProject/Images.xcassets/Contents.json +6 -0
  73. package/template/ios/AwesomeProject/Images.xcassets/Splash.imageset/Contents.json +23 -0
  74. package/template/ios/AwesomeProject/Images.xcassets/Splash.imageset/Splash@1x.png +0 -0
  75. package/template/ios/AwesomeProject/Images.xcassets/Splash.imageset/Splash@2x.png +0 -0
  76. package/template/ios/AwesomeProject/Images.xcassets/Splash.imageset/Splash@3x.png +0 -0
  77. package/template/ios/AwesomeProject/Info.plist +89 -0
  78. package/template/ios/AwesomeProject/LaunchScreen.storyboard +40 -0
  79. package/template/ios/AwesomeProject/PrivacyInfo.xcprivacy +38 -0
  80. package/template/ios/AwesomeProject.xcodeproj/project.pbxproj +576 -0
  81. package/template/ios/AwesomeProject.xcodeproj/xcshareddata/xcschemes/AwesomeProject.xcscheme +88 -0
  82. package/template/ios/AwesomeProject.xcworkspace/contents.xcworkspacedata +10 -0
  83. package/template/ios/Podfile +68 -0
  84. package/template/ios/link-assets-manifest.json +69 -0
  85. package/template/jest.config.js +3 -0
  86. package/template/metro.config.js +24 -0
  87. package/template/package.json +68 -0
  88. package/template/react-native.config.js +7 -0
  89. package/template/src/assets/fonts/MonaSans-Black.ttf +0 -0
  90. package/template/src/assets/fonts/MonaSans-BlackItalic.ttf +0 -0
  91. package/template/src/assets/fonts/MonaSans-Bold.ttf +0 -0
  92. package/template/src/assets/fonts/MonaSans-BoldItalic.ttf +0 -0
  93. package/template/src/assets/fonts/MonaSans-ExtraBold.ttf +0 -0
  94. package/template/src/assets/fonts/MonaSans-ExtraBoldItalic.ttf +0 -0
  95. package/template/src/assets/fonts/MonaSans-ExtraLight.ttf +0 -0
  96. package/template/src/assets/fonts/MonaSans-ExtraLightItalic.ttf +0 -0
  97. package/template/src/assets/fonts/MonaSans-Italic.ttf +0 -0
  98. package/template/src/assets/fonts/MonaSans-Light.ttf +0 -0
  99. package/template/src/assets/fonts/MonaSans-LightItalic.ttf +0 -0
  100. package/template/src/assets/fonts/MonaSans-Medium.ttf +0 -0
  101. package/template/src/assets/fonts/MonaSans-MediumItalic.ttf +0 -0
  102. package/template/src/assets/fonts/MonaSans-Regular.ttf +0 -0
  103. package/template/src/assets/fonts/MonaSans-SemiBold.ttf +0 -0
  104. package/template/src/assets/fonts/MonaSans-SemiBoldItalic.ttf +0 -0
  105. package/template/src/assets/image/BackGroundAuth.png +0 -0
  106. package/template/src/assets/image/BackgroundVerification.png +0 -0
  107. package/template/src/assets/image/logo.png +0 -0
  108. package/template/src/assets/svg/add-circle.svg +5 -0
  109. package/template/src/assets/svg/airConditioning.svg +12 -0
  110. package/template/src/assets/svg/apple.svg +3 -0
  111. package/template/src/assets/svg/arrowDown.svg +3 -0
  112. package/template/src/assets/svg/back.svg +10 -0
  113. package/template/src/assets/svg/bag.svg +11 -0
  114. package/template/src/assets/svg/calender.svg +5 -0
  115. package/template/src/assets/svg/car.svg +10 -0
  116. package/template/src/assets/svg/carConfirm.svg +60 -0
  117. package/template/src/assets/svg/chatActive.svg +3 -0
  118. package/template/src/assets/svg/chatUnActive.svg +3 -0
  119. package/template/src/assets/svg/document-text.svg +6 -0
  120. package/template/src/assets/svg/gender.svg +11 -0
  121. package/template/src/assets/svg/google.svg +6 -0
  122. package/template/src/assets/svg/headphone.svg +3 -0
  123. package/template/src/assets/svg/homeActive.svg +3 -0
  124. package/template/src/assets/svg/homeUnActive.svg +3 -0
  125. package/template/src/assets/svg/logo.svg +18 -0
  126. package/template/src/assets/svg/logout.svg +5 -0
  127. package/template/src/assets/svg/maxBack.svg +4 -0
  128. package/template/src/assets/svg/message-text.svg +7 -0
  129. package/template/src/assets/svg/music.svg +5 -0
  130. package/template/src/assets/svg/noSmoking.svg +10 -0
  131. package/template/src/assets/svg/notification.svg +5 -0
  132. package/template/src/assets/svg/passenger.svg +4 -0
  133. package/template/src/assets/svg/phone.svg +3 -0
  134. package/template/src/assets/svg/rightArrow.svg +3 -0
  135. package/template/src/assets/svg/security-user.svg +5 -0
  136. package/template/src/assets/svg/star.svg +3 -0
  137. package/template/src/assets/svg/tick-circle.svg +4 -0
  138. package/template/src/assets/svg/trafficLight.svg +41 -0
  139. package/template/src/assets/svg/tripActive.svg +10 -0
  140. package/template/src/assets/svg/tripUnActive.svg +10 -0
  141. package/template/src/assets/svg/usbChargers.svg +3 -0
  142. package/template/src/assets/svg/user.svg +4 -0
  143. package/template/src/assets/svg/userActive.svg +3 -0
  144. package/template/src/assets/svg/userPlaceholder.svg +3 -0
  145. package/template/src/assets/svg/userUnActive.svg +3 -0
  146. package/template/src/components/AuthLayout/AuthLayout.tsx +170 -0
  147. package/template/src/components/AuthLayout/index.ts +1 -0
  148. package/template/src/components/BottomSheet/BottomSheet.tsx +73 -0
  149. package/template/src/components/BottomSheet/BottomSheetAlert.tsx +100 -0
  150. package/template/src/components/BottomSheet/CenterAlert.tsx +153 -0
  151. package/template/src/components/BottomSheet/index.ts +2 -0
  152. package/template/src/components/BottomTabBar/index.tsx +145 -0
  153. package/template/src/components/Button/RNButton.tsx +152 -0
  154. package/template/src/components/Button/index.ts +2 -0
  155. package/template/src/components/Common/Avatar.tsx +80 -0
  156. package/template/src/components/Common/Card.tsx +49 -0
  157. package/template/src/components/Common/CardBrandLogo.tsx +66 -0
  158. package/template/src/components/Common/Checkbox.tsx +65 -0
  159. package/template/src/components/Common/Chip.tsx +79 -0
  160. package/template/src/components/Common/CommonStyles.tsx +594 -0
  161. package/template/src/components/Common/Divider.tsx +33 -0
  162. package/template/src/components/Common/DriverTripCard.tsx +308 -0
  163. package/template/src/components/Common/Dropdown.tsx +161 -0
  164. package/template/src/components/Common/EmptyState.tsx +52 -0
  165. package/template/src/components/Common/FAB.tsx +68 -0
  166. package/template/src/components/Common/HeaderLocation.tsx +108 -0
  167. package/template/src/components/Common/Loader.tsx +23 -0
  168. package/template/src/components/Common/RatingStars.tsx +103 -0
  169. package/template/src/components/Common/RouteDots.tsx +98 -0
  170. package/template/src/components/Common/SegmentedControl.tsx +126 -0
  171. package/template/src/components/Common/SosButton.tsx +80 -0
  172. package/template/src/components/Common/SosSheet.tsx +344 -0
  173. package/template/src/components/Common/StarRating.tsx +58 -0
  174. package/template/src/components/Common/StatusBadge.tsx +56 -0
  175. package/template/src/components/Common/Toggle.tsx +66 -0
  176. package/template/src/components/Common/TripCard.tsx +247 -0
  177. package/template/src/components/Common/UploadBox.tsx +106 -0
  178. package/template/src/components/Container/MainContainer.tsx +76 -0
  179. package/template/src/components/Container/index.ts +1 -0
  180. package/template/src/components/Header/index.tsx +143 -0
  181. package/template/src/components/Icon/SvgIcons.tsx +1991 -0
  182. package/template/src/components/ImagePickerSheet/ImagePickerSheet.tsx +233 -0
  183. package/template/src/components/ImagePickerSheet/index.ts +2 -0
  184. package/template/src/components/Input/CountryDropdown.tsx +71 -0
  185. package/template/src/components/Input/OtpInput.tsx +117 -0
  186. package/template/src/components/Input/RNInput.tsx +138 -0
  187. package/template/src/components/Input/index.ts +4 -0
  188. package/template/src/components/Picker/DatePickerSheet.tsx +393 -0
  189. package/template/src/components/Picker/PassengerPickerSheet.tsx +237 -0
  190. package/template/src/components/Text/RNText.tsx +62 -0
  191. package/template/src/components/Text/index.ts +1 -0
  192. package/template/src/components/index.ts +44 -0
  193. package/template/src/hooks/useCurrentLocation.ts +72 -0
  194. package/template/src/localization/i18n.ts +29 -0
  195. package/template/src/localization/i18next.d.ts +11 -0
  196. package/template/src/localization/index.ts +4 -0
  197. package/template/src/localization/languageStorage.ts +27 -0
  198. package/template/src/localization/languages.ts +62 -0
  199. package/template/src/localization/resources/en.ts +703 -0
  200. package/template/src/localization/resources/fr.ts +703 -0
  201. package/template/src/localization/useLanguage.ts +42 -0
  202. package/template/src/navigation/AuthNavigation.tsx +23 -0
  203. package/template/src/navigation/BottomTabs.tsx +24 -0
  204. package/template/src/navigation/RootNavigation.tsx +27 -0
  205. package/template/src/navigation/RouteKey.ts +22 -0
  206. package/template/src/navigation/StackNavigation.tsx +52 -0
  207. package/template/src/navigation/paramLists.ts +25 -0
  208. package/template/src/redux/slice/app.ts +66 -0
  209. package/template/src/redux/slice/auth.ts +40 -0
  210. package/template/src/redux/slice/userProfile.ts +124 -0
  211. package/template/src/redux/store.ts +17 -0
  212. package/template/src/screen/auth/Login.tsx +69 -0
  213. package/template/src/screen/onboarding/LanguageSelection.tsx +231 -0
  214. package/template/src/screen/root/home/index.tsx +36 -0
  215. package/template/src/screen/root/profile/index.tsx +69 -0
  216. package/template/src/screen/shared/Chat.tsx +308 -0
  217. package/template/src/screen/shared/EditProfile.tsx +407 -0
  218. package/template/src/screen/shared/HelpSupport.tsx +678 -0
  219. package/template/src/screen/shared/LocationSearch.tsx +362 -0
  220. package/template/src/screen/shared/Messages.tsx +115 -0
  221. package/template/src/screen/shared/Notifications.tsx +86 -0
  222. package/template/src/screen/shared/PrivacyPolicy.tsx +297 -0
  223. package/template/src/screen/shared/Profile.tsx +118 -0
  224. package/template/src/screen/shared/Ratings.tsx +170 -0
  225. package/template/src/screen/shared/TermsConditions.tsx +315 -0
  226. package/template/src/screen/shared/profile/DriverProfile.tsx +262 -0
  227. package/template/src/screen/shared/profile/PassengerProfile.tsx +123 -0
  228. package/template/src/screen/shared/profile/ProfileParts.tsx +219 -0
  229. package/template/src/services/Config.ts +37 -0
  230. package/template/src/services/api.ts +37 -0
  231. package/template/src/services/index.ts +4 -0
  232. package/template/src/services/places.ts +320 -0
  233. package/template/src/services/storage.ts +33 -0
  234. package/template/src/theme/fonts.ts +30 -0
  235. package/template/src/theme/index.ts +3 -0
  236. package/template/src/theme/spacing.ts +66 -0
  237. package/template/src/theme/theme.ts +58 -0
  238. package/template/src/types/env.d.ts +8 -0
  239. package/template/src/types/index.ts +3 -0
  240. package/template/src/utils/card.ts +101 -0
  241. package/template/src/utils/constants.ts +39 -0
  242. package/template/src/utils/functions.ts +24 -0
  243. package/template/tsconfig.json +8 -0
@@ -0,0 +1,153 @@
1
+ import React from 'react';
2
+ import {
3
+ KeyboardAvoidingView,
4
+ Modal,
5
+ Platform,
6
+ Pressable,
7
+ StyleSheet,
8
+ TouchableOpacity,
9
+ View,
10
+ } from 'react-native';
11
+ import { moderateScale } from 'react-native-size-matters';
12
+ import { SPACING, THEME } from '../../theme';
13
+ import { RNButton } from '../Button';
14
+ import RNText from '../Text/RNText';
15
+ import { CloseIcon } from '../Icon/SvgIcons';
16
+
17
+ interface CenterAlertProps {
18
+ visible: boolean;
19
+ onClose?: () => void;
20
+ title: string;
21
+ description?: string;
22
+ confirmText?: string;
23
+ onConfirm?: () => void;
24
+ loading?: boolean;
25
+ confirmDisabled?: boolean;
26
+ children?: React.ReactNode;
27
+ }
28
+
29
+ const CenterAlert: React.FC<CenterAlertProps> = ({
30
+ visible,
31
+ onClose,
32
+ title,
33
+ description,
34
+ confirmText = 'Yes, Cancel',
35
+ onConfirm,
36
+ loading,
37
+ confirmDisabled,
38
+ children,
39
+ }) => (
40
+ <Modal
41
+ visible={visible}
42
+ transparent
43
+ animationType="fade"
44
+ statusBarTranslucent
45
+ // onRequestClose={onClose}
46
+ >
47
+ <KeyboardAvoidingView
48
+ style={styles.flex1}
49
+ behavior={Platform.OS === 'ios' ? 'padding' : undefined}
50
+ >
51
+ <Pressable style={styles.backdrop} onPress={onClose}>
52
+ <Pressable style={styles.card} onPress={() => {}}>
53
+ <TouchableOpacity
54
+ style={styles.closeBtn}
55
+ onPress={onClose}
56
+ hitSlop={10}
57
+ activeOpacity={0.7}
58
+ >
59
+ <View style={styles.closeCircle}>
60
+ <CloseIcon size={moderateScale(12)} color="#FFFFFF" />
61
+ </View>
62
+ </TouchableOpacity>
63
+
64
+ <RNText
65
+ font="semibold"
66
+ size={18}
67
+ color={THEME.text}
68
+ textAlign="center"
69
+ style={styles.title}
70
+ >
71
+ {title}
72
+ </RNText>
73
+
74
+ {description ? (
75
+ <RNText
76
+ size={13}
77
+ color={THEME.textSecondary}
78
+ textAlign="center"
79
+ style={styles.description}
80
+ >
81
+ {description}
82
+ </RNText>
83
+ ) : null}
84
+
85
+ {children ? <View style={styles.content}>{children}</View> : null}
86
+
87
+ <RNButton
88
+ title={confirmText}
89
+ onPress={onConfirm}
90
+ loading={loading}
91
+ disabled={confirmDisabled}
92
+ containerStyle={styles.btn}
93
+ />
94
+ </Pressable>
95
+ </Pressable>
96
+ </KeyboardAvoidingView>
97
+ </Modal>
98
+ );
99
+
100
+ export default CenterAlert;
101
+
102
+ const styles = StyleSheet.create({
103
+ flex1: {
104
+ flex: 1,
105
+ },
106
+ backdrop: {
107
+ flex: 1,
108
+ backgroundColor: 'rgba(0,0,0,0.45)',
109
+ alignItems: 'center',
110
+ justifyContent: 'center',
111
+ paddingHorizontal: moderateScale(36),
112
+ },
113
+ card: {
114
+ width: '100%',
115
+ backgroundColor: THEME.surface,
116
+ borderRadius: moderateScale(20),
117
+ paddingHorizontal: moderateScale(20),
118
+ paddingTop: moderateScale(28),
119
+ paddingBottom: moderateScale(20),
120
+ alignItems: 'center',
121
+ },
122
+ closeBtn: {
123
+ position: 'absolute',
124
+ top: moderateScale(10),
125
+ right: moderateScale(10),
126
+ padding: moderateScale(4),
127
+ },
128
+ closeCircle: {
129
+ width: moderateScale(20),
130
+ height: moderateScale(20),
131
+ borderRadius: moderateScale(10),
132
+ backgroundColor: THEME.primary,
133
+ alignItems: 'center',
134
+ justifyContent: 'center',
135
+ },
136
+ title: {
137
+ marginTop: moderateScale(2),
138
+ },
139
+ description: {
140
+ marginTop: moderateScale(10),
141
+ lineHeight: moderateScale(20),
142
+ paddingHorizontal: moderateScale(4),
143
+ },
144
+ content: {
145
+ width: '100%',
146
+ marginTop: moderateScale(16),
147
+ },
148
+ btn: {
149
+ marginTop: moderateScale(20),
150
+ width: '100%',
151
+ borderRadius: SPACING.radiusPill,
152
+ },
153
+ });
@@ -0,0 +1,2 @@
1
+ export { default as BottomSheet } from "./BottomSheet";
2
+ export { default as BottomSheetAlert } from "./BottomSheetAlert";
@@ -0,0 +1,145 @@
1
+ import React from "react";
2
+ import { Platform, Pressable, StyleSheet, View } from "react-native";
3
+ import { useSafeAreaInsets } from "react-native-safe-area-context";
4
+ import { moderateScale } from "react-native-size-matters";
5
+ import { THEME } from "../../theme";
6
+
7
+ import HomeActive from "../../assets/svg/homeActive.svg";
8
+ import HomeUnActive from "../../assets/svg/homeUnActive.svg";
9
+ import TripActive from "../../assets/svg/tripActive.svg";
10
+ import TripUnActive from "../../assets/svg/tripUnActive.svg";
11
+ import ChatActive from "../../assets/svg/chatActive.svg";
12
+ import ChatUnActive from "../../assets/svg/chatUnActive.svg";
13
+ import UserActive from "../../assets/svg/userActive.svg";
14
+ import UserUnActive from "../../assets/svg/userUnActive.svg";
15
+
16
+ interface BottomTabBarProps {
17
+ state: any;
18
+ navigation: any;
19
+ }
20
+
21
+ const ICON_MAP: Record<
22
+ string,
23
+ { Active: React.FC<any>; Inactive: React.FC<any> }
24
+ > = {
25
+ Home: { Active: HomeActive, Inactive: HomeUnActive },
26
+ Trips: { Active: TripActive, Inactive: TripUnActive },
27
+ Messages: { Active: ChatActive, Inactive: ChatUnActive },
28
+ Profile: { Active: UserActive, Inactive: UserUnActive },
29
+ };
30
+
31
+ const tabKey = (name: string) => {
32
+ if (name.includes("Home")) return "Home";
33
+ if (name.includes("Trips")) return "Trips";
34
+ if (name.includes("Messages")) return "Messages";
35
+ return "Profile";
36
+ };
37
+
38
+ const BottomTabBar: React.FC<BottomTabBarProps> = ({ state, navigation }) => {
39
+ const insets = useSafeAreaInsets();
40
+ return (
41
+ <View
42
+ style={[
43
+ styles.wrapper,
44
+ { paddingBottom: Math.max(insets.bottom, moderateScale(12)) },
45
+ ]}
46
+ >
47
+ <View style={styles.bar}>
48
+ {state.routes.map((route: any, index: number) => {
49
+ const isFocused = state.index === index;
50
+ const key = tabKey(route.name);
51
+ const cfg = ICON_MAP[key];
52
+ const Icon = isFocused ? cfg.Active : cfg.Inactive;
53
+
54
+ const onPress = () => {
55
+ const event = navigation.emit({
56
+ type: "tabPress",
57
+ target: route.key,
58
+ canPreventDefault: true,
59
+ });
60
+ if (!isFocused && !event.defaultPrevented)
61
+ navigation.navigate(route.name);
62
+ };
63
+
64
+ return (
65
+ <Pressable
66
+ key={route.key}
67
+ onPress={onPress}
68
+ style={styles.item}
69
+ hitSlop={8}
70
+ >
71
+ <View
72
+ style={[
73
+ styles.iconWrap,
74
+ isFocused && styles.iconWrapActive,
75
+ ]}
76
+ >
77
+ <Icon
78
+ width={moderateScale(26)}
79
+ height={moderateScale(26)}
80
+ />
81
+ {isFocused && <View style={styles.activeNotch} />}
82
+ </View>
83
+ </Pressable>
84
+ );
85
+ })}
86
+ </View>
87
+ </View>
88
+ );
89
+ };
90
+
91
+ export default BottomTabBar;
92
+
93
+ const styles = StyleSheet.create({
94
+ wrapper: {
95
+ position: "absolute",
96
+ left: 0,
97
+ right: 0,
98
+ bottom: 0,
99
+ paddingHorizontal: moderateScale(16),
100
+ paddingTop: moderateScale(8),
101
+ backgroundColor: "transparent",
102
+ },
103
+ bar: {
104
+ flexDirection: "row",
105
+ alignItems: "center",
106
+ justifyContent: "space-between",
107
+ backgroundColor: THEME.tabBg,
108
+ borderRadius: moderateScale(32),
109
+ paddingHorizontal: moderateScale(12),
110
+ paddingVertical: moderateScale(10),
111
+ shadowColor: "#000",
112
+ shadowOffset: { width: 0, height: 4 },
113
+ shadowOpacity: 0.08,
114
+ shadowRadius: 16,
115
+ elevation: 12,
116
+ ...Platform.select({ android: { elevation: 14 } }),
117
+ },
118
+ item: {
119
+ flex: 1,
120
+ alignItems: "center",
121
+ justifyContent: "center",
122
+ },
123
+ iconWrap: {
124
+ width: moderateScale(54),
125
+ height: moderateScale(54),
126
+ borderRadius: moderateScale(18),
127
+ alignItems: "center",
128
+ justifyContent: "center",
129
+ },
130
+ iconWrapActive: {
131
+ backgroundColor: THEME.primary,
132
+ overflow: "hidden",
133
+ borderRadius: moderateScale(18),
134
+ },
135
+ activeNotch: {
136
+ position: "absolute",
137
+ bottom: -1,
138
+ alignSelf: "center",
139
+ width: moderateScale(11.55),
140
+ height: moderateScale(4.23),
141
+ backgroundColor: THEME.tabBg,
142
+ borderTopLeftRadius: moderateScale(2),
143
+ borderTopRightRadius: moderateScale(2),
144
+ },
145
+ });
@@ -0,0 +1,152 @@
1
+ import React, { useCallback } from "react";
2
+ import {
3
+ ActivityIndicator,
4
+ Pressable,
5
+ StyleProp,
6
+ StyleSheet,
7
+ TextStyle,
8
+ View,
9
+ ViewStyle,
10
+ } from "react-native";
11
+ import Animated, {
12
+ useAnimatedStyle,
13
+ useSharedValue,
14
+ withSpring,
15
+ } from "react-native-reanimated";
16
+ import { moderateScale } from "react-native-size-matters";
17
+ import { SIZES, SPACING, THEME } from "../../theme";
18
+ import RNText from "../Text/RNText";
19
+
20
+ type Variant = "primary" | "secondary" | "outline" | "ghost" | "danger";
21
+
22
+ interface RNButtonProps {
23
+ title?: string;
24
+ onPress?: () => void;
25
+ variant?: Variant;
26
+ disabled?: boolean;
27
+ loading?: boolean;
28
+ containerStyle?: StyleProp<ViewStyle>;
29
+ textStyle?: StyleProp<TextStyle>;
30
+ leftIcon?: React.ReactNode;
31
+ rightIcon?: React.ReactNode;
32
+ children?: React.ReactNode;
33
+ height?: number;
34
+ textSize?: number;
35
+ }
36
+
37
+ const AnimatedPressable = Animated.createAnimatedComponent(Pressable);
38
+
39
+ const VARIANT_STYLES: Record<
40
+ Variant,
41
+ { bg: string; border: string; color: string }
42
+ > = {
43
+ primary: {
44
+ bg: THEME.primary,
45
+ border: THEME.primary,
46
+ color: THEME.textOnPrimary,
47
+ },
48
+ secondary: {
49
+ bg: THEME.primaryLight,
50
+ border: THEME.primaryLight,
51
+ color: THEME.primary,
52
+ },
53
+ outline: {
54
+ bg: "transparent",
55
+ border: THEME.primary,
56
+ color: THEME.primary,
57
+ },
58
+ ghost: {
59
+ bg: "transparent",
60
+ border: "transparent",
61
+ color: THEME.primary,
62
+ },
63
+ danger: {
64
+ bg: THEME.dangerLight,
65
+ border: THEME.dangerLight,
66
+ color: THEME.danger,
67
+ },
68
+ };
69
+
70
+ const RNButton: React.FC<RNButtonProps> = ({
71
+ title,
72
+ onPress,
73
+ variant = "primary",
74
+ disabled,
75
+ loading,
76
+ containerStyle,
77
+ textStyle,
78
+ leftIcon,
79
+ rightIcon,
80
+ children,
81
+ height = SIZES.buttonHeight,
82
+ textSize = 16,
83
+ }) => {
84
+ const scale = useSharedValue(1);
85
+ const animatedStyle = useAnimatedStyle(() => ({
86
+ transform: [{ scale: scale.value }],
87
+ }));
88
+
89
+ const onPressIn = useCallback(() => {
90
+ scale.value = withSpring(0.97, { damping: 18, stiffness: 220 });
91
+ }, [scale]);
92
+ const onPressOut = useCallback(() => {
93
+ scale.value = withSpring(1, { damping: 18, stiffness: 220 });
94
+ }, [scale]);
95
+
96
+ const v = VARIANT_STYLES[variant];
97
+
98
+ const inner =
99
+ children ??
100
+ (title ? (
101
+ <View style={styles.contentRow}>
102
+ {leftIcon}
103
+ <RNText font="semibold" size={textSize} color={v.color} style={textStyle}>
104
+ {title}
105
+ </RNText>
106
+ {rightIcon}
107
+ </View>
108
+ ) : null);
109
+
110
+ return (
111
+ <AnimatedPressable
112
+ disabled={disabled || loading}
113
+ onPress={onPress}
114
+ onPressIn={onPressIn}
115
+ onPressOut={onPressOut}
116
+ style={[
117
+ styles.shell,
118
+ {
119
+ height,
120
+ backgroundColor: v.bg,
121
+ borderColor: v.border,
122
+ borderWidth: variant === "outline" ? 1.2 : 0,
123
+ opacity: disabled ? 0.55 : 1,
124
+ },
125
+ styles.center,
126
+ containerStyle,
127
+ animatedStyle,
128
+ ]}
129
+ >
130
+ {loading ? <ActivityIndicator color={v.color} /> : inner}
131
+ </AnimatedPressable>
132
+ );
133
+ };
134
+
135
+ export default RNButton;
136
+
137
+ const styles = StyleSheet.create({
138
+ shell: {
139
+ borderRadius: SPACING.radiusPill,
140
+ overflow: "hidden",
141
+ },
142
+ center: {
143
+ alignItems: "center",
144
+ justifyContent: "center",
145
+ },
146
+ contentRow: {
147
+ flexDirection: "row",
148
+ alignItems: "center",
149
+ justifyContent: "center",
150
+ gap: moderateScale(8),
151
+ },
152
+ });
@@ -0,0 +1,2 @@
1
+ export { default as RNButton } from "./RNButton"
2
+ // export {default as RNButtonWhite} from "./RNButtonWhite"
@@ -0,0 +1,80 @@
1
+ import React from "react";
2
+ import {
3
+ Image,
4
+ ImageSourcePropType,
5
+ StyleProp,
6
+ StyleSheet,
7
+ View,
8
+ ViewStyle,
9
+ } from "react-native";
10
+ import { THEME } from "../../theme";
11
+ import RNText from "../Text/RNText";
12
+
13
+ interface AvatarProps {
14
+ uri?: string;
15
+ source?: ImageSourcePropType;
16
+ size?: number;
17
+ name?: string;
18
+ style?: StyleProp<ViewStyle>;
19
+ ring?: boolean;
20
+ }
21
+
22
+ const initials = (n?: string) =>
23
+ (n || "")
24
+ .split(/\s+/)
25
+ .map((s) => s[0])
26
+ .filter(Boolean)
27
+ .slice(0, 2)
28
+ .join("")
29
+ .toUpperCase();
30
+
31
+ const DEFAULT_AVATAR_URI = "https://picsum.photos/200/300";
32
+
33
+ const Avatar: React.FC<AvatarProps> = ({
34
+ uri = DEFAULT_AVATAR_URI,
35
+ source,
36
+ size = 44,
37
+ name,
38
+ style,
39
+ ring,
40
+ }) => {
41
+ const radius = size / 2;
42
+ const wrap = [
43
+ {
44
+ width: size,
45
+ height: size,
46
+ borderRadius: radius,
47
+ backgroundColor: THEME.primaryLight,
48
+ },
49
+ ring && { borderWidth: 2, borderColor: THEME.surface },
50
+ styles.center,
51
+ style,
52
+ ];
53
+ if (uri || source) {
54
+ return (
55
+ <View style={wrap}>
56
+ <Image
57
+ source={source ?? { uri }}
58
+ style={{ width: size, height: size, borderRadius: radius }}
59
+ />
60
+ </View>
61
+ );
62
+ }
63
+ return (
64
+ <View style={wrap}>
65
+ <RNText
66
+ font="semibold"
67
+ size={Math.round(size * 0.36)}
68
+ color={THEME.primary}
69
+ >
70
+ {initials(name) || "U"}
71
+ </RNText>
72
+ </View>
73
+ );
74
+ };
75
+
76
+ export default Avatar;
77
+
78
+ const styles = StyleSheet.create({
79
+ center: { alignItems: "center", justifyContent: "center", overflow: "hidden" },
80
+ });
@@ -0,0 +1,49 @@
1
+ import React from 'react';
2
+ import { StyleProp, StyleSheet, View, ViewStyle } from 'react-native';
3
+ import { SPACING, THEME } from '../../theme';
4
+
5
+ interface CardProps {
6
+ children?: React.ReactNode;
7
+ style?: StyleProp<ViewStyle>;
8
+ padding?: number;
9
+ bg?: string;
10
+ radius?: number;
11
+ shadow?: boolean;
12
+ }
13
+
14
+ const Card: React.FC<CardProps> = ({
15
+ children,
16
+ style,
17
+ padding,
18
+ bg = THEME.surface,
19
+ radius = SPACING.radiusLg,
20
+ shadow = false,
21
+ }) => (
22
+ <View
23
+ style={[
24
+ styles.card,
25
+ shadow && styles.shadow,
26
+ {
27
+ backgroundColor: bg,
28
+ borderRadius: radius,
29
+ padding: padding ?? SPACING.lg,
30
+ },
31
+ style,
32
+ ]}
33
+ >
34
+ {children}
35
+ </View>
36
+ );
37
+
38
+ export default Card;
39
+
40
+ const styles = StyleSheet.create({
41
+ card: { width: '100%', borderWidth: 1, borderColor: 'rgba(44, 26, 14, 0.1)' },
42
+ shadow: {
43
+ shadowColor: THEME.shadow,
44
+ shadowOffset: { width: 0, height: 2 },
45
+ shadowOpacity: 1,
46
+ shadowRadius: 8,
47
+ elevation: 2,
48
+ },
49
+ });
@@ -0,0 +1,66 @@
1
+ import React from "react";
2
+ import { StyleProp, StyleSheet, View, ViewStyle } from "react-native";
3
+ import { moderateScale } from "react-native-size-matters";
4
+ import { CardBrand, CARD_BRAND_LABEL } from "../../utils/card";
5
+ import { MastercardIcon, VisaIcon } from "../Icon/SvgIcons";
6
+ import RNText from "../Text/RNText";
7
+
8
+ interface CardBrandLogoProps {
9
+ brand: CardBrand;
10
+ size?: number;
11
+ /** Render light text for use on a dark card preview. */
12
+ light?: boolean;
13
+ style?: StyleProp<ViewStyle>;
14
+ }
15
+
16
+ /**
17
+ * Brand mark for a saved/preview card. Vector logos for Visa & Mastercard,
18
+ * a clean wordmark badge for the rest.
19
+ */
20
+ const CardBrandLogo: React.FC<CardBrandLogoProps> = ({
21
+ brand,
22
+ size = 24,
23
+ light = false,
24
+ style,
25
+ }) => {
26
+ if (brand === "visa") {
27
+ return (
28
+ <View style={style}>
29
+ <VisaIcon size={moderateScale(size)} />
30
+ </View>
31
+ );
32
+ }
33
+ if (brand === "mastercard") {
34
+ return (
35
+ <View style={style}>
36
+ <MastercardIcon size={moderateScale(size)} />
37
+ </View>
38
+ );
39
+ }
40
+ return (
41
+ <View style={[styles.badge, light && styles.badgeLight, style]}>
42
+ <RNText
43
+ font="bold"
44
+ size={11}
45
+ color={light ? "#FFFFFF" : "#2C1A0E"}
46
+ letterSpacing={0.4}
47
+ >
48
+ {CARD_BRAND_LABEL[brand].toUpperCase()}
49
+ </RNText>
50
+ </View>
51
+ );
52
+ };
53
+
54
+ export default CardBrandLogo;
55
+
56
+ const styles = StyleSheet.create({
57
+ badge: {
58
+ paddingHorizontal: moderateScale(8),
59
+ paddingVertical: moderateScale(4),
60
+ borderRadius: moderateScale(6),
61
+ backgroundColor: "rgba(44, 26, 14, 0.08)",
62
+ },
63
+ badgeLight: {
64
+ backgroundColor: "rgba(255, 255, 255, 0.18)",
65
+ },
66
+ });