diff options
| author | HATEC\SPVDEV001 <tri.susilo@altama.co.id> | 2023-07-05 17:01:24 +0700 |
|---|---|---|
| committer | HATEC\SPVDEV001 <tri.susilo@altama.co.id> | 2023-07-05 17:01:24 +0700 |
| commit | cb69cf4e6633bb9192cd7bdc0a0063541f67102f (patch) | |
| tree | c08a07c10c931628fdc8e10c29e16d0c6dc3f130 | |
| parent | 9272a07644a75d201753501cfff173b1260963ea (diff) | |
promotion program cart dan variant
| -rw-r--r-- | public/images/noun-discount-57964023.svg | 31 | ||||
| -rw-r--r-- | src/lib/product/components/Product/Product.jsx | 2 | ||||
| -rw-r--r-- | src/lib/product/components/Product/ProductDesktop.jsx | 73 | ||||
| -rw-r--r-- | src/lib/promotinProgram/components/PromotionType.jsx | 76 |
4 files changed, 145 insertions, 37 deletions
diff --git a/public/images/noun-discount-57964023.svg b/public/images/noun-discount-57964023.svg new file mode 100644 index 00000000..e9ce34e5 --- /dev/null +++ b/public/images/noun-discount-57964023.svg @@ -0,0 +1,31 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Generator: Adobe Illustrator 24.1.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) --> +<svg version="1.1" id="Layer_1" xmlns:serif="http://www.serif.com/" + xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 500 500" + style="enable-background:new 0 0 500 500;" xml:space="preserve"> +<style type="text/css"> + .st0{fill-rule:evenodd;clip-rule:evenodd;fill:#D8D8D8;} +</style> +<g transform="matrix(1,0,0,1,-240,-48)"> + <g> + <path class="st0" d="M478.7,69.3c2.9-3.2,7-5.1,11.3-5.1s8.4,1.8,11.3,5.1l23.4,26.4c4.5,5,10.3,8.6,16.8,10.4 + c6.5,1.7,13.4,1.5,19.7-0.6l33.4-11.2c4.1-1.4,8.6-0.9,12.3,1.2c3.7,2.2,6.4,5.8,7.2,10l7,34.6c1.3,6.6,4.6,12.6,9.3,17.4 + c4.8,4.8,10.8,8,17.4,9.3l34.6,7c4.2,0.9,7.9,3.5,10,7.2s2.6,8.2,1.2,12.3l-11.2,33.4c-2.1,6.4-2.3,13.2-0.6,19.7 + s5.4,12.3,10.4,16.8l26.4,23.4c3.2,2.9,5.1,7,5.1,11.3s-1.8,8.4-5.1,11.3l-26.4,23.4c-5,4.5-8.6,10.3-10.4,16.8 + c-1.7,6.5-1.5,13.4,0.6,19.7l11.2,33.4c1.4,4.1,0.9,8.6-1.2,12.3c-2.2,3.7-5.8,6.4-10,7.2l-34.6,7c-6.6,1.3-12.6,4.6-17.4,9.3 + c-4.8,4.8-8,10.8-9.3,17.4l-7,34.6c-0.9,4.2-3.5,7.9-7.2,10s-8.2,2.6-12.3,1.2l-33.4-11.2c-6.4-2.1-13.2-2.3-19.7-0.6 + c-6.5,1.7-12.3,5.4-16.8,10.4l-23.4,26.4c-2.9,3.2-7,5.1-11.3,5.1s-8.4-1.8-11.3-5.1l-23.4-26.4c-4.5-5-10.3-8.6-16.8-10.4 + c-6.5-1.7-13.4-1.5-19.7,0.6l-33.4,11.2c-4.1,1.4-8.6,0.9-12.3-1.2c-3.7-2.2-6.4-5.8-7.2-10l-7-34.6c-1.3-6.6-4.6-12.6-9.3-17.4 + c-4.8-4.8-10.8-8-17.4-9.3l-34.6-7c-4.2-0.9-7.9-3.5-10-7.2s-2.6-8.2-1.2-12.3l11.2-33.4c2.1-6.4,2.3-13.2,0.6-19.7 + c-1.7-6.5-5.4-12.3-10.4-16.8l-26.4-23.4c-3.2-2.9-5.1-7-5.1-11.3s1.8-8.4,5.1-11.3l26.4-23.4c5-4.5,8.6-10.3,10.4-16.8 + c1.7-6.5,1.5-13.4-0.6-19.7l-11.2-33.4c-1.4-4.1-0.9-8.6,1.2-12.3c2.2-3.7,5.8-6.4,10-7.2l34.6-7c6.6-1.3,12.6-4.6,17.4-9.3 + c4.8-4.8,8-10.8,9.3-17.4l7-34.6c0.9-4.2,3.5-7.9,7.2-10s8.2-2.6,12.3-1.2l33.4,11.2c6.4,2.1,13.2,2.3,19.7,0.6 + c6.5-1.7,12.3-5.4,16.8-10.4L478.7,69.3z M556.8,309.1c-30.7,0-55.7,24.9-55.7,55.7s24.9,55.7,55.7,55.7 + c30.7,0,55.7-24.9,55.7-55.7S587.5,309.1,556.8,309.1z M386.5,417.2l222.6-222.6c4.3-4.3,4.3-11.4,0-15.7s-11.4-4.3-15.7,0 + L370.8,401.5c-4.3,4.3-4.3,11.4,0,15.7C375.2,421.5,382.2,421.5,386.5,417.2z M556.8,331.4c18.4,0,33.4,15,33.4,33.4 + s-15,33.4-33.4,33.4s-33.4-15-33.4-33.4S538.4,331.4,556.8,331.4z M423.2,175.5c-30.7,0-55.7,24.9-55.7,55.7 + c0,30.7,24.9,55.7,55.7,55.7c30.7,0,55.7-24.9,55.7-55.7C478.9,200.5,453.9,175.5,423.2,175.5z M423.2,197.8 + c18.4,0,33.4,15,33.4,33.4s-15,33.4-33.4,33.4s-33.4-15-33.4-33.4S404.8,197.8,423.2,197.8z"/> + </g> +</g> +</svg> diff --git a/src/lib/product/components/Product/Product.jsx b/src/lib/product/components/Product/Product.jsx index 9521cbe4..9649fd21 100644 --- a/src/lib/product/components/Product/Product.jsx +++ b/src/lib/product/components/Product/Product.jsx @@ -29,7 +29,7 @@ const Product = ({ product }) => { return ( <> <ProductMobile product={product} wishlist={wishlist} toggleWishlist={toggleWishlist} /> - <ProductDesktop product={product} wishlist={wishlist} toggleWishlist={toggleWishlist} /> + <ProductDesktop products={product} wishlist={wishlist} toggleWishlist={toggleWishlist} /> </> ) } diff --git a/src/lib/product/components/Product/ProductDesktop.jsx b/src/lib/product/components/Product/ProductDesktop.jsx index d15e84d1..946529ce 100644 --- a/src/lib/product/components/Product/ProductDesktop.jsx +++ b/src/lib/product/components/Product/ProductDesktop.jsx @@ -19,17 +19,19 @@ import PromotionType from '@/lib/promotinProgram/components/PromotionType' import useAuth from '@/core/hooks/useAuth' import odooApi from '@/core/api/odooApi' -const ProductDesktop = ({ product, wishlist, toggleWishlist }) => { +const ProductDesktop = ({ products, wishlist, toggleWishlist }) => { const router = useRouter() const auth = useAuth() const { slug } = router.query + const [quantityActive, setQuantity] = useState(null) const [lowestPrice, setLowestPrice] = useState(null) + const [product, setProducts] = useState(products) const [addCartAlert, setAddCartAlert] = useState(false) const [promotionType, setPromotionType] = useState(false) const [promotionActiveId, setPromotionActiveId] = useState(null) - const [quantity, setQuantity] = useState(null) + const [selectVariantPromoActive, setSelectVariantPromoActive] = useState(null) const getLowestPrice = useCallback(() => { const prices = product.variants.map((variant) => variant.price) @@ -50,11 +52,13 @@ const ProductDesktop = ({ product, wishlist, toggleWishlist }) => { const setVariantQuantityRef = (variantId) => (element) => { if (element) { - setQuantity(element.value) + let variantIndex = product.variants.findIndex((varian) => varian.id == variantId) + product.variants[variantIndex].quantity = element.value } variantQuantityRefs.current[variantId] = element } + const validQuantity = (quantity) => { let isValid = true if (!quantity || quantity < 1 || isNaN(parseInt(quantity))) { @@ -70,13 +74,25 @@ const ProductDesktop = ({ product, wishlist, toggleWishlist }) => { return } const quantity = variantQuantityRefs.current[variantId].value + if (!validQuantity(quantity)) return - updateItemCart({ - productId: variantId, - quantity, - programLineId:promotionActiveId, - selected: true - }) + if(product.variants.length > 1){ + let variantIndex = product.variants.findIndex((varian) => varian.id == variantId) + updateItemCart({ + productId: variantId, + quantity, + programLineId: product.variants[variantIndex].programActive, + selected: true + }) + }{ + updateItemCart({ + productId: variantId, + quantity, + programLineId: promotionActiveId, + selected: true + }) + } + setAddCartAlert(true) } @@ -97,6 +113,11 @@ const ProductDesktop = ({ product, wishlist, toggleWishlist }) => { } } + const handlePromoClick = (variantId) => { + setSelectVariantPromoActive(variantId) + setPromotionType(true) + } + const productSimilarQuery = [ product?.name, `fq=-product_id_i:${product.id}`, @@ -180,7 +201,7 @@ const ProductDesktop = ({ product, wishlist, toggleWishlist }) => { variantId={product.variants[0].id} setPromotionActiveId={setPromotionActiveId} promotionActiveId={promotionActiveId} - quantity={quantity} + quantity={quantityActive} ></PromotionType> </div> </div> @@ -369,30 +390,40 @@ const ProductDesktop = ({ product, wishlist, toggleWishlist }) => { type='number' className='form-input w-16 py-2 text-center bg-gray_r-1' ref={setVariantQuantityRef(variant.id)} + onChange={setVariantQuantityRef(variant.id)} defaultValue={1} /> </td> <td className='flex gap-x-3'> - {index == 0 ? ( + {variant.programActive ? ( <ImageNext src='/images/noun-applied-check2.svg' alt='' height={60} width={60} - onClick={() => setPromotionType(true)} + onClick={() => handlePromoClick(variant.id)} className='cursor-pointer' ></ImageNext> ) : ( - <div className='w-[60px] flex justify-center'> + variant.hasProgram ? ( <div className='w-[60px] flex justify-center'> + <ImageNext + src='/images/noun-discount-5796402.svg' + alt='' + height={30} + width={30} + onClick={() => handlePromoClick(variant.id)} + className='cursor-pointer' + ></ImageNext> + </div>):( <div className='w-[60px] flex justify-center'> <ImageNext - src='/images/noun-discount-5796402.svg' + src='/images/noun-discount-57964023.svg' alt='' height={30} width={30} - onClick={() => setPromotionType(true)} className='cursor-pointer' ></ImageNext> - </div> + </div>) + )} <button type='button' @@ -430,7 +461,15 @@ const ProductDesktop = ({ product, wishlist, toggleWishlist }) => { close={() => setPromotionType(false)} > <div className='flex mt-4'> - <PromotionType isModal={true} ></PromotionType> + <PromotionType + isModal={true} + variantId={selectVariantPromoActive} + setPromotionActiveId={setPromotionActiveId} + promotionActiveId={promotionActiveId} + quantity={quantityActive} + product={product} + setProducts={setProducts} + ></PromotionType> </div> </BottomPopup> <BottomPopup diff --git a/src/lib/promotinProgram/components/PromotionType.jsx b/src/lib/promotinProgram/components/PromotionType.jsx index 0e36d2c1..44d1b524 100644 --- a/src/lib/promotinProgram/components/PromotionType.jsx +++ b/src/lib/promotinProgram/components/PromotionType.jsx @@ -11,13 +11,16 @@ const PromotionType = ({ variantId, setPromotionActiveId, promotionActiveId, - quantity + quantity, + product = null, + setProducts = null }) => { const [selectedPromo, setSelectedPromo] = useState(null) const [promotionType, setPromotionType] = useState(false) const [promos, setPromotionList] = useState(null) const [activeTitle, setActiveTitle] = useState(null) + const [quantitySet, setQuantity] = useState(quantity) useEffect(() => { const id = variantId @@ -30,6 +33,10 @@ const PromotionType = ({ } listProgram() setSelectedPromo(promotionActiveId) + if (product) { + const variant = product.variants.find((variant) => variant.id === variantId) + setQuantity(variant.quantity) + } }, []) const groupingData = promos?.reduce((groups, item) => { @@ -43,13 +50,31 @@ const PromotionType = ({ }, {}) const handlePromoClick = (promoId, minQty) => { - if (quantity >= minQty) { + if (quantitySet >= minQty) { if (promoId == selectedPromo) { setSelectedPromo(null) setPromotionActiveId(null) + if (product) { + const updateProdcuts = () => { + let variantIndex = product.variants.findIndex((varian) => varian.id == variantId) + product.variants[variantIndex].programActive = null + + setProducts(product) + } + updateProdcuts() + } } else { setSelectedPromo(promoId) setPromotionActiveId(promoId) + if (product) { + const updateProdcuts = () => { + let variantIndex = product.variants.findIndex((varian) => varian.id == variantId) + product.variants[variantIndex].programActive = promoId + + setProducts(product) + } + updateProdcuts() + } } } } @@ -108,7 +133,9 @@ const PromotionType = ({ : 'opacity-50 pointer-events-none' : 'opacity-100' } ${ - quantity >= item.minimumPurchaseQty ? '' : 'opacity-50 pointer-events-none' + quantitySet >= item.minimumPurchaseQty + ? '' + : 'opacity-50 pointer-events-none' } `} > <div className={`flex`}> @@ -130,20 +157,30 @@ const PromotionType = ({ </div> <p className='text-justify text-gray-500 line-clamp-3'>{item.name}</p> <div className='mt-4'> - {item.type.value === 'bundling' && ( - <> - <div className='flex gap-x-2 mt-3 items-center'> - <div className='text-danger-500 font-semibold '>Gratis</div> - <div className='text-gray_r-11 line-through text-caption-1 mt-1'> - {currencyFormat(item.price.priceDiscount)} + {/* {item.type.value === 'bundling' && ( + <> */} + <div className='flex gap-x-2 mt-3 justify-between items-center'> + <div className='flex gap-x-2 items-center '> + <div className='text-gray_r-11 line-through text-caption-1 mt-1'> + {currencyFormat(item.totalSavings)} + </div> + <div className='text-danger-500 font-semibold '>Gratis</div> + </div> + <div className='text-danger-500 font-semibold '> + {quantitySet < item.minimumPurchaseQty + ? 'Tambah ' + + (parseInt(item.minimumPurchaseQty) - + parseInt(quantitySet)) + + ' lagi' + : ''} </div> </div> - </> - )} - {item.type.value === 'special_price' && ( + {/* </> + )} */} + {/* {item.type.value === 'special_price' && ( <> <div className='flex gap-x-2 mt-3 items-center'> - <div className='text-danger-500 font-semibold '> {currencyFormat(item.price.priceDiscount)}</div> + <div className='text-danger-500 font-semibold '> {currencyFormat(item.totalSavings)}</div> </div> </> )} @@ -151,18 +188,19 @@ const PromotionType = ({ <> <div className='flex justify-between'> <div className='text-danger-500 font-semibold '> - {currencyFormat(item.price.priceDiscount)} + {currencyFormat(item.totalSavings)} </div> <div className='text-danger-500 font-semibold '> - {quantity < item.minimumPurchaseQty + {quantitySet < item.minimumPurchaseQty ? 'Tambah ' + - (parseInt(item.minimumPurchaseQty) - parseInt(quantity)) + + (parseInt(item.minimumPurchaseQty) - + parseInt(quantitySet)) + ' lagi' : ''} </div> </div> </> - )} + )} */} </div> </div> </div> @@ -224,7 +262,7 @@ const PromotionType = ({ <div className='badge-yellow text-black mb-1'>{promo.type.label}</div> <p className='text-justify line-clamp-2'>{promo.name}</p> <div className='text-danger-500 font-semibold mb-1 mt-1'> - {currencyFormat(promo.price.priceDiscount)} + {/* {currencyFormat(promo.totalSavings)} */} </div> {/* <div className='w-full bg-yellow-200 rounded-full h-1.5 mb-2'> <div className='bg-yellow-500 h-1.5 rounded-full w-[45%]'></div> @@ -252,7 +290,7 @@ const PromotionType = ({ variantId={variantId} setPromotionActiveId={setPromotionActiveId} promotionActiveId={promotionActiveId} - quantity={quantity} + quantity={quantitySet} ></PromotionType> </div> </BottomPopup> |
