import { View, Text, ScrollView, Dimensions, ActivityIndicator } from 'react-native';
import React, { useEffect, useMemo, useState } from 'react';
import NormalButton from './normal_button';
import Svg, { Path } from 'react-native-svg';
import { BookingIconSvg } from './SVG';
import { chargeStationService } from '../../service/chargeStationService';
import extractedInfoStore from '../../providers/extractedReservationInfo_store';
import { router } from 'expo-router';
import { useQuery, QueryClient, QueryClientProvider } from '@tanstack/react-query';
const queryClient = new QueryClient();
const calculateResponsivePadding = () => {
const screenHeight = Dimensions.get('window').height;
return screenHeight * 0.01; // 3% of screen height, adjust as needed
};
const RecentBookedRowItems = ({
chargingStationName,
chargingStationAddress,
chargeStationID
}: {
chargingStationName: string;
chargingStationAddress: string;
chargeStationID: string;
}) => (
{chargingStationName}
{chargingStationAddress}
重新預約}
onPress={() =>
router.push({
pathname: '/resultDetailPage',
params: {
chargeStationAddress: chargingStationAddress,
chargeStationID: chargeStationID,
chargeStationName: chargingStationName
}
})
}
buttonPressedStyle={{
backgroundColor: '#CFDEE4'
}}
extendedStyle={{
backgroundColor: '#E3F2F8',
paddingHorizontal: 16,
paddingVertical: 1,
borderRadius: 8
}}
/>
);
const fetchRecentBookings = async (retryCount = 0) => {
try {
// Fetch user's all reservations
const reservationResponse = await chargeStationService.fetchReservationHistories();
if (!reservationResponse || reservationResponse.length === 0) {
console.log('No reservation data returned');
return [];
}
// Find the two closest reservations
const now = new Date();
const closestReservations = reservationResponse
.sort((a, b) => {
const diffA = Math.abs(new Date(a.end_time) - now);
const diffB = Math.abs(new Date(b.end_time) - now);
return diffA - diffB;
})
.slice(0, 2);
// Fetch all charge station info
const allStations = await chargeStationService.fetchAllChargeStations();
if (!allStations) {
console.log('No charge station data returned');
return [];
}
//helper method to fetch all station
const findStationByConnectorId = (allStations, targetConnectorId) => {
console.log('Searching for connector ID:', targetConnectorId);
const station = allStations.find((station) => {
console.log(`Checking station ID: ${station.id}`);
if (!station.snapshot || !station.snapshot.EquipmentInfos) {
console.log('Station snapshot or EquipmentInfos is missing, skipping...');
return false;
}
return station.snapshot.EquipmentInfos.some((equipment) => {
console.log(` Checking equipment ID: ${equipment.EquipmentID}`);
if (!equipment.ConnectorInfos) {
console.log(' ConnectorInfos is missing, skipping...');
return false;
}
return equipment.ConnectorInfos.some((connector) => {
console.log(` Checking connector ID: ${connector.ConnectorID}`);
const isMatch = connector.ConnectorID === targetConnectorId;
if (isMatch) console.log(' Match found!');
return isMatch;
});
});
});
if (station) {
console.log('Matching station found:', station.id);
} else {
console.log('No matching station found');
}
return station;
};
// Extract station IDs from the closest reservations
const stationIds = closestReservations
.map((reservation) => {
try {
const snapshot = JSON.parse(reservation.snapshot);
if (snapshot.stationID) {
return snapshot.stationID;
} else if (snapshot.connector) {
const station = findStationByConnectorId(allStations, snapshot.connector);
return station ? station.id : null;
}
return null;
} catch (error) {
console.error('Error processing reservation:', error);
return null;
}
})
.filter((id) => id !== null);
if (stationIds.length === 0) {
console.log('No valid station IDs found');
return [];
}
// Filter and extract station information
const extractedInfo = stationIds
.map((id) => allStations.find((station) => station.id === id))
.filter((station) => station !== undefined)
.map((station) => ({
stationID: station.id,
address: station.snapshot.Address,
stationName: station.snapshot.StationName
}));
// Update the store with extracted information
extractedInfoStore.getState().setExtractedInfo(extractedInfo);
return extractedInfo;
} catch (error) {
console.error(`Error in fetchRecentBookings (attempt ${retryCount + 1}):`, error);
if (retryCount < 2) {
// Retry up to 3 times (0, 1, 2)
console.log(`Retrying... (attempt ${retryCount + 2})`);
return fetchRecentBookings(retryCount + 1);
} else {
console.log('Max retries reached. Returning empty array.');
return [];
}
}
};
const RecentlyBookedScrollView = () => {
const {
data: extractedInfo,
isLoading,
error
} = useQuery('recentBookings', () => fetchRecentBookings(), {
staleTime: 5 * 60 * 1000, // 5 minutes
cacheTime: 10 * 60 * 1000, // 10 minutes
retry: 3, // This will work alongside our custom retry logic
retryDelay: 1000 // Wait 1 second between retries
});
const memoizedExtractedInfo = useMemo(() => extractedInfo || [], [extractedInfo]);
if (isLoading) {
return ;
}
if (error) {
console.error('Error fetching data:', error);
return Error loading recent bookings. Please try again later.;
}
return (
近期預約過
{isLoading ? (
) : (
{memoizedExtractedInfo.map((item, index) => (
))}
)}
);
};
const RecentlyBookedScrollViewWithQueryClient = () => (
);
export default RecentlyBookedScrollViewWithQueryClient;