|
|
@@ -2,6 +2,8 @@
|
|
|
|
|
|
import { useState, useMemo } from "react";
|
|
|
import { useRouter } from "next/navigation";
|
|
|
+import { Swiper, SwiperSlide } from 'swiper/react';
|
|
|
+import Big from 'big.js';
|
|
|
import { useAppDispatch, useAppSelector } from "@/store/hooks";
|
|
|
import { useCustomToast } from "@utils/hooks/useToast";
|
|
|
import {
|
|
|
@@ -9,21 +11,15 @@ import {
|
|
|
clearAddToCartProduct
|
|
|
} from '@/store/slices/addToCartDialogSlice';
|
|
|
import { useAddProduct } from "@utils/hooks/useAddToCart";
|
|
|
+import {useConfig} from "@/utils/hooks/useConfig";
|
|
|
import { overlayLoading } from "@/components/theme/ui/kernel/loading/api";
|
|
|
-import {
|
|
|
- Drawer,
|
|
|
- DrawerContent,
|
|
|
- DrawerHeader,
|
|
|
- DrawerBody,
|
|
|
- DrawerFooter
|
|
|
-} from "@heroui/drawer";
|
|
|
+
|
|
|
import type {
|
|
|
ProductOption,
|
|
|
ResolvedVariant
|
|
|
} from "@/components/catalog/type";
|
|
|
-import ImgSwiperInAddToCartModal from "./ImgSwiperInAddToCartModal";
|
|
|
+import CommonModal from "@/components/theme/ui/CommonModal";
|
|
|
import ProductOptionsInAddToCartModal from "./ProductOptionsInAddToCartModal";
|
|
|
-import FooterBtnInAddToCartModal from "./FooterBtnInAddToCartModal";
|
|
|
import { Price } from "@components/theme/ui/Price";
|
|
|
import {
|
|
|
isValueAvailable,
|
|
|
@@ -38,6 +34,8 @@ import {
|
|
|
export default function AddToCartModal() {
|
|
|
const router = useRouter();
|
|
|
const dispatch = useAppDispatch();
|
|
|
+ const {getCurrentCurrencyItem} = useConfig();
|
|
|
+ const currentCurrency = getCurrentCurrencyItem();
|
|
|
const {isOpen, product} = useAppSelector((state) => state.addToCartDialog);
|
|
|
|
|
|
const { appendProductToCart } = useAddProduct();
|
|
|
@@ -147,11 +145,11 @@ export default function AddToCartModal() {
|
|
|
return { variant: null, totalLinePrice: 0, totalNowPrice: 0, save: 0 };
|
|
|
}
|
|
|
if(variant.priceIndices && variant.priceIndices.length > 0) {
|
|
|
- totalLinePrice = Number(variant.priceIndices[0].regular_min_price) * productQty;
|
|
|
- totalNowPrice = Number(variant.priceIndices[0].min_price) * productQty;
|
|
|
+ totalLinePrice = Big(variant.priceIndices[0].regular_min_price).times(productQty).toNumber();
|
|
|
+ totalNowPrice = Big(variant.priceIndices[0].min_price).times(productQty).toNumber();
|
|
|
}
|
|
|
if(totalLinePrice !== totalNowPrice) {
|
|
|
- save = -(totalLinePrice - totalNowPrice);
|
|
|
+ save = Big(totalNowPrice).minus(totalLinePrice).toNumber();
|
|
|
}
|
|
|
|
|
|
return {
|
|
|
@@ -202,7 +200,7 @@ export default function AddToCartModal() {
|
|
|
return res;
|
|
|
}
|
|
|
|
|
|
- const addToCartHandler = async (callback: ()=> void) => {
|
|
|
+ const addToCartHandler = async () => {
|
|
|
if(!isCurrentSelectionAvailable) {
|
|
|
showToast("The selected options are not available!", "warning");
|
|
|
return;
|
|
|
@@ -210,10 +208,10 @@ export default function AddToCartModal() {
|
|
|
|
|
|
if(currentVariantInfo.variant) {
|
|
|
await addProductToCart();
|
|
|
- callback();
|
|
|
+ closeModal();
|
|
|
}
|
|
|
};
|
|
|
- const buyNowHandler = async (callback: ()=> void) => {
|
|
|
+ const buyNowHandler = async () => {
|
|
|
if(!isCurrentSelectionAvailable) {
|
|
|
showToast("The selected options are not available!", "warning");
|
|
|
return;
|
|
|
@@ -221,7 +219,7 @@ export default function AddToCartModal() {
|
|
|
|
|
|
if(currentVariantInfo.variant) {
|
|
|
const res = await addProductToCart();
|
|
|
- callback();
|
|
|
+ closeModal();
|
|
|
if(res && !res.error) {
|
|
|
const responseData = res.data;
|
|
|
if(responseData && responseData.success) {
|
|
|
@@ -237,83 +235,104 @@ export default function AddToCartModal() {
|
|
|
dispatch(clearAddToCartProduct());
|
|
|
}, 300);
|
|
|
};
|
|
|
- const openChange = (e:boolean) => {
|
|
|
- if(!e) {
|
|
|
- closeModal();
|
|
|
- }
|
|
|
- }
|
|
|
|
|
|
- return (
|
|
|
- <Drawer
|
|
|
- backdrop={"blur"}
|
|
|
- placement="bottom"
|
|
|
- isDismissable={false}
|
|
|
- isKeyboardDismissDisabled={true}
|
|
|
- isOpen={isOpen}
|
|
|
- hideCloseButton
|
|
|
- onOpenChange={(e) => openChange(e)}
|
|
|
- >
|
|
|
- <DrawerContent className="rounded-none h-17/20 max-h-none">
|
|
|
- {(onClose) => (
|
|
|
- <>
|
|
|
- <DrawerHeader className="flex flex-col gap-1">
|
|
|
- <div>
|
|
|
- Select Options
|
|
|
- <button className="absolute top-2.5 right-2.5 w-6 h-6" onClick={onClose}>
|
|
|
- <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>
|
|
|
- {/**产品图片 */}
|
|
|
- {images.length > 0 && (
|
|
|
- <div>
|
|
|
- <ImgSwiperInAddToCartModal images={images} />
|
|
|
- </div>
|
|
|
- )}
|
|
|
- </DrawerHeader>
|
|
|
- <DrawerBody className="drawer-body relative">
|
|
|
- <div>
|
|
|
- {/**产品选项 */}
|
|
|
- <div className="box-border w-full">
|
|
|
- <ProductOptionsInAddToCartModal
|
|
|
- productOptions={productOptions}
|
|
|
- selected={selected}
|
|
|
- disabledMap={disabledMap}
|
|
|
- onOptionClick={handleOptionClick}
|
|
|
- />
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </DrawerBody>
|
|
|
- <DrawerFooter className="flex-col border-t border-gray-200 gap-y-4 p-4">
|
|
|
- <div className="flex justify-between items-center">
|
|
|
- <Price
|
|
|
- className="text-ly-14 text-ly-gray line-through"
|
|
|
- amount={String(currentVariantInfo.totalLinePrice)}
|
|
|
- currencyCode="USD"
|
|
|
- />
|
|
|
- <div className="flex items-center">
|
|
|
- <Price
|
|
|
- className="text-ly-14 bg-ly-gold py-0.5 px-1"
|
|
|
- amount={String(currentVariantInfo.save)}
|
|
|
- currencyCode="USD"
|
|
|
- />
|
|
|
- <Price
|
|
|
- className="text-ly-20 font-bold ml-1.5"
|
|
|
- amount={String(currentVariantInfo.totalNowPrice)}
|
|
|
- currencyCode="USD"
|
|
|
- />
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <div>
|
|
|
- <FooterBtnInAddToCartModal
|
|
|
- isAvailable={isCurrentSelectionAvailable}
|
|
|
- onAddToCart={()=> addToCartHandler(onClose)}
|
|
|
- onBuyNow={()=> buyNowHandler(onClose)}
|
|
|
- />
|
|
|
- </div>
|
|
|
- </DrawerFooter>
|
|
|
- </>
|
|
|
+
|
|
|
+ return (<>
|
|
|
+ <CommonModal
|
|
|
+ isOpen={isOpen}
|
|
|
+ onClose={closeModal}
|
|
|
+ fullyCustomer={true}
|
|
|
+ contentClassName="absolute box-border transition-transform duration-300 ease-out bottom-0 left-0 w-full p-4 bg-white rounded-t-xl"
|
|
|
+ body={<>
|
|
|
+
|
|
|
+ <div className="flex justify-between items-center text-ly-16">
|
|
|
+ Select Options
|
|
|
+ <button className="flex-none w-6 h-6" onClick={closeModal} type="button">
|
|
|
+ <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>
|
|
|
+
|
|
|
+ {images.length > 0 && (
|
|
|
+ <div className="w-full mt-4">
|
|
|
+ <Swiper
|
|
|
+ spaceBetween={10}
|
|
|
+ slidesPerView={3}
|
|
|
+ >
|
|
|
+ {images.map((img) => {
|
|
|
+ return (
|
|
|
+ <SwiperSlide key={img.id} className="w-24 h-32">
|
|
|
+ <img className="block h-full w-full object-cover" src={img.publicPath} />
|
|
|
+ </SwiperSlide>
|
|
|
+ );
|
|
|
+ })}
|
|
|
+ </Swiper>
|
|
|
+ </div>
|
|
|
)}
|
|
|
- </DrawerContent>
|
|
|
- </Drawer>
|
|
|
- );
|
|
|
+
|
|
|
+ <div className="box-border w-full mt-6 h-73.75 overflow-y-auto scrollbar-thin scrollbar-thumb-gray-100">
|
|
|
+ <div className="box-border w-full">
|
|
|
+ <ProductOptionsInAddToCartModal
|
|
|
+ productOptions={productOptions}
|
|
|
+ selected={selected}
|
|
|
+ disabledMap={disabledMap}
|
|
|
+ onOptionClick={handleOptionClick}
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div className="box-border w-full border-t-1 border-[#f2f2f2] mt-1.5 pt-3">
|
|
|
+ <div className="flex justify-between items-center">
|
|
|
+ <Price
|
|
|
+ className="text-ly-14 text-ly-gray line-through"
|
|
|
+ amount={String(currentVariantInfo.totalLinePrice)}
|
|
|
+ currencyCode={currentCurrency.code}
|
|
|
+ />
|
|
|
+ <div className="flex items-center">
|
|
|
+ <Price
|
|
|
+ className="text-ly-14 bg-ly-gold py-0.5 px-1"
|
|
|
+ amount={String(currentVariantInfo.save)}
|
|
|
+ currencyCode={currentCurrency.code}
|
|
|
+ />
|
|
|
+ <Price
|
|
|
+ className="text-ly-20 font-bold ml-1.5"
|
|
|
+ amount={String(currentVariantInfo.totalNowPrice)}
|
|
|
+ currencyCode={currentCurrency.code}
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ {isCurrentSelectionAvailable ?
|
|
|
+ <>
|
|
|
+ <div className="flex justify-between gap-3 mt-3">
|
|
|
+ <button className="flex-1 flex justify-center items-center h-12 text-ly-16 font-bold text-white rounded-3xl bg-ly-deepgreen"
|
|
|
+ type="button"
|
|
|
+ onClick={buyNowHandler}
|
|
|
+ >
|
|
|
+ Buy now
|
|
|
+ </button>
|
|
|
+ <button className="flex-1 flex justify-center items-center h-12 text-ly-16 font-bold text-white rounded-3xl bg-ly-middlegreen"
|
|
|
+ type="button"
|
|
|
+ onClick={addToCartHandler}
|
|
|
+ >
|
|
|
+ Add to bag
|
|
|
+ </button>
|
|
|
+ </div>
|
|
|
+ {/* <button className="flex justify-center items-center w-full mt-3 h-12 text-ly-16 font-bold text-white rounded-3xl bg-[#ffc43a]" type="button">
|
|
|
+ <img className="h-6 w-18.75" src="/image/payment/paypal-logo.svg" />
|
|
|
+ </button> */}
|
|
|
+ </>
|
|
|
+ :
|
|
|
+ <p className="text-center text-ly-14">The selected options are not available!</p>
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ </div>
|
|
|
+
|
|
|
+
|
|
|
+ </>}
|
|
|
+ />
|
|
|
+ </>);
|
|
|
+
|
|
|
+
|
|
|
}
|