//the size of the TabView will follow its parent-container's size.
import * as React from 'react';
import {
View,
Text,
useWindowDimensions,
StyleSheet,
ImageSourcePropType,
ScrollView,
ActivityIndicator,
Pressable,
Alert
} from 'react-native';
import { TabView, SceneMap, TabBar } from 'react-native-tab-view';
import { IndividualCouponComponent } from '../accountPages/walletPageComponent';
import { formatCouponDate } from '../../util/lib';
import { useCallback, useEffect, useRef, useState } from 'react';
import { walletService } from '../../service/walletService';
import { useChargingStore } from '../../providers/scan_qr_payload_store';
import { chargeStationService } from '../../service/chargeStationService';
import { router } from 'expo-router';
import axios from 'axios';
export interface TabItem {
imgURL: ImageSourcePropType;
date: string;
time: string;
chargeStationName: string;
chargeStationAddress: string;
distance: string;
}
interface TabViewComponentProps {
titles: string[];
}
const FirstRoute = ({
coupons,
loading,
handleCouponClick
}: {
coupons: any;
loading: boolean;
handleCouponClick: any;
}) => {
return (
{loading ? (
) : (
{coupons.filter(
(coupon: any) =>
coupon.permission == true &&
coupon.is_consumed === false &&
(coupon.expire_date === null || new Date(coupon.expire_date) > new Date())
).length === 0 ? (
暫時戶口沒有優惠券。
) : (
coupons
.filter(
(coupon: any) =>
coupon.permission == true &&
coupon.is_consumed === false &&
(coupon.expire_date === null ||
new Date(coupon.expire_date) > new Date())
)
.sort(
(a: any, b: any) =>
new Date(a.expire_date).getTime() - new Date(b.expire_date).getTime()
)
.slice(0, 30)
.map((coupon: any, index: any) => (
))
)}
)}
);
};
const SecondRoute = ({ coupons }: { coupons: any }) => (
{coupons
.filter(
(coupon: any) =>
coupon.is_consumed === true ||
(coupon.expire_date !== null && new Date(coupon.expire_date) < new Date())
)
.slice(0, 30)
.map((coupon: any, index: any) => (
))}
);
const CouponTabViewComponent: React.FC = ({ titles }) => {
const layout = useWindowDimensions();
const [loading, setLoading] = useState(false);
const [coupons, setCoupons] = useState([]);
const [userID, setUserID] = useState('');
const {
current_price_store,
setCurrentPriceStore,
stationID,
promotion_code,
setPromotionCode,
setCouponDetail,
coupon_detail,
total_power,
setTotalPower,
setProcessedCouponStore,
setSumOfCoupon
} = useChargingStore();
useEffect(() => {
const fetchData = async () => {
try {
setLoading(true);
const info = await walletService.getCustomerInfo();
const coupon = await walletService.getCouponForSpecificUser(info.id);
setUserID(info.id);
setCoupons(coupon);
} catch (error) {
console.log(error);
} finally {
setLoading(false);
}
};
fetchData();
}, []);
//fetch current price for coupon valid calculation
useEffect(() => {
const fetchCurrentPrice = async () => {
try {
const response = await chargeStationService.getOriginalPriceInPay(stationID);
setCurrentPriceStore(response);
} catch (error) {
// More specific error handling
if (axios.isAxiosError(error)) {
const errorMessage = error.response?.data?.message || 'Network error occurred';
Alert.alert('Error', `Unable to fetch price: ${errorMessage}`, [
{
text: 'OK',
onPress: () => {
cleanupData();
router.push('/mainPage');
}
}
]);
} else {
Alert.alert('Error', 'An unexpected error occurred while fetching the price', [
{
text: 'OK',
onPress: () => {
cleanupData();
router.push('/mainPage');
}
}
]);
}
}
};
fetchCurrentPrice();
}, []);
const handleCouponClick = async (clickedCoupon: string) => {
let temp_promotion_code = [...promotion_code];
if (!current_price_store) {
Alert.alert('Error', 'Unable to fetch price', [
{
text: 'OK',
onPress: () => {
cleanupData();
router.push('/mainPage');
}
}
]);
return;
}
let orderAmount = current_price_store * total_power;
//when i click on a coupon, if coupone doesnt already exist in the stack, i add it to the stack
if (!promotion_code.includes(clickedCoupon)) {
const found_coupon = coupons.find((coupon: any) => coupon.id === clickedCoupon);
temp_promotion_code = [...promotion_code, found_coupon.id];
try {
const valid = await chargeStationService.validateCoupon(temp_promotion_code, orderAmount);
if (valid === true) {
setCouponDetail([...coupon_detail, found_coupon]);
setPromotionCode([...promotion_code, clickedCoupon]);
} else {
Alert.alert('不符合使用優惠券的條件', '請查看優惠卷的詳情,例如是否需要滿足最低消費金額。');
}
} catch (error) {
console.log(error);
}
} else {
//coupon already exists, this de-select the coupon
const index_of_clicked_coupon = promotion_code.findIndex((i) => i === clickedCoupon);
const newPromotionCode = [...promotion_code];
newPromotionCode.splice(index_of_clicked_coupon, 1);
setPromotionCode(newPromotionCode);
const newCouponDetail = coupon_detail.filter((detail: any) => detail.id !== clickedCoupon);
setCouponDetail(newCouponDetail);
}
};
const cleanupData = () => {
setPromotionCode([]);
setCouponDetail([]);
setProcessedCouponStore([]);
setSumOfCoupon(0);
setTotalPower(null);
};
const renderScene = useCallback(
({ route }: { route: any }) => {
switch (route.key) {
case 'firstRoute':
return ;
case 'secondRoute':
return ;
default:
return null;
}
},
[coupons, loading, handleCouponClick]
);
const [routes] = React.useState([
{ key: 'firstRoute', title: titles[0] },
{ key: 'secondRoute', title: titles[1] }
]);
const [index, setIndex] = React.useState(0);
const renderTabBar = (props: any) => (
);
return (
(
{route.title}
)
}}
/>
);
};
export default CouponTabViewComponent;
const styles = StyleSheet.create({
container: { flexDirection: 'row' },
image: { width: 100, height: 100, margin: 15, borderRadius: 10 },
textContainer: { flexDirection: 'column', gap: 8, marginTop: 20 },
floatingButton: {
elevation: 5,
shadowColor: '#000',
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.25,
shadowRadius: 3.84
}
});