bookingMenuPage.tsx 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. import { View, Text, StyleSheet, ScrollView, Dimensions, ActivityIndicator, RefreshControl, Alert } from 'react-native';
  2. import TabViewComponent, { TabItem } from '../global/tabView';
  3. import NormalButton from '../global/normal_button';
  4. import { SafeAreaView } from 'react-native-safe-area-context';
  5. import RecentlyBookedScrollView from '../global/recentlyBookedScrollView';
  6. import { router } from 'expo-router';
  7. import { useCallback, useEffect, useMemo, useState } from 'react';
  8. import { chargeStationService } from '../../service/chargeStationService';
  9. import { calculateDistance } from '../global/distanceCalculator';
  10. import React from 'react';
  11. import BookingTabViewComponent from '../global/bookingTabViewComponent';
  12. interface BookingMenuPageProps {}
  13. const BookingMenuPageComponent: React.FC<BookingMenuPageProps> = () => {
  14. //check for unpaid penalties
  15. useEffect(() => {
  16. const checkUnpaidPenalties = async () => {
  17. try {
  18. const reservationHistories = await chargeStationService.fetchReservationHistories();
  19. const unpaidPenalties = reservationHistories.filter(
  20. (reservation) => reservation.penalty_fee > 0 && reservation.penalty_paid_status === false
  21. );
  22. if (unpaidPenalties.length > 0) {
  23. const mostRecentUnpaidReservation = unpaidPenalties.reduce((mostRecent, current) => {
  24. return new Date(mostRecent.created_at) > new Date(current.created_at) ? mostRecent : current;
  25. }, unpaidPenalties[0]);
  26. Alert.alert(
  27. '未付罰款',
  28. '您有未支付的罰款。請先支付罰款後再開始充電。',
  29. [
  30. {
  31. text: '查看詳情',
  32. onPress: () => {
  33. // Navigate to a page showing penalty details
  34. router.push({
  35. pathname: '(auth)/(tabs)/(home)/penaltyPaymentPage',
  36. params: {
  37. book_time: mostRecentUnpaidReservation.book_time,
  38. end_time: mostRecentUnpaidReservation.end_time,
  39. actual_end_time: mostRecentUnpaidReservation.actual_end_time,
  40. penalty_fee: mostRecentUnpaidReservation.penalty_fee,
  41. format_order_id: mostRecentUnpaidReservation.format_order_id,
  42. id: mostRecentUnpaidReservation.id,
  43. stationName:
  44. mostRecentUnpaidReservation.connector.EquipmentID.StationID.snapshot
  45. .StationName,
  46. address:
  47. mostRecentUnpaidReservation.connector.EquipmentID.StationID.snapshot
  48. .Address
  49. }
  50. });
  51. }
  52. },
  53. {
  54. text: '返回',
  55. onPress: () => {
  56. if (router.canGoBack()) {
  57. router.back();
  58. } else {
  59. router.push('/mainPage');
  60. }
  61. }
  62. }
  63. ],
  64. { cancelable: false }
  65. );
  66. }
  67. } catch (error) {
  68. console.error('Error checking unpaid penalties:', error);
  69. // Handle the error appropriately (e.g., show an error message to the user)
  70. }
  71. };
  72. checkUnpaidPenalties();
  73. }, []);
  74. // console.log('BookingMenuPageComponent rendering');
  75. const [refreshing, setRefreshing] = useState(false);
  76. const [refetchTrigger, setRefetchTrigger] = useState(0);
  77. const calculateResponsivePadding = useCallback(() => {
  78. const screenHeight = Dimensions.get('window').height;
  79. return screenHeight * 0.03;
  80. }, []);
  81. const calculateTabViewHeight = useCallback(() => {
  82. const screenHeight = Dimensions.get('window').height;
  83. if (screenHeight > 800) return 500;
  84. else if (screenHeight > 550) return 300;
  85. else return 150;
  86. }, []);
  87. const onRefresh = useCallback(() => {
  88. setRefreshing(true);
  89. setRefetchTrigger((prev) => prev + 1);
  90. // Simulate a delay to show the refresh indicator
  91. setTimeout(() => {
  92. setRefreshing(false);
  93. }, 1000);
  94. }, []);
  95. return (
  96. <SafeAreaView edges={['top', 'left', 'right']} className="flex-1 bg-white">
  97. <ScrollView
  98. className="flex-1 mt-8"
  99. nestedScrollEnabled={true}
  100. showsVerticalScrollIndicator={false}
  101. refreshControl={
  102. <RefreshControl
  103. refreshing={refreshing}
  104. onRefresh={onRefresh}
  105. colors={['#34657b']} // Android
  106. tintColor="#34657b" // iOS
  107. />
  108. }
  109. >
  110. <View className="mx-[5%]">
  111. <View>
  112. <Text className="text-5xl pt-1 pb-6">預約</Text>
  113. <NormalButton
  114. title={<Text style={{ color: 'white', fontSize: 16, fontWeight: '800' }}>+ 新增預約</Text>}
  115. // onPress={() => router.push('reservationLocationPage')}
  116. onPress={() => Alert.alert('即將推出', '此功能即將推出,敬請期待!')}
  117. extendedStyle={{ padding: calculateResponsivePadding() }}
  118. />
  119. </View>
  120. <RecentlyBookedScrollView />
  121. </View>
  122. <View className="flex-1" style={{ height: calculateTabViewHeight() }}>
  123. <BookingTabViewComponent titles={['已預約', '已完成']} refetchTrigger={refetchTrigger} />
  124. {/* <TabViewComponent
  125. titles={['已預約', '已完成']}
  126. tabItems={tabItems}
  127. isLoading={isLoading}
  128. completedReservationTabItems={completedReservationTabItems}
  129. /> */}
  130. </View>
  131. </ScrollView>
  132. </SafeAreaView>
  133. );
  134. };
  135. export default React.memo(BookingMenuPageComponent);