| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343 |
- import { View, Text, ActivityIndicator, AppState } from 'react-native';
- import React, { useCallback, useEffect, useRef, useState } from 'react';
- import ChargingPageComponent from '../../../../component/chargingPage/chargingPageComponent';
- import { chargeStationService } from '../../../../service/chargeStationService';
- import ChargingPenaltyPageComponent from '../../../../component/chargingPage/chargingPenaltyComponent';
- import NoChargingOngoingPageComponent from '../../../../component/chargingPage/noChargingOngoingPageComponent';
- import { useFocusEffect } from 'expo-router';
- import ChargingHurryUpPageComponent from '../../../../component/chargingPage/chargingHurryUpPageComponent';
- import FutureReservationPageComponent from '../../../../component/chargingPage/futureReservationPageComponent';
- import ChargingFinishPageComponent from '../../../../component/chargingPage/chargingFinishPageComponent';
- const fakeData = [
- {
- createdAt: '2024-08-26T10:15:30.123Z',
- updatedAt: '2024-08-26T10:15:30.123Z',
- id: 'a1b2c3d4-e5f6-7890-abcd-1234567890ab',
- book_time: '2024-08-26T11:00:00.000Z',
- end_time: '2024-08-26T13:00:00.000Z',
- actual_start_time: '2024-08-26T11:05:23.456Z',
- actual_end_time: '2024-08-26T12:01:23.456Z',
- total_power: null,
- type: 'charging',
- penalty_fee: null,
- total_fee: 150,
- snapshot:
- '{"type":"charging","stationID":"2408261122116801000","connector":"101708260802474001","user":"user123-456-789","book_time":"2024-08-26T11:00:00.000Z","end_time":"2024-08-26T13:00:00.000Z","total_fee":150,"car":"car123-456-789"}',
- remark: null,
- promotion_name: null,
- promotion_msg: null,
- format_order_id: '730998640260820241015301234',
- Soc: 45,
- connector: {
- createdAt: '2024-08-01T09:00:00.000Z',
- updatedAt: '2024-08-26T10:00:00.000Z',
- id: 'conn123-456-789',
- ConnectorID: '101708260802474001',
- VoltageLowerLimits: 380,
- ConnectorType: 4,
- VoltageUpperLimits: 1000,
- NationalStandard: 2015,
- ConnectorName: 'A枪',
- Current: 250,
- Power: 180000,
- Status: 'charging',
- ParkStatus: 'occupied',
- LockStatus: 'locked',
- EquipmentID: {
- createdAt: '2024-08-01T09:00:00.000Z',
- updatedAt: '2024-08-26T10:00:00.000Z',
- id: 'equip123-456-789',
- EquipmentID: '1017082608024740',
- EquipmentLat: 22.310709,
- EquipmentLng: 114.22301,
- EquipmentType: 1,
- EquipmentName: '1桩',
- EquipmentModel: 'GCE-D180-Y-F',
- Power: 180000,
- StationID: {
- createdAt: '2024-08-01T09:00:00.000Z',
- updatedAt: '2024-08-26T10:00:00.000Z',
- id: '2408261122116801000',
- snapshot:
- '{"StationName":"CRAZY CHARGE (Example Street)","Address":"123 Example Street, Hong Kong"}',
- self_active_status_fk: 'active',
- business_hours_fk: '24/7',
- qr_code: 'qr_code_data',
- image: 'station_image_url',
- price: 3
- }
- }
- },
- user: {
- createdAt: '2024-01-01T00:00:00.000Z',
- updatedAt: '2024-08-26T10:00:00.000Z',
- id: 'user123-456-789',
- firstname: 'John',
- lastname: 'Doe',
- nickname: 'JD',
- email: 'john.doe@example.com',
- password: '$2b$10$hashedpasswordexample',
- phone: 12345678,
- ic_card: '0000001234567890',
- wallet: 5000,
- icon_url: 'user_icon_url',
- remark: null,
- address: '456 User Street, Hong Kong',
- status_fk: '1',
- gender: 'man',
- birthday: '1990/01/01',
- ic_car_id: null
- },
- status: {
- id: '2',
- createdAt: '2024-07-16T14:58:40.630Z',
- updatedAt: '2024-07-16T14:58:40.630Z',
- description: 'charging'
- },
- car: {
- createdAt: '2024-01-01T00:00:00.000Z',
- updatedAt: '2024-08-26T10:00:00.000Z',
- id: 'car123-456-789',
- license_plate: 'AB1234',
- car_brand: {
- createdAt: '2024-01-01T00:00:00.000Z',
- updatedAt: '2024-01-01T00:00:00.000Z',
- id: 'brand123-456-789',
- name: 'BWD',
- img_url: 'tesla_logo_url'
- },
- car_type: {
- createdAt: '2024-01-01T00:00:00.000Z',
- updatedAt: '2024-01-01T00:00:00.000Z',
- id: 'type123-456-789',
- name: 'Model 3',
- capacitance: 75,
- capacitance_unit: 'kwh',
- type_image_url: 'model3_image_url'
- }
- }
- }
- ];
- //***********************************************************************
- //而家start time & end time 一樣就當Walk in, walkin 會改左d字眼在ChargingHurryUpPageComponent
- //如果以後scan qr code可選時間, ChargingHurryUp display 字眼個logic 就要改
- //***********************************************************************
- const ChargingPage = () => {
- const [data, setData] = useState();
- const [isLoading, setIsLoading] = useState(false);
- const [currentStatus, setCurrentStatus] = useState('');
- const intervalRef = useRef(null);
- const lastUpdateTimeRef = useRef(Date.now());
- const fetchReservationData = useCallback(async () => {
- setIsLoading(true);
- try {
- const now = new Date();
- const response = await chargeStationService.fetchReservationHistories();
- lastUpdateTimeRef.current = Date.now();
- if (Object.keys(response).length === 0) {
- console.log('no reservation data');
- setCurrentStatus('noReservation');
- } else {
- // Check for recently finished reservations
- const finishedReservation = response.find((r) => {
- if (r.status.id === '8' && r.actual_end_time) {
- const endTime = new Date(r.actual_end_time);
- const timeDifference = now.getTime() - endTime.getTime();
- return timeDifference <= 1 * 60 * 1000; // Within 1 minutes
- }
- return false;
- });
- if (finishedReservation) {
- console.log('now', now);
- console.log('Finished reservation found:', finishedReservation);
- setCurrentStatus('finishReservation');
- setData(finishedReservation);
- } else {
- // Existing checks for other reservation types
- const penaltyReservation = response.filter(
- (r) => r.actual_start_time != null && r.actual_end_time != null && r.connector.Status === 7
- );
- if (penaltyReservation.length > 0) {
- setCurrentStatus('penaltyReservation');
- setData(penaltyReservation);
- } else {
- // Check for ongoing reservations (已插槍的預約)
- const onGoingReservation = response.filter(
- (r) => r.status.id === '7' && r.actual_end_time == null
- );
- // console.log('onGoingReservation', onGoingReservation);
- if (onGoingReservation.length > 0) {
- setCurrentStatus('onGoingReservation');
- setData(onGoingReservation);
- } else {
- // Check for recently passed reservations (仍未開始插槍充電的預約)
- const recentlyPassedReservations = 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 (recentlyPassedReservations.length > 0) {
- console.log(' i am recentlyPassedReservation', recentlyPassedReservations);
- setCurrentStatus('recentlyPassedReservations');
- setData(recentlyPassedReservations);
- } else {
- const futureReservation = response.filter((r) => {
- const bookTime = new Date(r.book_time);
- const fifteenMinutesAfterBookTime = new Date(bookTime.getTime() + 15 * 60 * 1000);
- return now < bookTime || (now > bookTime && now <= fifteenMinutesAfterBookTime);
- });
- if (futureReservation.length > 0) {
- futureReservation.sort((a, b) => new Date(a.end_time) - new Date(b.end_time));
- const closestReservation = futureReservation[0];
- setCurrentStatus('futureReservation');
- setData(closestReservation);
- } else {
- //if you are here, it means there are no future reservations (but there are past reservations)
- setCurrentStatus('noReservation');
- }
- }
- }
- }
- }
- }
- } catch (error) {
- console.error('Error fetching reservation histories:', error);
- } finally {
- setIsLoading(false);
- }
- }, []);
- const checkAndUpdateData = useCallback(() => {
- const currentTime = Date.now();
- const timeSinceLastUpdate = currentTime - lastUpdateTimeRef.current;
- if (timeSinceLastUpdate > 60000) {
- // If more than a minute has passed
- fetchReservationData();
- }
- }, [fetchReservationData]);
- useEffect(() => {
- const subscription = AppState.addEventListener('change', (nextAppState) => {
- if (nextAppState === 'active') {
- checkAndUpdateData();
- }
- });
- return () => {
- subscription.remove();
- };
- }, [checkAndUpdateData]);
- useEffect(() => {
- fetchReservationData();
- intervalRef.current = setInterval(fetchReservationData, 60000);
- return () => {
- if (intervalRef.current) {
- clearInterval(intervalRef.current);
- }
- };
- }, [fetchReservationData]);
- useFocusEffect(
- useCallback(() => {
- let isActive = true;
- const fetchData = async () => {
- try {
- await fetchReservationData();
- } catch (error) {
- console.error('Error in useFocusEffect:', error);
- }
- };
- fetchData();
- // Cleanup function
- return () => {
- isActive = false;
- // Any additional cleanup logic can go here
- };
- }, [fetchReservationData])
- );
- if (isLoading) {
- return (
- <View className="flex-1 justify-center bg-white">
- <ActivityIndicator color="#34657b" size="large" />
- </View>
- );
- }
- return (
- <View className="flex-1">
- {currentStatus === 'noReservation' && <NoChargingOngoingPageComponent />}
- {currentStatus === 'penaltyReservation' && <ChargingPenaltyPageComponent data={data} />}
- {currentStatus === 'onGoingReservation' && <ChargingPageComponent data={data} />}
- {currentStatus === 'recentlyPassedReservations' && <ChargingHurryUpPageComponent data={data} />}
- {currentStatus === 'futureReservation' && <FutureReservationPageComponent data={data} />}
- {currentStatus === 'finishReservation' && <ChargingFinishPageComponent data={data} />}
- </View>
- );
- };
- export default ChargingPage;
- // const fetchReservationData = useCallback(async () => {
- // setIsLoading(true);
- // try {
- // const now = new Date();
- // const response = await chargeStationService.fetchReservationHistories();
- // //先睇有無預約
- // if (Object.keys(response).length === 0) {
- // console.log('no reservation data');
- // setCurrentStatus('noReservation');
- // } else {
- // //二睇有無正在進行中 已插槍的預約
- // const onGoingReservation = response.filter((r) => r.status.id === '7');
- // if (onGoingReservation.length > 0) {
- // setCurrentStatus('onGoingReservation');
- // setData(onGoingReservation);
- // } else {
- // //三睇有無正在進行中的預約但仍未開始插槍充電的預約
- // //example: 訂單在10點開始, 現時為10點05分,用戶仍未插槍。
- // const recentlyPassedReservations = 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 (recentlyPassedReservations.length > 0) {
- // console.log(' i am recentlyPassedReservation', recentlyPassedReservations);
- // setCurrentStatus('recentlyPassedReservations');
- // setData(recentlyPassedReservations);
- // } else {
- // //睇未來最近一次的預約
- // const futureReservation = response.filter((r) => {
- // const bookTime = new Date(r.book_time);
- // const fifteenMinutesAfterBookTime = new Date(bookTime.getTime() + 15 * 60 * 1000);
- // return now < bookTime || (now > bookTime && now <= fifteenMinutesAfterBookTime);
- // });
- // if (futureReservation.length > 0) {
- // futureReservation.sort((a, b) => new Date(a.end_time) - new Date(b.end_time));
- // const closestReservation = futureReservation[0];
- // console.log('i am closest reservation', closestReservation);
- // setCurrentStatus('futureReservation');
- // setData(closestReservation);
- // }
- // }
- // }
- // }
- // } catch (error) {
- // console.error('Error fetching reservation histories:', error);
- // } finally {
- // setIsLoading(false);
- // }
- // }, []);
|