@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,231 @@
1
+ import React, { useState } from 'react';
2
+ import {
3
+ Image,
4
+ ScrollView,
5
+ StyleSheet,
6
+ TouchableOpacity,
7
+ View,
8
+ } from 'react-native';
9
+ import { moderateScale } from 'react-native-size-matters';
10
+ import { showMessage } from 'react-native-flash-message';
11
+
12
+ import { Header, MainContainer, RNButton, RNText } from '../../components';
13
+ import { CheckIcon } from '../../components/Icon/SvgIcons';
14
+ import { FONT_SIZE, SPACING, THEME } from '../../theme';
15
+ import { useLanguage } from '../../localization';
16
+ import { LanguageCode, LanguageOption } from '../../localization/languages';
17
+
18
+ const LOGO = require('../../assets/image/logo.png');
19
+
20
+ interface LanguageSelectionProps {
21
+ /** "onboarding" = first-launch step, "settings" = change later */
22
+ route?: { params?: { mode?: 'onboarding' | 'settings' } };
23
+ }
24
+
25
+ const LanguageSelection: React.FC<LanguageSelectionProps> = ({ route }) => {
26
+ const mode = route?.params?.mode ?? 'onboarding';
27
+ const isOnboarding = mode === 'onboarding';
28
+
29
+ const { t, current, languages, changeLanguage } = useLanguage();
30
+ const [selected, setSelected] = useState<LanguageCode>(current);
31
+
32
+ const onCardPress = (lang: LanguageOption) => {
33
+ setSelected(lang.code);
34
+ if (!isOnboarding && lang.code !== current) {
35
+ // Settings mode applies instantly across the whole app.
36
+ changeLanguage(lang.code);
37
+ showMessage({
38
+ message: t('language.changedTo', { language: lang.nativeLabel }),
39
+ type: 'success',
40
+ });
41
+ }
42
+ };
43
+
44
+ const onContinue = () => {
45
+ changeLanguage(selected, { markSelected: true });
46
+ // Onboarding gate (StackNavigation) re-renders into the app automatically.
47
+ };
48
+
49
+ return (
50
+ <MainContainer gradient statusBarStyle="light-content">
51
+ {!isOnboarding && (
52
+ <Header title={t('language.settingsTitle')} safeArea={false} />
53
+ )}
54
+
55
+ <ScrollView
56
+ contentContainerStyle={styles.scroll}
57
+ showsVerticalScrollIndicator={false}
58
+ >
59
+ {isOnboarding && (
60
+ <View style={styles.brand}>
61
+ <View style={styles.logoWrap}>
62
+ <Image source={LOGO} style={styles.logo} resizeMode="contain" />
63
+ </View>
64
+ </View>
65
+ )}
66
+
67
+ <View style={styles.titleBlock}>
68
+ <RNText font="bold" size={FONT_SIZE.h4} color={THEME.text}>
69
+ {isOnboarding
70
+ ? t('language.onboardingTitle')
71
+ : t('language.settingsTitle')}
72
+ </RNText>
73
+ <RNText
74
+ size={FONT_SIZE.base}
75
+ color={THEME.textSecondary}
76
+ style={styles.subtitle}
77
+ >
78
+ {isOnboarding
79
+ ? t('language.onboardingSubtitle')
80
+ : t('language.settingsSubtitle')}
81
+ </RNText>
82
+ </View>
83
+
84
+ <View style={styles.list}>
85
+ {languages.map(lang => (
86
+ <LanguageCard
87
+ key={lang.code}
88
+ lang={lang}
89
+ active={selected === lang.code}
90
+ onPress={() => onCardPress(lang)}
91
+ />
92
+ ))}
93
+ </View>
94
+ </ScrollView>
95
+
96
+ {isOnboarding && (
97
+ <View style={styles.footer}>
98
+ <RNButton title={t('common.continue')} onPress={onContinue} />
99
+ </View>
100
+ )}
101
+ </MainContainer>
102
+ );
103
+ };
104
+
105
+ const LanguageCard: React.FC<{
106
+ lang: LanguageOption;
107
+ active: boolean;
108
+ onPress: () => void;
109
+ }> = ({ lang, active, onPress }) => (
110
+ <TouchableOpacity
111
+ activeOpacity={0.85}
112
+ onPress={onPress}
113
+ style={[styles.card, active && styles.cardActive]}
114
+ >
115
+ <View style={styles.flagWrap}>
116
+ <RNText size={moderateScale(26)}>{lang.flag}</RNText>
117
+ </View>
118
+ <View style={styles.cardText}>
119
+ <RNText font="semibold" size={FONT_SIZE.xl} color={THEME.text}>
120
+ {lang.nativeLabel}
121
+ </RNText>
122
+ <RNText
123
+ size={FONT_SIZE.sm}
124
+ color={THEME.textSecondary}
125
+ style={styles.cardSub}
126
+ >
127
+ {lang.englishLabel}
128
+ </RNText>
129
+ </View>
130
+ <View style={[styles.radio, active && styles.radioActive]}>
131
+ {active ? (
132
+ <CheckIcon size={moderateScale(14)} color={THEME.textOnPrimary} />
133
+ ) : null}
134
+ </View>
135
+ </TouchableOpacity>
136
+ );
137
+
138
+ export default LanguageSelection;
139
+
140
+ const styles = StyleSheet.create({
141
+ scroll: {
142
+ flexGrow: 1,
143
+ paddingHorizontal: SPACING.hPadding,
144
+ paddingTop: moderateScale(12),
145
+ paddingBottom: moderateScale(24),
146
+ },
147
+ brand: {
148
+ alignItems: 'center',
149
+ marginTop: moderateScale(24),
150
+ marginBottom: moderateScale(28),
151
+ },
152
+ logoWrap: {
153
+ width: moderateScale(96),
154
+ height: moderateScale(96),
155
+ borderRadius: moderateScale(28),
156
+ backgroundColor: THEME.surface,
157
+ alignItems: 'center',
158
+ justifyContent: 'center',
159
+ shadowColor: THEME.shadow,
160
+ shadowOffset: { width: 0, height: 8 },
161
+ shadowOpacity: 1,
162
+ shadowRadius: 16,
163
+ elevation: 4,
164
+ },
165
+ logo: {
166
+ width: moderateScale(64),
167
+ height: moderateScale(64),
168
+ },
169
+ titleBlock: {
170
+ marginBottom: moderateScale(24),
171
+ },
172
+ subtitle: {
173
+ marginTop: moderateScale(8),
174
+ lineHeight: moderateScale(20),
175
+ },
176
+ list: {
177
+ gap: moderateScale(14),
178
+ },
179
+ card: {
180
+ flexDirection: 'row',
181
+ alignItems: 'center',
182
+ backgroundColor: THEME.surface,
183
+ borderRadius: moderateScale(18),
184
+ paddingVertical: moderateScale(16),
185
+ paddingHorizontal: moderateScale(16),
186
+ borderWidth: 1.5,
187
+ borderColor: THEME.border,
188
+ shadowColor: THEME.shadow,
189
+ shadowOffset: { width: 0, height: 4 },
190
+ shadowOpacity: 1,
191
+ shadowRadius: 10,
192
+ elevation: 2,
193
+ },
194
+ cardActive: {
195
+ borderColor: THEME.primary,
196
+ backgroundColor: THEME.primaryFaint,
197
+ },
198
+ flagWrap: {
199
+ width: moderateScale(48),
200
+ height: moderateScale(48),
201
+ borderRadius: moderateScale(14),
202
+ backgroundColor: THEME.backgroundAlt,
203
+ alignItems: 'center',
204
+ justifyContent: 'center',
205
+ },
206
+ cardText: {
207
+ flex: 1,
208
+ marginLeft: moderateScale(14),
209
+ },
210
+ cardSub: {
211
+ marginTop: moderateScale(2),
212
+ },
213
+ radio: {
214
+ width: moderateScale(24),
215
+ height: moderateScale(24),
216
+ borderRadius: moderateScale(12),
217
+ borderWidth: 2,
218
+ borderColor: THEME.inputBorder,
219
+ alignItems: 'center',
220
+ justifyContent: 'center',
221
+ },
222
+ radioActive: {
223
+ backgroundColor: THEME.primary,
224
+ borderColor: THEME.primary,
225
+ },
226
+ footer: {
227
+ paddingHorizontal: SPACING.hPadding,
228
+ paddingTop: moderateScale(8),
229
+ paddingBottom: moderateScale(8),
230
+ },
231
+ });
@@ -0,0 +1,36 @@
1
+ import React from "react";
2
+ import { StyleSheet, Text, View } from "react-native";
3
+ import { SafeAreaView } from "react-native-safe-area-context";
4
+ import { moderateScale } from "react-native-size-matters";
5
+ import { FONTS } from "../../../theme/fonts";
6
+ import { THEME } from "../../../theme";
7
+
8
+ const Home = () => {
9
+ return (
10
+ <SafeAreaView style={styles.container}>
11
+ <View style={styles.content}>
12
+ <Text style={styles.title}>Home Screen</Text>
13
+ </View>
14
+ </SafeAreaView>
15
+ );
16
+ };
17
+
18
+ export default Home;
19
+
20
+ const styles = StyleSheet.create({
21
+ container: {
22
+ flex: 1,
23
+ backgroundColor: THEME.background,
24
+ },
25
+ content: {
26
+ flex: 1,
27
+ alignItems: "center",
28
+ justifyContent: "center",
29
+ paddingHorizontal: moderateScale(24),
30
+ },
31
+ title: {
32
+ fontFamily: FONTS.bold,
33
+ fontSize: moderateScale(22),
34
+ color: THEME.text,
35
+ },
36
+ });
@@ -0,0 +1,69 @@
1
+ import React from "react";
2
+ import { StyleSheet, Text, TouchableOpacity, View } from "react-native";
3
+ import { SafeAreaView } from "react-native-safe-area-context";
4
+ import { moderateScale } from "react-native-size-matters";
5
+ import { useDispatch } from "react-redux";
6
+ import { logout } from "../../../redux/slice/auth";
7
+ import { clearStorageValue } from "../../../services/storage";
8
+ import { IS_LOGGED_IN } from "../../../utils/constants";
9
+ import { FONTS } from "../../../theme/fonts";
10
+ import { THEME } from "../../../theme";
11
+
12
+ const Profile = () => {
13
+ const dispatch = useDispatch();
14
+
15
+ const onLogout = () => {
16
+ // Clear the persisted dummy session, then reset auth state. The top-level
17
+ // guard swaps back to the Auth (Login) stack automatically.
18
+ clearStorageValue(IS_LOGGED_IN);
19
+ dispatch(logout());
20
+ };
21
+
22
+ return (
23
+ <SafeAreaView style={styles.container}>
24
+ <View style={styles.content}>
25
+ <Text style={styles.title}>Profile Screen</Text>
26
+
27
+ <TouchableOpacity
28
+ style={styles.button}
29
+ activeOpacity={0.8}
30
+ onPress={onLogout}
31
+ >
32
+ <Text style={styles.buttonText}>Logout</Text>
33
+ </TouchableOpacity>
34
+ </View>
35
+ </SafeAreaView>
36
+ );
37
+ };
38
+
39
+ export default Profile;
40
+
41
+ const styles = StyleSheet.create({
42
+ container: {
43
+ flex: 1,
44
+ backgroundColor: THEME.background,
45
+ },
46
+ content: {
47
+ flex: 1,
48
+ alignItems: "center",
49
+ justifyContent: "center",
50
+ paddingHorizontal: moderateScale(24),
51
+ },
52
+ title: {
53
+ fontFamily: FONTS.bold,
54
+ fontSize: moderateScale(22),
55
+ color: THEME.text,
56
+ marginBottom: moderateScale(28),
57
+ },
58
+ button: {
59
+ backgroundColor: THEME.danger,
60
+ paddingVertical: moderateScale(14),
61
+ paddingHorizontal: moderateScale(44),
62
+ borderRadius: moderateScale(12),
63
+ },
64
+ buttonText: {
65
+ fontFamily: FONTS.semibold,
66
+ fontSize: moderateScale(16),
67
+ color: THEME.textOnPrimary,
68
+ },
69
+ });
@@ -0,0 +1,308 @@
1
+ import React, { useEffect, useRef, useState } from "react";
2
+ import {
3
+ FlatList,
4
+ KeyboardAvoidingView,
5
+ Platform,
6
+ StyleSheet,
7
+ TextInput,
8
+ TouchableOpacity,
9
+ View,
10
+ } from "react-native";
11
+ import { useNavigation, useRoute } from "@react-navigation/native";
12
+ import { useDispatch, useSelector } from "react-redux";
13
+ import { moderateScale } from "react-native-size-matters";
14
+ import Svg, { Path } from "react-native-svg";
15
+ import { Avatar, MainContainer, RNText } from "../../components";
16
+ import { THEME, SPACING, FONTS } from "../../theme";
17
+ import { RootState } from "../../redux/store";
18
+ import { sendMessage } from "../../redux/slice/chat";
19
+ import { useLanguage } from "../../localization";
20
+ import {
21
+ ArrowRightIcon,
22
+ ArrowRightSmallIcon,
23
+ CarIcon,
24
+ ChevronLeftIcon,
25
+ } from "../../components/Icon/SvgIcons";
26
+
27
+ const SendPlaneIcon: React.FC<{ size?: number; color?: string }> = ({
28
+ size = 18,
29
+ color = "#fff",
30
+ }) => (
31
+ <Svg width={size} height={size} viewBox="0 0 24 24" fill="none">
32
+ <Path
33
+ d="M21.5 2.5L11 13"
34
+ stroke={color}
35
+ strokeWidth={1.8}
36
+ strokeLinecap="round"
37
+ strokeLinejoin="round"
38
+ />
39
+ <Path
40
+ d="M21.5 2.5L15 21.5L11 13L2.5 9L21.5 2.5Z"
41
+ stroke={color}
42
+ strokeWidth={1.8}
43
+ strokeLinecap="round"
44
+ strokeLinejoin="round"
45
+ />
46
+ </Svg>
47
+ );
48
+
49
+ const Chat: React.FC = () => {
50
+ const nav = useNavigation<any>();
51
+ const route = useRoute<any>();
52
+ const dispatch = useDispatch();
53
+ const { t } = useLanguage();
54
+ const flatListRef = useRef<FlatList>(null);
55
+ const convId = route.params?.conversationId || "c1";
56
+ const title = route.params?.title || "Matt Mitchell";
57
+ const conv = useSelector(
58
+ (s: RootState) =>
59
+ s.chat.conversations.find((c) => c.id === convId) ||
60
+ s.chat.conversations[0],
61
+ );
62
+ const [text, setText] = useState("");
63
+
64
+ useEffect(() => {
65
+ const t = setTimeout(
66
+ () => flatListRef.current?.scrollToEnd({ animated: false }),
67
+ 80,
68
+ );
69
+ return () => clearTimeout(t);
70
+ }, []);
71
+
72
+ const onSend = () => {
73
+ if (!text.trim()) return;
74
+ dispatch(sendMessage({ conversationId: conv.id, text }));
75
+ setText("");
76
+ setTimeout(
77
+ () => flatListRef.current?.scrollToEnd({ animated: true }),
78
+ 80,
79
+ );
80
+ };
81
+
82
+ return (
83
+ <MainContainer gradient>
84
+ <KeyboardAvoidingView
85
+ style={styles.flex}
86
+ behavior={Platform.OS === "ios" ? "padding" : undefined}
87
+ >
88
+ <View style={styles.header}>
89
+ <TouchableOpacity
90
+ onPress={() => nav.goBack()}
91
+ activeOpacity={0.7}
92
+ hitSlop={10}
93
+ style={styles.backBtn}
94
+ >
95
+ <ChevronLeftIcon size={moderateScale(22)} color={THEME.text} />
96
+ </TouchableOpacity>
97
+ <Avatar name={title} size={moderateScale(44)} />
98
+ <View style={styles.headerText}>
99
+ <RNText font="semibold" size={16} color={THEME.text}>
100
+ {title}
101
+ </RNText>
102
+ <RNText
103
+ size={12}
104
+ color={THEME.textMuted}
105
+ style={{ marginTop: moderateScale(2) }}
106
+ >
107
+ {t("messages.repliesIn")}
108
+ </RNText>
109
+ </View>
110
+ </View>
111
+
112
+ <View style={styles.routeBar}>
113
+ <View style={styles.routeRow}>
114
+ <CarIcon size={moderateScale(18)} color={THEME.primary} />
115
+ <RNText
116
+ font="semibold"
117
+ size={14}
118
+ color={THEME.text}
119
+ style={{ marginLeft: moderateScale(8) }}
120
+ >
121
+ {conv.route.from}
122
+ </RNText>
123
+ <ArrowRightSmallIcon
124
+ size={moderateScale(14)}
125
+ color={THEME.text}
126
+ />
127
+ <RNText font="semibold" size={14} color={THEME.text}>
128
+ {conv.route.to}
129
+ </RNText>
130
+ <View style={styles.flex} />
131
+ <ArrowRightIcon size={moderateScale(18)} color={THEME.text} />
132
+ </View>
133
+ <RNText
134
+ size={11}
135
+ color={THEME.textMuted}
136
+ style={{ marginTop: moderateScale(2), marginLeft: moderateScale(26) }}
137
+ >
138
+ {t("messages.passengerCount")}
139
+ </RNText>
140
+ </View>
141
+
142
+ <FlatList
143
+ ref={flatListRef}
144
+ data={conv.messages}
145
+ keyExtractor={(m) => m.id}
146
+ contentContainerStyle={styles.list}
147
+ showsVerticalScrollIndicator={false}
148
+ onContentSizeChange={() =>
149
+ flatListRef.current?.scrollToEnd({ animated: false })
150
+ }
151
+ renderItem={({ item }) => {
152
+ const isMine = item.sender === "me";
153
+ return (
154
+ <View
155
+ style={[
156
+ styles.bubble,
157
+ isMine ? styles.mine : styles.other,
158
+ ]}
159
+ >
160
+ <RNText
161
+ size={14}
162
+ color={isMine ? "#fff" : THEME.text}
163
+ style={styles.bubbleText}
164
+ >
165
+ {item.text}
166
+ </RNText>
167
+ <RNText
168
+ size={11}
169
+ color={
170
+ isMine ? "rgba(255,255,255,0.85)" : THEME.textMuted
171
+ }
172
+ style={styles.timeText}
173
+ >
174
+ {item.time}
175
+ </RNText>
176
+ </View>
177
+ );
178
+ }}
179
+ />
180
+
181
+ <View style={styles.inputBar}>
182
+ <View style={styles.inputWrap}>
183
+ <TextInput
184
+ value={text}
185
+ onChangeText={setText}
186
+ placeholder={t("messages.typeMessage")}
187
+ placeholderTextColor={THEME.textPlaceholder}
188
+ style={styles.input}
189
+ multiline
190
+ />
191
+ </View>
192
+ <TouchableOpacity
193
+ onPress={onSend}
194
+ style={styles.sendBtn}
195
+ activeOpacity={0.85}
196
+ >
197
+ <SendPlaneIcon size={moderateScale(18)} color="#fff" />
198
+ </TouchableOpacity>
199
+ </View>
200
+ </KeyboardAvoidingView>
201
+ </MainContainer>
202
+ );
203
+ };
204
+
205
+ export default Chat;
206
+
207
+ const styles = StyleSheet.create({
208
+ flex: { flex: 1 },
209
+ header: {
210
+ flexDirection: "row",
211
+ alignItems: "center",
212
+ paddingHorizontal: moderateScale(16),
213
+ paddingTop: moderateScale(8),
214
+ paddingBottom: moderateScale(12),
215
+ },
216
+ backBtn: {
217
+ width: moderateScale(36),
218
+ height: moderateScale(36),
219
+ alignItems: "flex-start",
220
+ justifyContent: "center",
221
+ },
222
+ headerText: {
223
+ marginLeft: moderateScale(10),
224
+ flex: 1,
225
+ },
226
+ routeBar: {
227
+ marginHorizontal: moderateScale(20),
228
+ paddingVertical: moderateScale(10),
229
+ borderTopWidth: 1,
230
+ borderBottomWidth: 1,
231
+ borderColor: THEME.divider,
232
+ },
233
+ routeRow: {
234
+ flexDirection: "row",
235
+ alignItems: "center",
236
+ gap: moderateScale(6),
237
+ },
238
+ list: {
239
+ paddingHorizontal: moderateScale(20),
240
+ paddingVertical: moderateScale(14),
241
+ gap: moderateScale(10),
242
+ },
243
+ bubble: {
244
+ maxWidth: "80%",
245
+ paddingHorizontal: moderateScale(14),
246
+ paddingVertical: moderateScale(10),
247
+ borderRadius: moderateScale(18),
248
+ },
249
+ mine: {
250
+ backgroundColor: THEME.primary,
251
+ alignSelf: "flex-end",
252
+ borderBottomRightRadius: moderateScale(6),
253
+ },
254
+ other: {
255
+ backgroundColor: "#F5E5D3",
256
+ alignSelf: "flex-start",
257
+ borderBottomLeftRadius: moderateScale(6),
258
+ },
259
+ bubbleText: {
260
+ lineHeight: moderateScale(20),
261
+ fontFamily: FONTS.regular,
262
+ },
263
+ timeText: {
264
+ marginTop: moderateScale(4),
265
+ },
266
+ inputBar: {
267
+ flexDirection: "row",
268
+ alignItems: "center",
269
+ paddingHorizontal: moderateScale(16),
270
+ paddingVertical: moderateScale(10),
271
+ gap: moderateScale(10),
272
+ },
273
+ inputWrap: {
274
+ flex: 1,
275
+ backgroundColor: "#fff",
276
+ borderRadius: SPACING.radiusPill,
277
+ paddingHorizontal: moderateScale(18),
278
+ paddingVertical: Platform.OS === "ios" ? moderateScale(12) : moderateScale(4),
279
+ minHeight: moderateScale(46),
280
+ justifyContent: "center",
281
+ shadowColor: THEME.shadow,
282
+ shadowOffset: { width: 0, height: 2 },
283
+ shadowOpacity: 0.08,
284
+ shadowRadius: 8,
285
+ elevation: 2,
286
+ },
287
+ input: {
288
+ fontFamily: FONTS.regular,
289
+ fontSize: moderateScale(14),
290
+ color: THEME.text,
291
+ padding: 0,
292
+ margin: 0,
293
+ maxHeight: moderateScale(100),
294
+ },
295
+ sendBtn: {
296
+ width: moderateScale(46),
297
+ height: moderateScale(46),
298
+ borderRadius: moderateScale(23),
299
+ backgroundColor: THEME.primary,
300
+ alignItems: "center",
301
+ justifyContent: "center",
302
+ shadowColor: THEME.primary,
303
+ shadowOffset: { width: 0, height: 4 },
304
+ shadowOpacity: 0.25,
305
+ shadowRadius: 8,
306
+ elevation: 4,
307
+ },
308
+ });