|
|
@@ -1,3 +1,4 @@
|
|
|
+// app/(auth)/(tabs)/(home)/totalPayment.tsx
|
|
|
import { router, useFocusEffect, useNavigation } from 'expo-router';
|
|
|
import {
|
|
|
View,
|
|
|
@@ -25,7 +26,10 @@ import axios from 'axios';
|
|
|
import sha256 from 'crypto-js/sha256';
|
|
|
import { walletService } from '../../../../service/walletService';
|
|
|
import AsyncStorage from '@react-native-async-storage/async-storage';
|
|
|
+import { useTranslation } from '../../../../util/hooks/useTranslation';
|
|
|
+
|
|
|
const TotalPayment = () => {
|
|
|
+ const { t } = useTranslation();
|
|
|
const {
|
|
|
promotion_code,
|
|
|
stationID,
|
|
|
@@ -79,9 +83,9 @@ const TotalPayment = () => {
|
|
|
// 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}`, [
|
|
|
+ Alert.alert(t('common.error'), `${t('wallet.error_fetching_balance')}: ${errorMessage}`, [
|
|
|
{
|
|
|
- text: 'OK',
|
|
|
+ text: t('common.ok'),
|
|
|
onPress: () => {
|
|
|
cleanupData();
|
|
|
router.push('/mainPage');
|
|
|
@@ -89,9 +93,9 @@ const TotalPayment = () => {
|
|
|
}
|
|
|
]);
|
|
|
} else {
|
|
|
- Alert.alert('Error', 'An unexpected error occurred while fetching the price', [
|
|
|
+ Alert.alert(t('common.error'), t('wallet.error_fetching_balance'), [
|
|
|
{
|
|
|
- text: 'OK',
|
|
|
+ text: t('common.ok'),
|
|
|
onPress: () => {
|
|
|
cleanupData();
|
|
|
router.push('/mainPage');
|
|
|
@@ -142,8 +146,8 @@ const TotalPayment = () => {
|
|
|
setOutTradeNo('');
|
|
|
paymentInitiatedTime.current = null;
|
|
|
Alert.alert(
|
|
|
- 'Payment Timeout',
|
|
|
- 'The payment status check has timed out. Please check your payment history.'
|
|
|
+ t('payment.payment_timeout_title'),
|
|
|
+ t('payment.payment_timeout_message')
|
|
|
);
|
|
|
}
|
|
|
}
|
|
|
@@ -166,14 +170,14 @@ const TotalPayment = () => {
|
|
|
// console.log('outTradeNo in scanQR Page checkpaymentstatus ', outTradeNo);
|
|
|
const result = await walletService.checkPaymentStatus(outTradeNo);
|
|
|
setPaymentStatus(result);
|
|
|
- // console.log('checkPaymentStatus from scan QR checkpaymentStatus', result);
|
|
|
+ // console.log('checkPaymentStatus from scan QR checkpaymentstatus', result);
|
|
|
|
|
|
- if (result && !result.some((item) => item.errmsg?.includes('處理中'))) {
|
|
|
+ if (result && !result.some((item) => item.errmsg?.includes(t('payment.processing')))) {
|
|
|
// Payment successful
|
|
|
// console.log('totalFee', totalFee);
|
|
|
- Alert.alert('付款已成功', `你已成功增值。請重新掃描去啟動充電槍。`, [
|
|
|
+ Alert.alert(t('payment.payment_success_title'), t('payment.payment_success_message', { amount: totalPrice }), [
|
|
|
{
|
|
|
- text: '確認',
|
|
|
+ text: t('payment.confirm'),
|
|
|
onPress: async () => {
|
|
|
cleanupData();
|
|
|
router.push('/mainPage');
|
|
|
@@ -181,9 +185,9 @@ const TotalPayment = () => {
|
|
|
}
|
|
|
]);
|
|
|
} else {
|
|
|
- Alert.alert('付款失敗', '請再試一次。', [
|
|
|
+ Alert.alert(t('payment.payment_failed_title'), t('payment.payment_failed_message'), [
|
|
|
{
|
|
|
- text: '確定',
|
|
|
+ text: t('payment.ok'),
|
|
|
onPress: () => {
|
|
|
cleanupData();
|
|
|
router.push('/mainPage');
|
|
|
@@ -196,7 +200,7 @@ const TotalPayment = () => {
|
|
|
paymentInitiatedTime.current = null;
|
|
|
} catch (error) {
|
|
|
console.error('Failed to check payment status:', error);
|
|
|
- Alert.alert('Error', 'Failed to check payment status. Please check your payment history.');
|
|
|
+ Alert.alert(t('common.error'), t('payment.payment_status_check_failed'));
|
|
|
}
|
|
|
};
|
|
|
const showLoadingAndNavigate = async () => {
|
|
|
@@ -222,31 +226,31 @@ const TotalPayment = () => {
|
|
|
let car, user_id, walletBalance, price_for_pay;
|
|
|
setLoading(true);
|
|
|
if (currentPriceTotalPayment === null) {
|
|
|
- Alert.alert('Please wait', 'Still loading price information...');
|
|
|
+ Alert.alert(t('payment.processing'), t('payment.wait_loading_price'));
|
|
|
return;
|
|
|
}
|
|
|
//fetch car with proper try catch
|
|
|
try {
|
|
|
car = await chargeStationService.getUserDefaultCars();
|
|
|
if (!car?.data?.id) {
|
|
|
- Alert.alert('Failed to fetch UDCC', 'Please try again later');
|
|
|
+ Alert.alert(t('payment.error_title'), t('payment.failed_fetch_udcc'));
|
|
|
return;
|
|
|
}
|
|
|
} catch (error) {
|
|
|
console.error('Failed to fetch user default car:', error);
|
|
|
- Alert.alert('Failed to fetch UDC', 'Please try again later');
|
|
|
+ Alert.alert(t('payment.error_title'), t('payment.failed_fetch_udc'));
|
|
|
return;
|
|
|
}
|
|
|
//fetch user id with proper try catch
|
|
|
try {
|
|
|
user_id = await authenticationService.getUserInfo();
|
|
|
if (!user_id?.data?.id) {
|
|
|
- Alert.alert('Failed to fetch userID', 'Please try again later');
|
|
|
+ Alert.alert(t('payment.error_title'), t('payment.failed_fetch_userid'));
|
|
|
return;
|
|
|
}
|
|
|
} catch (error) {
|
|
|
console.error('Failed to fetch user ID:', error);
|
|
|
- Alert.alert('Failed to fetch user ID', 'Please try again later');
|
|
|
+ Alert.alert(t('payment.error_title'), t('payment.failed_fetch_userid'));
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
@@ -255,7 +259,7 @@ const TotalPayment = () => {
|
|
|
walletBalance = await walletService.getWalletBalance();
|
|
|
} catch (error) {
|
|
|
console.error('Failed to fetch user wallet:', error);
|
|
|
- Alert.alert('Failed to fetch user wallet', 'Please try again later');
|
|
|
+ Alert.alert(t('payment.error_title'), t('payment.failed_fetch_wallet'));
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
@@ -276,11 +280,11 @@ const TotalPayment = () => {
|
|
|
|
|
|
if (unpaidPenalties.length > 0) {
|
|
|
Alert.alert(
|
|
|
- '未付罰款',
|
|
|
- '您有未支付的罰款。請先支付罰款後再重新掃描充電。',
|
|
|
+ t('payment.unpaid_penalty_title'),
|
|
|
+ t('payment.unpaid_penalty_message'),
|
|
|
[
|
|
|
{
|
|
|
- text: '查看詳情',
|
|
|
+ text: t('payment.view_details'),
|
|
|
onPress: () => {
|
|
|
// Navigate to a page showing penalty details
|
|
|
cleanupData();
|
|
|
@@ -298,7 +302,7 @@ const TotalPayment = () => {
|
|
|
}
|
|
|
},
|
|
|
{
|
|
|
- text: '返回',
|
|
|
+ text: t('scanQr.back'),
|
|
|
onPress: () => {
|
|
|
cleanupData();
|
|
|
if (router.canGoBack()) {
|
|
|
@@ -315,7 +319,7 @@ const TotalPayment = () => {
|
|
|
}
|
|
|
}
|
|
|
} catch (error) {
|
|
|
- Alert.alert('Error', 'Failed to fetch reservation histories for penalty checking purpose');
|
|
|
+ Alert.alert(t('common.error'), t('scanQr.failed_fetch_reservations'));
|
|
|
}
|
|
|
|
|
|
const now = new Date();
|
|
|
@@ -347,9 +351,9 @@ const TotalPayment = () => {
|
|
|
|
|
|
// check if user has enough wallet, if not, link to qf pay page
|
|
|
if (totalPrice === null) {
|
|
|
- Alert.alert('Error', 'Unable to fetch totalPrice', [
|
|
|
+ Alert.alert(t('common.error'), t('scanQr.failed_fetch_totalprice'), [
|
|
|
{
|
|
|
- text: 'OK',
|
|
|
+ text: t('common.ok'),
|
|
|
onPress: () => {
|
|
|
cleanupData();
|
|
|
router.push('/mainPage');
|
|
|
@@ -383,9 +387,9 @@ const TotalPayment = () => {
|
|
|
if (response.error) {
|
|
|
console.log('Error1', response.error);
|
|
|
// Handle error response from the service
|
|
|
- Alert.alert('掃描失敗 請稍後再試。', response.message || '未知錯誤', [
|
|
|
+ Alert.alert(t('payment.scan_failed'), response.message || t('payment.unknown_error'), [
|
|
|
{
|
|
|
- text: '返回主頁',
|
|
|
+ text: t('payment.back_main'),
|
|
|
onPress: () => {
|
|
|
cleanupData();
|
|
|
router.push('/mainPage');
|
|
|
@@ -396,18 +400,18 @@ const TotalPayment = () => {
|
|
|
}
|
|
|
|
|
|
if (response === 200 || response === 201) {
|
|
|
- Alert.alert('啟動成功', '請按下確認並等待頁面稍後自動跳轉至充電介面', [
|
|
|
+ Alert.alert(t('payment.charging_started_title'), t('payment.charging_started_message'), [
|
|
|
{
|
|
|
- text: '確認',
|
|
|
+ text: t('payment.confirm'),
|
|
|
onPress: showLoadingAndNavigate
|
|
|
}
|
|
|
]);
|
|
|
} else {
|
|
|
console.log('Error111', response, payloadForPay.connector);
|
|
|
|
|
|
- Alert.alert('掃描失敗 請稍後再試。', response.error_msg || '未知錯誤', [
|
|
|
+ Alert.alert(t('payment.scan_failed'), response.error_msg || t('payment.unknown_error'), [
|
|
|
{
|
|
|
- text: '返回主頁',
|
|
|
+ text: t('payment.back_main'),
|
|
|
onPress: () => {
|
|
|
cleanupData();
|
|
|
router.push('/mainPage');
|
|
|
@@ -417,9 +421,9 @@ const TotalPayment = () => {
|
|
|
}
|
|
|
} catch (error) {
|
|
|
console.error('Payment submission failed:', error);
|
|
|
- Alert.alert('錯誤', '付款提交失敗,請稍後再試。', [
|
|
|
+ Alert.alert(t('common.error'), t('payment.payment_submit_failed'), [
|
|
|
{
|
|
|
- text: 'OK',
|
|
|
+ text: t('common.ok'),
|
|
|
onPress: () => {
|
|
|
cleanupData();
|
|
|
router.push('/mainPage');
|
|
|
@@ -467,7 +471,7 @@ const TotalPayment = () => {
|
|
|
const obj = {
|
|
|
// appcode: '6937EF25DF6D4FA78BB2285441BC05E9',
|
|
|
appcode: '636E234FB30D43598FC8F0140A1A7282',
|
|
|
- goods_name: 'Crazy Charge 錢包增值',
|
|
|
+ goods_name: t('payment.wallet_top_up'),
|
|
|
out_trade_no: response,
|
|
|
paysource: 'crazycharge_checkout',
|
|
|
return_url: 'https://crazycharge.com.hk/completed',
|
|
|
@@ -498,26 +502,26 @@ const TotalPayment = () => {
|
|
|
try {
|
|
|
const supported = await Linking.canOpenURL(url);
|
|
|
if (supported) {
|
|
|
- Alert.alert('', '偵測到您錢包餘額不足,現在為您跳轉到充值頁面', [
|
|
|
+ Alert.alert('', t('payment.insufficient_balance_redirect'), [
|
|
|
{
|
|
|
- text: '確定',
|
|
|
+ text: t('payment.ok'),
|
|
|
onPress: async () => {
|
|
|
await Linking.openURL(url);
|
|
|
}
|
|
|
}
|
|
|
]);
|
|
|
} else {
|
|
|
- Alert.alert('錯誤', '請稍後再試');
|
|
|
+ Alert.alert(t('common.error'), t('payment.try_again_later'));
|
|
|
}
|
|
|
} catch (error) {
|
|
|
console.error('Top-up failed:', error);
|
|
|
- Alert.alert('Error', '一次性付款失敗,請稍後再試');
|
|
|
+ Alert.alert(t('common.error'), t('payment.one_time_payment_failed'));
|
|
|
}
|
|
|
} else {
|
|
|
- Alert.alert('Error', 'failed to fetch outTradeNo.');
|
|
|
+ Alert.alert(t('common.error'), t('payment.failed_fetch_outtrade'));
|
|
|
}
|
|
|
} catch (error) {
|
|
|
- Alert.alert('錯誤', '一次性付款失敗,請稍後再試');
|
|
|
+ Alert.alert(t('common.error'), t('payment.one_time_payment_failed'));
|
|
|
}
|
|
|
};
|
|
|
|
|
|
@@ -527,7 +531,7 @@ const TotalPayment = () => {
|
|
|
<View className="flex-1 justify-center items-center bg-black/50">
|
|
|
<View className="bg-white p-6 rounded-lg items-center">
|
|
|
<ActivityIndicator size="large" color="#02677D" />
|
|
|
- <Text className="mt-3">請稍候...</Text>
|
|
|
+ <Text className="mt-3">{t('common.please_wait')}</Text>
|
|
|
</View>
|
|
|
</View>
|
|
|
</Modal>
|
|
|
@@ -547,29 +551,29 @@ const TotalPayment = () => {
|
|
|
</Pressable>
|
|
|
</View>
|
|
|
<View style={{ marginTop: 25 }}>
|
|
|
- <Text style={{ fontSize: 45, paddingBottom: 12 }}>付款概要</Text>
|
|
|
+ <Text style={{ fontSize: 45, paddingBottom: 12 }}>{t('payment.summary_title')}</Text>
|
|
|
|
|
|
<View>
|
|
|
<View className="flex-row justify-between">
|
|
|
- <Text className="text-base lg:text-lg ">充電費用</Text>
|
|
|
+ <Text className="text-base lg:text-lg ">{t('payment.charging_fee')}</Text>
|
|
|
<Text className="text-base lg:text-lg">
|
|
|
- HK $ {currentPriceTotalPayment ? currentPriceTotalPayment * total_power : 'Loading...'}
|
|
|
+ HK $ {currentPriceTotalPayment ? currentPriceTotalPayment * total_power : t('common.loading')}
|
|
|
</Text>
|
|
|
</View>
|
|
|
|
|
|
<Text style={styles.grayColor} className="text-sm lg:text-base mt-4">
|
|
|
- 結算電度數 : {total_power == 80 ? '充滿停機' : `${total_power} KWh`}
|
|
|
+ {t('payment.settled_kwh')}: {total_power == 80 ? t('payment.full_charge') : `${total_power} KWh`}
|
|
|
</Text>
|
|
|
<Text style={styles.grayColor} className="text-sm lg:text-base mt-4">
|
|
|
- 每度電價錢 : $ {currentPriceTotalPayment ? currentPriceTotalPayment : 'Loading...'}
|
|
|
+ {t('payment.price_per_kwh')}: $ {currentPriceTotalPayment ? currentPriceTotalPayment : t('common.loading')}
|
|
|
</Text>
|
|
|
<Text style={styles.grayColor} className="text-sm lg:text-base mt-4">
|
|
|
- 注: 跨時段充電將按不同時段的單價分別計费,實際充電量可能浮動
|
|
|
+ {t('payment.note')}
|
|
|
</Text>
|
|
|
<View className="h-0.5 my-3 bg-[#f4f4f4]" />
|
|
|
|
|
|
{processed_coupon_store && processed_coupon_store.length > 0 && (
|
|
|
- <Text className="text-base lg:text-lg mb-4 lg:mb-6">優惠劵</Text>
|
|
|
+ <Text className="text-base lg:text-lg mb-4 lg:mb-6">{t('payment.coupon')}</Text>
|
|
|
)}
|
|
|
{processed_coupon_store &&
|
|
|
processed_coupon_store?.map((couponObj: any) => (
|
|
|
@@ -584,12 +588,12 @@ const TotalPayment = () => {
|
|
|
/>
|
|
|
<View key={couponObj.coupon_detail.id} className="flex flex-col ml-2 lg:ml-4 ">
|
|
|
<Text className="text-base lg:text-xl text-[#888888] ">
|
|
|
- ${couponObj.coupon_detail.amount} 現金劵
|
|
|
+ ${couponObj.coupon_detail.amount} {t('wallet.coupon.cash_voucher')}
|
|
|
</Text>
|
|
|
<Text className=" text-sm lg:text-base my-1 lg:mt-2 lg:mb-4 text-[#888888]">
|
|
|
- 有效期{' '}
|
|
|
+ {t('wallet.coupon.valid_until')}{' '}
|
|
|
<Text className="font-[500] text-[#02677D]">
|
|
|
- 至 {couponObj.coupon_detail.expire_date.slice(0, 10)}
|
|
|
+ {t('common.to_date', { date: couponObj.coupon_detail.expire_date.slice(0, 10) })}
|
|
|
</Text>
|
|
|
</Text>
|
|
|
</View>
|
|
|
@@ -611,8 +615,8 @@ const TotalPayment = () => {
|
|
|
<View className="h-0.5 my-3 bg-[#f4f4f4]" />
|
|
|
)}
|
|
|
<View className="flex-row justify-between">
|
|
|
- <Text className="text-xl">總計</Text>
|
|
|
- <Text className="text-3xl">HK$ {totalPrice !== null ? totalPrice : 'Loading...'}</Text>
|
|
|
+ <Text className="text-xl">{t('payment.total')}</Text>
|
|
|
+ <Text className="text-3xl">HK$ {totalPrice !== null ? totalPrice : t('common.loading')}</Text>
|
|
|
</View>
|
|
|
<View className="mt-4 ">
|
|
|
<NormalButton
|
|
|
@@ -624,7 +628,7 @@ const TotalPayment = () => {
|
|
|
fontWeight: '800'
|
|
|
}}
|
|
|
>
|
|
|
- {loading ? '處理中...' : '付款確認'}
|
|
|
+ {loading ? t('common.processing') : t('payment.confirm_payment')}
|
|
|
</Text>
|
|
|
}
|
|
|
onPress={handlePay}
|
|
|
@@ -647,4 +651,4 @@ const styles = StyleSheet.create({
|
|
|
greenColor: {
|
|
|
color: '#02677D'
|
|
|
}
|
|
|
-});
|
|
|
+});
|