import { CameraView, useCameraPermissions } from 'expo-camera';
import { useEffect, useRef, useState } from 'react';
import {
ActivityIndicator,
Alert,
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 { width: screenWidth, height: screenHeight } = Dimensions.get('window');
const ChooseCar = ({ carData, loading, selectedCar, setSelectedCar }) => {
const isLargeScreen = screenHeight >= 800;
const defaultImageUrl = require('../../../../assets/car1.png');
return (
{loading ? (
) : (
{
if (router.canGoBack()) {
router.back();
} else {
router.replace('mainPage');
}
}}
>
選擇充電車輛
{carData.map((car, index) => (
{
setSelectedCar(car.id);
console.log(car.id);
}}
isSelected={selectedCar === car.id}
// imageUrl={image}
VehicleName={car.name}
isDefault={car.isDefault}
/>
))}
)}
);
};
const ScanQrPage = () => {
// State declarations
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('');
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();
if (status !== 'granted') {
alert('需要相機權限以掃描QR碼');
}
})();
}, []);
// Effect for fetching user's cars
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();
}, []);
// Effect for fetching user ID
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();
}, []);
if (!permission) {
return ;
}
if (!permission.granted) {
return (
需要相機權限以掃描QR碼,請在設定中開啟相機權限
);
}
// // 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
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}`);
//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 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,
user: userID,
book_time: now,
end_time: now,
total_power: 0,
total_fee: 0,
promotion_code: '',
car: selectedCar,
type: 'walking'
};
const startCharging = async (scanResult: string) => {
try {
if (selectedCar === '') {
Alert.alert('請選擇車輛');
return;
}
const response = await walletService.submitPayment(
dataForSubmission.stationID,
scanResult,
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 from startCharging', response);
router.push('(auth)/(tabs)/(charging)/chargingPage');
} else {
console.log('Failed to start chargi12312312ng:', response);
Alert.alert('掃描失敗 請稍後再試。', response);
}
} catch (error) {
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 (
{loading ? (
) : (
請選擇充電車輛{'\n'}及掃瞄充電座上的二維碼
router.push('assistancePage')}>
需要協助?
)}
);
};
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;