noChargingOngoingPageComponent.tsx 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  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. const [newAvailableConnectors, setNewAvailableConnectors] = useState([]);
  11. useFocusEffect(
  12. useCallback(() => {
  13. let isMounted = true; // Simple cleanup flag
  14. const fetchAllConnectors = async () => {
  15. try {
  16. const newAvailableConnectors = await chargeStationService.NewfetchAvailableConnectors();
  17. // Only update state if component is still mounted
  18. if (isMounted) {
  19. // Sort the connectors based on stationID
  20. const sortedConnectors = [...newAvailableConnectors].sort((a, b) => {
  21. // Custom sorting order
  22. const order = {
  23. '2405311022116801000': 1, // 觀塘偉業街
  24. '2411291610329331000': 2, // 黃竹坑
  25. '2501161430118231000': 3 // 沙頭角
  26. };
  27. return (order[a.stationID] || 999) - (order[b.stationID] || 999);
  28. });
  29. setNewAvailableConnectors(sortedConnectors);
  30. }
  31. } catch (error) {
  32. console.error('Fetch error:', error);
  33. }
  34. };
  35. fetchAllConnectors();
  36. // Simple cleanup - prevents state updates if component unmounts
  37. return () => {
  38. isMounted = false;
  39. };
  40. }, []) // Add any missing dependencies here if needed
  41. );
  42. const StationRow = ({ item }: { item: any }) => {
  43. //use different image for different station based on station id, if not found, use default image.
  44. const stationID = item.stationID;
  45. const stationImages = {
  46. //沙頭角
  47. '2501161430118231000': require('../../assets/dummyStationPicture5.jpeg'),
  48. //黃竹坑
  49. '2411291610329331000': require('../../assets/dummyStationPicture4.jpeg'),
  50. //觀塘
  51. '2405311022116801000': require('../../assets/dummyStationPicture.png')
  52. };
  53. // const imageSource = stationImages[stationID] || require('../../assets/dummyStationPicture.png');
  54. const imgObj = item.image? {uri: item.image} : require('../../assets/dummyStationPicture.png')
  55. return (
  56. <Pressable
  57. onPress={() => {
  58. router.push({
  59. pathname: '/resultDetailPage',
  60. params: {
  61. chargeStationAddress: item.address,
  62. chargeStationID: item.stationID,
  63. chargeStationName: item.stationName,
  64. availableConnectors: item.availableConnectors,
  65. // imageSource: imageSource
  66. imageSource: item.image,
  67. stationLng: item.stationLng,
  68. stationLat: item.stationLat
  69. }
  70. });
  71. }}
  72. >
  73. <View className="flex flex-1 flex-row w-full ">
  74. <Image style={styles.image} source={imgObj} />
  75. <View className="flex flex-col gap-2 mt-5 mr-2">
  76. <Text
  77. style={{
  78. fontWeight: '700',
  79. color: '#02677D',
  80. fontSize: 20
  81. }}
  82. >
  83. {item.stationName}
  84. </Text>
  85. <View className="flex flex-row justify-between space-x-2">
  86. <Text
  87. style={{
  88. fontWeight: '400',
  89. fontSize: 16,
  90. color: '#222222'
  91. }}
  92. >
  93. {item.address}
  94. </Text>
  95. </View>
  96. <Text
  97. style={{
  98. fontWeight: '400',
  99. fontSize: 16,
  100. color: '#888888'
  101. }}
  102. >
  103. 現時可用充電槍數目: {item.availableConnectors}
  104. </Text>
  105. </View>
  106. </View>
  107. </Pressable>
  108. );
  109. };
  110. return (
  111. <SafeAreaView edges={['top', 'left', 'right']} className="flex-1 bg-white">
  112. <ScrollView className="flex-1 mt-8 " nestedScrollEnabled={true} showsVerticalScrollIndicator={false}>
  113. <View className="">
  114. <View className="">
  115. <Text className="text-5xl pt-1 pb-6 mx-[5%]">暫無正在進行的充電</Text>
  116. <View>
  117. <Text className="text-lg mx-[5%] mb-6">立刻前往Crazy Charge 充電站充電吧!</Text>
  118. <View className="">
  119. {newAvailableConnectors?.map((item, index) => (
  120. <View key={index}>
  121. <View className="border-b border-gray-200" />
  122. <StationRow item={item} key={index} />
  123. </View>
  124. ))}
  125. </View>
  126. </View>
  127. </View>
  128. </View>
  129. </ScrollView>
  130. </SafeAreaView>
  131. );
  132. };
  133. const styles = StyleSheet.create({
  134. grayColor: {
  135. color: '#888888'
  136. },
  137. greenColor: {
  138. color: '#02677D'
  139. },
  140. image: {
  141. width: 100,
  142. height: 100,
  143. margin: 15,
  144. borderRadius: 10
  145. }
  146. });
  147. export default NoChargingOngoingPageComponent;
  148. // const styles = StyleSheet.create({
  149. // container: {
  150. // flexDirection: 'row',
  151. // width: '100%',
  152. // flex: 1
  153. // },
  154. // textContainer: {
  155. // flex: 1,
  156. // flexDirection: 'column',
  157. // gap: 8,
  158. // marginTop: 20,
  159. // marginRight: 8 // Add right margin to prevent text from touching the edge
  160. // }
  161. // });