diff options
Diffstat (limited to 'src/core')
| -rw-r--r-- | src/core/components/elements/Product/cartProductsList.jsx | 267 |
1 files changed, 267 insertions, 0 deletions
diff --git a/src/core/components/elements/Product/cartProductsList.jsx b/src/core/components/elements/Product/cartProductsList.jsx new file mode 100644 index 00000000..5887b425 --- /dev/null +++ b/src/core/components/elements/Product/cartProductsList.jsx @@ -0,0 +1,267 @@ +import Link from '@/core/components/elements/Link/Link' +import Image from '@/core/components/elements/Image/Image' +import LogoSpinner from '../Spinner/LogoSpinner' +import { TrashIcon } from '@heroicons/react/24/outline' +import { useEffect } from 'react' +import { createSlug } from '@/core/utils/slug' +import currencyFormat from '@/core/utils/currencyFormat' + +const CardProdcuctsList = ({ + isLoading, + products, + source, + handlePopUpPromo = () => {}, + toggleSelected = () => {}, + updateQuantity = () => {}, + setDeleteConfirmation = () => {} +}) => { + + return ( + <table className='table-cart'> + <thead> + <tr> + <th colSpan={2}>Nama Produk</th> + <th>Jumlah</th> + <th>Harga</th> + <th>Subtotal</th> + {source == 'cart' && <th>Action</th>} + </tr> + </thead> + <tbody> + {isLoading && ( + <tr> + <td colSpan={6}> + <div className='container flex justify-center my-4'> + <LogoSpinner width={48} height={48} /> + </div> + </td> + </tr> + )} + {!isLoading && (!products || products?.length == 0) && ( + <tr> + <td colSpan={6}>Keranjang belanja anda masih kosong</td> + </tr> + )} + {products && + products?.map((product) => ( + <> + {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'> + {product.program ? ( + <> + <div className='flex border border-solid border-red-600 rounded-md p-1'> + <span className='text-red-600'>{product.program.type.label}</span> + </div> + <div className='flex'> + {product.program.type.value == 'merchandise' ? ( + <>Selamat anda mendapatkan merchandise indoteknik.com</> + ) : ( + <> + Selamat! Pembelian anda lebih hemat + <span className='text-red-600 font-semibold ml-2'> + {' '} + {currencyFormat(product.program?.totalSavings)} + </span> + </> + )} + </div> + </> + ) : ( + <> + <div className='flex border border-solid border-red-600 rounded-md p-1'> + <span className='text-red-600'>Promo</span> + </div> + <div className='flex'>Pilih Promo Yang Tersedia Bisa lebih Hemat</div> + </> + )} + <div + onClick={() => + handlePopUpPromo(product.id, product.quantity, product.program?.id) + } + className='ml-auto text-red-500 flex gap-x-1 cursor-pointer' + > + <div className='font-semibold'> Cek Promo</div> + <div> + <svg + aria-hidden='true' + fill='none' + stroke='currentColor' + stroke-width='1.5' + viewBox='0 0 20 24' + className='h-5 w-5 font-semibold' + > + <path + d='M8.25 4.5l7.5 7.5-7.5 7.5' + stroke-linecap='round' + stroke-linejoin='round' + ></path> + </svg> + </div> + </div> + </div> + </td> + </tr> + )} + <tr + key={product.id} + className={`${product.hasProgram ? '!border-t-0 !border-b-0' : ''}`} + > + <td className='relative'> + {source == 'cart' && ( + <> + <ComponentCanBuy canBuy={product.canBuy} /> + <input + type='checkbox' + onClick={() => toggleSelected(product.id)} + checked={product?.selected} + className='accent-danger-500 w-4' + /> + </> + )} + </td> + <td className='flex relative'> + <ComponentCanBuy canBuy={product.canBuy} /> + <Link + href={createSlug('/shop/product/', product?.parent.name, product?.parent.id)} + 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-28 w-full rounded-md' + /> + </Link> + <div className='px-2 text-left'> + <Link + href={createSlug('/shop/product/', product?.parent.name, product?.parent.id)} + className='line-clamp-2 leading-6 !text-gray_r-12 font-normal' + > + {product?.parent?.name} + </Link> + <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> + </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={product?.quantity} + disabled={source === 'cart' ? false : true} + onChange={(e) => updateQuantity(e.target.value, product?.id)} + onBlur={(e) => updateQuantity(e.target.value, product?.id, 'BLUR')} + /> + </td> + <td className='relative'> + <ComponentCanBuy canBuy={product.canBuy} /> + {product?.hasFlashsale ? ( + <> + <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 className='font-normal mt-1'> + {currencyFormat(product?.price?.priceDiscount)} + </div> + </> + ) : ( + <div className='font-normal mt-1'>{currencyFormat(product?.price?.price)}</div> + )} + </td> + <td className='relative'> + <ComponentCanBuy canBuy={product.canBuy} /> + <div className='text-danger-500 font-medium'> + {currencyFormat(product?.price?.priceDiscount * product?.quantity)} + </div> + </td> + {source == 'cart' && ( + <td> + <div className='flex justify-center items-center h-full'> + <button + className='btn-red p-1 ml-1' + onClick={() => setDeleteConfirmation(product)} + > + <TrashIcon className='w-4' /> + </button> + </div> + </td> + )} + </tr> + {/* Component for promotion program product */} + {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 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> + )} + </> + ))} + </tbody> + </table> + ) +} + +const ComponentCanBuy = ({ canBuy }) => + !canBuy && <div className='absolute w-full h-full bg-gray_r-3/40 top-0 left-0' /> + +export default CardProdcuctsList |
