|
|
@@ -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>
|
|
|
);
|
|
|
};
|