noChargingOngoingPageComponent.tsx 10 KB

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