@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,247 @@
1
+ import React from "react";
2
+ import type { TFunction } from "i18next";
3
+ import { StyleProp, StyleSheet, TouchableOpacity, View, ViewStyle } from "react-native";
4
+ import { moderateScale } from "react-native-size-matters";
5
+ import Avatar from "./Avatar";
6
+ import Card from "./Card";
7
+ import StatusBadge from "./StatusBadge";
8
+ import RNText from "../Text/RNText";
9
+ import { CheckCircleIcon } from "../Icon/SvgIcons";
10
+ import { THEME } from "../../theme";
11
+ import { useLanguage } from "../../localization";
12
+ import { Trip, TripStatus } from "../../redux/slice/trip";
13
+
14
+ interface TripCardProps {
15
+ trip: Trip;
16
+ onPress?: () => void;
17
+ style?: StyleProp<ViewStyle>;
18
+ }
19
+
20
+ const STATUS_TONE: Record<
21
+ TripStatus,
22
+ "success" | "warning" | "danger" | "info" | "primary"
23
+ > = {
24
+ available: "info",
25
+ fully_booked: "warning",
26
+ confirmed: "success",
27
+ in_progress: "primary",
28
+ completed: "success",
29
+ cancelled: "danger",
30
+ };
31
+
32
+ /** Localized status label, falling back to the English literal where no key exists. */
33
+ const statusLabel = (t: TFunction, status: TripStatus): string => {
34
+ switch (status) {
35
+ case "confirmed":
36
+ return t("tripStatus.confirmed");
37
+ case "completed":
38
+ return t("tripStatus.completed");
39
+ case "cancelled":
40
+ return t("tripStatus.cancelled");
41
+ case "available":
42
+ return t("tripStatus.available");
43
+ case "fully_booked":
44
+ return t("tripStatus.fullyBooked");
45
+ case "in_progress":
46
+ return t("tripStatus.inProgress");
47
+ default:
48
+ return status;
49
+ }
50
+ };
51
+
52
+ const TripCard: React.FC<TripCardProps> = ({ trip, onPress, style }) => {
53
+ const { t } = useLanguage();
54
+ return (
55
+ <TouchableOpacity onPress={onPress} activeOpacity={0.9} disabled={!onPress}>
56
+ <Card shadow padding={moderateScale(16)} style={[styles.card, style]}>
57
+ <View style={styles.headerRow}>
58
+ <Avatar
59
+ uri={trip.driverAvatarUri || undefined}
60
+ name={trip.driverName}
61
+ size={moderateScale(44)}
62
+ />
63
+ <View style={styles.headerInfo}>
64
+ <RNText font="semibold" size={15} color={THEME.text}>
65
+ {trip.driverName}
66
+ </RNText>
67
+ <View style={styles.metaRow}>
68
+ <RNText size={12} color={THEME.textMuted}>
69
+ {t("common.tripsCount", { count: trip.driverTrips })}
70
+ </RNText>
71
+ <RNText size={12} color={THEME.textMuted} style={styles.metaDot}>
72
+ ·
73
+ </RNText>
74
+ <RNText size={12} color={THEME.star}>
75
+
76
+ </RNText>
77
+ <RNText
78
+ size={12}
79
+ color={THEME.textMuted}
80
+ style={styles.ratingValue}
81
+ >
82
+ {trip.driverRating}
83
+ </RNText>
84
+ </View>
85
+ </View>
86
+ {trip.status === "confirmed" || trip.status === "completed" ? (
87
+ <View style={styles.confirmedRow}>
88
+ <CheckCircleIcon size={moderateScale(15)} color={THEME.success} />
89
+ <RNText
90
+ font="medium"
91
+ size={12}
92
+ color={THEME.success}
93
+ style={styles.confirmedLabel}
94
+ >
95
+ {statusLabel(t, trip.status)}
96
+ </RNText>
97
+ </View>
98
+ ) : (
99
+ <StatusBadge
100
+ label={statusLabel(t, trip.status)}
101
+ tone={STATUS_TONE[trip.status]}
102
+ />
103
+ )}
104
+ </View>
105
+
106
+ <View style={styles.timelineWrap}>
107
+ <View style={styles.timelineRow}>
108
+ <RNText
109
+ size={13}
110
+ font="medium"
111
+ color={THEME.text}
112
+ style={styles.timelineTime}
113
+ >
114
+ {trip.from.time || "08:00"}
115
+ </RNText>
116
+ <View style={styles.timelineDotFilled} />
117
+ <RNText
118
+ size={13}
119
+ color={THEME.text}
120
+ style={styles.timelinePlace}
121
+ >
122
+ {trip.from.city}
123
+ {trip.from.area ? `, ${trip.from.area}` : ""}
124
+ </RNText>
125
+ </View>
126
+ <View style={styles.timelineConnector}>
127
+ <View style={styles.timeColSpacer} />
128
+ <View style={styles.timelineDashCol}>
129
+ {Array.from({ length: 4 }).map((_, i) => (
130
+ <View key={i} style={styles.timelineDashSegment} />
131
+ ))}
132
+ </View>
133
+ </View>
134
+ <View style={styles.timelineRow}>
135
+ <RNText
136
+ size={13}
137
+ font="medium"
138
+ color={THEME.text}
139
+ style={styles.timelineTime}
140
+ >
141
+ {trip.to.time || "11:15"}
142
+ </RNText>
143
+ <View style={styles.timelineDotFilled} />
144
+ <RNText
145
+ size={13}
146
+ color={THEME.text}
147
+ style={styles.timelinePlace}
148
+ >
149
+ {trip.to.city}
150
+ {trip.to.area ? `, ${trip.to.area}` : ""}
151
+ </RNText>
152
+ </View>
153
+ </View>
154
+
155
+ <View style={styles.footer}>
156
+ <RNText font="semibold" size={15} color={THEME.text}>
157
+ {trip.date}, {trip.weekday}
158
+ </RNText>
159
+ <RNText font="semibold" size={15} color={THEME.text}>
160
+ {t('common.seatCount', { count: 1 })}
161
+ </RNText>
162
+ </View>
163
+ </Card>
164
+ </TouchableOpacity>
165
+ );
166
+ };
167
+
168
+ export default TripCard;
169
+
170
+ const styles = StyleSheet.create({
171
+ card: {
172
+ borderRadius: moderateScale(20),
173
+ },
174
+ headerRow: {
175
+ flexDirection: "row",
176
+ alignItems: "center",
177
+ },
178
+ headerInfo: {
179
+ flex: 1,
180
+ marginLeft: moderateScale(12),
181
+ },
182
+ metaRow: {
183
+ flexDirection: "row",
184
+ alignItems: "center",
185
+ marginTop: moderateScale(2),
186
+ },
187
+ metaDot: {
188
+ marginHorizontal: moderateScale(4),
189
+ },
190
+ ratingValue: {
191
+ marginLeft: moderateScale(3),
192
+ },
193
+ confirmedRow: {
194
+ flexDirection: "row",
195
+ alignItems: "center",
196
+ },
197
+ confirmedLabel: {
198
+ marginLeft: moderateScale(4),
199
+ },
200
+ timelineWrap: {
201
+ marginTop: moderateScale(14),
202
+ },
203
+ timelineRow: {
204
+ flexDirection: "row",
205
+ alignItems: "center",
206
+ },
207
+ timelineTime: {
208
+ width: moderateScale(44),
209
+ },
210
+ timelinePlace: {
211
+ flex: 1,
212
+ marginLeft: moderateScale(12),
213
+ },
214
+ timelineDotFilled: {
215
+ width: moderateScale(9),
216
+ height: moderateScale(9),
217
+ borderRadius: moderateScale(5),
218
+ backgroundColor: THEME.primary,
219
+ },
220
+ timelineConnector: {
221
+ flexDirection: "row",
222
+ },
223
+ timeColSpacer: {
224
+ width: moderateScale(44),
225
+ },
226
+ timelineDashCol: {
227
+ width: moderateScale(9),
228
+ alignItems: "center",
229
+ paddingVertical: moderateScale(2),
230
+ },
231
+ timelineDashSegment: {
232
+ width: moderateScale(1.5),
233
+ height: moderateScale(3),
234
+ marginVertical: moderateScale(1.5),
235
+ backgroundColor: THEME.primary,
236
+ opacity: 0.6,
237
+ },
238
+ footer: {
239
+ flexDirection: "row",
240
+ justifyContent: "space-between",
241
+ alignItems: "center",
242
+ marginTop: moderateScale(14),
243
+ paddingTop: moderateScale(12),
244
+ borderTopWidth: 1,
245
+ borderTopColor: THEME.divider,
246
+ },
247
+ });
@@ -0,0 +1,106 @@
1
+ import React from "react";
2
+ import {
3
+ Image,
4
+ StyleProp,
5
+ StyleSheet,
6
+ TouchableOpacity,
7
+ View,
8
+ ViewStyle,
9
+ } from "react-native";
10
+ import { moderateScale } from "react-native-size-matters";
11
+ import { SPACING, THEME } from "../../theme";
12
+ import RNText from "../Text/RNText";
13
+ import { CloseIcon, CloudUploadIcon } from "../Icon/SvgIcons";
14
+ import { useLanguage } from "../../localization";
15
+
16
+ interface UploadBoxProps {
17
+ title: string;
18
+ hint?: string;
19
+ imageUri?: string | null;
20
+ onPress?: () => void;
21
+ onRemove?: () => void;
22
+ height?: number;
23
+ containerStyle?: StyleProp<ViewStyle>;
24
+ }
25
+
26
+ /**
27
+ * Dashed upload card used across the driver onboarding flow
28
+ * (driving license front/back, document uploads). Shows an upload
29
+ * prompt when empty and an image preview with a remove action once filled.
30
+ */
31
+ const UploadBox: React.FC<UploadBoxProps> = ({
32
+ title,
33
+ hint,
34
+ imageUri,
35
+ onPress,
36
+ onRemove,
37
+ height = moderateScale(130),
38
+ containerStyle,
39
+ }) => {
40
+ const { t } = useLanguage();
41
+ const hintText = hint ?? t("common.uploadFormatsHint");
42
+ if (imageUri) {
43
+ return (
44
+ <View style={[styles.box, styles.filled, { height }, containerStyle]}>
45
+ <Image source={{ uri: imageUri }} style={StyleSheet.absoluteFill} />
46
+ <TouchableOpacity
47
+ style={styles.remove}
48
+ onPress={onRemove}
49
+ hitSlop={8}
50
+ >
51
+ <CloseIcon size={moderateScale(14)} color="#fff" />
52
+ </TouchableOpacity>
53
+ </View>
54
+ );
55
+ }
56
+
57
+ return (
58
+ <TouchableOpacity
59
+ activeOpacity={0.8}
60
+ onPress={onPress}
61
+ style={[styles.box, { height }, containerStyle]}
62
+ >
63
+ <CloudUploadIcon size={moderateScale(28)} color={THEME.primary} />
64
+ <RNText font="bold" size={14} color={THEME.text} style={styles.title}>
65
+ {title}
66
+ </RNText>
67
+ {hintText ? (
68
+ <RNText size={12} color={THEME.textSecondary} style={styles.hint}>
69
+ {hintText}
70
+ </RNText>
71
+ ) : null}
72
+ </TouchableOpacity>
73
+ );
74
+ };
75
+
76
+ export default UploadBox;
77
+
78
+ const styles = StyleSheet.create({
79
+ box: {
80
+ borderRadius: SPACING.radiusLg,
81
+ borderWidth: 1.5,
82
+ borderColor: THEME.primary,
83
+ borderStyle: "dashed",
84
+ backgroundColor: THEME.primaryFaint,
85
+ alignItems: "center",
86
+ justifyContent: "center",
87
+ paddingHorizontal: moderateScale(16),
88
+ },
89
+ filled: {
90
+ overflow: "hidden",
91
+ backgroundColor: THEME.surfaceMuted,
92
+ },
93
+ title: { marginTop: moderateScale(10) },
94
+ hint: { marginTop: moderateScale(4) },
95
+ remove: {
96
+ position: "absolute",
97
+ top: moderateScale(8),
98
+ right: moderateScale(8),
99
+ width: moderateScale(24),
100
+ height: moderateScale(24),
101
+ borderRadius: moderateScale(12),
102
+ backgroundColor: THEME.primary,
103
+ alignItems: "center",
104
+ justifyContent: "center",
105
+ },
106
+ });
@@ -0,0 +1,76 @@
1
+ import React, { memo } from "react";
2
+ import {
3
+ ImageBackground,
4
+ ImageSourcePropType,
5
+ StatusBar,
6
+ StyleProp,
7
+ StyleSheet,
8
+ View,
9
+ ViewStyle,
10
+ } from "react-native";
11
+ import LinearGradient from "react-native-linear-gradient";
12
+ import { SafeAreaView, Edges } from "react-native-safe-area-context";
13
+ import { THEME } from "../../theme";
14
+
15
+ interface MainContainerProps {
16
+ children?: React.ReactNode;
17
+ background?: ImageSourcePropType | null;
18
+ edges?: Edges;
19
+ bgColor?: string;
20
+ statusBarStyle?: "light-content" | "dark-content";
21
+ style?: StyleProp<ViewStyle>;
22
+ contentStyle?: StyleProp<ViewStyle>;
23
+ gradient?: boolean;
24
+ gradientColors?: string[];
25
+ gradientStart?: { x: number; y: number };
26
+ gradientEnd?: { x: number; y: number };
27
+ }
28
+
29
+ const MainContainer: React.FC<MainContainerProps> = memo(
30
+ ({
31
+ children,
32
+ background,
33
+ edges = ["top", "bottom"] as const,
34
+ bgColor = THEME.background,
35
+ statusBarStyle = "dark-content",
36
+ style,
37
+ contentStyle,
38
+ gradient = false,
39
+ gradientColors = ["#FAE1CF", "#FFFFFF"],
40
+ gradientStart = { x: 0, y: 0 },
41
+ gradientEnd = { x: 0, y: 0.4 },
42
+ }) => (
43
+ <View style={[styles.root, { backgroundColor: bgColor }, style]}>
44
+ <StatusBar
45
+ barStyle={statusBarStyle}
46
+ backgroundColor="transparent"
47
+ translucent
48
+ />
49
+ {gradient ? (
50
+ <LinearGradient
51
+ colors={gradientColors}
52
+ start={gradientStart}
53
+ end={gradientEnd}
54
+ style={StyleSheet.absoluteFill}
55
+ />
56
+ ) : null}
57
+ {background ? (
58
+ <ImageBackground
59
+ source={background}
60
+ style={StyleSheet.absoluteFill}
61
+ resizeMode="cover"
62
+ />
63
+ ) : null}
64
+ <SafeAreaView edges={edges} style={[styles.safe, contentStyle]}>
65
+ {children}
66
+ </SafeAreaView>
67
+ </View>
68
+ ),
69
+ );
70
+
71
+ export default MainContainer;
72
+
73
+ const styles = StyleSheet.create({
74
+ root: { flex: 1 },
75
+ safe: { flex: 1 },
76
+ });
@@ -0,0 +1 @@
1
+ export {default as MainContainer} from "./MainContainer"
@@ -0,0 +1,143 @@
1
+ import React from "react";
2
+ import {
3
+ StyleProp,
4
+ StyleSheet,
5
+ TouchableOpacity,
6
+ View,
7
+ ViewStyle,
8
+ } from "react-native";
9
+ import { useNavigation } from "@react-navigation/native";
10
+ import { useSafeAreaInsets } from "react-native-safe-area-context";
11
+ import { moderateScale } from "react-native-size-matters";
12
+ import { SIZES, THEME } from "../../theme";
13
+ import { ChevronLeftIcon } from "../Icon/SvgIcons";
14
+ import RNText from "../Text/RNText";
15
+
16
+ export interface HeaderProps {
17
+ title?: string;
18
+ titleColor?: string;
19
+ rightLabel?: string;
20
+ onRightPress?: () => void;
21
+ rightIcon?: React.ReactNode;
22
+ leftIcon?: React.ReactNode;
23
+ onBack?: () => void;
24
+ showBack?: boolean;
25
+ safeArea?: boolean;
26
+ background?: string;
27
+ containerStyle?: StyleProp<ViewStyle>;
28
+ }
29
+
30
+ const Header: React.FC<HeaderProps> = ({
31
+ title,
32
+ titleColor = THEME.text,
33
+ rightLabel,
34
+ onRightPress,
35
+ rightIcon,
36
+ leftIcon,
37
+ onBack,
38
+ showBack = true,
39
+ safeArea = true,
40
+ background = "transparent",
41
+ containerStyle,
42
+ }) => {
43
+ const nav = useNavigation();
44
+ const insets = useSafeAreaInsets();
45
+
46
+ const handleBack = () => {
47
+ if (onBack) return onBack();
48
+ if (nav.canGoBack()) nav.goBack();
49
+ };
50
+
51
+ return (
52
+ <View
53
+ style={[
54
+ styles.container,
55
+ { backgroundColor: background },
56
+ safeArea && { paddingTop: insets.top + moderateScale(6) },
57
+ containerStyle,
58
+ ]}
59
+ >
60
+ <View style={styles.side}>
61
+ {showBack || leftIcon ? (
62
+ <TouchableOpacity
63
+ onPress={handleBack}
64
+ activeOpacity={0.7}
65
+ hitSlop={10}
66
+ style={styles.iconBtn}
67
+ >
68
+ {leftIcon ?? (
69
+ <ChevronLeftIcon size={moderateScale(22)} color={THEME.text} />
70
+ )}
71
+ </TouchableOpacity>
72
+ ) : null}
73
+ </View>
74
+
75
+ <View style={styles.titleWrap}>
76
+ {title ? (
77
+ <RNText
78
+ font="semibold"
79
+ size={17}
80
+ color={titleColor}
81
+ numberOfLines={1}
82
+ textAlign="center"
83
+ >
84
+ {title}
85
+ </RNText>
86
+ ) : null}
87
+ </View>
88
+
89
+ <View style={[styles.side, styles.sideRight]}>
90
+ {rightLabel ? (
91
+ <TouchableOpacity
92
+ onPress={onRightPress}
93
+ activeOpacity={0.7}
94
+ hitSlop={10}
95
+ >
96
+ <RNText font="medium" size={14} color={THEME.primary}>
97
+ {rightLabel}
98
+ </RNText>
99
+ </TouchableOpacity>
100
+ ) : rightIcon ? (
101
+ <TouchableOpacity
102
+ onPress={onRightPress}
103
+ activeOpacity={0.7}
104
+ hitSlop={10}
105
+ style={styles.iconBtn}
106
+ >
107
+ {rightIcon}
108
+ </TouchableOpacity>
109
+ ) : null}
110
+ </View>
111
+ </View>
112
+ );
113
+ };
114
+
115
+ export default Header;
116
+
117
+ const styles = StyleSheet.create({
118
+ container: {
119
+ width: "100%",
120
+ flexDirection: "row",
121
+ alignItems: "center",
122
+ height: SIZES.headerHeight,
123
+ paddingHorizontal: moderateScale(8),
124
+ paddingBottom: moderateScale(8),
125
+ },
126
+ side: {
127
+ width: moderateScale(56),
128
+ alignItems: "flex-start",
129
+ justifyContent: "center",
130
+ },
131
+ sideRight: { alignItems: "flex-end" },
132
+ iconBtn: {
133
+ width: moderateScale(40),
134
+ height: moderateScale(40),
135
+ alignItems: "center",
136
+ justifyContent: "center",
137
+ },
138
+ titleWrap: {
139
+ flex: 1,
140
+ alignItems: "center",
141
+ justifyContent: "center",
142
+ },
143
+ });