|
|
import React, { useEffect, useState } from "react"; |
|
|
import { |
|
|
View, |
|
|
Text, |
|
|
StyleSheet, |
|
|
TouchableOpacity, |
|
|
ActivityIndicator, |
|
|
ScrollView, |
|
|
Image, |
|
|
Alert, |
|
|
Linking, |
|
|
SafeAreaView, |
|
|
StatusBar, |
|
|
Platform, |
|
|
Modal, |
|
|
} from "react-native"; |
|
|
import { useTranslation } from "react-i18next"; |
|
|
import BackIcon from "../../components/BackIcon"; |
|
|
import MassageIcon from "../../components/MassageIcon"; |
|
|
import fontSize from "../../utils/fontsizeUtils"; |
|
|
import { useNavigation } from "@react-navigation/native"; |
|
|
import { NativeStackNavigationProp } from "@react-navigation/native-stack"; |
|
|
import { useRoute, RouteProp } from "@react-navigation/native"; |
|
|
import { ordersApi, OrderDetailsType } from "../../services/api/orders"; |
|
|
import { payApi } from "../../services/api/payApi"; |
|
|
import useUserStore from "../../store/user"; |
|
|
import OrderIcon from "../../components/OrderIcon"; |
|
|
import InfoIcon from "../../components/InfoIcon"; |
|
|
import Progress from "./Progress"; |
|
|
import AddressIcon from "../../components/AddressIcon"; |
|
|
import EditIcon from "../../components/ColorfulEditIcon"; |
|
|
import BrightnessIcon from "../../components/BrightnessIcon"; |
|
|
import PhoneIcon from "../../components/PhoneIcon"; |
|
|
import ShoppingBagIcon from "../../components/ShoppingBagIcon"; |
|
|
import PowerIcon from "../../components/PowerIcon"; |
|
|
import CardIcon from "../../components/ShoppingCartIcon"; |
|
|
import WhatsAppIcon from "../../components/WatchAppIcon"; |
|
|
import { useOrderListStore } from "../../store/orderList"; |
|
|
|
|
|
export const OrderDetails = () => { |
|
|
const navigation = useNavigation<NativeStackNavigationProp<any>>(); |
|
|
const { t } = useTranslation(); |
|
|
const route = useRoute< |
|
|
RouteProp< |
|
|
{ |
|
|
OrderDetails: { |
|
|
orderId: string; |
|
|
}; |
|
|
}, |
|
|
"OrderDetails" |
|
|
> |
|
|
>(); |
|
|
const [orderDetails, setOrderDetails] = useState<OrderDetailsType>(); |
|
|
const [isLoading, setIsLoading] = useState(true); |
|
|
const { deleteOrder, changeOrder,updateOrderShippingInfo } = useOrderListStore(); |
|
|
const [showPaymentModal, setShowPaymentModal] = useState(false); |
|
|
const [selectedPayment, setSelectedPayment] = useState<string | null>(null); |
|
|
const [currentTab, setCurrentTab] = useState("online"); |
|
|
const [tabs, setTabs] = useState([ |
|
|
{ |
|
|
id: "online", |
|
|
label: t("order.payment.online"), |
|
|
options: [ |
|
|
{ id: "Brainnel Pay", label: "Brainnel Pay", icon: "💳" }, |
|
|
{ id: "Wave", label: "Wave", icon: "💸" }, |
|
|
{ id: "Paypal", label: "Paypal", icon: "🅿️" }, |
|
|
{ id: "Bank Card", label: t("order.payment.bank_card"), icon: "💳" }, |
|
|
], |
|
|
}, |
|
|
{ |
|
|
id: "offline", |
|
|
label: t("order.payment.offline"), |
|
|
options: [], |
|
|
}, |
|
|
]); |
|
|
const [selectedCurrency, setSelectedCurrency] = useState("USD"); |
|
|
const [convertedAmount, setConvertedAmount] = useState<{ |
|
|
converted_amount: number; |
|
|
item_key: string; |
|
|
original_amount: number; |
|
|
}[]>([]); |
|
|
const [isConverting, setIsConverting] = useState(false); |
|
|
const { user } = useUserStore(); |
|
|
const [isPaymentLoading, setIsPaymentLoading] = useState(false); |
|
|
|
|
|
const getOrderDetails = async () => { |
|
|
try { |
|
|
setIsLoading(true); |
|
|
const response = await ordersApi.getOrderDetails(route.params.orderId); |
|
|
setOrderDetails(response); |
|
|
} catch (error) { |
|
|
console.error("Error fetching order details:", error); |
|
|
} finally { |
|
|
setIsLoading(false); |
|
|
} |
|
|
}; |
|
|
|
|
|
useEffect(() => { |
|
|
getOrderDetails(); |
|
|
}, []); |
|
|
//拨打电话 |
|
|
const callPhone = async (phoneNumber: string) => { |
|
|
const url = `tel:${phoneNumber}`; |
|
|
|
|
|
try { |
|
|
await Linking.openURL(url); // 直接尝试打开拨号界面 |
|
|
} catch (error) { |
|
|
Alert.alert(t("error"), t("order.error.phone_open")); |
|
|
console.error("拨号失败:", error); |
|
|
} |
|
|
}; |
|
|
|
|
|
const onSelectPayment = (paymentId: string) => { |
|
|
if (paymentId === "Paypal") { |
|
|
setIsConverting(true); |
|
|
const data = { |
|
|
from_currency: orderDetails?.currency || "", |
|
|
to_currency: selectedCurrency, |
|
|
amounts: { |
|
|
total_amount: orderDetails?.total_amount || 0, |
|
|
domestic_shipping_fee: orderDetails?.domestic_shipping_fee || 0, |
|
|
shipping_fee: orderDetails?.shipping_fee || 0, |
|
|
}, |
|
|
}; |
|
|
payApi |
|
|
.convertCurrency(data) |
|
|
.then((res) => { |
|
|
setConvertedAmount(res.converted_amounts_list); |
|
|
setIsConverting(false); |
|
|
}) |
|
|
.catch((error) => { |
|
|
console.error("Currency conversion failed:", error); |
|
|
setIsConverting(false); |
|
|
}); |
|
|
} |
|
|
setSelectedPayment(paymentId); |
|
|
}; |
|
|
|
|
|
const onSelectCurrency = (currency: string) => { |
|
|
setSelectedCurrency(currency); |
|
|
setIsConverting(true); |
|
|
const data = { |
|
|
from_currency: orderDetails?.currency || "", |
|
|
to_currency: currency, |
|
|
amounts: { |
|
|
total_amount: orderDetails?.total_amount || 0, |
|
|
domestic_shipping_fee: orderDetails?.domestic_shipping_fee || 0, |
|
|
shipping_fee: orderDetails?.shipping_fee || 0, |
|
|
}, |
|
|
}; |
|
|
payApi |
|
|
.convertCurrency(data) |
|
|
.then((res) => { |
|
|
setConvertedAmount(res.converted_amounts_list); |
|
|
setIsConverting(false); |
|
|
}) |
|
|
.catch((error) => { |
|
|
console.error("Currency conversion failed:", error); |
|
|
setIsConverting(false); |
|
|
}); |
|
|
}; |
|
|
|
|
|
const handlePaymentConfirm = async () => { |
|
|
if (!selectedPayment || !orderDetails?.order_id) return; |
|
|
setIsPaymentLoading(true); |
|
|
|
|
|
const paymentData = { |
|
|
order_id: orderDetails.order_id, |
|
|
payment_method: selectedPayment, |
|
|
currency: selectedPayment === "Paypal" ? selectedCurrency : user.currency, |
|
|
total_amount: selectedPayment === "Paypal" |
|
|
? convertedAmount.reduce((acc, item) => acc + item.converted_amount, 0) |
|
|
: orderDetails?.total_amount || 0, |
|
|
actual_amount: selectedPayment === "Paypal" |
|
|
? convertedAmount.reduce((acc, item) => acc + item.converted_amount, 0) |
|
|
: orderDetails?.actual_amount || 0, |
|
|
shipping_fee: selectedPayment === "Paypal" |
|
|
? convertedAmount.find(item => item.item_key === "shipping_fee")?.converted_amount || 0 |
|
|
: orderDetails?.shipping_fee || 0, |
|
|
domestic_shipping_fee: selectedPayment === "Paypal" |
|
|
? convertedAmount.find(item => item.item_key === "domestic_shipping_fee")?.converted_amount || 0 |
|
|
: orderDetails?.domestic_shipping_fee || 0 |
|
|
}; |
|
|
try { |
|
|
await ordersApi.updateOrderPaymentMethod(paymentData) |
|
|
|
|
|
const payData = { |
|
|
order_id: orderDetails.order_id, |
|
|
method: selectedPayment, |
|
|
currency: selectedPayment === "Paypal" ? selectedCurrency : user.currency, |
|
|
amount: selectedPayment === "Paypal" |
|
|
? convertedAmount.reduce((acc, item) => acc + item.converted_amount, 0) |
|
|
: orderDetails?.total_amount || 0 |
|
|
}; |
|
|
payApi |
|
|
.getPayInfo(payData) |
|
|
.then((res) => { |
|
|
if (res.success) { |
|
|
setIsPaymentLoading(false); |
|
|
setShowPaymentModal(false); |
|
|
navigation.navigate("Pay", { |
|
|
payUrl: res.payment_url, |
|
|
}); |
|
|
} |
|
|
}) |
|
|
.catch((err) => { |
|
|
Alert.alert(t("error"), t("order.error.payment_update")); |
|
|
setIsPaymentLoading(false); |
|
|
}) |
|
|
.finally(() => { |
|
|
setIsPaymentLoading(false); |
|
|
}); |
|
|
|
|
|
} catch (error) { |
|
|
Alert.alert(t("error"), t("order.error.payment_update")); |
|
|
setIsPaymentLoading(false); |
|
|
} |
|
|
}; |
|
|
|
|
|
return ( |
|
|
<SafeAreaView style={styles.safeArea}> |
|
|
<StatusBar barStyle="dark-content" backgroundColor="#fff" /> |
|
|
<View style={styles.safeAreaContent}> |
|
|
<View style={styles.header}> |
|
|
<TouchableOpacity onPress={() => navigation.goBack()}> |
|
|
<BackIcon /> |
|
|
</TouchableOpacity> |
|
|
<Text style={styles.title}>{t("order.details")}</Text> |
|
|
<MassageIcon size={22} /> |
|
|
</View> |
|
|
{isLoading ? ( |
|
|
<View style={styles.loadingContainer}> |
|
|
<ActivityIndicator size="large" color="#f77f3a" /> |
|
|
</View> |
|
|
) : orderDetails ? ( |
|
|
<View style={styles.container}> |
|
|
<ScrollView |
|
|
showsVerticalScrollIndicator={false} |
|
|
style={{ flex: 1 }} |
|
|
contentContainerStyle={{ paddingBottom: 70 }} |
|
|
> |
|
|
<View style={styles.orderStatus}> |
|
|
<View style={styles.orderStatusContent}> |
|
|
<View style={styles.orderStatusTitle}> |
|
|
<OrderIcon size={20} color="#3D3D3D" /> |
|
|
<Text style={styles.orderStatusTitleText}>{t("order.status")}</Text> |
|
|
</View> |
|
|
|
|
|
<View style={styles.orderStatusContentPreview}> |
|
|
<Progress |
|
|
statuses={route.params.orderId} |
|
|
labels={[ |
|
|
t("order.status.waiting_payment"), |
|
|
t("order.status.waiting_shipment"), |
|
|
t("order.status.in_transit"), |
|
|
t("order.status.waiting_receipt"), |
|
|
t("order.status.completed") |
|
|
]} |
|
|
/> |
|
|
</View> |
|
|
</View> |
|
|
</View> |
|
|
{/* 订单信息 */} |
|
|
<View style={styles.orderStatus}> |
|
|
<View style={styles.orderStatusContent}> |
|
|
<View style={styles.orderStatusTitle}> |
|
|
<InfoIcon size={20} color="#3D3D3D" /> |
|
|
<Text style={styles.orderStatusTitleText}>{t("order.information")}</Text> |
|
|
</View> |
|
|
<View style={styles.orderStatusContentPreview}> |
|
|
<View style={styles.orderId}> |
|
|
<Text style={styles.orderIdText}>{t("order.id")}</Text> |
|
|
<Text style={styles.orderIdText1}> |
|
|
{orderDetails.order_id} |
|
|
</Text> |
|
|
</View> |
|
|
<View style={styles.orderId}> |
|
|
<Text style={styles.orderIdText}>{t("order.create_time")}</Text> |
|
|
<Text style={styles.orderIdText1}> |
|
|
{orderDetails.create_time} |
|
|
</Text> |
|
|
</View> |
|
|
<View style={styles.orderId}> |
|
|
<Text style={styles.orderIdText}>{t("order.shipping_type")}</Text> |
|
|
<Text style={styles.orderIdText1}> |
|
|
{orderDetails.shipping_type === 0 ? t("order.shipping.sea") : t("order.shipping.air")} |
|
|
</Text> |
|
|
</View> |
|
|
</View> |
|
|
</View> |
|
|
</View> |
|
|
{/* 配送信息 */} |
|
|
<View style={styles.orderStatus}> |
|
|
<View style={styles.orderStatusContent}> |
|
|
<View style={styles.orderStatusTitle}> |
|
|
<AddressIcon size={22} color={"#3D3D3D"} /> |
|
|
<Text style={styles.orderStatusTitleText}>{t("order.delivery_info")}</Text> |
|
|
</View> |
|
|
<View style={styles.orderStatusContentPreview}> |
|
|
<View style={styles.orderStatusContentPreviewInformation}> |
|
|
<View style={styles.warehouse}> |
|
|
<View style={styles.recipientTitle}> |
|
|
<Text |
|
|
style={ |
|
|
styles.orderStatusContentPreviewInformationText |
|
|
} |
|
|
> |
|
|
{t("order.warehouse")} |
|
|
</Text> |
|
|
</View> |
|
|
<View style={styles.recipientTitle}> |
|
|
<EditIcon size={22} /> |
|
|
</View> |
|
|
<View style={styles.recipientTitle}> |
|
|
<Text>{orderDetails.receiver_address}</Text> |
|
|
</View> |
|
|
<View style={styles.recipientTitle}> |
|
|
<View style={styles.warehousePhone}> |
|
|
<View style={styles.warehousePhoneTextContainer}> |
|
|
<BrightnessIcon size={16} color="#3D3D3D" /> |
|
|
</View> |
|
|
<View style={styles.warehousePhoneTextContainer}> |
|
|
<Text style={styles.warehousePhoneText}> |
|
|
{t("order.contact_after_payment")} |
|
|
</Text> |
|
|
</View> |
|
|
</View> |
|
|
</View> |
|
|
</View> |
|
|
|
|
|
<View style={styles.recipient}> |
|
|
<View style={styles.recipientTitle}> |
|
|
<Text |
|
|
style={ |
|
|
styles.orderStatusContentPreviewInformationText |
|
|
} |
|
|
> |
|
|
{t("order.recipient")} |
|
|
</Text> |
|
|
</View> |
|
|
<View style={styles.recipientTitle}> |
|
|
<EditIcon size={22} /> |
|
|
</View> |
|
|
{/* 姓名 */} |
|
|
<View style={styles.recipientTitle}> |
|
|
<Text style={styles.recipientName}> |
|
|
{orderDetails.receiver_name} |
|
|
</Text> |
|
|
</View> |
|
|
|
|
|
{/* 电话 */} |
|
|
<View style={styles.recipientTitle}> |
|
|
<View style={styles.recipientPhoneContainer}> |
|
|
<PhoneIcon size={16} color="#3D3D3D" /> |
|
|
<Text style={styles.recipientPhone}> |
|
|
{orderDetails.receiver_phone} |
|
|
</Text> |
|
|
</View> |
|
|
</View> |
|
|
{/* watchApp */} |
|
|
<View style={styles.recipientTitle}> |
|
|
<View style={styles.recipientPhoneContainer}> |
|
|
<WhatsAppIcon size={16} /> |
|
|
<Text style={styles.recipientPhone}>WhatsApp:</Text> |
|
|
<Text style={styles.recipientPhone}> |
|
|
{orderDetails.receiver_phone} |
|
|
</Text> |
|
|
</View> |
|
|
</View> |
|
|
</View> |
|
|
</View> |
|
|
</View> |
|
|
</View> |
|
|
</View> |
|
|
{/* 商品信息 */} |
|
|
<View style={styles.orderStatus}> |
|
|
<View style={styles.orderStatusContent}> |
|
|
<View style={styles.orderStatusTitle}> |
|
|
<ShoppingBagIcon size={16} color="#3D3D3D" /> |
|
|
<Text style={styles.orderStatusTitleText}> |
|
|
{t("order.product_info")} ({orderDetails.items.length}) |
|
|
</Text> |
|
|
</View> |
|
|
<View style={styles.orderStatusContentPreview}> |
|
|
{orderDetails.items.map((item, index) => ( |
|
|
<View style={styles.productItem} key={index}> |
|
|
<View style={styles.productItemImage}> |
|
|
<Image |
|
|
source={{ uri: item.sku_image }} |
|
|
style={{ width: "100%", height: "100%" }} |
|
|
/> |
|
|
</View> |
|
|
<View style={styles.productItemInfo}> |
|
|
<View style={styles.productItemInfoName}> |
|
|
<Text style={styles.productItemInfoNameText}> |
|
|
{item.product_name} |
|
|
</Text> |
|
|
</View> |
|
|
<View style={styles.productItemInfoSku}> |
|
|
{item.sku_attributes.map((sku, index) => ( |
|
|
<Text |
|
|
key={index} |
|
|
style={styles.productItemInfoSkuText} |
|
|
> |
|
|
{sku.attribute_name}:{sku.attribute_value} |
|
|
</Text> |
|
|
))} |
|
|
{/* <text>{item.product_name}</text> */} |
|
|
</View> |
|
|
<View style={styles.productItemInfoPrice}> |
|
|
<Text |
|
|
style={{ |
|
|
color: "#f77f3a", |
|
|
fontSize: fontSize(16), |
|
|
fontWeight: "600", |
|
|
}} |
|
|
> |
|
|
{item.total_price} |
|
|
</Text> |
|
|
</View> |
|
|
</View> |
|
|
<View style={styles.productItemNum}> |
|
|
<Text style={styles.productItemNumText}> |
|
|
x{item.quantity} |
|
|
</Text> |
|
|
</View> |
|
|
</View> |
|
|
))} |
|
|
</View> |
|
|
<View style={styles.dottedLine}></View> |
|
|
|
|
|
<View style={styles.orderStatusContentPreview}> |
|
|
<TouchableOpacity style={styles.addCard}> |
|
|
<View style={styles.addCardBox}> |
|
|
<CardIcon size={16} color="#0098ef" /> |
|
|
<Text style={styles.addCardText}>{t("order.add_to_cart")}</Text> |
|
|
</View> |
|
|
</TouchableOpacity> |
|
|
</View> |
|
|
</View> |
|
|
</View> |
|
|
{/* 价格信息 */} |
|
|
<View style={styles.orderStatus}> |
|
|
<View style={styles.orderStatusContent}> |
|
|
<View style={styles.orderStatusTitle}> |
|
|
<PowerIcon size={20} color="#3D3D3D" /> |
|
|
<Text style={styles.orderStatusTitleText}>{t("order.price_details")}</Text> |
|
|
</View> |
|
|
<View style={styles.orderStatusContentPreview}> |
|
|
<View style={styles.orderId}> |
|
|
<Text style={styles.orderIdText}>{t("order.subtotal")}</Text> |
|
|
<Text style={styles.orderIdText1}> |
|
|
{orderDetails.total_amount} |
|
|
</Text> |
|
|
</View> |
|
|
<View style={styles.orderId}> |
|
|
<Text style={styles.orderIdText}> |
|
|
{t("order.platform_shipping")} |
|
|
</Text> |
|
|
<Text style={styles.orderIdText1}> |
|
|
{orderDetails.domestic_shipping_fee} |
|
|
</Text> |
|
|
</View> |
|
|
<View style={styles.orderId}> |
|
|
<Text style={styles.orderIdText}> |
|
|
{t("order.international_shipping")} |
|
|
</Text> |
|
|
<Text style={styles.orderIdText1}> |
|
|
{orderDetails.shipping_fee} |
|
|
</Text> |
|
|
</View> |
|
|
<View style={styles.dottedLine}></View> |
|
|
<View style={styles.orderId}> |
|
|
<Text style={styles.TotalText}>{t("order.total")}</Text> |
|
|
<Text style={styles.TotalPrice}> |
|
|
{orderDetails.total_amount} |
|
|
</Text> |
|
|
</View> |
|
|
<View> |
|
|
<Text style={styles.orderRemakeText}> |
|
|
+ ${orderDetails.shipping_fee} {t("order.estimated_shipping")} |
|
|
(COD) |
|
|
</Text> |
|
|
</View> |
|
|
</View> |
|
|
</View> |
|
|
</View> |
|
|
</ScrollView> |
|
|
{/* 代付款 */} |
|
|
{orderDetails.order_status === 0 && ( |
|
|
<View style={styles.bottomButtons}> |
|
|
<TouchableOpacity |
|
|
style={styles.bottomButton1} |
|
|
onPress={() => { |
|
|
deleteOrder(route.params.orderId); |
|
|
}} |
|
|
> |
|
|
<Text style={styles.bottomButtonText1}>{t("order.cancel")}</Text> |
|
|
</TouchableOpacity> |
|
|
<TouchableOpacity |
|
|
style={styles.bottomButton} |
|
|
onPress={() => { |
|
|
setShowPaymentModal(true); |
|
|
}} |
|
|
> |
|
|
<Text style={styles.bottomButtonText}>{t("order.pay")}</Text> |
|
|
</TouchableOpacity> |
|
|
</View> |
|
|
)} |
|
|
{/* 待发货 */} |
|
|
{orderDetails.order_status === 1 && ( |
|
|
<View style={styles.bottomButtons}> |
|
|
<TouchableOpacity |
|
|
style={styles.bottomButton1} |
|
|
onPress={() => { |
|
|
callPhone("15903995548"); |
|
|
}} |
|
|
> |
|
|
<Text style={styles.bottomButtonText1}>{t("order.contact_shipping")}</Text> |
|
|
</TouchableOpacity> |
|
|
<TouchableOpacity |
|
|
style={styles.bottomButton} |
|
|
onPress={() => { |
|
|
changeOrder(route.params.orderId, 2); |
|
|
navigation.goBack(); |
|
|
}} |
|
|
> |
|
|
<Text style={styles.bottomButtonText}>{t("order.cancel")}</Text> |
|
|
</TouchableOpacity> |
|
|
</View> |
|
|
)} |
|
|
{/* 代收货 */} |
|
|
{orderDetails.order_status === 2 && ( |
|
|
<View style={styles.bottomButtons}> |
|
|
<TouchableOpacity style={styles.bottomButton1} onPress={() => {}}> |
|
|
<Text style={styles.bottomButtonText1}>{t("order.check_logistics")}</Text> |
|
|
</TouchableOpacity> |
|
|
<TouchableOpacity |
|
|
style={styles.bottomButton} |
|
|
onPress={() => { |
|
|
updateOrderShippingInfo(route.params.orderId,{ |
|
|
shipping_status: 0, |
|
|
shipping_info: { |
|
|
shipping_company: "string", |
|
|
shipping_no: "string", |
|
|
shipping_info: {} |
|
|
} |
|
|
}); |
|
|
navigation.goBack(); |
|
|
}} |
|
|
> |
|
|
<Text style={styles.bottomButtonText}>{t("order.confirm_receipt")}</Text> |
|
|
</TouchableOpacity> |
|
|
</View> |
|
|
)} |
|
|
{/* 已完成 */} |
|
|
{orderDetails.order_status === 3 && ( |
|
|
<View style={styles.bottomButtons}> |
|
|
<TouchableOpacity |
|
|
style={styles.bottomButton1} |
|
|
onPress={() => { |
|
|
deleteOrder(route.params.orderId); |
|
|
navigation.goBack(); |
|
|
}} |
|
|
> |
|
|
<Text style={styles.bottomButtonText1}>{t("order.cancel")}</Text> |
|
|
</TouchableOpacity> |
|
|
<TouchableOpacity style={styles.bottomButton}> |
|
|
<Text style={styles.bottomButtonText}>{t("order.pay_now")}</Text> |
|
|
</TouchableOpacity> |
|
|
</View> |
|
|
)} |
|
|
{/* 已取消 */} |
|
|
{orderDetails.order_status === 4 && ( |
|
|
<View style={styles.bottomButtons}> |
|
|
<TouchableOpacity style={styles.bottomButton1} onPress={() => {}}> |
|
|
<Text style={styles.bottomButtonText1}>{t("order.add_to_cart")}</Text> |
|
|
</TouchableOpacity> |
|
|
<TouchableOpacity style={styles.bottomButton}> |
|
|
<Text style={styles.bottomButtonText}>{t("order.reorder")}</Text> |
|
|
</TouchableOpacity> |
|
|
</View> |
|
|
)} |
|
|
</View> |
|
|
) : ( |
|
|
<Text>{t("order.unable_to_load")}</Text> |
|
|
)} |
|
|
</View> |
|
|
|
|
|
<Modal |
|
|
visible={showPaymentModal} |
|
|
transparent={true} |
|
|
animationType="slide" |
|
|
onRequestClose={() => setShowPaymentModal(false)} |
|
|
> |
|
|
<View style={styles.modalOverlay}> |
|
|
<View style={styles.modalContent}> |
|
|
<View style={styles.modalHeader}> |
|
|
<Text style={styles.modalTitle}>{t("order.select_payment")}</Text> |
|
|
<TouchableOpacity onPress={() => setShowPaymentModal(false)}> |
|
|
<Text style={styles.closeButton}>×</Text> |
|
|
</TouchableOpacity> |
|
|
</View> |
|
|
|
|
|
<View style={styles.tabs}> |
|
|
{tabs.map((tab) => ( |
|
|
<TouchableOpacity |
|
|
key={tab.id} |
|
|
style={[styles.tab, currentTab === tab.id && styles.tabActive]} |
|
|
onPress={() => setCurrentTab(tab.id)} |
|
|
> |
|
|
<Text style={[styles.tabText, currentTab === tab.id && styles.tabTextActive]}> |
|
|
{tab.label} |
|
|
</Text> |
|
|
</TouchableOpacity> |
|
|
))} |
|
|
</View> |
|
|
|
|
|
<ScrollView style={styles.paymentOptions}> |
|
|
{tabs |
|
|
.find((tab) => tab.id === currentTab) |
|
|
?.options.map((option) => ( |
|
|
<View key={option.id}> |
|
|
<TouchableOpacity |
|
|
style={[ |
|
|
styles.paymentOption, |
|
|
selectedPayment === option.id && styles.paymentSelected, |
|
|
]} |
|
|
onPress={() => onSelectPayment(option.id)} |
|
|
> |
|
|
<View style={styles.paymentContent}> |
|
|
<View style={styles.defaultPaymentContainer}> |
|
|
<Text style={styles.paymentIcon}>{option.icon}</Text> |
|
|
<Text style={styles.paymentLabel}>{option.label}</Text> |
|
|
</View> |
|
|
</View> |
|
|
<View style={styles.radioButton}> |
|
|
<View |
|
|
style={[ |
|
|
styles.radioInner, |
|
|
selectedPayment === option.id && styles.radioInnerSelected, |
|
|
]} |
|
|
/> |
|
|
</View> |
|
|
</TouchableOpacity> |
|
|
|
|
|
{/* PayPal Currency Selection */} |
|
|
{selectedPayment === "Paypal" && option.id === "Paypal" && ( |
|
|
<View style={styles.currencySelectorContainer}> |
|
|
<Text style={styles.currencySelectorTitle}>{t("order.select_currency")}</Text> |
|
|
<View style={styles.currencyOptions}> |
|
|
<TouchableOpacity |
|
|
style={[ |
|
|
styles.currencyOption, |
|
|
selectedCurrency === "USD" && styles.selectedCurrencyOption, |
|
|
]} |
|
|
onPress={() => onSelectCurrency("USD")} |
|
|
> |
|
|
<Text style={styles.currencyText}>USD</Text> |
|
|
</TouchableOpacity> |
|
|
<TouchableOpacity |
|
|
style={[ |
|
|
styles.currencyOption, |
|
|
selectedCurrency === "EUR" && styles.selectedCurrencyOption, |
|
|
]} |
|
|
onPress={() => onSelectCurrency("EUR")} |
|
|
> |
|
|
<Text style={styles.currencyText}>EUR</Text> |
|
|
</TouchableOpacity> |
|
|
</View> |
|
|
|
|
|
<View style={styles.totalContainer}> |
|
|
{!isConverting && ( |
|
|
<Text style={styles.totalText}> |
|
|
{selectedCurrency === "USD" ? "$" : "€"} |
|
|
{convertedAmount |
|
|
.reduce((acc, item) => acc + item.converted_amount, 0) |
|
|
.toFixed(2)} |
|
|
</Text> |
|
|
)} |
|
|
{isConverting && ( |
|
|
<ActivityIndicator |
|
|
size="small" |
|
|
color="#ff6000" |
|
|
style={styles.loadingIndicator} |
|
|
/> |
|
|
)} |
|
|
</View> |
|
|
</View> |
|
|
)} |
|
|
</View> |
|
|
))} |
|
|
</ScrollView> |
|
|
|
|
|
<View style={styles.modalFooter}> |
|
|
<TouchableOpacity |
|
|
style={styles.cancelButton} |
|
|
onPress={() => setShowPaymentModal(false)} |
|
|
> |
|
|
<Text style={styles.cancelButtonText}>{t("cancel")}</Text> |
|
|
</TouchableOpacity> |
|
|
<TouchableOpacity |
|
|
style={[styles.confirmButton, (!selectedPayment || isPaymentLoading) && styles.disabledButton]} |
|
|
onPress={handlePaymentConfirm} |
|
|
disabled={!selectedPayment || isPaymentLoading} |
|
|
> |
|
|
{isPaymentLoading ? ( |
|
|
<ActivityIndicator size="small" color="#fff" /> |
|
|
) : ( |
|
|
<Text style={styles.confirmButtonText}>{t("order.confirm_payment")}</Text> |
|
|
)} |
|
|
</TouchableOpacity> |
|
|
</View> |
|
|
</View> |
|
|
</View> |
|
|
</Modal> |
|
|
</SafeAreaView> |
|
|
); |
|
|
}; |
|
|
|
|
|
const styles = StyleSheet.create({ |
|
|
safeArea: { |
|
|
flex: 1, |
|
|
backgroundColor: '#fff', |
|
|
}, |
|
|
safeAreaContent: { |
|
|
flex: 1, |
|
|
paddingTop: 0, |
|
|
}, |
|
|
container: { |
|
|
flex: 1, |
|
|
backgroundColor: "#f8f9fa", |
|
|
}, |
|
|
header: { |
|
|
flexDirection: "row", |
|
|
justifyContent: "space-between", |
|
|
alignItems: "center", |
|
|
padding: 16, |
|
|
backgroundColor: "#fff", |
|
|
shadowColor: "#000", |
|
|
shadowOffset: { |
|
|
width: 0, |
|
|
height: 2, |
|
|
}, |
|
|
shadowOpacity: 0.1, |
|
|
shadowRadius: 3, |
|
|
elevation: 3, |
|
|
}, |
|
|
title: { |
|
|
fontSize: fontSize(16), |
|
|
fontWeight: "600", |
|
|
}, |
|
|
orderStatus: { |
|
|
paddingInline: 16, |
|
|
marginTop: 10, |
|
|
}, |
|
|
orderStatusContent: { |
|
|
backgroundColor: "#fff", |
|
|
borderRadius: 16, |
|
|
}, |
|
|
orderStatusTitle: { |
|
|
flexDirection: "row", |
|
|
alignItems: "center", |
|
|
borderBottomWidth: 1, |
|
|
borderColor: "#f5f5f5", |
|
|
padding: 10, |
|
|
}, |
|
|
orderStatusTitleText: { |
|
|
fontSize: fontSize(16), |
|
|
fontWeight: "600", |
|
|
marginLeft: 10, |
|
|
}, |
|
|
orderStatusContentPreview: { |
|
|
padding: 10, |
|
|
justifyContent: "center", |
|
|
}, |
|
|
productItem: { |
|
|
flexDirection: "row", |
|
|
width: "100%", |
|
|
borderBottomWidth: 1, |
|
|
borderColor: "#f5f5f5", |
|
|
padding: 10, |
|
|
}, |
|
|
productItemImage: { |
|
|
width: "15%", |
|
|
height: 50, |
|
|
borderRadius: 10, |
|
|
}, |
|
|
productItemInfo: { |
|
|
width: "75%", |
|
|
justifyContent: "space-between", |
|
|
paddingLeft: 10, |
|
|
}, |
|
|
productItemNum: { |
|
|
width: "10%", |
|
|
alignItems: "center", |
|
|
justifyContent: "flex-end", |
|
|
}, |
|
|
productItemNumText: { |
|
|
fontSize: fontSize(16), |
|
|
color: "#999", |
|
|
}, |
|
|
productItemInfoName: { |
|
|
width: "100%", |
|
|
paddingVertical: 5, |
|
|
}, |
|
|
productItemInfoNameText: { |
|
|
fontSize: fontSize(13), |
|
|
fontWeight: "600", |
|
|
}, |
|
|
productItemInfoSkuText: { |
|
|
fontSize: fontSize(13), |
|
|
color: "#999", |
|
|
}, |
|
|
productItemInfoSku: { |
|
|
width: "100%", |
|
|
paddingVertical: 5, |
|
|
}, |
|
|
productItemInfoPrice: { |
|
|
width: "100%", |
|
|
paddingVertical: 5, |
|
|
}, |
|
|
orderStatusContentPreviewInformation: { |
|
|
flexDirection: "row", |
|
|
justifyContent: "space-between", |
|
|
width: "100%", |
|
|
}, |
|
|
|
|
|
loadingContainer: { |
|
|
flex: 1, |
|
|
justifyContent: "center", |
|
|
alignItems: "center", |
|
|
}, |
|
|
orderId: { |
|
|
flexDirection: "row", |
|
|
justifyContent: "space-between", |
|
|
paddingVertical: 10, |
|
|
width: "100%", |
|
|
}, |
|
|
orderIdText: { |
|
|
color: "#999", |
|
|
width: "50%", |
|
|
fontSize: fontSize(14), |
|
|
}, |
|
|
orderIdText1: { |
|
|
width: "50%", |
|
|
textAlign: "right", |
|
|
fontSize: fontSize(14), |
|
|
}, |
|
|
TotalText: { |
|
|
color: "#f77f3a", |
|
|
fontSize: fontSize(18), |
|
|
fontWeight: "600", |
|
|
width: "50%", |
|
|
}, |
|
|
TotalPrice: { |
|
|
color: "#f77f3a", |
|
|
fontSize: fontSize(18), |
|
|
fontWeight: "600", |
|
|
width: "50%", |
|
|
textAlign: "right", |
|
|
}, |
|
|
warehouse: { |
|
|
width: "50%", |
|
|
}, |
|
|
recipientTitle: { |
|
|
paddingVertical: 5, |
|
|
}, |
|
|
recipientPhoneContainer: { |
|
|
flexDirection: "row", |
|
|
alignItems: "center", |
|
|
}, |
|
|
recipient: { |
|
|
width: "50%", |
|
|
}, |
|
|
orderStatusContentPreviewInformationText: { |
|
|
fontSize: fontSize(16), |
|
|
fontWeight: "600", |
|
|
}, |
|
|
warehousePhone: { |
|
|
padding: 5, |
|
|
backgroundColor: "#f9f9f9", |
|
|
borderRadius: 10, |
|
|
width: "90%", |
|
|
flexDirection: "row", |
|
|
alignItems: "center", |
|
|
}, |
|
|
warehousePhoneText: { |
|
|
fontSize: fontSize(14), |
|
|
fontWeight: "400", |
|
|
color: "#3D3D3D", |
|
|
}, |
|
|
warehousePhoneTextContainer: { |
|
|
paddingRight: 5, |
|
|
}, |
|
|
recipientName: { |
|
|
fontSize: fontSize(16), |
|
|
fontWeight: "600", |
|
|
}, |
|
|
recipientPhone: { |
|
|
fontSize: fontSize(14), |
|
|
fontWeight: "400", |
|
|
color: "#3D3D3D", |
|
|
}, |
|
|
dottedLine: { |
|
|
width: "100%", |
|
|
borderBottomWidth: 2, |
|
|
borderColor: "#f5f5f5", |
|
|
borderStyle: "dashed", |
|
|
}, |
|
|
orderRemakeText: { |
|
|
fontSize: fontSize(14), |
|
|
fontWeight: "400", |
|
|
color: "#999", |
|
|
}, |
|
|
addCard: { |
|
|
width: "100%", |
|
|
justifyContent: "center", |
|
|
alignItems: "center", |
|
|
}, |
|
|
addCardBox: { |
|
|
padding: 10, |
|
|
borderWidth: 1, |
|
|
borderColor: "#0098ef", |
|
|
borderRadius: 10, |
|
|
backgroundColor: "#e2f2fd", |
|
|
opacity: 0.5, |
|
|
flexDirection: "row", |
|
|
alignItems: "center", |
|
|
}, |
|
|
addCardText: { |
|
|
fontSize: fontSize(16), |
|
|
fontWeight: "600", |
|
|
color: "#0098ef", |
|
|
marginLeft: 5, |
|
|
}, |
|
|
bottomButtons: { |
|
|
position: "absolute", |
|
|
bottom: 0, |
|
|
width: "100%", |
|
|
flexDirection: "row", |
|
|
justifyContent: "center", |
|
|
alignItems: "center", |
|
|
padding: 10, |
|
|
backgroundColor: "#fff", |
|
|
shadowColor: "#000", |
|
|
shadowOffset: { |
|
|
width: 0, |
|
|
height: -4, |
|
|
}, |
|
|
shadowOpacity: 0.1, |
|
|
shadowRadius: 3, |
|
|
elevation: 3, |
|
|
}, |
|
|
bottomButton1: { |
|
|
padding: 10, |
|
|
marginHorizontal: 10, |
|
|
alignItems: "center", |
|
|
backgroundColor: "#f0f0f0", |
|
|
borderRadius: 5, |
|
|
flex: 1, |
|
|
}, |
|
|
bottomButton: { |
|
|
padding: 10, |
|
|
marginHorizontal: 10, |
|
|
alignItems: "center", |
|
|
backgroundColor: "#fe7f42", |
|
|
borderRadius: 5, |
|
|
flex: 1, |
|
|
}, |
|
|
bottomButtonText: { |
|
|
fontSize: fontSize(18), |
|
|
fontWeight: "600", |
|
|
color: "#fff", |
|
|
}, |
|
|
bottomButtonText1: { |
|
|
fontSize: fontSize(18), |
|
|
fontWeight: "600", |
|
|
color: "#999", |
|
|
}, |
|
|
modalOverlay: { |
|
|
flex: 1, |
|
|
backgroundColor: 'rgba(0, 0, 0, 0.5)', |
|
|
justifyContent: 'flex-end', |
|
|
}, |
|
|
modalContent: { |
|
|
backgroundColor: '#fff', |
|
|
borderTopLeftRadius: 20, |
|
|
borderTopRightRadius: 20, |
|
|
padding: 20, |
|
|
maxHeight: '80%', |
|
|
}, |
|
|
modalHeader: { |
|
|
flexDirection: 'row', |
|
|
justifyContent: 'space-between', |
|
|
alignItems: 'center', |
|
|
marginBottom: 20, |
|
|
}, |
|
|
modalTitle: { |
|
|
fontSize: fontSize(18), |
|
|
fontWeight: '600', |
|
|
}, |
|
|
closeButton: { |
|
|
fontSize: fontSize(24), |
|
|
color: '#999', |
|
|
}, |
|
|
tabs: { |
|
|
flexDirection: 'row', |
|
|
marginBottom: 15, |
|
|
borderBottomWidth: 1, |
|
|
borderBottomColor: '#f5f5f5', |
|
|
}, |
|
|
tab: { |
|
|
paddingVertical: 10, |
|
|
paddingHorizontal: 15, |
|
|
marginRight: 10, |
|
|
}, |
|
|
tabActive: { |
|
|
borderBottomWidth: 2, |
|
|
borderBottomColor: '#FF5100', |
|
|
}, |
|
|
tabText: { |
|
|
fontSize: fontSize(16), |
|
|
color: '#666', |
|
|
}, |
|
|
tabTextActive: { |
|
|
color: '#FF5100', |
|
|
fontWeight: '500', |
|
|
}, |
|
|
paymentOptions: { |
|
|
maxHeight: 300, |
|
|
}, |
|
|
paymentOption: { |
|
|
flexDirection: 'row', |
|
|
alignItems: 'center', |
|
|
justifyContent: 'space-between', |
|
|
padding: 15, |
|
|
backgroundColor: '#F8F8F8', |
|
|
borderRadius: 8, |
|
|
marginBottom: 10, |
|
|
}, |
|
|
paymentSelected: { |
|
|
backgroundColor: '#FFF0E8', |
|
|
borderWidth: 1, |
|
|
borderColor: '#FF5100', |
|
|
}, |
|
|
paymentContent: { |
|
|
flex: 1, |
|
|
}, |
|
|
defaultPaymentContainer: { |
|
|
flexDirection: 'row', |
|
|
alignItems: 'center', |
|
|
}, |
|
|
paymentIcon: { |
|
|
fontSize: fontSize(24), |
|
|
marginRight: 8, |
|
|
}, |
|
|
paymentLabel: { |
|
|
fontSize: fontSize(16), |
|
|
fontWeight: '500', |
|
|
}, |
|
|
radioButton: { |
|
|
width: 20, |
|
|
height: 20, |
|
|
borderRadius: 10, |
|
|
borderWidth: 2, |
|
|
borderColor: '#FF5100', |
|
|
alignItems: 'center', |
|
|
justifyContent: 'center', |
|
|
}, |
|
|
radioInner: { |
|
|
width: 10, |
|
|
height: 10, |
|
|
borderRadius: 5, |
|
|
backgroundColor: 'transparent', |
|
|
}, |
|
|
radioInnerSelected: { |
|
|
backgroundColor: '#FF5100', |
|
|
}, |
|
|
modalFooter: { |
|
|
flexDirection: 'row', |
|
|
justifyContent: 'space-between', |
|
|
marginTop: 20, |
|
|
paddingTop: 20, |
|
|
borderTopWidth: 1, |
|
|
borderTopColor: '#f5f5f5', |
|
|
}, |
|
|
cancelButton: { |
|
|
flex: 1, |
|
|
padding: 15, |
|
|
marginRight: 10, |
|
|
borderRadius: 25, |
|
|
borderWidth: 1, |
|
|
borderColor: '#999', |
|
|
alignItems: 'center', |
|
|
}, |
|
|
confirmButton: { |
|
|
flex: 1, |
|
|
padding: 15, |
|
|
marginLeft: 10, |
|
|
borderRadius: 25, |
|
|
backgroundColor: '#FF5100', |
|
|
alignItems: 'center', |
|
|
}, |
|
|
disabledButton: { |
|
|
backgroundColor: '#ccc', |
|
|
}, |
|
|
cancelButtonText: { |
|
|
fontSize: fontSize(16), |
|
|
color: '#666', |
|
|
}, |
|
|
confirmButtonText: { |
|
|
fontSize: fontSize(16), |
|
|
color: '#fff', |
|
|
fontWeight: '600', |
|
|
}, |
|
|
currencySelectorContainer: { |
|
|
padding: 15, |
|
|
backgroundColor: '#f8f8f8', |
|
|
borderRadius: 8, |
|
|
marginTop: 10, |
|
|
}, |
|
|
currencySelectorTitle: { |
|
|
fontSize: fontSize(14), |
|
|
color: '#666', |
|
|
marginBottom: 10, |
|
|
}, |
|
|
currencyOptions: { |
|
|
flexDirection: 'row', |
|
|
marginBottom: 10, |
|
|
}, |
|
|
currencyOption: { |
|
|
paddingVertical: 8, |
|
|
paddingHorizontal: 15, |
|
|
borderRadius: 20, |
|
|
borderWidth: 1, |
|
|
borderColor: '#ddd', |
|
|
marginRight: 10, |
|
|
}, |
|
|
selectedCurrencyOption: { |
|
|
backgroundColor: '#FFF0E8', |
|
|
borderColor: '#FF5100', |
|
|
}, |
|
|
currencyText: { |
|
|
fontSize: fontSize(14), |
|
|
color: '#333', |
|
|
}, |
|
|
totalContainer: { |
|
|
flexDirection: 'row', |
|
|
alignItems: 'center', |
|
|
justifyContent: 'flex-end', |
|
|
}, |
|
|
totalText: { |
|
|
fontSize: fontSize(16), |
|
|
fontWeight: '600', |
|
|
color: '#FF5100', |
|
|
}, |
|
|
loadingIndicator: { |
|
|
marginLeft: 10, |
|
|
}, |
|
|
});
|
|
|
|