noChargingOngoingPageComponent.tsx 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. import { View, Text, ScrollView, StyleSheet, ActivityIndicator, Pressable, Image } from 'react-native';
  2. import { SafeAreaView } from 'react-native-safe-area-context';
  3. import NormalButton from '../global/normal_button';
  4. import { router, useFocusEffect } from 'expo-router';
  5. import { useCallback, useEffect, useState } from 'react';
  6. import { chargeStationService } from '../../service/chargeStationService';
  7. // const RETRY_DELAY = 2000; // 2 seconds
  8. // const MAX_RETRIES = 3; // Maximum number of retry attempts
  9. const NoChargingOngoingPageComponent = () => {
  10. //fetch charge station info
  11. // const [chargeStationInfo, setChargeStationInfo] = useState([]);
  12. // const [availableConnectors, setAvailableConnectors] = useState({});
  13. // useEffect(() => {
  14. // const fetchChargeStationInfo = async () => {
  15. // try {
  16. // const chargeStationInfo = await chargeStationService.fetchAllChargeStations();
  17. // console.log('chargeStationInfo in noChargingOngoingPageComponent', chargeStationInfo);
  18. // const onlyWaiYipStreetStation = chargeStationInfo.filter(
  19. // (station) => station.id == '2405311022116801000'
  20. // );
  21. // setChargeStationInfo(onlyWaiYipStreetStation);
  22. // // setChargeStationInfo(chargeStationInfo);
  23. // } catch (error) {
  24. // console.error('Error fetching charge station info:', error);
  25. // }
  26. // };
  27. // fetchChargeStationInfo();
  28. // }, []);
  29. // useEffect(() => {
  30. // const fetchChargeStationInfo = async () => {
  31. // try {
  32. // const chargeStationInfo = await chargeStationService.fetchAllChargeStations();
  33. // setChargeStationInfo(chargeStationInfo);
  34. // } catch (error) {
  35. // console.error('Error fetching charge station info:', error);
  36. // }
  37. // };
  38. // fetchChargeStationInfo();
  39. // }, []);
  40. // const fetchConnectorWithRetry = async (stationId, retryCount = 0) => {
  41. // try {
  42. // const response = await chargeStationService.fetchAvailableConnectors(stationId);
  43. // if (response === 500 || !response) {
  44. // throw new Error('Server error');
  45. // }
  46. // return response;
  47. // } catch (error) {
  48. // if (retryCount < MAX_RETRIES) {
  49. // // console.log(`Retrying fetch for station ${stationId}, attempt ${retryCount + 1}`);
  50. // await new Promise((resolve) => setTimeout(resolve, RETRY_DELAY));
  51. // return fetchConnectorWithRetry(stationId, retryCount + 1);
  52. // }
  53. // // console.error(`Failed to fetch connectors for station ${stationId} after ${MAX_RETRIES} attempts:`, error);
  54. // return null;
  55. // }
  56. // };
  57. // useEffect(() => {
  58. // const fetchAllConnectors = async () => {
  59. // try {
  60. // const connectorData = {};
  61. // for (const station of chargeStationInfo) {
  62. // const stationConnectors = await fetchConnectorWithRetry(station.id);
  63. // if (stationConnectors !== null) {
  64. // connectorData[station.id] = stationConnectors;
  65. // // Update state immediately for each successful fetch
  66. // setAvailableConnectors((prev) => ({
  67. // ...prev,
  68. // [station.id]: stationConnectors
  69. // }));
  70. // }
  71. // }
  72. // } catch (error) {
  73. // console.error('Error fetching connectors:', error);
  74. // }
  75. // };
  76. // if (chargeStationInfo.length > 0) {
  77. // fetchAllConnectors();
  78. // }
  79. // }, [chargeStationInfo]);
  80. const [newAvailableConnectors, setNewAvailableConnectors] = useState([]);
  81. useFocusEffect(
  82. useCallback(() => {
  83. let isMounted = true; // Simple cleanup flag
  84. const fetchAllConnectors = async () => {
  85. try {
  86. const newAvailableConnectors = await chargeStationService.NewfetchAvailableConnectors();
  87. console.log('Fetched connectors:', newAvailableConnectors);
  88. // Only update state if component is still mounted
  89. if (isMounted) {
  90. // Sort the connectors based on stationID
  91. const sortedConnectors = [...newAvailableConnectors].sort((a, b) => {
  92. // Custom sorting order
  93. const order = {
  94. '2405311022116801000': 1, // 觀塘偉業街
  95. '2411291610329331000': 2, // 黃竹坑
  96. '2501161430118231000': 3 // 沙頭角
  97. };
  98. return (order[a.stationID] || 999) - (order[b.stationID] || 999);
  99. });
  100. console.log('newAvailableConnectors', sortedConnectors);
  101. setNewAvailableConnectors(sortedConnectors);
  102. }
  103. } catch (error) {
  104. console.error('Fetch error:', error);
  105. }
  106. };
  107. fetchAllConnectors();
  108. // Simple cleanup - prevents state updates if component unmounts
  109. return () => {
  110. isMounted = false;
  111. };
  112. }, []) // Add any missing dependencies here if needed
  113. );
  114. const StationRow = ({ item }: { item: any }) => {
  115. //use different image for different station based on station id, if not found, use default image.
  116. const stationID = item.stationID;
  117. const stationImages = {
  118. //沙頭角
  119. '2501161430118231000': require('../../assets/dummyStationPicture5.jpeg'),
  120. //黃竹坑
  121. '2411291610329331000': require('../../assets/dummyStationPicture4.jpeg'),
  122. //觀塘
  123. '2405311022116801000': require('../../assets/dummyStationPicture.png')
  124. };
  125. // const imageSource = stationImages[stationID] || require('../../assets/dummyStationPicture.png');
  126. return (
  127. <Pressable
  128. onPress={() => {
  129. router.push({
  130. pathname: '/resultDetailPage',
  131. params: {
  132. chargeStationAddress: item.address,
  133. chargeStationID: item.stationID,
  134. chargeStationName: item.stationName,
  135. availableConnectors: item.availableConnectors,
  136. // imageSource: imageSource
  137. imageSource: item.image,
  138. stationLng: item.stationLng,
  139. stationLat: item.stationLat
  140. }
  141. });
  142. }}
  143. >
  144. <View className="flex flex-1 flex-row w-full ">
  145. <Image style={styles.image} source={{ uri: item.image }} />
  146. <View className="flex flex-col gap-2 mt-5 mr-2">
  147. <Text
  148. style={{
  149. fontWeight: '700',
  150. color: '#02677D',
  151. fontSize: 20
  152. }}
  153. >
  154. {item.stationName}
  155. </Text>
  156. <View className="flex flex-row justify-between space-x-2">
  157. <Text
  158. style={{
  159. fontWeight: '400',
  160. fontSize: 16,
  161. color: '#222222'
  162. }}
  163. >
  164. {item.address}
  165. </Text>
  166. </View>
  167. <Text
  168. style={{
  169. fontWeight: '400',
  170. fontSize: 16,
  171. color: '#888888'
  172. }}
  173. >
  174. 現時可用充電槍數目: {item.availableConnectors}
  175. </Text>
  176. </View>
  177. </View>
  178. </Pressable>
  179. );
  180. };
  181. return (
  182. <SafeAreaView edges={['top', 'left', 'right']} className="flex-1 bg-white">
  183. <ScrollView className="flex-1 mt-8 " nestedScrollEnabled={true} showsVerticalScrollIndicator={false}>
  184. <View className="">
  185. <View className="">
  186. <Text className="text-5xl pt-1 pb-6 mx-[5%]">暫無正在進行的充電</Text>
  187. <View>
  188. <Text className="text-lg mx-[5%] mb-6">立刻前往Crazy Charge 充電站充電吧!</Text>
  189. <View className="">
  190. {newAvailableConnectors?.map((item, index) => (
  191. <View key={index}>
  192. <View className=" border-b border-gray-200" />
  193. <StationRow item={item} key={index} />
  194. </View>
  195. ))}
  196. </View>
  197. </View>
  198. </View>
  199. </View>
  200. </ScrollView>
  201. </SafeAreaView>
  202. );
  203. };
  204. const styles = StyleSheet.create({
  205. grayColor: {
  206. color: '#888888'
  207. },
  208. greenColor: {
  209. color: '#02677D'
  210. },
  211. image: {
  212. width: 100,
  213. height: 100,
  214. margin: 15,
  215. borderRadius: 10
  216. }
  217. });
  218. export default NoChargingOngoingPageComponent;
  219. // const styles = StyleSheet.create({
  220. // container: {
  221. // flexDirection: 'row',
  222. // width: '100%',
  223. // flex: 1
  224. // },
  225. // textContainer: {
  226. // flex: 1,
  227. // flexDirection: 'column',
  228. // gap: 8,
  229. // marginTop: 20,
  230. // marginRight: 8 // Add right margin to prevent text from touching the edge
  231. // }
  232. // });