chargingHurryUpPageComponent.tsx 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. import { View, Text, ScrollView, StyleSheet, ActivityIndicator, Alert, Modal } from 'react-native';
  2. import React, { useEffect, useState } from 'react';
  3. import { SafeAreaView } from 'react-native-safe-area-context';
  4. import NormalButton from '../global/normal_button';
  5. import { router } from 'expo-router';
  6. import { chargeStationService } from '../../service/chargeStationService';
  7. import { format, addHours } from 'date-fns';
  8. import { toZonedTime } from 'date-fns-tz';
  9. import { convertToHKTime } from '../../util/lib';
  10. const ChargingHurryUpPageComponent = ({ data = {} }) => {
  11. // ***************************************************************
  12. // 2 整個useEffect listen to data. 有新data就轉頁
  13. // ***************************************************************
  14. const reservationData = Array.isArray(data) ? data[0] : data;
  15. const [stationInfo, setStationInfo] = useState(null);
  16. const [loading, setLoading] = useState(false);
  17. const [isLoading, setIsLoading] = useState(false);
  18. const plan = reservationData.book_time === reservationData.end_time ? '充滿停機' : '按每度電結算';
  19. const kwh = reservationData.total_power === null ? '' : `${reservationData.total_power} kWh`;
  20. const walkinStatus = reservationData.book_time === reservationData.end_time ? true : false;
  21. useEffect(() => {
  22. setLoading(true);
  23. if (
  24. reservationData &&
  25. reservationData.connector &&
  26. reservationData.connector.EquipmentID &&
  27. reservationData.connector.EquipmentID.StationID
  28. ) {
  29. try {
  30. const parsedSnapshot = JSON.parse(reservationData.connector.EquipmentID.StationID.snapshot);
  31. setStationInfo(parsedSnapshot);
  32. } catch (error) {
  33. console.error('Error parsing station snapshot:', error);
  34. }
  35. }
  36. setLoading(false);
  37. }, [reservationData]);
  38. const startPayload = {
  39. StartChargeSeq: reservationData.format_order_id,
  40. ConnectorID: reservationData.connector.ConnectorID,
  41. StopBy: 0,
  42. StopValue: 0,
  43. StartBalance: 400.99
  44. };
  45. const handleStartCharge = async () => {
  46. setIsLoading(true);
  47. try {
  48. console.log('startPayload', startPayload);
  49. const response = await chargeStationService.startCharging(startPayload);
  50. if (response) {
  51. console.log('handleStartCharge begins, response received:', response);
  52. setIsLoading(false);
  53. Alert.alert('啟動成功', '請稍後等待頁面自動跳轉至充電介面', [{ text: 'OK', onPress: () => {} }]);
  54. setTimeout(() => {
  55. router.push('chargingPage');
  56. }, 15000);
  57. } else {
  58. setIsLoading(false);
  59. Alert.alert('啟動失敗');
  60. console.log('啟動失敗');
  61. }
  62. } catch (error) {
  63. setIsLoading(false);
  64. console.log(error);
  65. Alert.alert('發生錯誤', '請稍後再試');
  66. }
  67. };
  68. return (
  69. <SafeAreaView edges={['top', 'left', 'right']} className="flex-1 bg-white">
  70. <ScrollView className="flex-1 mt-8 " nestedScrollEnabled={true} showsVerticalScrollIndicator={false}>
  71. <View className="mx-[5%]">
  72. <View className="">
  73. <Text className="text-5xl pt-1 pb-6">{walkinStatus ? '掃描成功' : '預約已經開始'}</Text>
  74. <Text className="text-base">
  75. {walkinStatus
  76. ? '請按下方按鈕啟動充電槍,當充電槍啟動成功後會自動跳轉至充電介面。'
  77. : '到達充電站後,按下方按鈕開始充電。'}
  78. </Text>
  79. {loading ? (
  80. <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
  81. <ActivityIndicator color="#34657b" />
  82. </View>
  83. ) : (
  84. <>
  85. <Text className="text-2xl py-4 ">
  86. {walkinStatus ? '你的充電資訊為:' : '你的預約為:'}
  87. </Text>
  88. <View className="border-gray-200 border rounded-md">
  89. <View className="flex-1 mt-4 mx-[5%] ">
  90. <View className="flex-1 flex-row items-center pb-3">
  91. <View className="flex-1 flex-column">
  92. <Text style={styles.grayColor} className="text-base">
  93. 日期
  94. </Text>
  95. <Text style={styles.greenColor} className="text-4xl text-center pt-2">
  96. {convertToHKTime(reservationData.book_time)
  97. .hkDate.split('/')
  98. .reverse()
  99. .slice(1)
  100. .join('月')}
  101. </Text>
  102. </View>
  103. <View className="flex-1 flex-column">
  104. <Text style={styles.grayColor} className="text-base pl-7">
  105. 時間
  106. </Text>
  107. <Text style={styles.greenColor} className="text-4xl text-center pt-2">
  108. {convertToHKTime(reservationData.book_time).hkTime.slice(0, 5)}
  109. </Text>
  110. </View>
  111. </View>
  112. <View className="flex-1 flex-column justify-center space-y-1 pb-3">
  113. <Text style={styles.grayColor} className="text-base">
  114. 充電地點
  115. </Text>
  116. {loading ? (
  117. <ActivityIndicator size="small" />
  118. ) : (
  119. <>
  120. <Text style={styles.greenColor} className="text-2xl ">
  121. {stationInfo?.StationName || 'N/A'}
  122. </Text>
  123. <Text style={styles.grayColor} className="text-sm">
  124. {stationInfo?.Address || 'N/A'}
  125. </Text>
  126. </>
  127. )}
  128. </View>
  129. <View className="flex-1 flex-row pb-3 ">
  130. <View className="flex-column flex-1">
  131. <Text style={styles.grayColor} className="text-base">
  132. 方案
  133. </Text>
  134. <Text style={styles.greenColor} className="text-lg">
  135. {plan}
  136. </Text>
  137. <Text style={styles.grayColor} className="text-sm">
  138. {kwh}
  139. </Text>
  140. </View>
  141. <View className="flex-column flex-1">
  142. <Text style={styles.grayColor} className="text-base">
  143. 車輛
  144. </Text>
  145. <Text style={styles.greenColor} className="text-lg">
  146. {reservationData.car.car_brand.name}
  147. </Text>
  148. <Text style={styles.greenColor} className="text-lg">
  149. {reservationData.car.car_type.name}
  150. </Text>
  151. </View>
  152. </View>
  153. </View>
  154. </View>
  155. <View className="pt-6">
  156. <NormalButton
  157. title={<Text className="text-white text-lg">發動充電樁 - 開始充電</Text>}
  158. onPress={() => handleStartCharge()}
  159. />
  160. </View>
  161. <View className="pt-6">
  162. <NormalButton
  163. title={<Text className="text-white text-lg">返回主頁</Text>}
  164. onPress={() => router.push('mainPage')}
  165. />
  166. </View>
  167. </>
  168. )}
  169. </View>
  170. </View>
  171. </ScrollView>
  172. <Modal transparent={true} animationType="fade" visible={isLoading} onRequestClose={() => {}}>
  173. <View
  174. style={{
  175. flex: 1,
  176. justifyContent: 'center',
  177. alignItems: 'center',
  178. backgroundColor: 'rgba(0,0,0,0.5)'
  179. }}
  180. >
  181. <View style={{ backgroundColor: 'white', padding: 20, borderRadius: 10, alignItems: 'center' }}>
  182. <ActivityIndicator />
  183. <Text style={{ marginTop: 10 }}>正在啟動充電...</Text>
  184. </View>
  185. </View>
  186. </Modal>
  187. </SafeAreaView>
  188. );
  189. };
  190. const styles = StyleSheet.create({
  191. grayColor: {
  192. color: '#888888'
  193. },
  194. greenColor: {
  195. color: '#02677D'
  196. }
  197. });
  198. export default ChargingHurryUpPageComponent;