diff options
| author | it-fixcomart <it@fixcomart.co.id> | 2024-06-21 11:01:35 +0700 |
|---|---|---|
| committer | it-fixcomart <it@fixcomart.co.id> | 2024-06-21 11:01:35 +0700 |
| commit | 220190db66bcc1c6db78180c593f21e9cf8f363c (patch) | |
| tree | 1517faa9636a6b3b2cc8d468a57b1fe476c229d7 /src-migrate/modules/cart | |
| parent | 208b234320b6c42491a4e87a1c3db3abab9c1715 (diff) | |
| parent | 1cf754b4d8da1aa28700ffc3dad67081f6daf9a5 (diff) | |
Merge branch 'promotion-program' into feature/all-promotion
Diffstat (limited to 'src-migrate/modules/cart')
| -rw-r--r-- | src-migrate/modules/cart/components/CartSummaryMobile.tsx | 111 | ||||
| -rw-r--r-- | src-migrate/modules/cart/components/Item.tsx | 83 | ||||
| -rw-r--r-- | src-migrate/modules/cart/components/ItemAction.tsx | 8 | ||||
| -rw-r--r-- | src-migrate/modules/cart/components/ItemPromo.tsx | 12 | ||||
| -rw-r--r-- | src-migrate/modules/cart/components/ItemSelect.tsx | 8 |
5 files changed, 197 insertions, 25 deletions
diff --git a/src-migrate/modules/cart/components/CartSummaryMobile.tsx b/src-migrate/modules/cart/components/CartSummaryMobile.tsx new file mode 100644 index 00000000..d9f72e0e --- /dev/null +++ b/src-migrate/modules/cart/components/CartSummaryMobile.tsx @@ -0,0 +1,111 @@ +import style from '../styles/summary.module.css'; + +import React, { useState } from 'react'; +import formatCurrency from '~/libs/formatCurrency'; +import clsxm from '~/libs/clsxm'; +import { Button, Skeleton } from '@chakra-ui/react'; +import _ from 'lodash'; +import { ChevronDownIcon } from '@heroicons/react/24/outline'; +import BottomPopup from '@/core/components/elements/Popup/BottomPopup'; +import useDevice from '@/core/hooks/useDevice'; + +type Props = { + total?: number; + discount?: number; + subtotal?: number; + tax?: number; + shipping?: number; + grandTotal?: number; + isLoaded: boolean; +}; + +const CartSummaryMobile = ({ + total, + discount, + subtotal, + tax, + shipping, + grandTotal, + isLoaded = false, +}: Props) => { + const [showPopup, setShowPopup] = useState(false); + return ( + <> + <BottomPopup + className=' !h-[35%]' + title='Ringkasan Pensanan' + active={showPopup} + close={() => setShowPopup(false)} + > + <div className='mt-4'> + <div className='flex flex-col gap-y-3'> + <Skeleton isLoaded={isLoaded} className={style.line}> + <span className={style.label}>Total Belanja</span> + <span className={style.value}> + Rp {formatCurrency(subtotal || 0)} + </span> + </Skeleton> + + <Skeleton isLoaded={isLoaded} className={style.line}> + <span className={style.label}>Total Diskon</span> + <span className={clsxm(style.value, style.discount)}> + - Rp {formatCurrency(discount || 0)} + </span> + </Skeleton> + + <div className={style.divider} /> + + <Skeleton isLoaded={isLoaded} className={style.line}> + <span className={style.label}>Subtotal</span> + <span className={style.value}> + Rp {formatCurrency(total || 0)} + </span> + </Skeleton> + + <Skeleton isLoaded={isLoaded} className={style.line}> + <span className={style.label}>Tax 11%</span> + <span className={style.value}>Rp {formatCurrency(tax || 0)}</span> + </Skeleton> + + <Skeleton isLoaded={isLoaded} className={style.line}> + <span className={style.label}>Biaya Kirim</span> + <span className={style.value}> + Rp {formatCurrency(shipping || 0)} + </span> + </Skeleton> + + <div className={style.divider} /> + <Skeleton isLoaded={isLoaded} className={style.line}> + <span className={clsxm(style.label, style.grandTotal)}> + Grand Total + </span> + <span className={style.value}> + Rp {formatCurrency(grandTotal || 0)} + </span> + </Skeleton> + </div> + </div> + </BottomPopup> + <div className='flex flex-col gap-y-3'> + <Skeleton isLoaded={isLoaded} className={style.line}> + <span className={clsxm(style.label, style.grandTotal)}> + Grand Total + </span> + <button + onClick={() => setShowPopup(true)} + className='bg-gray-300 w-6 h-6 items-center justify-center cursor-pointer hover:bg-red-400 md:hidden ' + > + <ChevronDownIcon className='h-6 w-6 text-white' /> + </button> + </Skeleton> + <Skeleton isLoaded={isLoaded} className={style.line}> + <span className={style.value}> + Rp {formatCurrency(grandTotal || 0)} + </span> + </Skeleton> + </div> + </> + ); +}; + +export default CartSummaryMobile; diff --git a/src-migrate/modules/cart/components/Item.tsx b/src-migrate/modules/cart/components/Item.tsx index 48e568e0..6ded6373 100644 --- a/src-migrate/modules/cart/components/Item.tsx +++ b/src-migrate/modules/cart/components/Item.tsx @@ -1,17 +1,17 @@ import style from '../styles/item.module.css' -import Image from 'next/image' -import React from 'react' import { Skeleton, SkeletonProps, Tooltip } from '@chakra-ui/react' import { InfoIcon } from 'lucide-react' +import Image from 'next/image' +import Link from 'next/link' import { PROMO_CATEGORY } from '~/constants/promotion' - import formatCurrency from '~/libs/formatCurrency' +import { createSlug } from '~/libs/slug' import { CartItem as CartItemProps } from '~/types/cart' -import CartItemPromo from './ItemPromo' import CartItemAction from './ItemAction' +import CartItemPromo from './ItemPromo' import CartItemSelect from './ItemSelect' type Props = { @@ -20,8 +20,6 @@ type Props = { } const CartItem = ({ item, editable = true }: Props) => { - const image = item?.image || item?.parent?.image - return ( <div className={style.wrapper}> {item.cart_type === 'promotion' && ( @@ -47,13 +45,12 @@ const CartItem = ({ item, editable = true }: Props) => { <div className={style.mainProdWrapper}> {editable && <CartItemSelect item={item} />} <div className='w-4' /> - <div className={style.image}> - {image && <Image src={image} alt={item.name} width={128} height={128} />} - {!image && <div className={style.noImage}>No Image</div>} - </div> + + <CartItem.Image item={item} /> <div className={style.details}> - <div className={style.name}>{item.name}</div> + <CartItem.Name item={item} /> + <div className='mt-2 flex justify-between w-full'> <div className='flex flex-col gap-y-1'> {item.cart_type === 'promotion' && ( @@ -68,18 +65,22 @@ const CartItem = ({ item, editable = true }: Props) => { )} {item.cart_type === 'product' && ( - <> + <div className={style.discPriceSection}> + {item.price.discount_percentage > 0 && ( + <span className={style.priceBefore}> + Rp {formatCurrency((item.price.price || 0))} + </span> + )} + <div className={style.price}> - {item.price.price > 0 && `Rp ${formatCurrency(item.price.price)}`} - {item.price.price === 0 && '-'} + {item.price.price_discount > 0 && `Rp ${formatCurrency(item.price.price_discount)}`} + {item.price.price_discount === 0 && '-'} </div> - <div>{item.code}</div> - </> + </div> )} - <div> - {item.weight} Kg - </div> + <div>{item.cart_type === 'product' && item.code}</div> + <div>{Math.round(item.weight * 10) / 10} Kg</div> </div> {editable && <CartItemAction item={item} />} @@ -97,6 +98,50 @@ const CartItem = ({ item, editable = true }: Props) => { ) } +CartItem.Image = function CartItemImage({ item }: { item: CartItemProps }) { + const image = item?.image || item?.parent?.image + + return ( + <> + {item.cart_type === 'promotion' && ( + <div className={style.image}> + {image && <Image src={image} alt={item.name} width={128} height={128} />} + {!image && <div className={style.noImage}>No Image</div>} + </div> + )} + + {item.cart_type === 'product' && ( + <Link + href={createSlug('/shop/product/', item.parent.name, item.parent.id.toString())} + className={style.image} + > + {image && <Image src={image} alt={item.name} width={128} height={128} />} + {!image && <div className={style.noImage}>No Image</div>} + </Link> + )} + </> + ) +} + +CartItem.Name = function CartItemName({ item }: { item: CartItemProps }) { + return ( + <> + {item.cart_type === 'promotion' && ( + <div className={style.name}>{item.name}</div> + )} + + {item.cart_type === 'product' && ( + <Link + href={createSlug('/shop/product/', item.parent.name, item.parent.id.toString())} + className={style.name} + > + {item.name} + </Link> + )} + </> + ) +} + CartItem.Skeleton = function CartItemSkeleton(props: SkeletonProps & { count: number }) { return Array.from({ length: props.count }).map((_, index) => ( <Skeleton key={index} diff --git a/src-migrate/modules/cart/components/ItemAction.tsx b/src-migrate/modules/cart/components/ItemAction.tsx index 859c758c..e73d507b 100644 --- a/src-migrate/modules/cart/components/ItemAction.tsx +++ b/src-migrate/modules/cart/components/ItemAction.tsx @@ -51,7 +51,13 @@ const CartItemAction = ({ item }: Props) => { if (typeof auth !== 'object' || isNaN(debounceQty)) return setIsLoadQuantity(true) - await upsertUserCart(auth.id, item.cart_type, item.id, debounceQty, item.selected) + await upsertUserCart({ + userId: auth.id, + type: item.cart_type, + id: item.id, + qty: debounceQty, + selected: item.selected, + }) await loadCart(auth.id) setIsLoadQuantity(false) } diff --git a/src-migrate/modules/cart/components/ItemPromo.tsx b/src-migrate/modules/cart/components/ItemPromo.tsx index bc507578..878e17ac 100644 --- a/src-migrate/modules/cart/components/ItemPromo.tsx +++ b/src-migrate/modules/cart/components/ItemPromo.tsx @@ -1,7 +1,8 @@ import style from '../styles/item-promo.module.css' import Image from 'next/image' -import React from 'react' +import Link from 'next/link' +import { createSlug } from '~/libs/slug' import { CartProduct } from '~/types/cart' @@ -12,12 +13,15 @@ type Props = { const CartItemPromo = ({ product }: Props) => { return ( <div key={product.id} className={style.wrapper}> - <div className={style.imageWrapper}> + <Link href={createSlug('/shop/product/', product.parent.name, product.parent.id.toString())} className={style.imageWrapper}> {product?.image && <Image src={product.image} alt={product.name} width={128} height={128} className={style.image} />} - </div> + </Link> <div className={style.details}> - <div className={style.name}>{product.display_name}</div> + <Link href={createSlug('/shop/product/', product.parent.name, product.parent.id.toString())} className={style.name}> + {product.display_name} + </Link> + <div className='flex w-full'> <div className="flex flex-col"> <div className={style.code}>{product.code}</div> diff --git a/src-migrate/modules/cart/components/ItemSelect.tsx b/src-migrate/modules/cart/components/ItemSelect.tsx index 1d8886a2..b904a1de 100644 --- a/src-migrate/modules/cart/components/ItemSelect.tsx +++ b/src-migrate/modules/cart/components/ItemSelect.tsx @@ -21,7 +21,13 @@ const CartItemSelect = ({ item }: Props) => { if (typeof auth !== 'object') return setIsLoad(true) - await upsertUserCart(auth.id, item.cart_type, item.id, item.quantity, e.target.checked) + await upsertUserCart({ + userId: auth.id, + type: item.cart_type, + id: item.id, + qty: item.quantity, + selected: e.target.checked + }) await loadCart(auth.id) setIsLoad(false) } |
