import { View, Text, ScrollView, FlatList, Pressable, ActivityIndicator, Image, Modal, Alert, TextInput } from 'react-native'; import NormalButton from '../global/normal_button'; import { SafeAreaView } from 'react-native-safe-area-context'; import { router, useFocusEffect } from 'expo-router'; import { useColorScheme } from 'nativewind'; import RecentlyBookedScrollView from '../global/recentlyBookedScrollView'; import { BellIconSvg, HomeIconSvg, MyBookingIconSvg, WhatsAppSvg, WalletSvg, MyWalletSvg, QrCodeIconSvg, VipCodeIconSvg } from '../global/SVG'; import { AuthContext } from '../../context/AuthProvider'; import { useCallback, useContext, useEffect, useState } from 'react'; import { authenticationService } from '../../service/authService'; import { chargeStationService } from '../../service/chargeStationService'; import { walletService } from '../../service/walletService'; import useUserInfoStore from '../../providers/userinfo_store'; import NormalInput from '../global/normal_input'; import { usePushNotifications } from '../../app/hooks/usePushNotifications'; import { notificationStorage } from '../notificationStorage'; import { handleGoWhatsApp } from '../../util/index'; interface HomePageProps {} const HomePage: React.FC = () => { const now = new Date(); const { user } = useContext(AuthContext); const { userID, currentPrice, setUserID, setCurrentPrice, setNotifySessionID } = useUserInfoStore(); const { colorScheme, toggleColorScheme } = useColorScheme(); const [showLicencePlateMessage, setShowLicencePlateMessage] = useState(false); const [licensePlate, setLicensePlate] = useState(''); const [showConfirmationModal, setShowConfirmationModal] = useState(false); const [showOnboarding, setShowOnboarding] = useState(true); const [mainPromotion, setMainPromotion] = useState([]); const [mainPromotionImage, setMainPromotionImage] = useState(''); const [reservationAfter2025, setReservationAfter2025] = useState([]); const [isLoadingReservations, setIsLoadingReservations] = useState(true); const [unreadCount, setUnreadCount] = useState(0); useEffect(() => { const fetchIDandCheckLicensePlate = async () => { try { const response = await authenticationService.getUserInfo(); //if success, set user ID, if (response) { setNotifySessionID(response.data.notify_session_id); setUserID(response.data.id); //after setting id, also check if the user has a valid license plate, if not, show message if (!response.data.cars || !Array.isArray(response.data.cars)) { Alert.alert('無法檢測車輛資訊', '請稍後再試'); setShowLicencePlateMessage(false); } if (response.data.cars.length === 1 && response.data.cars[0].license_plate === '0000') { setShowLicencePlateMessage(true); } } else { Alert.alert('fail to set user/notification session ID'); } } catch (error) { console.log(error); } }; const fetchCurrentPrice = async () => { try { const response = await chargeStationService.getCurrentPrice(); if (response) { setCurrentPrice(response); } } catch (error) { console.log('main page fetch current price error', error); } }; const fetchMainPromotion = async () => { try { const response = await chargeStationService.getAdvertise(); if (response) { const mainPromo = response.filter((item: any) => item.is_main)[0]; setMainPromotion(mainPromo); if (mainPromo) { const mainPromoImage = await chargeStationService.getProcessedImageUrl(mainPromo.image_url); if (mainPromoImage) { setMainPromotionImage(mainPromoImage); } } } } catch (error) { console.log('Error fetching promotion:', error); } }; fetchMainPromotion(); const fetchWithAllSettled = async () => { const results = await Promise.allSettled([ fetchIDandCheckLicensePlate(), fetchCurrentPrice(), fetchMainPromotion() ]); }; fetchWithAllSettled(); }, []); useFocusEffect( useCallback(() => { let isActive = true; const fetchData = async () => { setIsLoadingReservations(true); // Start loading try { const results = await Promise.allSettled([ chargeStationService.fetchReservationHistories(), chargeStationService.getAdvertise() ]); if (!isActive) return; // Handle reservation data if (results[0].status === 'fulfilled') { const year2025 = new Date('2025-02-01T00:00:00.000Z'); const reservationAfter2025 = results[0].value.filter((r: any) => { const date = new Date(r.createdAt); return date > year2025; }); setReservationAfter2025(reservationAfter2025); } else if (results[0].status === 'rejected') { Alert.alert('Error fetching reservations:', results[0].reason); } // Get viewed notifications const viewedNotifications = await notificationStorage.getViewedNotifications(); let totalUnread = 0; // Count unread reservations if (results[0].status === 'fulfilled') { const unreadReservations = reservationAfter2025.filter((r: any) => { return !viewedNotifications.some((vn: any) => vn.id === r.id); }); totalUnread += unreadReservations.length; } // Count unread promotions if (results[1].status === 'fulfilled') { const unreadPromotions = results[1].value.filter((p: any) => { return !viewedNotifications.some((vn) => vn.id === p.id); }); totalUnread += unreadPromotions.length; } setUnreadCount(totalUnread); } catch (error) { if (!isActive) return; Alert.alert('Error fetching data'); } finally { if (isActive) { setIsLoadingReservations(false); } } }; fetchData(); console.log('iiiiiii'); return () => { isActive = false; }; }, []) ); const saveLicensePlate = async (licensePlate: string) => { try { const response = await chargeStationService.addCar( licensePlate, '1834d087-bfc1-4f90-8f09-805e3d9422b5', 'f599470d-53a5-4026-99c0-2dab34c77f39', true ); if (response === true) { console.log('License plate saved successfully'); } else { Alert.alert('無法保存車牌號碼', '請稍後再試'); } } catch (error) { Alert.alert('暫時無法保存車牌號碼', '請稍後再試'); } }; return ( {/* Add Modal component */} {mainPromotionImage && ( setShowOnboarding(false)} > setShowOnboarding(false)} > 點擊任意位置關閉 )} {showLicencePlateMessage && ( setShowLicencePlateMessage(false)} > {!showConfirmationModal ? ( // License Plate Input Modal 請添加您的車牌號碼 為更好地為您提供服務,請在您的帳戶中添加車牌號碼。 setLicensePlate(s)} extendedStyle={{ borderRadius: 12, marginBottom: 0 }} textContentType="none" autoComplete="off" keyboardType="default" /> 確定} onPress={() => { //here when users click confirm, i want to pop another modal that say you have entered "xxxxxx", click confirm to continue if (!licensePlate.trim()) { Alert.alert('請輸入車牌號碼'); return; } if (licensePlate.trim().length < 4 || licensePlate.trim().length > 10) { Alert.alert('無效的車牌號碼', '請輸入有效的車牌號碼'); return; } setShowConfirmationModal(true); }} /> ) : ( // Confirmation Modal 確認車牌號碼 您輸入的車牌號碼為:{licensePlate} 取消} onPress={() => setShowConfirmationModal(false)} /> 確認} onPress={() => { saveLicensePlate(licensePlate); setShowConfirmationModal(false); setShowLicencePlateMessage(false); setLicensePlate(''); }} /> )} )} 你好! router.push({ pathname: 'notificationPage' })} disabled={isLoadingReservations} className="z-10 w-10 items-center justify-center" hitSlop={{ top: 20, bottom: 20, left: 20, right: 20 }} > {unreadCount > 0 && ( {unreadCount} )} handleGoWhatsApp()}> {user?.nickname} {/* router.push('searchPage')}> 搜尋充電站或地區.. */} router.push('scanQrPage')} // onPress={() => router.push('optionPage')} title={ 掃描及充電 } extendedStyle={{ alignItems: 'flex-start', padding: 24 }} /> {/* router.push('bookingMenuPage')} onPress={() => Alert.alert('即將推出', '此功能即將推出,敬請期待!')} //onPress={() => notificationStorage.clearStorage()} title={ 我的預約 } extendedStyle={{ alignItems: 'flex-start', padding: 24 }} /> */} router.push('/(account)/(wallet)/walletPage')} title={ 錢包 } extendedStyle={{ alignItems: 'flex-start', padding: 24 }} /> console.log('掃瞄及充電')} onPress={() => router.push('vipQrPage')} title={ 專屬會員二維碼 } extendedStyle={{ alignItems: 'flex-start', padding: 24 }} /> ); }; export default HomePage;