Ian Fung 1 year ago
parent
commit
37c456c634

+ 297 - 457
app/(auth)/(tabs)/(home)/scanQrPage.tsx

@@ -1,331 +1,3 @@
-// import { CameraView, useCameraPermissions } from 'expo-camera';
-// import { useEffect, useRef, useState } from 'react';
-// import { ActivityIndicator, Dimensions, Pressable, ScrollView, StyleSheet, Text, Vibration, View } from 'react-native';
-// import ChooseCarForChargingRow from '../../../../component/global/chooseCarForChargingRow';
-// import { CrossLogoWhiteSvg, QuestionSvg } from '../../../../component/global/SVG';
-// import { router } from 'expo-router';
-// import { chargeStationService } from '../../../../service/chargeStationService';
-// import { authenticationService } from '../../../../service/authService';
-// import { walletService } from '../../../../service/walletService';
-
-// const ScanQrPage = () => {
-//     const [permission, requestPermission] = useCameraPermissions();
-//     const [scanned, setScanned] = useState(false);
-//     const viewRef = useRef(null);
-//     const [scannedResult, setScannedResult] = useState('');
-//     const [selectedCar, setSelectedCar] = useState('');
-//     const [userID, setUserID] = useState<string>('');
-//     const now = new Date();
-
-//     useEffect(() => {
-//         (async () => {
-//             const { status } = await requestPermission();
-//             if (status !== 'granted') {
-//                 alert('需要相機權限以掃描QR碼');
-//             }
-//         })();
-//     }, []);
-
-//     useEffect(() => {
-//         const fetchID = async () => {
-//             try {
-//                 const response = await authenticationService.getUserInfo();
-//                 if (response) {
-//                     setUserID(response.data.id);
-//                 } else {
-//                     console.log('fail to set user ID');
-//                 }
-//             } catch (error) {
-//                 console.log(error);
-//             }
-//         };
-//         fetchID();
-//     }, []);
-
-//     // useEffect(() => {
-//     //     console.log(selectedCar);
-//     // }, [selectedCar]);
-
-//     if (!permission) {
-//         return <View />;
-//     }
-
-//     if (!permission.granted) {
-//         return (
-//             <View className="flex-1 justify-center items-center">
-//                 <Text style={{ textAlign: 'center' }}>需要相機權限以掃描QR碼,請在設定中開啟相機權限</Text>
-//             </View>
-//         );
-//     }
-
-//     const { width: screenWidth, height: screenHeight } = Dimensions.get('window');
-
-//     const handleBarCodeScanned = ({ bounds, data, type }: { bounds: any; data: any; type: any }) => {
-//         const { origin, size } = bounds;
-//         // Calculate the size of the square transparent area
-//         const transparentAreaSize = Math.min(screenWidth * 0.6, screenHeight * 0.3);
-//         const transparentAreaX = (screenWidth - transparentAreaSize) / 2;
-//         const transparentAreaY = (screenHeight - transparentAreaSize) / 2;
-
-//         // Check if the barcode is within the transparent area
-//         if (
-//             origin.x >= transparentAreaX &&
-//             origin.y >= transparentAreaY &&
-//             origin.x + size.width <= transparentAreaX + transparentAreaSize &&
-//             origin.y + size.height <= transparentAreaY + transparentAreaSize
-//         ) {
-//             setScanned(true);
-//             setScannedResult(data);
-//             Vibration.vibrate(100);
-//             console.log(` type: ${type}            data: ${data}  typeofData ${typeof data}`);
-//             startCharging(data);
-//             setTimeout(() => {
-//                 setScanned(false);
-//             }, 5000);
-//         }
-//     };
-
-//     const ChooseCar = () => {
-
-//         const [loading, setLoading] = useState(false);
-//         const isLargeScreen = screenHeight >= 800;
-//         const [carData, setCarData] = useState([]);
-//         const defaultImageUrl = require('../../../../assets/car1.png');
-//         useEffect(() => {
-//             const fetchAllCars = async () => {
-//                 setLoading(true);
-//                 try {
-//                     const response = await chargeStationService.getUserCars();
-//                     if (response) {
-//                         // console.log(response.data);
-//                         const carTypes = response.data.map((item: any) => ({
-//                             id: item.id,
-//                             name: item.car_type.name,
-//                             image: item.car_type.type_image_url
-//                         }));
-//                         // console.log('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', carTypes);
-//                         let updatedCarTypes = [...carTypes];
-//                         for (let i = 0; i < carTypes.length; i++) {
-//                             const car = updatedCarTypes[i];
-//                             const imageUrl = await chargeStationService.getProcessedImageUrl(car.image);
-//                             updatedCarTypes[i] = {
-//                                 ...car,
-//                                 image: imageUrl
-//                             };
-//                         }
-//                         setCarData(updatedCarTypes);
-//                         return true;
-//                     }
-//                 } catch (error) {
-//                     console.log(error);
-//                 } finally {
-//                     setLoading(false);
-//                 }
-//             };
-//             fetchAllCars();
-//         }, []);
-
-//         return (
-//             <View
-//                 style={{
-//                     ...(isLargeScreen
-//                         ? {
-//                               marginTop: '10%',
-//                               marginBottom: '12%',
-//                               paddingBottom: 12
-//                           }
-//                         : {
-//                               flex: 1,
-//                               alignItems: 'center',
-//                               justifyContent: 'center'
-//                           })
-//                 }}
-//             >
-//                 <View className="justify-center items-center flex-1 ">
-//                     <View
-//                         style={{
-//                             ...(isLargeScreen
-//                                 ? {}
-//                                 : {
-//                                       backgroundColor: 'rgba(0,0,0,0.7)'
-//                                   })
-//                         }}
-//                     >
-//                         {loading ? (
-//                             <View className="w-full">
-//                                 <ActivityIndicator color="#34657b" />
-//                             </View>
-//                         ) : (
-//                             <View className="w-full bg-[#000000B3]">
-//                                 <View className="flex-row items-center justify-between mx-[5%] ">
-//                                     <Pressable
-//                                         className="pt-4 "
-//                                         onPress={() => {
-//                                             if (router.canGoBack()) {
-//                                                 router.back();
-//                                             } else {
-//                                                 router.replace('mainPage');
-//                                             }
-//                                         }}
-//                                     >
-//                                         <CrossLogoWhiteSvg />
-//                                     </Pressable>
-
-//                                     <Text className="text-base text-white pt-2">選擇充電車輛</Text>
-//                                     <Text className="text-xl text-white pt-2"></Text>
-//                                 </View>
-
-//                                 <ScrollView
-//                                     horizontal={true}
-//                                     showsHorizontalScrollIndicator={false}
-//                                     contentContainerStyle={{
-//                                         alignItems: 'center',
-//                                         flexDirection: 'row',
-//                                         marginVertical: 12
-//                                     }}
-//                                     className="space-x-2 mx-[5%]"
-//                                 >
-//                                     {carData.map((car, index) => (
-//                                         <ChooseCarForChargingRow
-//                                             key={`${car.name}+${index}`}
-//                                             image={car.image}
-//                                             onPress={() => {
-//                                                 setSelectedCar(car.id);
-//                                                 console.log(car.id);
-//                                             }}
-//                                             isSelected={selectedCar === car.id}
-//                                             // imageUrl={image}
-//                                             VehicleName={car.name}
-//                                             isDefault={car.isDefault}
-//                                         />
-//                                     ))}
-//                                 </ScrollView>
-//                             </View>
-//                         )}
-//                     </View>
-//                 </View>
-//             </View>
-//         );
-//     };
-
-//     const dataForSubmission = {
-//         stationID: '2405311022116801000',
-//         connector: scannedResult,
-//         user: userID,
-//         book_time: now,
-//         end_time: now,
-//         total_power: 0,
-//         total_fee: 0,
-//         promotion_code: '',
-//         car: selectedCar,
-//         type: 'walking'
-//     };
-
-//     const startCharging = async () => {
-//         try {
-//             const response = await walletService.submitPayment(
-//                 dataForSubmission.stationID,
-//                 dataForSubmission.connector,
-//                 dataForSubmission.user,
-//                 dataForSubmission.book_time,
-//                 dataForSubmission.end_time,
-//                 dataForSubmission.total_power,
-//                 dataForSubmission.total_fee,
-//                 dataForSubmission.promotion_code,
-//                 dataForSubmission.car,
-//                 dataForSubmission.type
-//             );
-
-//             if (response) {
-//                 console.log('Charging started', response);
-//                 router.push('(auth)/(tabs)/(charging)/chargingPage');
-//             } else {
-//                 console.log('Failed to start charging:', response);
-//             }
-//         } catch (error) {
-//             console.log('Failed to start charging:', error);
-//         }
-//     };
-
-//     return (
-//         <View style={styles.container} ref={viewRef}>
-//             <CameraView
-//                 style={styles.camera}
-//                 facing="back"
-//                 barcodeScannerSettings={{
-//                     barcodeTypes: ['qr']
-//                 }}
-//                 onBarcodeScanned={scanned ? undefined : handleBarCodeScanned}
-//                 responsiveOrientationWhenOrientationLocked={true}
-//             >
-//                 <View style={styles.overlay}>
-//                     <View style={styles.topOverlay}>
-//                         <ChooseCar />
-//                     </View>
-//                     <View style={styles.centerRow}>
-//                         <View style={styles.leftOverlay}></View>
-//                         <View style={styles.transparentArea}></View>
-//                         <View style={styles.rightOverlay} />
-//                     </View>
-//                     <View className="items-center justify-between" style={styles.bottomOverlay}>
-//                         <View>
-//                             <Text className="text-white text-lg font-bold mt-2 ">請掃瞄充電座上的二維碼</Text>
-//                         </View>
-//                         <View className="flex-row space-x-2 items-center ">
-//                             <QuestionSvg />
-
-//                             <Pressable onPress={() => router.push('assistancePage')}>
-//                                 <Text className="text-white text-base">需要協助?</Text>
-//                             </Pressable>
-//                         </View>
-//                         <View />
-//                     </View>
-//                 </View>
-//             </CameraView>
-//         </View>
-//     );
-// };
-
-// const styles = StyleSheet.create({
-//     container: {
-//         flex: 1
-//     },
-//     camera: {
-//         flex: 1
-//     },
-//     overlay: {
-//         flex: 1
-//     },
-//     topOverlay: {
-//         flex: 35,
-//         alignItems: 'center',
-//         backgroundColor: 'rgba(0,0,0,0.5)'
-//     },
-//     centerRow: {
-//         flex: 30,
-//         flexDirection: 'row'
-//     },
-//     leftOverlay: {
-//         flex: 20,
-//         backgroundColor: 'rgba(0,0,0,0.5)'
-//     },
-//     transparentArea: {
-//         flex: 60,
-//         aspectRatio: 1,
-//         position: 'relative'
-//     },
-
-//     rightOverlay: {
-//         flex: 20,
-//         backgroundColor: 'rgba(0,0,0,0.5)'
-//     },
-//     bottomOverlay: {
-//         flex: 35,
-//         backgroundColor: 'rgba(0,0,0,0.5)'
-//     }
-// });
-
-// export default ScanQrPage;
 import { CameraView, useCameraPermissions } from 'expo-camera';
 import { useEffect, useRef, useState } from 'react';
 import {
@@ -346,7 +18,96 @@ import { chargeStationService } from '../../../../service/chargeStationService';
 import { authenticationService } from '../../../../service/authService';
 import { walletService } from '../../../../service/walletService';
 
+const { width: screenWidth, height: screenHeight } = Dimensions.get('window');
+
+const ChooseCar = ({ carData, loading, selectedCar, setSelectedCar }) => {
+    const isLargeScreen = screenHeight >= 800;
+    const defaultImageUrl = require('../../../../assets/car1.png');
+
+    return (
+        <View
+            style={{
+                ...(isLargeScreen
+                    ? {
+                          marginTop: '10%',
+                          marginBottom: '12%',
+                          paddingBottom: 12
+                      }
+                    : {
+                          flex: 1,
+                          alignItems: 'center',
+                          justifyContent: 'center'
+                      })
+            }}
+        >
+            <View className="justify-center items-center flex-1 ">
+                <View
+                    style={{
+                        ...(isLargeScreen
+                            ? {}
+                            : {
+                                  backgroundColor: 'rgba(0,0,0,0.7)'
+                              })
+                    }}
+                >
+                    {loading ? (
+                        <View className="w-full">
+                            <ActivityIndicator color="#34657b" />
+                        </View>
+                    ) : (
+                        <View className="w-full bg-[#000000B3]">
+                            <View className="flex-row items-center justify-between mx-[5%] ">
+                                <Pressable
+                                    className="pt-4 "
+                                    onPress={() => {
+                                        if (router.canGoBack()) {
+                                            router.back();
+                                        } else {
+                                            router.replace('mainPage');
+                                        }
+                                    }}
+                                >
+                                    <CrossLogoWhiteSvg />
+                                </Pressable>
+
+                                <Text className="text-base text-white pt-2">選擇充電車輛</Text>
+                                <Text className="text-xl text-white pt-2"></Text>
+                            </View>
+
+                            <ScrollView
+                                horizontal={true}
+                                showsHorizontalScrollIndicator={false}
+                                contentContainerStyle={{
+                                    alignItems: 'center',
+                                    flexDirection: 'row',
+                                    marginVertical: 12
+                                }}
+                                className="space-x-2 mx-[5%]"
+                            >
+                                {carData.map((car, index) => (
+                                    <ChooseCarForChargingRow
+                                        key={`${car.name}+${index}`}
+                                        image={car.image}
+                                        onPress={() => {
+                                            setSelectedCar(car.id);
+                                            console.log(car.id);
+                                        }}
+                                        isSelected={selectedCar === car.id}
+                                        // imageUrl={image}
+                                        VehicleName={car.name}
+                                        isDefault={car.isDefault}
+                                    />
+                                ))}
+                            </ScrollView>
+                        </View>
+                    )}
+                </View>
+            </View>
+        </View>
+    );
+};
 const ScanQrPage = () => {
+    // State declarations
     const [permission, requestPermission] = useCameraPermissions();
     const [scanned, setScanned] = useState(false);
     const viewRef = useRef(null);
@@ -355,8 +116,10 @@ const ScanQrPage = () => {
     const [userID, setUserID] = useState<string>('');
     const now = new Date();
     const [loading, setLoading] = useState(false);
+    const [loading2, setLoading2] = useState(false);
     const [carData, setCarData] = useState([]);
-   
+
+    // Effect for requesting camera permissions
     useEffect(() => {
         (async () => {
             const { status } = await requestPermission();
@@ -366,6 +129,7 @@ const ScanQrPage = () => {
         })();
     }, []);
 
+    // Effect for fetching user's cars
     useEffect(() => {
         const fetchAllCars = async () => {
             setLoading(true);
@@ -399,6 +163,8 @@ const ScanQrPage = () => {
         };
         fetchAllCars();
     }, []);
+
+    // Effect for fetching user ID
     useEffect(() => {
         const fetchID = async () => {
             try {
@@ -415,10 +181,6 @@ const ScanQrPage = () => {
         fetchID();
     }, []);
 
-    useEffect(() => {
-        console.log(selectedCar);
-    }, [selectedCar]);
-
     if (!permission) {
         return <View />;
     }
@@ -431,8 +193,33 @@ const ScanQrPage = () => {
         );
     }
 
-    const { width: screenWidth, height: screenHeight } = Dimensions.get('window');
-
+    // // Function to handle barcode scanning
+    // const handleBarCodeScanned = ({ bounds, data, type }: { bounds: any; data: any; type: any }) => {
+    //     const { origin, size } = bounds;
+    //     // Calculate the size of the square transparent area
+    //     const transparentAreaSize = Math.min(screenWidth * 0.6, screenHeight * 0.3);
+    //     const transparentAreaX = (screenWidth - transparentAreaSize) / 2;
+    //     const transparentAreaY = (screenHeight - transparentAreaSize) / 2;
+
+    //     // Check if the barcode is within the transparent area
+    //     if (
+    //         origin.x >= transparentAreaX &&
+    //         origin.y >= transparentAreaY &&
+    //         origin.x + size.width <= transparentAreaX + transparentAreaSize &&
+    //         origin.y + size.height <= transparentAreaY + transparentAreaSize
+    //     ) {
+    //         setScanned(true);
+    //         setScannedResult(data);
+    //         Vibration.vibrate(100);
+    //         console.log(` type: ${type}   data: ${data}  typeofData ${typeof data}`);
+    //         startCharging(data);
+    //         setTimeout(() => {
+    //             setScanned(false);
+    //         }, 2000);
+    //     }
+    // };
+
+    // Function to handle barcode scanning
     const handleBarCodeScanned = ({ bounds, data, type }: { bounds: any; data: any; type: any }) => {
         const { origin, size } = bounds;
         // Calculate the size of the square transparent area
@@ -450,101 +237,92 @@ const ScanQrPage = () => {
             setScanned(true);
             setScannedResult(data);
             Vibration.vibrate(100);
-            console.log(` type: ${type}            data: ${data}  typeofData ${typeof data}`);
+            console.log(` type: ${type}   data: ${data}  typeofData ${typeof data}`);
+            //HERE I will not be startCharging, I will call a function to check
             startCharging(data);
             setTimeout(() => {
                 setScanned(false);
             }, 2000);
         }
     };
+    //WAIT FOR KUN TO CREATE ANOTHER API,
+    //USE THE NEW API FOR SCAN QR CODE FUNCTIONALITY
+    // ***********************************************************
+    // **************************************************************
+    // **************************************************************
+    // **************************************************************
+    // **************************************************************
+    // **************************************************************
+    // **************************************************************
+    // **************************************************************
+    const checkCurrentReservation = async () => {
+        const now = new Date();
+        try {
+            console.log('i am checking current reservation');
+            const response = await chargeStationService.fetchReservationHistories();
+            if (response) {
+                //check if any reservation is within 15 minutes
+                console.log('response of checkCurrentReservation', response);
+                const filteredResponse = response.filter((r) => {
+                    const bookTime = new Date(r.book_time);
+                    const fifteenMinutesAfterBookTime = new Date(bookTime.getTime() + 15 * 60 * 1000);
+                    const isWithin15MinutesAndStatus6 =
+                        now > bookTime && now <= fifteenMinutesAfterBookTime && r.status.id === '6';
+                    return isWithin15MinutesAndStatus6;
+                });
+                if (filteredResponse.length > 0) {
+                    console.log('there is a reservation within 15 minutes');
+                    return filteredResponse;
+                }
+            }
+            //meaning no reservation within 15 minutes
+            else {
+                console.log('no reservation within 15 minutes');
+                return false;
+            }
+        } catch (error) {
+            console.log(error);
+        }
+    };
 
-    const ChooseCar = ({ carData, loading, selectedCar, setSelectedCar }) => {
-        const isLargeScreen = screenHeight >= 800;
-        const defaultImageUrl = require('../../../../assets/car1.png');
-
-        return (
-            <View
-                style={{
-                    ...(isLargeScreen
-                        ? {
-                              marginTop: '10%',
-                              marginBottom: '12%',
-                              paddingBottom: 12
-                          }
-                        : {
-                              flex: 1,
-                              alignItems: 'center',
-                              justifyContent: 'center'
-                          })
-                }}
-            >
-                <View className="justify-center items-center flex-1 ">
-                    <View
-                        style={{
-                            ...(isLargeScreen
-                                ? {}
-                                : {
-                                      backgroundColor: 'rgba(0,0,0,0.7)'
-                                  })
-                        }}
-                    >
-                        {loading ? (
-                            <View className="w-full">
-                                <ActivityIndicator color="#34657b" />
-                            </View>
-                        ) : (
-                            <View className="w-full bg-[#000000B3]">
-                                <View className="flex-row items-center justify-between mx-[5%] ">
-                                    <Pressable
-                                        className="pt-4 "
-                                        onPress={() => {
-                                            if (router.canGoBack()) {
-                                                router.back();
-                                            } else {
-                                                router.replace('mainPage');
-                                            }
-                                        }}
-                                    >
-                                        <CrossLogoWhiteSvg />
-                                    </Pressable>
-
-                                    <Text className="text-base text-white pt-2">選擇充電車輛</Text>
-                                    <Text className="text-xl text-white pt-2"></Text>
-                                </View>
-
-                                <ScrollView
-                                    horizontal={true}
-                                    showsHorizontalScrollIndicator={false}
-                                    contentContainerStyle={{
-                                        alignItems: 'center',
-                                        flexDirection: 'row',
-                                        marginVertical: 12
-                                    }}
-                                    className="space-x-2 mx-[5%]"
-                                >
-                                    {carData.map((car, index) => (
-                                        <ChooseCarForChargingRow
-                                            key={`${car.name}+${index}`}
-                                            image={car.image}
-                                            onPress={() => {
-                                                setSelectedCar(car.id);
-                                                console.log(car.id);
-                                            }}
-                                            isSelected={selectedCar === car.id}
-                                            // imageUrl={image}
-                                            VehicleName={car.name}
-                                            isDefault={car.isDefault}
-                                        />
-                                    ))}
-                                </ScrollView>
-                            </View>
-                        )}
-                    </View>
-                </View>
-            </View>
-        );
+    const checkQrCode = async (data: string) => {
+        setLoading2(true);
+        const connectorID = data;
+        try {
+            const response = await checkCurrentReservation();
+            if (response) {
+                console.log('checking if scan code is for this reservation, from checkQrCode', response);
+                //if there is a reservation within 15 minutes
+                const checkIfScanCodeIsForThisReservation = response.connector.id === data;
+                if (checkIfScanCodeIsForThisReservation) {
+                    startCharging(data);
+                    return true;
+                } else {
+                    console.log(
+                        'The user indeed has a valid reservation, but the reservation is not for this charging machine.'
+                    );
+                    Alert.alert('您預約了另一座充電座\n請前往正確的充電座進行充電。');
+                    return false;
+                }
+            } else {
+                //if there is no reservation within 15 minutes
+                //meaing these are walk in clients wanting to charge
+                //first, i have to check the current time,
+                //if the availability of current time slot is not available then i return alert
+            }
+        } catch (error) {
+            console.log(error);
+        }
     };
 
+    // **************************************************************
+    // **************************************************************
+    // **************************************************************
+    // **************************************************************
+    // **************************************************************
+    // **************************************************************
+    // **************************************************************
+    //prepare data for submission
     const dataForSubmission = {
         stationID: '2405311022116801000',
         connector: scannedResult,
@@ -558,7 +336,7 @@ const ScanQrPage = () => {
         type: 'walking'
     };
 
-    const startCharging = async (scanResult) => {
+    const startCharging = async (scanResult: string) => {
         try {
             if (selectedCar === '') {
                 Alert.alert('請選擇車輛');
@@ -579,7 +357,7 @@ const ScanQrPage = () => {
             );
 
             if (response) {
-                console.log('Charging stasdasdasdarted', response);
+                console.log('Charging started from startCharging', response);
                 router.push('(auth)/(tabs)/(charging)/chargingPage');
             } else {
                 console.log('Failed to start chargi12312312ng:', response);
@@ -589,47 +367,109 @@ const ScanQrPage = () => {
             console.log('Failed to start charging:', error);
         }
     };
+    const abc = new Date();
+
+    async function checkIfConnectorIsAvailable(stationID: string) {
+        try {
+            const apiResponse = await chargeStationService.fetchSpecificChargeStation(stationID);
+            if (apiResponse) {
+                console.log('apiResponse', apiResponse);
+                const inputDate = new Date();
+                const formattedDate =
+                    (inputDate.getMonth() + 1).toString().padStart(2, '0') +
+                    '/' +
+                    inputDate.getDate().toString().padStart(2, '0');
+
+                // Get the hours and minutes
+                const hours = inputDate.getHours();
+                const minutes = inputDate.getMinutes();
+
+                // Round down to the nearest 30-minute slot
+                const slotStart = `${hours.toString().padStart(2, '0')}:${minutes < 30 ? '00' : '30'}`;
+                console.log('slotStart', slotStart);
+
+                const findSlot = (date, start) => {
+                    const dayData = apiResponse.find((day) => day.date === date);
+                    if (!dayData) return null;
+
+                    return dayData.range.find((slot) => slot.start === start);
+                };
+
+                const currentSlot = findSlot(formattedDate, slotStart);
+                console.log('currentSlot', currentSlot);
+
+                let nextSlotStart;
+                if (slotStart.endsWith('30')) {
+                    nextSlotStart = `${(hours + 1).toString().padStart(2, '0')}:00`;
+                } else {
+                    nextSlotStart = `${hours.toString().padStart(2, '0')}:30`;
+                }
+                const nextSlot = findSlot(formattedDate, nextSlotStart);
+                console.log('nextSlot', nextSlot);
+                return {
+                    currentSlot,
+                    nextSlot
+                };
+            } else {
+                console.log('no response from fetchSpecificChargeStation in scanQRcode Page');
+                return false;
+            }
+        } catch (error) {
+            console.log(error);
+        }
+    }
+
+    const adbc = checkIfConnectorIsAvailable('2405311022116801000');
+    console.log(adbc);
 
     return (
         <View style={styles.container} ref={viewRef}>
-            <CameraView
-                style={styles.camera}
-                facing="back"
-                barcodeScannerSettings={{
-                    barcodeTypes: ['qr']
-                }}
-                onBarcodeScanned={scanned ? undefined : handleBarCodeScanned}
-                responsiveOrientationWhenOrientationLocked={true}
-            >
-                <View style={styles.overlay}>
-                    <View style={styles.topOverlay}>
-                        <ChooseCar
-                            carData={carData}
-                            loading={loading}
-                            selectedCar={selectedCar}
-                            setSelectedCar={setSelectedCar}
-                        />
-                    </View>
-                    <View style={styles.centerRow}>
-                        <View style={styles.leftOverlay}></View>
-                        <View style={styles.transparentArea}></View>
-                        <View style={styles.rightOverlay} />
-                    </View>
-                    <View className="items-center justify-between" style={styles.bottomOverlay}>
-                        <View>
-                            <Text className="text-white text-lg font-bold mt-2 ">請掃瞄充電座上的二維碼</Text>
+            {loading ? (
+                <View className="flex-1 items-center justify-center">
+                    <ActivityIndicator />
+                </View>
+            ) : (
+                <CameraView
+                    style={styles.camera}
+                    facing="back"
+                    barcodeScannerSettings={{
+                        barcodeTypes: ['qr']
+                    }}
+                    onBarcodeScanned={scanned ? undefined : handleBarCodeScanned}
+                    responsiveOrientationWhenOrientationLocked={true}
+                >
+                    <View style={styles.overlay}>
+                        <View style={styles.topOverlay}>
+                            <ChooseCar
+                                carData={carData}
+                                loading={loading}
+                                selectedCar={selectedCar}
+                                setSelectedCar={setSelectedCar}
+                            />
                         </View>
-                        <View className="flex-row space-x-2 items-center ">
-                            <QuestionSvg />
+                        <View style={styles.centerRow}>
+                            <View style={styles.leftOverlay}></View>
+                            <View style={styles.transparentArea}></View>
+                            <View style={styles.rightOverlay} />
+                        </View>
+                        <View className="items-center justify-between" style={styles.bottomOverlay}>
+                            <View>
+                                <Text className="text-white text-lg font-bold mt-2 text-center">
+                                    請選擇充電車輛{'\n'}及掃瞄充電座上的二維碼
+                                </Text>
+                            </View>
+                            <View className="flex-row space-x-2 items-center ">
+                                <QuestionSvg />
 
-                            <Pressable onPress={() => router.push('assistancePage')}>
-                                <Text className="text-white text-base">需要協助?</Text>
-                            </Pressable>
+                                <Pressable onPress={() => router.push('assistancePage')}>
+                                    <Text className="text-white text-base">需要協助?</Text>
+                                </Pressable>
+                            </View>
+                            <View />
                         </View>
-                        <View />
                     </View>
-                </View>
-            </CameraView>
+                </CameraView>
+            )}
         </View>
     );
 };

+ 45 - 25
component/bookingMenuPage/makingBookingPageComponent.tsx

@@ -80,6 +80,8 @@ const MakingBookingPageComponent = () => {
     const [distance, setDistance] = useState<string | null>(null);
     const [upcomingReservations, setUpcomingReservation] = useState([]);
     const [carLoadingState, setCarLoadingState] = useState(false);
+    const [isDateLoading, setIsDateLoading] = useState(true);
+
     useEffect(() => {
         const getCurrentLocation = async () => {
             let { status } = await Location.requestForegroundPermissionsAsync();
@@ -310,14 +312,16 @@ const MakingBookingPageComponent = () => {
         const fetchConnectorOptions = async () => {
             try {
                 const fetchedData = await chargeStationService.fetchSpecificChargeStation(chargeStationID);
-
+                console.log('fetchedDate', fetchedData);
                 const dateObject = fetchedData.find((item) => item.date === selectedDate);
+                console.log('dateObject', dateObject);
                 if (!dateObject) {
                     setAvailableConnectorDropdownOptions([]);
                     return;
                 }
 
                 const rangeObject = dateObject.range.find((range) => range.start === selectedTime);
+                console.log('rangeObject', rangeObject);
                 if (!rangeObject) {
                     setAvailableConnectorDropdownOptions([]);
                     return;
@@ -327,6 +331,8 @@ const MakingBookingPageComponent = () => {
                     .filter((connector) => connector.Status === 2)
                     .map((connector) => connector.ConnectorID);
 
+                console.log('connectorIDs', connectorIDs);
+
                 setAvailableConnectorDropdownOptions(connectorIDs);
             } catch (error) {
                 console.error('Error fetching charge station data:', error);
@@ -344,13 +350,22 @@ const MakingBookingPageComponent = () => {
 
     useEffect(() => {
         const fetchingAvailableDates = async () => {
-            const fetchedDates = await chargeStationService.fetchAvailableDates(chargeStationID);
+            setIsDateLoading(true);
+            try {
+                const fetchedDates = await chargeStationService.fetchAvailableDates(chargeStationID);
+                console.log('fetchedDates', fetchedDates);
+                setAvailableDate(fetchedDates);
 
-            setAvailableDate(fetchedDates);
+                console.log(fetchedDates.slice(0, 3));
+            } catch (error) {
+                console.error('Error fetching available dates:', error);
+            } finally {
+                setIsDateLoading(false);
+            }
         };
 
         fetchingAvailableDates();
-    }, []);
+    }, [chargeStationID]);
 
     const handleNavigationPress = () => {
         const latitude = chargeStationLat;
@@ -637,28 +652,33 @@ const MakingBookingPageComponent = () => {
                             }}
                             isSelected={selectedDrawer === 2}
                         >
-                            <View className="flex-row w-full flex-wrap mb-1 ">
-                                {availableDate.slice(0, 3).map((date) => (
-                                    <Pressable
-                                        key={date}
-                                        className={`${
-                                            selectedDate === date ? 'bg-[#34667c] ' : 'bg-white'
-                                        } border border-[#34667c]  rounded-lg w-[22%] items-center mt-1 mr-1 mb-1`}
-                                        onPress={() => {
-                                            setSelectedDate(date);
-                                        }}
-                                    >
-                                        <Text
-                                            className={`text-base p-2  ${
-                                                selectedDate === date ? 'text-white' : 'text-[#34667c]'
-                                            } `}
+                            {isDateLoading ? (
+                                <View className="flex-1 items-center justify-center py-4">
+                                    <ActivityIndicator size="large" color="#34667c" />
+                                </View>
+                            ) : (
+                                <View className="flex-row w-full flex-wrap mb-1 ">
+                                    {availableDate.slice(0, 3).map((date) => (
+                                        <Pressable
+                                            key={date}
+                                            className={`${
+                                                selectedDate === date ? 'bg-[#34667c] ' : 'bg-white'
+                                            } border border-[#34667c]  rounded-lg w-[22%] items-center mt-1 mr-1 mb-1`}
+                                            onPress={() => {
+                                                setSelectedDate(date);
+                                            }}
                                         >
-                                            {date}
-                                        </Text>
-                                    </Pressable>
-                                ))}
-                            </View>
-
+                                            <Text
+                                                className={`text-base p-2  ${
+                                                    selectedDate === date ? 'text-white' : 'text-[#34667c]'
+                                                } `}
+                                            >
+                                                {date}
+                                            </Text>
+                                        </Pressable>
+                                    ))}
+                                </View>
+                            )}
                             {selectedDate !== '' && (
                                 <>
                                     <Text className="text-lg pr-2 ">選擇時間</Text>

+ 0 - 0
component/chargingPage/chargingPage.tsx


+ 0 - 72
component/global/birthday_select.tsx

@@ -1,72 +0,0 @@
-import React, { useState } from 'react';
-import { View, StyleSheet } from 'react-native';
-import DropdownSelect from './dropdown_select';
-
-type BirthdaySelectProps = {
-    onSelect: (year: string, month: string, day: string) => void;
-};
-const BirthdaySelect: React.FC<BirthdaySelectProps> = ({ onSelect }) => {
-    const [selectedYear, setSelectedYear] = useState('');
-    const [selectedMonth, setSelectedMonth] = useState('');
-    const [selectedDay, setSelectedDay] = useState('');
-
-    const birthYearOptions = Array.from({ length: 100 }, (_, i) => {
-        const year = new Date().getFullYear() - i;
-        return { label: year.toString(), value: year.toString() };
-    });
-
-    const birthMonthOptions = Array.from({ length: 12 }, (_, i) => {
-        const month = i + 1;
-        return { label: month.toString(), value: month.toString() };
-    });
-
-    const birthDayOptions = Array.from({ length: 31 }, (_, i) => {
-        const day = i + 1;
-        return { label: day.toString(), value: day.toString() };
-    });
-
-    const handleSelect = (type: string, value: string) => {
-        if (type === 'year') {
-            setSelectedYear(value);
-        } else if (type === 'month') {
-            setSelectedMonth(value);
-        } else if (type === 'day') {
-            setSelectedDay(value);
-        }
-
-        if (selectedYear && selectedMonth && selectedDay) {
-            onSelect(selectedYear, selectedMonth, selectedDay);
-        }
-    };
-
-    return (
-        <View style={styles.container}>
-            <DropdownSelect
-                onSelect={(value) => handleSelect('year', value)}
-                dropdownOptions={birthYearOptions}
-                placeholder={'年份'}
-                extendedStyle={{ paddingLeft: 10 }}
-            />
-            <DropdownSelect
-                onSelect={(value) => handleSelect('month', value)}
-                dropdownOptions={birthMonthOptions}
-                placeholder={'月份'}
-                extendedStyle={{ paddingLeft: 10 }}
-            />
-            <DropdownSelect
-                onSelect={(value) => handleSelect('day', value)}
-                dropdownOptions={birthDayOptions}
-                placeholder={'日期'}
-                extendedStyle={{ paddingLeft: 10 }}
-            />
-        </View>
-    );
-};
-const styles = StyleSheet.create({
-    container: {
-        display: 'flex',
-        flexDirection: 'row',
-        gap: 10
-    }
-});
-export default BirthdaySelect;

+ 14 - 24
component/registrationMultiStepForm/formComponent/formPages/basicInformation.tsx

@@ -5,13 +5,11 @@ import DateModal from '../../../global/date_input';
 import NormalButton from '../../../global/normal_button';
 import useSignUpStore from '../../../../providers/signup_form_store';
 import DropdownSelect from '../../../global/dropdown_select';
+import TestingDropDownSelect from '../../../global/testingDropDownSelect';
 
 type basicInformationProps = {
     goToNextPage: () => void;
 };
-type BirthdaySelectProps = {
-    onSelect: (year: string, month: string, day: string) => void;
-};
 
 const BasicInformation: React.FC<basicInformationProps> = ({ goToNextPage }) => {
     const { signUpFormData, setSignUpFormData } = useSignUpStore();
@@ -108,37 +106,30 @@ const BasicInformation: React.FC<basicInformationProps> = ({ goToNextPage }) =>
                     />
 
                     <View className="">
-                        <DropdownSelect
+                        {/* <TestingDropDownSelect
+                            dropdownOptions={genderDropdownOptions}
                             onSelect={(value) => {
                                 setSignUpFormData({
                                     ...signUpFormData,
                                     gender: value
                                 });
                             }}
-                            dropdownOptions={genderDropdownOptions}
                             placeholder={'性別'}
                             extendedStyle={{ paddingLeft: 10, paddingVertical: 13 }}
-                        />
-
-                        {/* <DateModal
-                            placeholder={signUpFormData.birthDate ? signUpFormData.birthDate : 'DD/MM/YY'}
-                            onDateChange={(date) => {
+                        /> */}
+                        <DropdownSelect
+                            onSelect={(value) => {
                                 setSignUpFormData({
                                     ...signUpFormData,
-                                    birthDate: date
+                                    gender: value
                                 });
                             }}
-                        /> */}
+                            dropdownOptions={genderDropdownOptions}
+                            placeholder={'性別'}
+                            extendedStyle={{ paddingLeft: 10, paddingVertical: 18 }}
+                        />
                     </View>
-
-                    <View className=" flex flex-row ">
-                        {/* <DropdownSelect
-                            onSelect={(value) => handleSelect('month', value)}
-                            dropdownOptions={birthMonthOptions}
-                            placeholder={'生日月份'}
-                            extendedStyle={{ paddingLeft: 10, paddingVertical: 13, marginRight: 6 }}
-                        /> */}
-
+                    <View className="flex flex-row">
                         <DropdownSelect
                             onSelect={(value) => {
                                 setSignUpFormData({
@@ -148,7 +139,7 @@ const BasicInformation: React.FC<basicInformationProps> = ({ goToNextPage }) =>
                             }}
                             dropdownOptions={birthMonthOptions}
                             placeholder={'生日月份'}
-                            extendedStyle={{ paddingLeft: 10, paddingVertical: 13, marginRight: 6 }}
+                            extendedStyle={{ paddingLeft: 10, paddingVertical: 18, marginRight: 6 }}
                         />
                         <DropdownSelect
                             onSelect={(value) => {
@@ -159,10 +150,9 @@ const BasicInformation: React.FC<basicInformationProps> = ({ goToNextPage }) =>
                             }}
                             dropdownOptions={birthDayOptions}
                             placeholder={'日期'}
-                            extendedStyle={{ paddingLeft: 10, paddingVertical: 13, marginLeft: 6 }}
+                            extendedStyle={{ paddingLeft: 10, paddingVertical: 18, marginLeft: 6 }}
                         />
                     </View>
-
                     <NormalButton
                         title={<Text style={{ color: '#fff' }}>下一步</Text>}
                         onPress={handleNext}

+ 25 - 0
component/registrationMultiStepForm/multi_step_form.tsx

@@ -4,12 +4,37 @@ import { useEffect } from 'react';
 import useSignUpStore from '../../providers/signup_form_store';
 import Form from '../registrationMultiStepForm/formComponent/form';
 import { SafeAreaView } from 'react-native-safe-area-context';
+import useVehicleStore from '../../providers/vehicle_store';
 
 const MultiStepForm: React.FC = () => {
     const { signUpFormData } = useSignUpStore();
+    const {
+        vehicleBrand,
+        vehicleModel,
+        BrandID,
+        ModelID,
+        licensePlate,
+        setVehicleBrand,
+        setVehicleModel,
+        setBrandID,
+        setModelID,
+        setLicensePlate
+    } = useVehicleStore();
+
     // logging to check if parent component can successfully receive user input in the multi-step form
     useEffect(() => {
         console.log('Current Zustand Store:', signUpFormData);
+        console.log(
+            'VehicleStore',
+            vehicleBrand,
+            vehicleModel,
+            'BrandID',
+            BrandID,
+            'ModelID',
+            ModelID,
+            'licensePlate',
+            licensePlate
+        );
     }, [signUpFormData]);
 
     return (

+ 4 - 4
package-lock.json

@@ -35,7 +35,7 @@
         "nativewind": "^2.0.11",
         "react": "18.2.0",
         "react-native": "0.74.1",
-        "react-native-element-dropdown": "^2.12.0",
+        "react-native-element-dropdown": "^2.12.1",
         "react-native-gesture-handler": "~2.16.1",
         "react-native-keyboard-aware-scroll-view": "^0.9.5",
         "react-native-maps": "1.14.0",
@@ -13252,9 +13252,9 @@
       }
     },
     "node_modules/react-native-element-dropdown": {
-      "version": "2.12.0",
-      "resolved": "https://registry.npmjs.org/react-native-element-dropdown/-/react-native-element-dropdown-2.12.0.tgz",
-      "integrity": "sha512-Zi9a4vGPztXVdvogg5c2a7xLZDB30YqsXH5EqbeHw6WAnoj5dkj4o/HjfZtxu2DHuT/ipBXDBo5gLG0gDMm5Nw==",
+      "version": "2.12.1",
+      "resolved": "https://registry.npmjs.org/react-native-element-dropdown/-/react-native-element-dropdown-2.12.1.tgz",
+      "integrity": "sha512-Z3uWNFBoezDEsy9AZJxoDc9DxoAdfeprUjaInmbuzYOk6R0Y0UZ659JIalX20XNvrNRWJUfSZwbM94jWYNsIyw==",
       "dependencies": {
         "lodash": "^4.17.21"
       },

+ 1 - 1
package.json

@@ -36,7 +36,7 @@
     "nativewind": "^2.0.11",
     "react": "18.2.0",
     "react-native": "0.74.1",
-    "react-native-element-dropdown": "^2.12.0",
+    "react-native-element-dropdown": "^2.12.1",
     "react-native-gesture-handler": "~2.16.1",
     "react-native-keyboard-aware-scroll-view": "^0.9.5",
     "react-native-maps": "1.14.0",

+ 4 - 0
service/walletService.tsx

@@ -169,9 +169,13 @@ class WalletService {
             if (response.status === 200 || response.status === 201) {
                 console.log('submit payment successful:', response.data);
                 return response.data;
+            } else {
+                console.log('submit payment failed:', response.status);
+                return false;
             }
         } catch (error) {
             console.log(error);
+            return false;
         }
     }