penaltyPaymentPageComponent.tsx 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. import { View, Text, ScrollView, Pressable, StyleSheet, Alert } from 'react-native';
  2. import { SafeAreaView } from 'react-native-safe-area-context';
  3. import { router, useLocalSearchParams, useNavigation } from 'expo-router';
  4. import NormalButton from '../global/normal_button';
  5. import { useEffect } from 'react';
  6. import { chargeStationService } from '../../service/chargeStationService';
  7. import useUserInfoStore from '../../providers/userinfo_store';
  8. const PenaltyPaymentPageComponent = () => {
  9. const params = useLocalSearchParams();
  10. const { userID } = useUserInfoStore();
  11. console.log('params in penaltyPaymentPageComponent', params);
  12. const navigation = useNavigation();
  13. useEffect(() => {
  14. navigation.setOptions({
  15. gestureEnabled: false
  16. });
  17. }, [navigation]);
  18. const convertBookingDateTime = (isoDateString: string): { date: string; time: string } => {
  19. const bookingDate = new Date(isoDateString);
  20. // Adjust to local time (+8 hours)
  21. bookingDate.setHours(bookingDate.getHours());
  22. // Format date as "MM-DD"
  23. const date = `${(bookingDate.getMonth() + 1).toString().padStart(2, '0')}-${bookingDate
  24. .getDate()
  25. .toString()
  26. .padStart(2, '0')}`;
  27. // Format time as "HH:mm"
  28. const time = `${bookingDate.getHours().toString().padStart(2, '0')}:${bookingDate
  29. .getMinutes()
  30. .toString()
  31. .padStart(2, '0')}`;
  32. return { date, time };
  33. };
  34. const calculateUserEndTime = (actualEndTimeStr: string, penaltyFee: string): string => {
  35. const actualEndTime = new Date(actualEndTimeStr);
  36. const penaltyMinutes = Math.floor(parseFloat(penaltyFee) / 3); // $3 per minute
  37. const userEndTime = new Date(actualEndTime.getTime() + penaltyMinutes * 60000); // add minutes
  38. return userEndTime.toISOString();
  39. };
  40. const { date, time } = convertBookingDateTime(params.book_time);
  41. const { date: end_date, time: end_time } = convertBookingDateTime(params.end_time as string);
  42. const { date: actual_end_date, time: actual_end_time } = convertBookingDateTime(params.actual_end_time as string);
  43. const { time: user_end_time } = convertBookingDateTime(
  44. calculateUserEndTime(params.actual_end_time as string, params.penalty_fee as string)
  45. );
  46. const payload = {
  47. userId: userID,
  48. amount: parseFloat(params.penalty_fee as string),
  49. reservationId: params.id
  50. };
  51. const handlePayment = async () => {
  52. try {
  53. const result = await chargeStationService.payPenalty(payload);
  54. if (result) {
  55. Alert.alert('支付成功', '罰款已成功支付', [
  56. { text: '確認', onPress: () => router.replace('/mainPage') }
  57. ]);
  58. } else {
  59. Alert.alert('支付失敗', '請稍後再試');
  60. }
  61. } catch (error) {
  62. console.error('Payment error:', error);
  63. Alert.alert('支付錯誤', '發生錯誤,請稍後再試');
  64. }
  65. };
  66. return (
  67. <SafeAreaView style={{ flex: 1, backgroundColor: 'white' }} edges={['top', 'left', 'right']}>
  68. <ScrollView className="flex-1" showsVerticalScrollIndicator={false}>
  69. <View className="flex-1">
  70. <View className="pl-8 pt-8">
  71. <Text className="text-3xl mt-8">尚未繳付罰款的充電記錄</Text>
  72. </View>
  73. <View className="flex-1 mt-4 mx-[5%]">
  74. <View className="flex-1 flex-row items-center pb-3">
  75. <View className="flex-1 flex-column">
  76. <Text style={styles.grayColor} className="text-base">
  77. 實際充電到期時間
  78. </Text>
  79. <Text style={styles.greenColor} className="text-4xl text-center pt-2">
  80. {actual_end_time}
  81. </Text>
  82. </View>
  83. <View className="flex-1 flex-column">
  84. <Text style={styles.grayColor} className="text-base pl-7">
  85. 實際充電結束時間
  86. </Text>
  87. <Text style={styles.greenColor} className="text-4xl text-center pt-2">
  88. {user_end_time}
  89. </Text>
  90. </View>
  91. </View>
  92. <View className="flex-1 flex-column justify-center space-y-1 pb-3">
  93. <Text style={styles.grayColor} className="text-base">
  94. 充電日期
  95. </Text>
  96. <Text style={styles.greenColor} className="text-base">
  97. {date}
  98. </Text>
  99. </View>
  100. {/* <View className="flex-1 flex-column justify-center space-y-1 pb-3">
  101. <Text style={styles.grayColor} className="text-base">
  102. 充電地點
  103. </Text>
  104. <Text style={styles.greenColor} className="text-base ">
  105. Crazy Charge(偉業街)
  106. </Text>
  107. </View> */}
  108. <View className="flex-1 flex-column justify-center space-y-1 pb-3">
  109. <Text style={styles.grayColor} className="text-base">
  110. 罰款金額
  111. </Text>
  112. <Text style={styles.greenColor} className="text-lg ">
  113. {params.penalty_fee}
  114. </Text>
  115. </View>
  116. <View className="flex-1 flex-column justify-center space-y-1 pb-3">
  117. <Text style={styles.grayColor} className="text-base">
  118. 訂單編號
  119. </Text>
  120. <Text style={styles.greenColor} className=" ">
  121. {params.format_order_id}
  122. </Text>
  123. </View>
  124. </View>
  125. </View>
  126. <View className="border-t mx-4 border-[#CCCCCC]"></View>
  127. <View className="flex-1 mx-[5%] mt-4 space-y-1">
  128. <View className="mt-4">
  129. <NormalButton
  130. title={
  131. <Text
  132. style={{
  133. color: 'white',
  134. fontSize: 16,
  135. fontWeight: '800'
  136. }}
  137. >
  138. 支付罰款
  139. </Text>
  140. }
  141. // onPress={handlePayment}
  142. onPress={() => {
  143. Alert.alert('將會從錢包餘額扣除款項以繳交罰款', '', [
  144. { text: '取消', style: 'cancel' },
  145. { text: '確認', onPress: handlePayment }
  146. ]);
  147. }}
  148. extendedStyle={{ padding: 24, marginTop: 24 }}
  149. />
  150. </View>
  151. </View>
  152. </ScrollView>
  153. </SafeAreaView>
  154. );
  155. };
  156. export default PenaltyPaymentPageComponent;
  157. const styles = StyleSheet.create({
  158. grayColor: {
  159. color: '#888888'
  160. },
  161. greenColor: {
  162. color: '#02677D'
  163. }
  164. });