|
@@ -1,6 +1,6 @@
|
|
|
"use client";
|
|
"use client";
|
|
|
|
|
|
|
|
-import {useState, useEffect, useRef, Suspense} from "react";
|
|
|
|
|
|
|
+import {useState, useEffect, useRef} from "react";
|
|
|
|
|
|
|
|
import { LoadingSpinner } from "@components/common/LoadingSpinner";
|
|
import { LoadingSpinner } from "@components/common/LoadingSpinner";
|
|
|
import CheckoutShippingMethodLoading from "./CheckoutShippingMethodLoading";
|
|
import CheckoutShippingMethodLoading from "./CheckoutShippingMethodLoading";
|
|
@@ -11,30 +11,34 @@ import {
|
|
|
ShipAddressFormData,
|
|
ShipAddressFormData,
|
|
|
BillAddressFormData,
|
|
BillAddressFormData,
|
|
|
FullAddressFormData,
|
|
FullAddressFormData,
|
|
|
- CreateCheckoutAddressVariables
|
|
|
|
|
|
|
+ CreateCheckoutAddressVariables,
|
|
|
} from "@/types/checkout/type";
|
|
} from "@/types/checkout/type";
|
|
|
import AddressResultDisplay from "./AddressResultDisplay";
|
|
import AddressResultDisplay from "./AddressResultDisplay";
|
|
|
import AddressResultDisplayLoading from "./AddressResultDisplayLoading";
|
|
import AddressResultDisplayLoading from "./AddressResultDisplayLoading";
|
|
|
-import CheckoutAddressModal from "./CheckoutAddressModal";
|
|
|
|
|
import ShippingAddressCheckout from "./ShippingAddressCheckout";
|
|
import ShippingAddressCheckout from "./ShippingAddressCheckout";
|
|
|
import BillingAddressCheckout from "./BillingAddressCheckout";
|
|
import BillingAddressCheckout from "./BillingAddressCheckout";
|
|
|
import {ShippingMethodCheckout,RefShippingMethodsHandle} from "./ShippingMethodCheckout";
|
|
import {ShippingMethodCheckout,RefShippingMethodsHandle} from "./ShippingMethodCheckout";
|
|
|
import { useCustomToast } from "@/utils/hooks/useToast";
|
|
import { useCustomToast } from "@/utils/hooks/useToast";
|
|
|
import {useCheckoutAddress} from "@/utils/hooks/useCheckoutAddress"
|
|
import {useCheckoutAddress} from "@/utils/hooks/useCheckoutAddress"
|
|
|
import {useCheckoutPaymentMethod} from "@/utils/hooks/useCheckoutPaymentMethod";
|
|
import {useCheckoutPaymentMethod} from "@/utils/hooks/useCheckoutPaymentMethod";
|
|
|
-import { useAppSelector,useAppDispatch } from "@/store/hooks";
|
|
|
|
|
|
|
+import {useCheckoutShippingMethod} from "@/utils/hooks/useCheckoutShippingMethod";
|
|
|
|
|
+import { useAppDispatch,useAppStore } from "@/store/hooks";
|
|
|
import { updateCart } from "@/store/slices/cart-slice";
|
|
import { updateCart } from "@/store/slices/cart-slice";
|
|
|
import { useCartDetail } from "@utils/hooks/useCartDetail";
|
|
import { useCartDetail } from "@utils/hooks/useCartDetail";
|
|
|
-import PaymentMethodCheckout from "./PaymentMethodCheckout";
|
|
|
|
|
|
|
+import {PaymentMethodCheckout,RefPaymentMethodsHandle} from "./PaymentMethodCheckout";
|
|
|
import LoadingPaymentMethod from "./LoadingPaymentMethod";
|
|
import LoadingPaymentMethod from "./LoadingPaymentMethod";
|
|
|
import CheckoutPlaceOrder from "./CheckoutPlaceOrder";
|
|
import CheckoutPlaceOrder from "./CheckoutPlaceOrder";
|
|
|
-
|
|
|
|
|
|
|
+import CommonModal from "@/components/theme/ui/CommonModal";
|
|
|
|
|
+import {useSaveCheckoutCart} from "@/utils/hooks/useSaveCheckoutCart";
|
|
|
|
|
+import { formatCartDetail, shippingAddressToCartAddress, billingAddressToCartAddress } from "@/utils/cartDetailTools";
|
|
|
|
|
+import { overlayLoading } from "@/components/theme/ui/kernel/loading/api";
|
|
|
|
|
+import { CartDetail } from "@/types/cart/type";
|
|
|
/***
|
|
/***
|
|
|
* 不用useForShipping字段了
|
|
* 不用useForShipping字段了
|
|
|
* 以shipping address 为准,根据shippingaddress 设置billing address
|
|
* 以shipping address 为准,根据shippingaddress 设置billing address
|
|
|
- * @todo 保存完地址之后要重新获取运输方式和支付方式
|
|
|
|
|
- * @todo 变更运输方式后重新获取支付方式
|
|
|
|
|
- * @todo redux本地存储购物车详情优化(slice定义修改;useCartDetail自定义hook修改;最后结账也统一优化购物车详情获取)
|
|
|
|
|
|
|
+ * 保存完地址之后要重新获取运输方式和支付方式
|
|
|
|
|
+ * 变更运输方式后重新获取支付方式
|
|
|
|
|
+ * @todo 购物车为空 跳转到空购物车页面
|
|
|
*/
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -94,41 +98,78 @@ function generateSaveCheckoutAddressParam(formData: FullAddressFormData):CreateC
|
|
|
|
|
|
|
|
export default function CheckoutWrapper({
|
|
export default function CheckoutWrapper({
|
|
|
loginEmail,
|
|
loginEmail,
|
|
|
- countries
|
|
|
|
|
|
|
+ countries,
|
|
|
}: {
|
|
}: {
|
|
|
loginEmail: string;
|
|
loginEmail: string;
|
|
|
- countries: Country[]
|
|
|
|
|
|
|
+ countries: Country[],
|
|
|
}) {
|
|
}) {
|
|
|
|
|
+
|
|
|
const dispatch = useAppDispatch();
|
|
const dispatch = useAppDispatch();
|
|
|
- const { getCartDetail } = useCartDetail();
|
|
|
|
|
|
|
+ const { cartData } = useCartDetail();
|
|
|
|
|
+ const {saveCheckoutCart} = useSaveCheckoutCart();
|
|
|
|
|
+
|
|
|
|
|
+ const {
|
|
|
|
|
+ data: shippingMethodDatas,
|
|
|
|
|
+ loading: shippingMethodLoading,
|
|
|
|
|
+ error: shippingMethodError,
|
|
|
|
|
+ getShippingMethod,
|
|
|
|
|
+ } = useCheckoutShippingMethod();
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ const selectedPaymentMethod = cartData?.paymentMethod ?? 'paypal_smart_button';
|
|
|
|
|
|
|
|
const {
|
|
const {
|
|
|
data: paymentMethodDatas,
|
|
data: paymentMethodDatas,
|
|
|
loading: paymentMethodLoading,
|
|
loading: paymentMethodLoading,
|
|
|
error: paymentMethodError,
|
|
error: paymentMethodError,
|
|
|
getPaymentMethod,
|
|
getPaymentMethod,
|
|
|
- savePaymentMethod
|
|
|
|
|
} = useCheckoutPaymentMethod();
|
|
} = useCheckoutPaymentMethod();
|
|
|
|
|
|
|
|
const { showToast } = useCustomToast();
|
|
const { showToast } = useCustomToast();
|
|
|
const { getCheckoutAddress, saveCheckoutAddress } = useCheckoutAddress(loginEmail);
|
|
const { getCheckoutAddress, saveCheckoutAddress } = useCheckoutAddress(loginEmail);
|
|
|
|
|
|
|
|
const methodShiippingRef = useRef<RefShippingMethodsHandle>(null);
|
|
const methodShiippingRef = useRef<RefShippingMethodsHandle>(null);
|
|
|
|
|
+ const methodPaymentRef = useRef<RefPaymentMethodsHandle>(null);
|
|
|
|
|
|
|
|
|
|
|
|
|
// useForm() 只会在组件初始化时读取一次 defaultValues
|
|
// useForm() 只会在组件初始化时读取一次 defaultValues
|
|
|
const addressForm = useForm<FullAddressFormData>({
|
|
const addressForm = useForm<FullAddressFormData>({
|
|
|
mode: "onBlur", // 或 "onChange"
|
|
mode: "onBlur", // 或 "onChange"
|
|
|
- reValidateMode: "onChange",
|
|
|
|
|
|
|
+ reValidateMode: "onChange",
|
|
|
|
|
+ defaultValues: {
|
|
|
|
|
+ "shippingAddressId": "",
|
|
|
|
|
+ "shippingEmail": loginEmail,
|
|
|
|
|
+ "shippingFirstName": "",
|
|
|
|
|
+ "shippingLastName": "jack",
|
|
|
|
|
+ "shippingCompanyName": "",
|
|
|
|
|
+ "shippingAddress": "",
|
|
|
|
|
+ "shippingCountry": "US",
|
|
|
|
|
+ "shippingState": "",
|
|
|
|
|
+ "shippingCity": "",
|
|
|
|
|
+ "shippingPostcode": "",
|
|
|
|
|
+ "shippingPhoneNumber": "",
|
|
|
|
|
+ "billingAddressId": "",
|
|
|
|
|
+ "billingEmail": "",
|
|
|
|
|
+ "billingFirstName": "",
|
|
|
|
|
+ "billingLastName": "",
|
|
|
|
|
+ "billingCompanyName": "",
|
|
|
|
|
+ "billingAddress": "",
|
|
|
|
|
+ "billingCountry": "US",
|
|
|
|
|
+ "billingState": "",
|
|
|
|
|
+ "billingCity": "",
|
|
|
|
|
+ "billingPostcode": "",
|
|
|
|
|
+ "billingPhoneNumber": "",
|
|
|
|
|
+ "billingSameAsShipping": true
|
|
|
|
|
+ }
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
const [addressModalOpen, setAddressModalOpen] = useState(false);
|
|
const [addressModalOpen, setAddressModalOpen] = useState(false);
|
|
|
- const [loadingData, setLoadingData] = useState(true);
|
|
|
|
|
- const [serverShippingAddress, setServerShippingAddress] = useState<ShipAddressFormData | null>(null);
|
|
|
|
|
|
|
+ const [loadingAddress, setLoadingAddress] = useState(true); // 初始加载地址数据时的loading状态
|
|
|
|
|
|
|
|
|
|
+ const serverShippingAddress = useRef<ShipAddressFormData | null>(null);
|
|
|
const serverBillingAddress = useRef<BillAddressFormData | null>(null);
|
|
const serverBillingAddress = useRef<BillAddressFormData | null>(null);
|
|
|
|
|
|
|
|
- const [addressSaving, setAddressSaving] = useState(false);
|
|
|
|
|
|
|
+ const [addressSaving, setAddressSaving] = useState(false); // 保存地址时的loading状态
|
|
|
|
|
|
|
|
// 开发环境会执行两次 https://zh-hans.react.dev/learn/synchronizing-with-effects#how-to-handle-the-effect-firing-twice-in-development
|
|
// 开发环境会执行两次 https://zh-hans.react.dev/learn/synchronizing-with-effects#how-to-handle-the-effect-firing-twice-in-development
|
|
|
useEffect(() => {
|
|
useEffect(() => {
|
|
@@ -137,14 +178,13 @@ export default function CheckoutWrapper({
|
|
|
...shippingAddress,
|
|
...shippingAddress,
|
|
|
...billingAddress,
|
|
...billingAddress,
|
|
|
});
|
|
});
|
|
|
- setServerShippingAddress({
|
|
|
|
|
- ...shippingAddress
|
|
|
|
|
- });
|
|
|
|
|
|
|
+
|
|
|
|
|
+ serverShippingAddress.current = shippingAddress;
|
|
|
serverBillingAddress.current = billingAddress;
|
|
serverBillingAddress.current = billingAddress;
|
|
|
|
|
|
|
|
- setLoadingData(false);
|
|
|
|
|
|
|
+ setLoadingAddress(false);
|
|
|
}, ()=> {
|
|
}, ()=> {
|
|
|
- setLoadingData(false);
|
|
|
|
|
|
|
+ setLoadingAddress(false);
|
|
|
});
|
|
});
|
|
|
}, []);
|
|
}, []);
|
|
|
|
|
|
|
@@ -152,9 +192,9 @@ export default function CheckoutWrapper({
|
|
|
const openAddressModal = () => {
|
|
const openAddressModal = () => {
|
|
|
setAddressModalOpen(true);
|
|
setAddressModalOpen(true);
|
|
|
|
|
|
|
|
- if(serverShippingAddress && serverBillingAddress.current) {
|
|
|
|
|
|
|
+ if(serverShippingAddress.current && serverBillingAddress.current) {
|
|
|
addressForm.reset({
|
|
addressForm.reset({
|
|
|
- ...serverShippingAddress,
|
|
|
|
|
|
|
+ ...serverShippingAddress.current,
|
|
|
...serverBillingAddress.current,
|
|
...serverBillingAddress.current,
|
|
|
});
|
|
});
|
|
|
}
|
|
}
|
|
@@ -167,19 +207,20 @@ export default function CheckoutWrapper({
|
|
|
};
|
|
};
|
|
|
const addressFormOnSubmit = async (formData: FullAddressFormData) => {
|
|
const addressFormOnSubmit = async (formData: FullAddressFormData) => {
|
|
|
// console.log('addressFormOnSubmit ---- ',formData); return;
|
|
// console.log('addressFormOnSubmit ---- ',formData); return;
|
|
|
- // 保存完地址之后还要重新请求地址,把保存后的地址id同步到表单里;
|
|
|
|
|
- // 还需要获取运输方式
|
|
|
|
|
-
|
|
|
|
|
|
|
+ if(addressSaving) {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
const saveAddressParam = generateSaveCheckoutAddressParam(formData);
|
|
const saveAddressParam = generateSaveCheckoutAddressParam(formData);
|
|
|
setAddressSaving(true);
|
|
setAddressSaving(true);
|
|
|
try {
|
|
try {
|
|
|
|
|
|
|
|
const res = await saveCheckoutAddress(saveAddressParam);
|
|
const res = await saveCheckoutAddress(saveAddressParam);
|
|
|
console.log('CREATE_CHECKOUT_ADDRESS res ====== ',res);
|
|
console.log('CREATE_CHECKOUT_ADDRESS res ====== ',res);
|
|
|
- if(methodShiippingRef.current) {
|
|
|
|
|
- methodShiippingRef.current.reloadSHippingMethods();
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ // 地址保存成功后重新获取运输方式和支付方式
|
|
|
|
|
+ getShippingMethod();
|
|
|
|
|
+ getPaymentMethod();
|
|
|
|
|
|
|
|
|
|
+ // 保存完地址之后还要重新请求地址,把保存后的地址id同步到表单里;
|
|
|
const queryAddressRes = await getCheckoutAddress();
|
|
const queryAddressRes = await getCheckoutAddress();
|
|
|
if(queryAddressRes !== null) {
|
|
if(queryAddressRes !== null) {
|
|
|
addressForm.resetField('shippingAddressId',{
|
|
addressForm.resetField('shippingAddressId',{
|
|
@@ -188,10 +229,14 @@ export default function CheckoutWrapper({
|
|
|
addressForm.resetField('billingAddressId',{
|
|
addressForm.resetField('billingAddressId',{
|
|
|
defaultValue: queryAddressRes.billingAddress.billingAddressId
|
|
defaultValue: queryAddressRes.billingAddress.billingAddressId
|
|
|
});
|
|
});
|
|
|
- setServerShippingAddress({
|
|
|
|
|
- ...queryAddressRes.shippingAddress
|
|
|
|
|
- });
|
|
|
|
|
|
|
+
|
|
|
|
|
+ serverShippingAddress.current = queryAddressRes.shippingAddress;
|
|
|
serverBillingAddress.current = queryAddressRes.billingAddress;
|
|
serverBillingAddress.current = queryAddressRes.billingAddress;
|
|
|
|
|
+ // 同步地址到购物车详情
|
|
|
|
|
+ dispatch(updateCart({
|
|
|
|
|
+ billingAddress: billingAddressToCartAddress(queryAddressRes.billingAddress),
|
|
|
|
|
+ shippingAddress: shippingAddressToCartAddress(queryAddressRes.shippingAddress)
|
|
|
|
|
+ }));
|
|
|
|
|
|
|
|
}
|
|
}
|
|
|
setAddressModalOpen(false);
|
|
setAddressModalOpen(false);
|
|
@@ -208,7 +253,27 @@ export default function CheckoutWrapper({
|
|
|
|
|
|
|
|
|
|
|
|
|
const handlePaymentMethodChange = async (method: string,title: string) => {
|
|
const handlePaymentMethodChange = async (method: string,title: string) => {
|
|
|
-
|
|
|
|
|
|
|
+ let shippingMethod = '-1';
|
|
|
|
|
+ if(methodShiippingRef.current) {
|
|
|
|
|
+ shippingMethod = methodShiippingRef.current.getSelectShipMethod();
|
|
|
|
|
+ }
|
|
|
|
|
+ overlayLoading.start();
|
|
|
|
|
+ const saveRes = await saveCheckoutCart({
|
|
|
|
|
+ shippingMethod: shippingMethod,
|
|
|
|
|
+ paymentMethod: method,
|
|
|
|
|
+ couponCode: '-1'
|
|
|
|
|
+ });
|
|
|
|
|
+ overlayLoading.stop();
|
|
|
|
|
+ if(!saveRes.error) {
|
|
|
|
|
+ if(saveRes.data) {
|
|
|
|
|
+ const newCartDetail = formatCartDetail(saveRes.data);
|
|
|
|
|
+ dispatch(updateCart(newCartDetail));
|
|
|
|
|
+ }
|
|
|
|
|
+ } else {
|
|
|
|
|
+ showToast(saveRes.msg, 'danger');
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /*
|
|
|
const res = await savePaymentMethod({ paymentMethod: method });
|
|
const res = await savePaymentMethod({ paymentMethod: method });
|
|
|
console.log('savePaymentMethod res ====== ',res);
|
|
console.log('savePaymentMethod res ====== ',res);
|
|
|
if(!res.error) {
|
|
if(!res.error) {
|
|
@@ -220,7 +285,95 @@ export default function CheckoutWrapper({
|
|
|
} else {
|
|
} else {
|
|
|
showToast(res.msg, 'danger');
|
|
showToast(res.msg, 'danger');
|
|
|
}
|
|
}
|
|
|
|
|
+ */
|
|
|
|
|
+ };
|
|
|
|
|
+ const handleShippingMethodChange = async (method: string) => {
|
|
|
|
|
+ overlayLoading.start();
|
|
|
|
|
+ const saveRes = await saveCheckoutCart({
|
|
|
|
|
+ shippingMethod: method,
|
|
|
|
|
+ paymentMethod: '-1',
|
|
|
|
|
+ couponCode: '-1'
|
|
|
|
|
+ });
|
|
|
|
|
+ overlayLoading.stop();
|
|
|
|
|
+ if(!saveRes.error) {
|
|
|
|
|
+ if(saveRes.data) {
|
|
|
|
|
+ const newCartDetail = formatCartDetail(saveRes.data);
|
|
|
|
|
+ dispatch(updateCart(newCartDetail));
|
|
|
|
|
+ }
|
|
|
|
|
+ // 保存成功之后需要重新获取支付方式
|
|
|
|
|
+ getPaymentMethod();
|
|
|
|
|
+ } else {
|
|
|
|
|
+ showToast(saveRes.msg, 'danger');
|
|
|
|
|
+ }
|
|
|
|
|
+ /*
|
|
|
|
|
+ const res = await saveShippingMethod({ shippingMethod: method });
|
|
|
|
|
+ if(!res.error) {
|
|
|
|
|
+ // 保存成功之后需要重新获取购物车详情和支付方式
|
|
|
|
|
+ getCartDetail();
|
|
|
|
|
+ getPaymentMethod();
|
|
|
|
|
+ } else {
|
|
|
|
|
+ showToast(res.msg, 'danger');
|
|
|
|
|
+ }*/
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ // 下单
|
|
|
|
|
+ // 1. 校验地址 运输方式,支付方式;
|
|
|
|
|
+ // 2. 根据购物车详情判断是否需要传下单参数: 地址,运输方式,支付方式
|
|
|
|
|
+ const handlePlaceOrder = async () => {
|
|
|
|
|
+ // 校验地址
|
|
|
|
|
+ const addressValid = await addressForm.trigger();
|
|
|
|
|
+
|
|
|
|
|
+ if(!addressValid) {
|
|
|
|
|
+ showToast('Please fill in the address information correctly.', 'danger');
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+ if(methodShiippingRef.current) {
|
|
|
|
|
+ const shippingMethodValid = await methodShiippingRef.current.validateShipMethod();
|
|
|
|
|
+ if(!shippingMethodValid) {
|
|
|
|
|
+ showToast('Please select a shipping method.', 'danger');
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+ } else {
|
|
|
|
|
+ showToast('Please wait for shipping method loading.', 'danger');
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if(methodPaymentRef.current) {
|
|
|
|
|
+ const paymentMethodValid = await methodPaymentRef.current.validatePaymentMethod();
|
|
|
|
|
+ if(!paymentMethodValid) {
|
|
|
|
|
+ showToast('Please select a payment method.', 'danger');
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+ } else {
|
|
|
|
|
+ showToast('Please wait for payment method loading.', 'danger');
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+ if(!cartData) {
|
|
|
|
|
+ showToast('Please add product to your cart.', 'danger');
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ //如果购物车详情没有保存过支付方式,则需要保存支付方式
|
|
|
|
|
+ if(cartData?.paymentMethod === null) {
|
|
|
|
|
+ const pmethod = methodPaymentRef?.current.getSelectPaymentMethod();
|
|
|
|
|
+ const saveRes = await saveCheckoutCart({
|
|
|
|
|
+ shippingMethod: '-1',
|
|
|
|
|
+ paymentMethod: pmethod,
|
|
|
|
|
+ couponCode: '-1'
|
|
|
|
|
+ });
|
|
|
|
|
+ if(!saveRes.error) {
|
|
|
|
|
+ if(saveRes.data) {
|
|
|
|
|
+ const newCartDetail = formatCartDetail(saveRes.data);
|
|
|
|
|
+ dispatch(updateCart(newCartDetail));
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return true;
|
|
|
};
|
|
};
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
// function tt() {
|
|
// function tt() {
|
|
|
// const arr = [
|
|
// const arr = [
|
|
|
// ['US','3803800217'],
|
|
// ['US','3803800217'],
|
|
@@ -244,37 +397,64 @@ export default function CheckoutWrapper({
|
|
|
<section className="w-full">
|
|
<section className="w-full">
|
|
|
<div>
|
|
<div>
|
|
|
{/* <button className="w-25 h-8 bg-amber-500 flex items-center justify-center" onClick={tt}>test</button> */}
|
|
{/* <button className="w-25 h-8 bg-amber-500 flex items-center justify-center" onClick={tt}>test</button> */}
|
|
|
- {loadingData ? <AddressResultDisplayLoading />
|
|
|
|
|
- :<AddressResultDisplay shippingAddress={serverShippingAddress}
|
|
|
|
|
- onAddressModalOpenClick={openAddressModal}
|
|
|
|
|
- />}
|
|
|
|
|
- <CheckoutAddressModal
|
|
|
|
|
|
|
+ {loadingAddress ?
|
|
|
|
|
+ <AddressResultDisplayLoading />
|
|
|
|
|
+ :
|
|
|
|
|
+ <AddressResultDisplay shippingAddress={cartData?.shippingAddress ?? null}
|
|
|
|
|
+ onAddressModalOpenClick={openAddressModal}
|
|
|
|
|
+ />
|
|
|
|
|
+ }
|
|
|
|
|
+ <CommonModal
|
|
|
isOpen={addressModalOpen}
|
|
isOpen={addressModalOpen}
|
|
|
onClose={closeAddressModal}
|
|
onClose={closeAddressModal}
|
|
|
|
|
+ header={
|
|
|
|
|
+ <div className="w-full box-border p-3.75 h-14.5 flex justify-between items-center">
|
|
|
|
|
+ <span>Shipping Address</span>
|
|
|
|
|
+ <button className="w-6 h-6" onClick={() => closeAddressModal(false)}>
|
|
|
|
|
+ <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth="1.5" stroke="currentColor" aria-hidden="true" data-slot="icon" className="h-6 transition-all ease-in-out hover:scale-110"><path strokeLinecap="round" strokeLinejoin="round" d="M6 18 18 6M6 6l12 12"></path></svg>
|
|
|
|
|
+ </button>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ }
|
|
|
body={
|
|
body={
|
|
|
- <>
|
|
|
|
|
- <FormProvider {...addressForm}>
|
|
|
|
|
- <form>
|
|
|
|
|
- <ShippingAddressCheckout countries={countries} />
|
|
|
|
|
- <BillingAddressCheckout countries={countries} />
|
|
|
|
|
- </form>
|
|
|
|
|
- </FormProvider>
|
|
|
|
|
- </>
|
|
|
|
|
|
|
+ <div className="box-border w-full h-full p-3.75">
|
|
|
|
|
+ <p className="text-ly-12 leading-ly-20">
|
|
|
|
|
+ Select a billing address from your address book or enter a new address.
|
|
|
|
|
+ </p>
|
|
|
|
|
+ <div>
|
|
|
|
|
+ <FormProvider {...addressForm}>
|
|
|
|
|
+ <form>
|
|
|
|
|
+ <ShippingAddressCheckout countries={countries} />
|
|
|
|
|
+ <BillingAddressCheckout countries={countries} />
|
|
|
|
|
+ </form>
|
|
|
|
|
+ </FormProvider>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
}
|
|
}
|
|
|
footer={
|
|
footer={
|
|
|
|
|
+ <div className="box-border w-full p-3.75">
|
|
|
<button className="block flex justify-center items-center w-full h-12 bg-ly-green rounded-3xl text-white text-ly-16 font-bold"
|
|
<button className="block flex justify-center items-center w-full h-12 bg-ly-green rounded-3xl text-white text-ly-16 font-bold"
|
|
|
onClick={addressForm.handleSubmit(addressFormOnSubmit)}
|
|
onClick={addressForm.handleSubmit(addressFormOnSubmit)}
|
|
|
>
|
|
>
|
|
|
{addressSaving ? <LoadingSpinner /> : 'Save'}
|
|
{addressSaving ? <LoadingSpinner /> : 'Save'}
|
|
|
</button>
|
|
</button>
|
|
|
|
|
+ </div>
|
|
|
}
|
|
}
|
|
|
/>
|
|
/>
|
|
|
</div>
|
|
</div>
|
|
|
<div className="mt-6 box-border px-4">
|
|
<div className="mt-6 box-border px-4">
|
|
|
<h3 className="text-ly-24 font-medium">Shipping Method</h3>
|
|
<h3 className="text-ly-24 font-medium">Shipping Method</h3>
|
|
|
- {/* <Suspense fallback={<CheckoutShippingMethodLoading />}> */}
|
|
|
|
|
- <ShippingMethodCheckout ref={methodShiippingRef} />
|
|
|
|
|
- {/* </Suspense> */}
|
|
|
|
|
|
|
+ {shippingMethodLoading ?
|
|
|
|
|
+
|
|
|
|
|
+ <CheckoutShippingMethodLoading />
|
|
|
|
|
+ :
|
|
|
|
|
+ <ShippingMethodCheckout
|
|
|
|
|
+ ref={methodShiippingRef}
|
|
|
|
|
+ shipMethods={shippingMethodDatas}
|
|
|
|
|
+ errorMsg={shippingMethodError}
|
|
|
|
|
+ onShipMethodChange={handleShippingMethodChange}
|
|
|
|
|
+ />
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
|
<div className="mt-6 box-border px-4">
|
|
<div className="mt-6 box-border px-4">
|
|
@@ -283,6 +463,7 @@ export default function CheckoutWrapper({
|
|
|
<LoadingPaymentMethod />
|
|
<LoadingPaymentMethod />
|
|
|
:
|
|
:
|
|
|
<PaymentMethodCheckout
|
|
<PaymentMethodCheckout
|
|
|
|
|
+ ref={methodPaymentRef}
|
|
|
errorMsg={paymentMethodError}
|
|
errorMsg={paymentMethodError}
|
|
|
paymentMethods={paymentMethodDatas}
|
|
paymentMethods={paymentMethodDatas}
|
|
|
onPaymentMethodChange={handlePaymentMethodChange}
|
|
onPaymentMethodChange={handlePaymentMethodChange}
|
|
@@ -293,10 +474,13 @@ export default function CheckoutWrapper({
|
|
|
<div className="mt-3 box-border px-4">
|
|
<div className="mt-3 box-border px-4">
|
|
|
<p className="text-ly-12 text-[#666666] leading-ly-20">By providing your information, you agree to Wiggins'sPrivacy Policyand Terms of Use.</p>
|
|
<p className="text-ly-12 text-[#666666] leading-ly-20">By providing your information, you agree to Wiggins'sPrivacy Policyand Terms of Use.</p>
|
|
|
<div className="mt-6 w-full">
|
|
<div className="mt-6 w-full">
|
|
|
- <CheckoutPlaceOrder />
|
|
|
|
|
|
|
+ <CheckoutPlaceOrder
|
|
|
|
|
+ paymentMethod={selectedPaymentMethod}
|
|
|
|
|
+ clickPlaceOrder={handlePlaceOrder}
|
|
|
|
|
+ />
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
</section>
|
|
</section>
|
|
|
|
|
|
|
|
);
|
|
);
|