optionPage.tsx 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  1. import {
  2. View,
  3. Text,
  4. ScrollView,
  5. Pressable,
  6. Image,
  7. Dimensions,
  8. ImageBackground,
  9. BackHandler,
  10. Alert
  11. } from 'react-native';
  12. import React, { useCallback, useEffect, useState } from 'react';
  13. import { SafeAreaView } from 'react-native-safe-area-context';
  14. import { router, useFocusEffect, useNavigation } from 'expo-router';
  15. import { CrossLogoSvg, PreviousPageBlackSvg, RightArrowIconSvg } from '../../../../component/global/SVG';
  16. import { useChargingStore } from '../../../../providers/scan_qr_payload_store';
  17. import { walletService } from '../../../../service/walletService';
  18. import { chargeStationService } from '../../../../service/chargeStationService';
  19. const optionPage = () => {
  20. const {
  21. total_power,
  22. setTotalPower,
  23. promotion_code,
  24. setPromotionCode,
  25. sum_of_coupon,
  26. setSumOfCoupon,
  27. setCouponDetail,
  28. current_price_store,
  29. setCurrentPriceStore,
  30. setProcessedCouponStore
  31. } = useChargingStore();
  32. const buttonText = [
  33. {
  34. power: '20度電',
  35. minute: '25分鐘',
  36. total_power: 20
  37. },
  38. {
  39. power: '25度電',
  40. minute: '30分鐘',
  41. total_power: 25
  42. },
  43. {
  44. power: '30度電',
  45. minute: '40分鐘',
  46. total_power: 30
  47. },
  48. {
  49. power: '40度電',
  50. minute: '45分鐘',
  51. total_power: 40
  52. },
  53. {
  54. power: '充滿停機',
  55. minute: '最多80度電',
  56. total_power: 80
  57. }
  58. ];
  59. const screenWidth = Dimensions.get('window').width;
  60. const [useableCoupon, setUseableCoupon] = useState([]);
  61. const navigation = useNavigation();
  62. //forbid user leftswipping
  63. useEffect(() => {
  64. navigation.setOptions({
  65. gestureEnabled: false
  66. });
  67. }, [navigation]);
  68. //fetch data to see if there is any available couponS
  69. useEffect(() => {
  70. const fetchData = async () => {
  71. try {
  72. const info = await walletService.getCustomerInfo();
  73. const coupon = await walletService.getCouponForSpecificUser(info.id);
  74. //filter by expire date is not past today.and is_consumed is fa.se.
  75. const useableConpon = coupon.filter((couponObj: any) => {
  76. const today = new Date();
  77. if (couponObj.expire_date === null) {
  78. return couponObj.is_consumed === false;
  79. }
  80. const expireDate = new Date(couponObj.expire_date);
  81. return expireDate > today && couponObj.is_consumed === false;
  82. });
  83. setUseableCoupon(useableConpon);
  84. // console.log(useableConpon);
  85. } catch (error) {
  86. console.log(error);
  87. }
  88. };
  89. fetchData();
  90. }, []);
  91. const cleanupData = () => {
  92. setTotalPower(null);
  93. setSumOfCoupon(0);
  94. setPromotionCode([]);
  95. setCouponDetail([]);
  96. setProcessedCouponStore([]);
  97. };
  98. // Add this effect to handle Android back button
  99. useFocusEffect(
  100. useCallback(() => {
  101. const onBackPress = () => {
  102. cleanupData();
  103. if (router.canGoBack()) {
  104. router.back();
  105. } else {
  106. router.replace('/scanQrPage');
  107. }
  108. return true;
  109. };
  110. BackHandler.addEventListener('hardwareBackPress', onBackPress);
  111. return () => BackHandler.removeEventListener('hardwareBackPress', onBackPress);
  112. }, [])
  113. );
  114. const displayedText =
  115. promotion_code.length > 0 ? `$ ${sum_of_coupon}劵` : useableCoupon.length > 0 ? '有可用劵' : '無可用劵';
  116. return (
  117. <SafeAreaView className="flex-1 bg-white" edges={['top', 'right', 'left']}>
  118. <ScrollView className="flex-1 mx-[5%]" showsVerticalScrollIndicator={false}>
  119. <View style={{ marginTop: 25 }}>
  120. <Pressable
  121. onPress={() => {
  122. if (router.canGoBack()) {
  123. cleanupData();
  124. router.back();
  125. } else {
  126. cleanupData();
  127. router.replace('/scanQrPage');
  128. }
  129. }}
  130. >
  131. <PreviousPageBlackSvg />
  132. </Pressable>
  133. </View>
  134. <View className="flex-1 flex-col justify-center items-center">
  135. {/* top word and logo */}
  136. <View className="flex-col justify-center items-center gap-2">
  137. {/* <Text className="text-2xl"> */}
  138. <Text className="text-2xl font-[600]">選擇充電度數</Text>
  139. <Image
  140. source={require('../../../../assets/battery.png')}
  141. style={{ width: screenWidth * 0.3, height: undefined, aspectRatio: 1 }}
  142. className="mb-2 md:mb-4 lg:mb-4 xl:mb-6 "
  143. />
  144. </View>
  145. {/* middle button */}
  146. <View className="flex-1 w-full mt-6">
  147. <View className="flex-row flex-wrap justify-center items-center gap-4 ">
  148. {/* not showing full power because it needs to be full width */}
  149. {buttonText
  150. .filter((item) => item.power != '充滿停機')
  151. .map((buttonTextObj: any, index) => (
  152. <Pressable
  153. key={index}
  154. className={`${total_power === buttonTextObj.total_power ? 'bg-[#02677D]' : ''}
  155. w-[45%] border border-[#02677D] p-1 md:p-2 lg:p-3 xl:p-4 py-4 lg:py-6 rounded-xl`}
  156. onPress={() => {
  157. setTotalPower(buttonTextObj.total_power);
  158. }}
  159. >
  160. <Text
  161. className={`${
  162. total_power === buttonTextObj.total_power
  163. ? 'text-white'
  164. : 'text-[#02677D]'
  165. } text-base lg:text-lg xl:text-xl text-center`}
  166. >
  167. {buttonTextObj.power}({buttonTextObj.minute})
  168. </Text>
  169. </Pressable>
  170. ))}
  171. {/* this is 充滿停機only */}
  172. {buttonText
  173. .filter((item) => item.power === '充滿停機')
  174. .map((item, index) => (
  175. <Pressable
  176. key={index}
  177. onPress={() => {
  178. setTotalPower(item.total_power);
  179. }}
  180. className={`${
  181. total_power === item.total_power ? 'bg-[#02677D]' : ''
  182. } w-[94%] border border-[#02677D] p-1 md:p-2 lg:p-3 xl:p-4 py-4 lg:py-6 rounded-xl`}
  183. >
  184. <Text
  185. className={`${
  186. total_power === item.total_power ? 'text-white' : 'text-[#02677D]'
  187. } text-base lg:text-lg xl:text-xl text-center`}
  188. >
  189. {item.power}({item.minute})
  190. </Text>
  191. </Pressable>
  192. ))}
  193. {/* coupon row */}
  194. <Pressable
  195. onPress={() => {
  196. if (!total_power) {
  197. Alert.alert(
  198. '選擇充電方案',
  199. '請先選擇充電方案再選擇優惠券',
  200. [{ text: '確定', style: 'default' }],
  201. {
  202. cancelable: true
  203. }
  204. );
  205. } else {
  206. Alert.alert('提提您', '使用優惠券的交易每度電以正價$3.5元計算!', [
  207. { text: '我知道了', onPress: () => router.push('/selectCoupon') }
  208. ]);
  209. }
  210. }}
  211. style={{ flex: 1, borderRadius: 10, overflow: 'hidden' }}
  212. >
  213. <ImageBackground
  214. source={require('../../../../assets/coupon.png')}
  215. style={{
  216. width: '100%',
  217. height: 72,
  218. borderRadius: 24,
  219. justifyContent: 'center',
  220. alignItems: 'flex-end'
  221. }}
  222. resizeMode="contain"
  223. >
  224. <Text className="text-white text-center text-base lg:text-lg xl:text-xl pr-6 md:pr-8 lg:pr-10 xl:pr-12">
  225. {displayedText}
  226. </Text>
  227. </ImageBackground>
  228. </Pressable>
  229. </View>
  230. </View>
  231. {/* confirm and cancel */}
  232. <View className="flex-row flex-wrap justify-center items-center gap-4 my-8 lg:my-12">
  233. <Pressable
  234. onPress={() => {
  235. cleanupData();
  236. if (router.canGoBack()) {
  237. router.back();
  238. } else {
  239. router.replace('/scanQrPage');
  240. }
  241. }}
  242. className="w-[45%] border border-[#02677D] p-1 md:p-2 lg:p-3 xl:p-4 py-4 lg:py-6 rounded-xl "
  243. >
  244. <Text className="text-[#02677D] text-base lg:text-lg xl:text-xl text-center">取消</Text>
  245. </Pressable>
  246. <Pressable
  247. onPress={() => {
  248. if (!total_power) {
  249. Alert.alert(
  250. '選擇充電方案',
  251. '請先選擇充電方案再確認',
  252. [{ text: '確定', style: 'default' }],
  253. {
  254. cancelable: true
  255. }
  256. );
  257. } else {
  258. router.push('/totalPayment');
  259. }
  260. }}
  261. className="w-[45%] border border-[#02677D] p-1 md:p-2 lg:p-3 xl:p-4 py-4 lg:py-6 rounded-xl "
  262. >
  263. <Text className="text-[#02677D] text-base lg:text-lg xl:text-xl text-center">確認</Text>
  264. </Pressable>
  265. </View>
  266. </View>
  267. </ScrollView>
  268. </SafeAreaView>
  269. );
  270. };
  271. export default optionPage;