diff options
Diffstat (limited to 'src/lib')
| -rw-r--r-- | src/lib/cart/components/Cart.jsx | 149 | ||||
| -rw-r--r-- | src/lib/checkout/components/Checkout.jsx | 194 | ||||
| -rw-r--r-- | src/lib/variant/components/VariantGroupCard.jsx | 67 |
3 files changed, 283 insertions, 127 deletions
diff --git a/src/lib/cart/components/Cart.jsx b/src/lib/cart/components/Cart.jsx index 45f2f770..f1584f98 100644 --- a/src/lib/cart/components/Cart.jsx +++ b/src/lib/cart/components/Cart.jsx @@ -59,7 +59,8 @@ const Cart = () => { ) setProducts(updatedProducts) } - processProducts() + // processProducts() + setProducts(cart.products) setIsLoading(false) } }, [cart]) @@ -86,6 +87,10 @@ const Cart = () => { if (product.quantity == '') continue if (!product.selected) continue + + if (product.canBuy == false) { + toggleSelected(product.id) + } let priceBeforeTax = product.price.price / 1.11 calculateTotalPriceBeforeTax += priceBeforeTax * product.quantity calculateTotalTaxAmount += (product.price.price - priceBeforeTax) * product.quantity @@ -153,7 +158,12 @@ const Cart = () => { productsToUpdate[productIndex].quantity = qty setProducts([...productsToUpdate]) - addCart(productId, qty, productsToUpdate[productIndex].selected) + addCart( + productId, + qty, + productsToUpdate[productIndex].selected, + productsToUpdate[productIndex].program?.id + ) } const toggleSelected = (productId) => { @@ -165,7 +175,12 @@ const Cart = () => { productsToUpdate[productIndex].selected = isSelected setProducts([...productsToUpdate]) - addCart(productId, productsToUpdate[productIndex].quantity, isSelected) + addCart( + productId, + productsToUpdate[productIndex].quantity, + isSelected, + productsToUpdate[productIndex].program?.id + ) } const selectedProduct = () => { @@ -259,7 +274,7 @@ const Cart = () => { {products && products?.map((product) => ( <> - {product.isPromo > 0 && ( + {product.hasProgram > 0 && ( <div className='flex gap-x-2 bg-yellow-100 p-2 items-center'> {product.program ? ( <> @@ -470,7 +485,7 @@ const Cart = () => { {products && products?.map((product) => ( <> - {product.isPromo > 0 && ( + {product.hasProgram && ( <tr className='!border-b-0 pb-0'> <td colSpan={6}> <div className='flex gap-x-2 bg-yellow-100 p-2 items-center'> @@ -489,7 +504,7 @@ const Cart = () => { Selamat! Pembelian anda lebih hemat <span className='text-red-600 font-semibold ml-2'> {' '} - {currencyFormat(product.program.price.priceDiscount)} + {currencyFormat(product.program?.totalSavings)} </span> </> )} @@ -539,9 +554,10 @@ const Cart = () => { )} <tr key={product.id} - className={`${product.isPromo ? '!border-t-0 !border-b-0' : ''}`} + className={`${product.hasProgram ? '!border-t-0 !border-b-0' : ''}`} > - <td> + <td className='relative'> + <ComponentCanBuy canBuy={product.canBuy} /> <input type='checkbox' onClick={() => toggleSelected(product.id)} @@ -549,7 +565,8 @@ const Cart = () => { className='accent-danger-500 w-4' /> </td> - <td className='flex'> + <td className='flex relative'> + <ComponentCanBuy canBuy={product.canBuy} /> <Link href={createSlug( '/shop/product/', @@ -583,7 +600,8 @@ const Cart = () => { </div> </div> </td> - <td> + <td className='relative'> + <ComponentCanBuy canBuy={product.canBuy} /> <input className='form-input w-16 py-2 text-center bg-gray_r-1' type='number' @@ -592,7 +610,8 @@ const Cart = () => { onBlur={(e) => updateQuantity(e.target.value, product?.id, 'BLUR')} /> </td> - <td> + <td className='relative'> + <ComponentCanBuy canBuy={product.canBuy} /> {product?.price?.discountPercentage > 0 && ( <div className='flex gap-x-1 items-center justify-center mt-3'> <div className='text-gray_r-11 line-through text-caption-1'> @@ -607,7 +626,8 @@ const Cart = () => { {currencyFormat(product?.price?.priceDiscount)} </div> </td> - <td> + <td className='relative'> + <ComponentCanBuy canBuy={product.canBuy} /> <div className='text-danger-500 font-medium'> {currencyFormat(product?.price?.priceDiscount * product?.quantity)} </div> @@ -623,54 +643,62 @@ const Cart = () => { </div> </td> </tr> - {product.program && ( - <tr key={product?.program?.id} className='!border-t-0'> - <td></td> - <td className='flex'> - <div className='w-[20%] flex-shrink-0'> - <Image - src={product.program.image} - alt={product.program.name} - className='object-contain object-center border border-gray_r-6 h-28 w-full rounded-md' - /> - </div> - <div className='px-2 text-left'> - <div className=''> - <span className='border border-solid border-red-600 rounded-md p-1 text-red-600'> - {product.program.type.label} - </span> - </div> - <div className='mt-2 line-clamp-2 leading-6'> - {product.program.name} - </div> - </div> - </td> - <td> - <input - className='form-input w-16 py-2 text-center bg-gray_r-1' - type='number' - value={1} - disabled - /> - </td> - <td> - {product?.price?.discountPercentage > 0 && ( - <div className='flex gap-x-1 items-center justify-center mt-3'> - <div className='text-gray_r-11 line-through text-caption-1'> - {currencyFormat(product?.price?.price)} + {product?.program?.items && ( + <tr key={product.program.id} className='!border-t-0'> + {product.program.items.map((item) => ( + <> + <td className='relative'> + <ComponentCanBuy canBuy={product.canBuy} /> + </td> + <td className='flex relative'> + <ComponentCanBuy canBuy={product.canBuy} /> + <div className='w-[20%] flex-shrink-0'> + <Image + src={item.parent.image} + alt={item.name} + className='object-contain object-center border border-gray_r-6 h-28 w-full rounded-md' + /> </div> - </div> - )} - <div className='font-normal mt-1'> - {product?.program?.price.priceDiscount > 0 ? 'Gratis' : ''} - </div> - </td> - <td> - <div className='text-danger-500 font-medium'> - {product.program.price.priceDiscount > 0 ? 'Gratis' : ''} - </div> - </td> - <td></td> + <div className='px-2 text-left'> + <div className=''> + <span className='border border-solid border-red-600 rounded-md p-1 text-red-600'> + {product.program.type.label} + </span> + </div> + <div className='mt-2 line-clamp-2 leading-6'>{item.name}</div> + </div> + </td> + <td className='relative'> + <ComponentCanBuy canBuy={product.canBuy} /> + <input + className='form-input w-16 py-2 text-center bg-gray_r-1' + type='number' + value={1} + disabled + /> + </td> + <td className='relative'> + <ComponentCanBuy canBuy={product.canBuy} /> + {item?.price?.discountPercentage > 0 && ( + <div className='flex gap-x-1 items-center justify-center mt-3'> + <div className='text-gray_r-11 line-through text-caption-1'> + {currencyFormat(product?.price?.price)} + </div> + </div> + )} + <div className='font-normal mt-1'> + {item?.price.priceDiscount > 0 ? 'Gratis' : ''} + </div> + </td> + <td className='relative'> + <ComponentCanBuy canBuy={product.canBuy} /> + <div className='text-danger-500 font-medium'> + {item.price.priceDiscount > 0 ? 'Gratis' : ''} + </div> + </td> + <td></td> + </> + ))} </tr> )} </> @@ -747,4 +775,7 @@ const Cart = () => { ) } +const ComponentCanBuy = ({ canBuy }) => + !canBuy && <div className='absolute w-full h-full bg-gray_r-3/40 top-0 left-0' /> + export default Cart diff --git a/src/lib/checkout/components/Checkout.jsx b/src/lib/checkout/components/Checkout.jsx index 09fdbd86..0eaab020 100644 --- a/src/lib/checkout/components/Checkout.jsx +++ b/src/lib/checkout/components/Checkout.jsx @@ -289,8 +289,8 @@ const Checkout = () => { <div className='flex gap-x-2 justify-between mb-4'> <div>Grand Total</div> <div className='font-semibold text-gray_r-12'> - {currencyFormat(cartCheckout?.grandTotal + - Math.round(parseInt(biayaKirim * 1.1) / 1000) * 1000 + {currencyFormat( + cartCheckout?.grandTotal + Math.round(parseInt(biayaKirim * 1.1) / 1000) * 1000 )} </div> </div> @@ -398,73 +398,131 @@ const Checkout = () => { </thead> <tbody> {products?.map((product) => ( - <tr key={product.id}> - <td className='flex'> - <div className='w-[20%] flex-shrink-0'> - <Image - src={product?.parent?.image} - alt={product?.name} - className='object-contain object-center border border-gray_r-6 h-40 w-full rounded-md' - /> - </div> - <div className='px-2 text-left'> - <div className='line-clamp-2 leading-6 !text-gray_r-12 font-normal'> - {product?.parent?.name} - </div> - <div className='text-gray_r-11 mt-2'> - {product?.code}{' '} - {product?.attributes.length > 0 - ? `| ${product?.attributes.join(', ')}` - : ''} - </div> - <div className='text-gray_r-11 mt-2'> - Berat item : {product?.weight} Kg + <> + <tr + key={product.id} + className={`${product.program ? '!border-t-0 !border-b-0' : ''}`} + > + <td className='flex'> + <div className='w-[20%] flex-shrink-0'> + <Image + src={product?.parent?.image} + alt={product?.name} + className='object-contain object-center border border-gray_r-6 h-40 w-full rounded-md' + /> </div> - </div> - </td> - <td> - <input - className='form-input w-16 py-2 text-center bg-gray_r-1' - type='number' - value={product?.quantity} - disabled - /> - </td> - <td> - {product?.price?.discountPercentage > 0 && ( - <div className='flex gap-x-1 items-center justify-center mt-3'> - <div className='text-gray_r-11 line-through text-caption-1'> - {currencyFormat(product?.price?.price)} + <div className='px-2 text-left'> + <div className='line-clamp-2 leading-6 !text-gray_r-12 font-normal'> + {product?.parent?.name} </div> - <div className='badge-solid-red'> - {product?.price?.discountPercentage}% + <div className='text-gray_r-11 mt-2'> + {product?.code}{' '} + {product?.attributes.length > 0 + ? `| ${product?.attributes.join(', ')}` + : ''} + </div> + <div className='text-gray_r-11 mt-2'> + Berat item : {product?.weight} Kg </div> </div> - )} - <div className='font-normal mt-1'> - {product.price.priceDiscount > 0 - ? currencyFormat(product?.price?.priceDiscount) - : 'Call For Price'} - </div> - </td> - <td> - <div className='text-danger-500 font-medium'> - {product.price.priceDiscount > 0 ? ( - currencyFormat(product?.price?.priceDiscount * product?.quantity) - ) : ( - <a - href={whatsappUrl('product', { - name: product.name, - url: createSlug('/shop/product/', product.name, product.id, true) - })} - className='underline' - > - Call For Price{' '} - </a> + </td> + <td> + <input + className='form-input w-16 py-2 text-center bg-gray_r-1' + type='number' + value={product?.quantity} + disabled + /> + </td> + <td> + {product?.price?.discountPercentage > 0 && ( + <div className='flex gap-x-1 items-center justify-center mt-3'> + <div className='text-gray_r-11 line-through text-caption-1'> + {currencyFormat(product?.price?.price)} + </div> + <div className='badge-solid-red'> + {product?.price?.discountPercentage}% + </div> + </div> )} - </div> - </td> - </tr> + <div className='font-normal mt-1'> + {product.price.priceDiscount > 0 + ? currencyFormat(product?.price?.priceDiscount) + : 'Call For Price'} + </div> + </td> + <td> + <div className='text-danger-500 font-medium'> + {product.price.priceDiscount > 0 ? ( + currencyFormat(product?.price?.priceDiscount * product?.quantity) + ) : ( + <a + href={whatsappUrl('product', { + name: product.name, + url: createSlug('/shop/product/', product.name, product.id, true) + })} + className='underline' + > + Call For Price{' '} + </a> + )} + </div> + </td> + </tr> + {product.program && + product.program.items && + product.program.items.map((item) => ( + <> + <tr key={product?.program?.id} className='!border-t-0'> + <td className='flex'> + <div className='w-[20%] flex-shrink-0'> + <Image + src={item.parent.image} + alt={item.name} + className='object-contain object-center border border-gray_r-6 h-40 w-full rounded-md' + /> + </div> + <div className='px-2 text-left'> + <div className=''> + <span className='border border-solid border-red-600 rounded-md p-1 text-red-600'> + {product.program.type.label} + </span> + </div> + <div className='mt-2 line-clamp-2 leading-6'> + {item.name} + </div> + </div> + </td> + <td> + <input + className='form-input w-16 py-2 text-center bg-gray_r-1' + type='number' + value={1} + disabled + /> + </td> + <td> + {item?.price?.discountPercentage > 0 && ( + <div className='flex gap-x-1 items-center justify-center mt-3'> + <div className='text-gray_r-11 line-through text-caption-1'> + {currencyFormat(product?.price?.price)} + </div> + </div> + )} + <div className='font-normal mt-1'> + {item?.price.priceDiscount > 0 ? 'Gratis' : ''} + </div> + </td> + <td> + <div className='text-danger-500 font-medium'> + {item.price.priceDiscount > 0 ? 'Gratis' : ''} + </div> + </td> + <td></td> + </tr> + </> + ))} + </> ))} </tbody> </table> @@ -487,7 +545,9 @@ const Checkout = () => { </div> <div className='flex gap-x-2 justify-between'> <div className='text-gray_r-11'>Total Diskon</div> - <div className='text-danger-500'>- {currencyFormat(cartCheckout?.totalDiscount)}</div> + <div className='text-danger-500'> + - {currencyFormat(cartCheckout?.totalDiscount)} + </div> </div> <div className='flex gap-x-2 justify-between'> <div className='text-gray_r-11'>Subtotal</div> @@ -511,8 +571,8 @@ const Checkout = () => { <div className='flex gap-x-2 justify-between mb-4'> <div>Grand Total</div> <div className='font-semibold text-gray_r-12'> - {currencyFormat(cartCheckout?.grandTotal + - Math.round(parseInt(biayaKirim * 1.1) / 1000) * 1000 + {currencyFormat( + cartCheckout?.grandTotal + Math.round(parseInt(biayaKirim * 1.1) / 1000) * 1000 )} </div> </div> diff --git a/src/lib/variant/components/VariantGroupCard.jsx b/src/lib/variant/components/VariantGroupCard.jsx index 8cb1eec4..aba6971f 100644 --- a/src/lib/variant/components/VariantGroupCard.jsx +++ b/src/lib/variant/components/VariantGroupCard.jsx @@ -1,14 +1,79 @@ import { useState } from 'react' import VariantCard from './VariantCard' +import Image from '@/core/components/elements/Image/Image' +import currencyFormat from '@/core/utils/currencyFormat' const VariantGroupCard = ({ variants, ...props }) => { + console.log('variant', variants) const [showAll, setShowAll] = useState(false) const variantsToShow = showAll ? variants : variants.slice(0, 2) return ( <> {variantsToShow?.map((variant, index) => ( - <VariantCard key={index} product={variant} {...props} /> + <> + <VariantCard key={index} product={variant} {...props} /> + {variant.program && + variant.program.items && + variant.program.items.map((item) => ( + <div key={item.id}> + <div className='flex gap-x-3'> + <div className='w-4/12 flex items-center gap-x-2'> + <Image + src={item.parent.image} + alt={item.name} + className='object-contain object-center border border-gray_r-6 h-32 w-full rounded-md' + /> + </div> + <div className='w-8/12 flex flex-col'> + <p className='product-card__title wrap-line-ellipsis-2'> + {item.name} + </p> + <p className='text-caption-2 text-gray_r-11 mt-1'> + {/* {product.code || '-'} + {product.attributes.length > 0 ? ` ・ ${product.attributes.join(', ')}` : ''} */} + </p> + <p className='text-caption-2 text-gray_r-11 mt-1'> + Berat Item : {item.weight} Kg + </p> + <div className='flex flex-wrap gap-x-1 items-center mt-auto'> + {item.price.discountPercentage > 0 && ( + <> + <p className='text-caption-2 text-gray_r-11 line-through'> + {currencyFormat(item.price.price)} + </p> + <span className='badge-red'>{item.price.discountPercentage}%</span> + </> + )} + </div> + <p className='text-caption-2 text-gray_r-11 mt-1'> + {item.price.priceDiscount > 0 + ? currencyFormat(item.price.priceDiscount) + + ' × ' + + item.quantity + + ' Barang' + : ''} + </p> + <p className='text-caption-2 text-gray_r-12 font-bold mt-2'> + {item.price.priceDiscount > 0 ? ( + currencyFormat(item.quantity * item.price.priceDiscount) + ) : ( + <a + href={whatsappUrl('product', { + name: item.name, + url: createSlug('/shop/product/', item.name, item.id, true) + })} + className='underline text-danger-500' + > + Call For Price{' '} + </a> + )} + </p> + </div> + </div> + </div> + ))} + </> ))} {variants.length > 2 && ( <button |
