homePage.tsx 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. import { View, Text, ScrollView, FlatList, Pressable, ActivityIndicator, Image, Modal, Alert } from 'react-native';
  2. import NormalButton from '../global/normal_button';
  3. import { SafeAreaView } from 'react-native-safe-area-context';
  4. import { router } from 'expo-router';
  5. import { useColorScheme } from 'nativewind';
  6. import RecentlyBookedScrollView from '../global/recentlyBookedScrollView';
  7. import {
  8. BellIconSvg,
  9. HomeIconSvg,
  10. MyBookingIconSvg,
  11. MyVehicleIconSvg,
  12. QrCodeIconSvg,
  13. VipCodeIconSvg
  14. } from '../global/SVG';
  15. import { AuthContext } from '../../context/AuthProvider';
  16. import { useContext, useEffect, useState } from 'react';
  17. import { authenticationService } from '../../service/authService';
  18. import { chargeStationService } from '../../service/chargeStationService';
  19. import { walletService } from '../../service/walletService';
  20. import useUserInfoStore from '../../providers/userinfo_store';
  21. interface HomePageProps {}
  22. const HomePage: React.FC<HomePageProps> = () => {
  23. const now = new Date();
  24. const { user } = useContext(AuthContext);
  25. const { userID, currentPrice, setUserID, setCurrentPrice } = useUserInfoStore();
  26. const { colorScheme, toggleColorScheme } = useColorScheme();
  27. useEffect(() => {
  28. // Set to light mode on component mount
  29. if (colorScheme === 'dark') {
  30. toggleColorScheme();
  31. }
  32. }, []);
  33. // Effect for fetching user ID
  34. useEffect(() => {
  35. const fetchID = async () => {
  36. try {
  37. const response = await authenticationService.getUserInfo();
  38. if (response) {
  39. setUserID(response.data.id);
  40. } else {
  41. console.log('fail to set user ID');
  42. }
  43. } catch (error) {
  44. console.log(error);
  45. }
  46. };
  47. fetchID();
  48. }, []);
  49. useEffect(() => {
  50. const fetchCurrentPrice = async () => {
  51. try {
  52. const response = await chargeStationService.getCurrentPrice();
  53. if (response) {
  54. // console.log('main page fetch current price', response);
  55. setCurrentPrice(response);
  56. }
  57. } catch (error) {
  58. console.log('main page fetch current price error', error);
  59. }
  60. };
  61. fetchCurrentPrice();
  62. }, []);
  63. // Add new state for modal visibility
  64. const [showOnboarding, setShowOnboarding] = useState(true);
  65. const [mainPromotion, setMainPromotion] = useState([]);
  66. const [mainPromotionImage, setMainPromotionImage] = useState('');
  67. useEffect(() => {
  68. const fetchMainPromotion = async () => {
  69. try {
  70. const response = await chargeStationService.getAdvertise();
  71. if (response) {
  72. const mainPromo = response.filter((item: any) => item.is_main)[0];
  73. setMainPromotion(mainPromo);
  74. if (mainPromo) {
  75. const mainPromoImage = await chargeStationService.getProcessedImageUrl(mainPromo.image_url);
  76. if (mainPromoImage) {
  77. setMainPromotionImage(mainPromoImage);
  78. }
  79. }
  80. }
  81. } catch (error) {
  82. console.log('Error fetching promotion:', error);
  83. }
  84. };
  85. fetchMainPromotion();
  86. }, []);
  87. return (
  88. <SafeAreaView edges={['top', 'left', 'right']} className="flex-1 bg-white">
  89. {/* Add Modal component */}
  90. {mainPromotionImage && (
  91. <Modal
  92. animationType="fade"
  93. transparent={true}
  94. visible={showOnboarding}
  95. onRequestClose={() => setShowOnboarding(false)}
  96. >
  97. <Pressable
  98. className="flex-1 bg-black/50 items-center justify-center"
  99. onPress={() => setShowOnboarding(false)}
  100. >
  101. <View className="w-[120%] rounded-2xl ">
  102. <Image
  103. source={{ uri: mainPromotionImage }}
  104. className="w-full aspect-square "
  105. resizeMode="contain"
  106. />
  107. <Text className="text-center mt-4 mb-2 text-gray-200">點擊任意位置關閉</Text>
  108. </View>
  109. </Pressable>
  110. </Modal>
  111. )}
  112. <ScrollView showsVerticalScrollIndicator={false} className="flex-1 mx-[5%] ">
  113. <View className=" flex-1 pt-8 ">
  114. <View className="flex-row items-center pb-4">
  115. <HomeIconSvg />
  116. <View className="pl-2 flex-1 flex-column ">
  117. <View className="flex-row justify-between mr-[10%]">
  118. <Text className="text-lg text-left pb-1">你好!</Text>
  119. <View className="relative">
  120. {/* <Pressable onPress={() => router.push('notificationPage')}>
  121. <View className="w-6 h-6">
  122. <BellIconSvg />
  123. </View>
  124. <View className="absolute -top-2 -right-2 bg-red-500 rounded-full w-5 h-5 items-center justify-center">
  125. <Text className="text-white text-xs font-bold">3</Text>
  126. </View>
  127. </Pressable> */}
  128. </View>
  129. </View>
  130. <Text className="text-4xl font-light ">{user?.nickname}</Text>
  131. </View>
  132. </View>
  133. <View className=" flex-1 justify-center ">
  134. <Pressable onPress={() => router.push('searchPage')}>
  135. <View
  136. style={{
  137. borderWidth: 1,
  138. padding: 24,
  139. borderRadius: 12,
  140. borderColor: '#bbbbbb',
  141. maxWidth: '100%'
  142. }}
  143. >
  144. <Text style={{ color: '#888888', fontSize: 16 }}>搜尋充電站或地區..</Text>
  145. </View>
  146. </Pressable>
  147. </View>
  148. </View>
  149. {/* <View className="flex-1">
  150. <RecentlyBookedScrollView />
  151. </View> */}
  152. <View className="flex-1">
  153. <View className=" my-4">
  154. <NormalButton
  155. // onPress={() => console.log('掃瞄及充電')}
  156. onPress={() => router.push('scanQrPage')}
  157. title={
  158. <View className="flex flex-row space-x-2 items-center">
  159. <QrCodeIconSvg />
  160. <Text className="text-white font-bold text-lg">掃描及充電</Text>
  161. </View>
  162. }
  163. extendedStyle={{
  164. alignItems: 'flex-start',
  165. padding: 24
  166. }}
  167. />
  168. </View>
  169. <View className="flex-1 flex-row justify-between gap-6">
  170. <View className="flex-1">
  171. <NormalButton
  172. // onPress={() => router.push('bookingMenuPage')}
  173. onPress={() => Alert.alert('即將推出', '此功能即將推出,敬請期待!')}
  174. title={
  175. <View className="flex flex-row space-x-2 items-center ">
  176. <MyBookingIconSvg />
  177. <Text className="text-white font-bold text-lg">我的預約</Text>
  178. </View>
  179. }
  180. extendedStyle={{
  181. alignItems: 'flex-start',
  182. padding: 24
  183. }}
  184. />
  185. </View>
  186. <View className="flex-1">
  187. {/* <NormalButton
  188. onPress={() => router.push('myVehiclePage')}
  189. title={
  190. <View className="flex flex-row space-x-2 items-center">
  191. <MyVehicleIconSvg />
  192. <Text className="text-white font-bold text-lg">我的車輛</Text>
  193. </View>
  194. }
  195. extendedStyle={{
  196. alignItems: 'flex-start',
  197. padding: 24
  198. }}
  199. /> */}
  200. <NormalButton
  201. onPress={() => router.push('accountMainPage')}
  202. title={
  203. <View className="flex flex-row space-x-2 items-center">
  204. <MyVehicleIconSvg />
  205. <Text className="text-white font-bold text-lg">我的帳戶</Text>
  206. </View>
  207. }
  208. extendedStyle={{
  209. alignItems: 'flex-start',
  210. padding: 24
  211. }}
  212. />
  213. </View>
  214. </View>
  215. <View className="mt-4">
  216. <NormalButton
  217. // onPress={() => console.log('掃瞄及充電')}
  218. onPress={() => router.push('vipQrPage')}
  219. title={
  220. <View className="flex flex-row items-center space-x-2">
  221. <VipCodeIconSvg />
  222. <Text className="text-white font-bold text-lg">專屬會員二維碼</Text>
  223. </View>
  224. }
  225. extendedStyle={{
  226. alignItems: 'flex-start',
  227. padding: 24
  228. }}
  229. />
  230. </View>
  231. </View>
  232. </ScrollView>
  233. </SafeAreaView>
  234. );
  235. };
  236. export default HomePage;