accountMainPageComponent.tsx 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. import { View, Text, ScrollView, Image, Switch, Pressable, Dimensions, Linking, Alert, AppState } from 'react-native';
  2. import { SafeAreaView } from 'react-native-safe-area-context';
  3. import { router, useFocusEffect } from 'expo-router';
  4. import { useAuth } from '../../context/AuthProvider';
  5. import * as Notifications from 'expo-notifications';
  6. import { useColorScheme } from 'nativewind';
  7. import Constants from 'expo-constants';
  8. import { useState, useEffect, useCallback } from 'react';
  9. import {
  10. AccountSettingIconSvg,
  11. ActivitySvg,
  12. MyCarSvg,
  13. DarkModeSvg,
  14. QuestionMarkIconSvg,
  15. SettingIconSvg,
  16. VipCodeIcoonSvg,
  17. WalletSvg,
  18. NotificationSvg,
  19. BookingIconSvg,
  20. UserTermsSvg,
  21. LanguageSvg
  22. } from '../global/SVG';
  23. import { usePushNotifications } from '../../app/hooks/usePushNotifications';
  24. import useUserInfoStore from '../../providers/userinfo_store';
  25. import { authenticationService } from '../../service/authService';
  26. import { handleGoWhatsApp } from '../../util/index';
  27. import { useTranslation } from '../../util/hooks/useTranslation';
  28. import LanguageSwitcher from '../registrationMultiStepForm/formComponent/formPages/languageSwitcher';
  29. const AccountMainPageComponent = () => {
  30. const { user, logout } = useAuth();
  31. const { colorScheme, toggleColorScheme } = useColorScheme();
  32. const screenWidth = Dimensions.get('window').width;
  33. const imageWidth = screenWidth * 0.9; // 90% of screen width
  34. const aspectRatio = 210 / 375;
  35. const [notificationsEnabled, setNotificationsEnabled] = useState(false);
  36. const { expoPushToken, notification } = usePushNotifications();
  37. const { notifySessionID } = useUserInfoStore();
  38. const { t } = useTranslation();
  39. //everytime i am on this screen, i check if permission is granted.
  40. useFocusEffect(
  41. useCallback(() => {
  42. const checkPermissionsAndToken = async () => {
  43. const { status } = await Notifications.getPermissionsAsync();
  44. setNotificationsEnabled(status === 'granted');
  45. if (status === 'granted') {
  46. //if status is granted, then i will fetch latest expo token to see if it is the same as notify_session_id
  47. const latestToken = await Notifications.getExpoPushTokenAsync({
  48. projectId: Constants.expoConfig?.extra?.eas?.projectId
  49. });
  50. //TODO: if latestToken = notify_session_id, do nothing
  51. if (latestToken.data === notifySessionID) {
  52. return;
  53. } else {
  54. const res = await authenticationService.changeNotifySessionID(latestToken.data);
  55. if (res) {
  56. console.log('Change notifySessionID Successfully!');
  57. } else {
  58. Alert.alert(t('account.notification_update_failed'), t('common.try_again_later'));
  59. }
  60. }
  61. //TODO: if latestToken != notify_session_id, update notify_session_id to latestToken
  62. }
  63. };
  64. checkPermissionsAndToken();
  65. const subscription = AppState.addEventListener('change', (nextAppState: string) => {
  66. if (nextAppState === 'active') {
  67. checkPermissionsAndToken();
  68. }
  69. });
  70. return () => {
  71. subscription.remove();
  72. };
  73. }, [expoPushToken]) // Add expoPushToken as a dependency
  74. );
  75. const toggleNotifications = async () => {
  76. Alert.alert(t('account.notification_settings'), t('account.notification_settings_message'), [
  77. {
  78. text: t('common.cancel'),
  79. style: 'cancel'
  80. },
  81. {
  82. text: t('account.go_to_settings'),
  83. onPress: () => Linking.openSettings()
  84. }
  85. ]);
  86. };
  87. return (
  88. <SafeAreaView className="flex-1 bg-white dark:bg-[#05181C]" edges={['top', 'left', 'right']}>
  89. <ScrollView className="flex-1 mx-[5%]" showsVerticalScrollIndicator={false}>
  90. <View style={{ marginTop: 25 }}>
  91. <Text style={{ fontSize: 48 }} className="text-black dark:text-white">
  92. {user?.nickname}
  93. </Text>
  94. </View>
  95. <View className="flex-row justify-between mt-4 ">
  96. <Pressable
  97. className="h-[114px] w-[30%] bg-[#e7f2f8] dark:bg-[#253336] items-center justify-center rounded-xl"
  98. onPress={() => router.push('/(account)/(wallet)/walletPage')}
  99. >
  100. <WalletSvg isDark={colorScheme == 'dark'} />
  101. <Text className="text-black dark:text-[#36DFFF]">{t('account.wallet')}</Text>
  102. </Pressable>
  103. <Pressable
  104. className="h-[114px] w-[30%] bg-[#e7f2f8] dark:bg-[#253336] items-center justify-center rounded-xl"
  105. onPress={() => router.replace('vipQrPage')}
  106. >
  107. <VipCodeIcoonSvg isDark={colorScheme == 'dark'} />
  108. <Text className="text-black dark:text-[#36DFFF]">VIP Code</Text>
  109. </Pressable>
  110. <Pressable
  111. className="h-[114px] w-[30%] bg-[#e7f2f8] dark:bg-[#253336] items-center justify-center rounded-xl"
  112. onPress={() => router.push('/activityRecordPage')}
  113. >
  114. <ActivitySvg isDark={colorScheme == 'dark'} />
  115. <Text className="text-black text-center dark:text-[#36DFFF]">{t('account.charging_history')}</Text>
  116. </Pressable>
  117. </View>
  118. <View className="my-4">
  119. {/* <Pressable onPress={() => router.push('uberVerificationPage')}>
  120. <Image
  121. resizeMode="contain"
  122. source={require('../../assets/uber20008.png')}
  123. style={{ width: imageWidth, height: imageWidth * aspectRatio, alignSelf: 'center' }}
  124. />
  125. </Pressable> */}
  126. </View>
  127. <View className="w-full h-1 bg-[#DBE4E8] dark:bg-[#253336]" />
  128. <View>
  129. <View className="py-4">
  130. <Pressable
  131. onPress={() => router.push('/accountSettingPage')}
  132. className="flex-row items-center"
  133. hitSlop={{
  134. top: 10,
  135. bottom: 10,
  136. left: 10,
  137. right: 10
  138. }}
  139. >
  140. <AccountSettingIconSvg isDark={colorScheme == 'dark'} />
  141. <Text className="text-lg pl-2 text-black dark:text-white">{t('account.account_management')}</Text>
  142. </Pressable>
  143. </View>
  144. <View className="h-0.5 bg-[#f4f4f4] dark:bg-[#5E6C70]" />
  145. <View className="py-4">
  146. <Pressable
  147. onPress={() => handleGoWhatsApp()}
  148. className="flex-row items-center"
  149. hitSlop={{
  150. top: 10,
  151. bottom: 10,
  152. left: 10,
  153. right: 10
  154. }}
  155. >
  156. <QuestionMarkIconSvg isDark={colorScheme == 'dark'} />
  157. <Text className="text-lg pl-2 text-black dark:text-white">WhatsApp</Text>
  158. </Pressable>
  159. </View>
  160. <View className="h-0.5 bg-[#f4f4f4] dark:bg-[#5E6C70]" />
  161. <View className=" py-4 ">
  162. <Pressable
  163. className="flex-row items-center"
  164. hitSlop={{
  165. top: 10,
  166. bottom: 10,
  167. left: 10,
  168. right: 10
  169. }}
  170. >
  171. <View className="flex flex-row justify-between w-full">
  172. <View className="flex flex-row items-center">
  173. <NotificationSvg isDark={colorScheme == 'dark'} />
  174. <Text className="text-lg pl-2 text-black dark:text-white">{t('account.allow_notifications')}</Text>
  175. </View>
  176. <Switch className='mr-8' value={notificationsEnabled} onChange={toggleNotifications} />
  177. </View>
  178. </Pressable>
  179. </View>
  180. <View className="h-0.5 bg-[#f4f4f4] dark:bg-[#5E6C70]" />
  181. <View className="py-4">
  182. <Pressable
  183. className="flex-row items-center"
  184. hitSlop={{
  185. top: 10,
  186. bottom: 10,
  187. left: 10,
  188. right: 10
  189. }}
  190. >
  191. <View className="flex flex-row justify-between w-full">
  192. <View className="flex flex-row items-center">
  193. <LanguageSvg isDark={colorScheme == 'dark'} />
  194. <Text className="text-lg pl-2 text-black dark:text-white">{t('account.select_language')}</Text>
  195. </View>
  196. <LanguageSwitcher/>
  197. </View>
  198. </Pressable>
  199. </View>
  200. <View className="h-0.5 bg-[#f4f4f4] dark:bg-[#5E6C70]" />
  201. <View className="py-4">
  202. <Pressable
  203. onPress={() => router.push('/accountUserTermsPage')}
  204. className="flex-row items-center"
  205. hitSlop={{
  206. top: 10,
  207. bottom: 10,
  208. left: 10,
  209. right: 10
  210. }}
  211. >
  212. <UserTermsSvg />
  213. <Text className="text-lg pl-2 text-black dark:text-white">{t('account.user_terms')}</Text>
  214. </Pressable>
  215. </View>
  216. <View className="h-0.5 bg-[#f4f4f4] dark:bg-[#5E6C70]" />
  217. <View className="py-4">
  218. <Pressable
  219. onPress={logout}
  220. className="flex-row items-center"
  221. hitSlop={{
  222. top: 10,
  223. bottom: 10,
  224. left: 10,
  225. right: 10
  226. }}
  227. >
  228. <SettingIconSvg isDark={colorScheme == 'dark'} />
  229. <Text className="text-lg pl-2 text-black dark:text-white">{t('account.logout')}</Text>
  230. </Pressable>
  231. </View>
  232. <View className="h-0.5 bg-[#f4f4f4] dark:bg-[#5E6C70]" />
  233. </View>
  234. </ScrollView>
  235. </SafeAreaView>
  236. );
  237. };
  238. export default AccountMainPageComponent;