noChargingOngoingPageComponent.tsx 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  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. import { useTranslation } from '../../util/hooks/useTranslation';
  8. // const RETRY_DELAY = 2000; // 2 seconds
  9. // const MAX_RETRIES = 3; // Maximum number of retry attempts
  10. const NoChargingOngoingPageComponent = () => {
  11. const { t, getCurrentLanguageConfig } = useTranslation(); // 使用翻译钩子
  12. const [newAvailableConnectors, setNewAvailableConnectors] = useState<any>([]);
  13. const isEn = getCurrentLanguageConfig()?.code === 'en';
  14. useFocusEffect(
  15. useCallback(() => {
  16. let isMounted = true; // Simple cleanup flag
  17. const fetchAllConnectors = async () => {
  18. try {
  19. const newAvailableConnectors = await chargeStationService.NewfetchAvailableConnectors(isEn);
  20. // Only update state if component is still mounted
  21. if (isMounted) {
  22. // Sort the connectors based on stationID
  23. const sortedConnectors = [...newAvailableConnectors].sort((a, b) => {
  24. // Custom sorting order
  25. const order: Record<string, number> = {
  26. '2405311022116801000': 1, // 觀塘偉業街
  27. '2411291610329331000': 2, // 黃竹坑
  28. '2501161430118231000': 3 // 沙頭角
  29. };
  30. return (order[a.stationID] || 999) - (order[b.stationID] || 999);
  31. });
  32. setNewAvailableConnectors(sortedConnectors);
  33. }
  34. } catch (error) {
  35. console.error('Fetch error:', error);
  36. }
  37. };
  38. fetchAllConnectors();
  39. // Simple cleanup - prevents state updates if component unmounts
  40. return () => {
  41. isMounted = false;
  42. };
  43. }, []) // Add any missing dependencies here if needed
  44. );
  45. const StationRow = ({ item }: { item: any }) => {
  46. let imgObj = null;
  47. if (item.image) {
  48. imgObj = { uri: item.image };
  49. } else {
  50. imgObj = require('../../assets/dummyStationPicture.png');
  51. }
  52. return (
  53. <Pressable
  54. onPress={() => {
  55. router.push({
  56. pathname: '/resultDetailPage',
  57. params: {
  58. chargeStationAddress: item.address,
  59. chargeStationID: item.stationID,
  60. chargeStationName: item.stationName,
  61. availableConnectors: item.availableConnectors,
  62. imageSource: item.image,
  63. stationLng: item.stationLng,
  64. stationLat: item.stationLat,
  65. pricemodel_id: item.pricemodel_id
  66. }
  67. });
  68. }}
  69. >
  70. <View className="flex flex-1 flex-row w-full ">
  71. <Image style={styles.image} source={imgObj} />
  72. <View className="flex flex-col gap-2 mt-5 mr-2 flex-1">
  73. <Text
  74. style={{
  75. fontWeight: '700',
  76. color: '#02677D',
  77. fontSize: 20,
  78. flexWrap: 'wrap',
  79. flexShrink: 1
  80. }}
  81. numberOfLines={0}
  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. flexWrap: 'wrap',
  92. flexShrink: 1
  93. }}
  94. numberOfLines={0}
  95. >
  96. {item.address}
  97. </Text>
  98. </View>
  99. <Text
  100. style={{
  101. fontWeight: '400',
  102. fontSize: 16,
  103. color: '#888888',
  104. flexWrap: 'wrap',
  105. flexShrink: 1
  106. }}
  107. numberOfLines={0}
  108. >
  109. {t('charging.no_ongoing.available_connectors')}: {item.availableConnectors}
  110. </Text>
  111. </View>
  112. </View>
  113. </Pressable>
  114. );
  115. };
  116. return (
  117. <SafeAreaView edges={['top', 'left', 'right']} className="flex-1 bg-white">
  118. <ScrollView className="flex-1 mt-8 " nestedScrollEnabled={true} showsVerticalScrollIndicator={false}>
  119. <View>
  120. <View>
  121. <Text className="text-5xl pt-1 pb-6 mx-[5%]">{t('charging.no_ongoing.title')}</Text>
  122. <View>
  123. <Text className="text-lg mx-[5%] mb-6">{t('charging.no_ongoing.subtitle')}</Text>
  124. <View>
  125. {newAvailableConnectors?.map((item: any, index: number) => (
  126. <View key={index}>
  127. <View className="border-b border-gray-200" />
  128. <StationRow item={item} key={index} />
  129. </View>
  130. ))}
  131. </View>
  132. </View>
  133. </View>
  134. </View>
  135. </ScrollView>
  136. </SafeAreaView>
  137. );
  138. };
  139. const styles = StyleSheet.create({
  140. grayColor: {
  141. color: '#888888'
  142. },
  143. greenColor: {
  144. color: '#02677D'
  145. },
  146. image: {
  147. width: 100,
  148. height: 100,
  149. margin: 15,
  150. borderRadius: 10
  151. }
  152. });
  153. export default NoChargingOngoingPageComponent;