summaryrefslogtreecommitdiff
path: root/src-migrate/modules/cart
diff options
context:
space:
mode:
Diffstat (limited to 'src-migrate/modules/cart')
-rw-r--r--src-migrate/modules/cart/components/Detail.tsx (renamed from src-migrate/modules/cart/components/CartDetail.tsx)22
-rw-r--r--src-migrate/modules/cart/components/Item.tsx109
-rw-r--r--src-migrate/modules/cart/components/ItemAction.tsx (renamed from src-migrate/modules/cart/components/CartItemAction.tsx)3
-rw-r--r--src-migrate/modules/cart/components/ItemPromo.tsx41
-rw-r--r--src-migrate/modules/cart/components/ItemSelect.tsx (renamed from src-migrate/modules/cart/components/CartItemSelect.tsx)2
-rw-r--r--src-migrate/modules/cart/components/Summary.tsx (renamed from src-migrate/modules/cart/ui/CartSummary.tsx)3
-rw-r--r--src-migrate/modules/cart/stores/useCartStore.ts4
-rw-r--r--src-migrate/modules/cart/styles/CartItem.module.css47
-rw-r--r--src-migrate/modules/cart/styles/ProductPromo.module.css24
-rw-r--r--src-migrate/modules/cart/styles/detail.module.css (renamed from src-migrate/modules/cart/styles/CartDetail.module.css)0
-rw-r--r--src-migrate/modules/cart/styles/item-action.module.css (renamed from src-migrate/modules/cart/styles/CartItemAction.module.css)0
-rw-r--r--src-migrate/modules/cart/styles/item-promo.module.css31
-rw-r--r--src-migrate/modules/cart/styles/item.module.css60
-rw-r--r--src-migrate/modules/cart/styles/summary.module.css (renamed from src-migrate/modules/cart/styles/CartSummary.module.css)0
-rw-r--r--src-migrate/modules/cart/ui/CartItem.tsx80
-rw-r--r--src-migrate/modules/cart/ui/ProductPromo.tsx33
16 files changed, 264 insertions, 195 deletions
diff --git a/src-migrate/modules/cart/components/CartDetail.tsx b/src-migrate/modules/cart/components/Detail.tsx
index 734c61d3..c9de086b 100644
--- a/src-migrate/modules/cart/components/CartDetail.tsx
+++ b/src-migrate/modules/cart/components/Detail.tsx
@@ -1,10 +1,14 @@
+import style from '../styles/detail.module.css'
+
import React, { useEffect, useMemo } from 'react'
+import Link from 'next/link'
+import { Button, Tooltip } from '@chakra-ui/react'
+
import { getAuth } from '~/common/libs/auth'
import { useCartStore } from '../stores/useCartStore'
-import CartItem from '../ui/CartItem'
-import style from '../styles/CartDetail.module.css'
-import CartSummary from '../ui/CartSummary'
-import { Button, Tooltip } from '@chakra-ui/react'
+
+import CartItem from './Item'
+import CartSummary from './Summary'
const CartDetail = () => {
const auth = getAuth()
@@ -46,7 +50,7 @@ const CartDetail = () => {
</div>
</div>
- <div className='w-full md:w-1/4 pl-6'>
+ <div className='w-full md:w-1/4 md:pl-6 mt-6 md:mt-0'>
<div className='border border-gray-300 p-4 rounded-md sticky top-[180px]'>
<CartSummary {...summary} isLoaded={!!cart} />
<div className='grid grid-cols-2 gap-x-3 mt-6'>
@@ -54,7 +58,8 @@ const CartDetail = () => {
<Button
colorScheme='yellow'
w='full'
- isDisabled={hasSelectedPromo || !hasSelected}>
+ isDisabled={hasSelectedPromo || !hasSelected}
+ >
Quotation
</Button>
</Tooltip>
@@ -62,7 +67,10 @@ const CartDetail = () => {
<Button
colorScheme='red'
w='full'
- isDisabled={!hasSelected}>
+ isDisabled={!hasSelected}
+ as={Link}
+ href='/shop/checkout'
+ >
Checkout
</Button>
</Tooltip>
diff --git a/src-migrate/modules/cart/components/Item.tsx b/src-migrate/modules/cart/components/Item.tsx
new file mode 100644
index 00000000..92beda86
--- /dev/null
+++ b/src-migrate/modules/cart/components/Item.tsx
@@ -0,0 +1,109 @@
+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 formatCurrency from '~/common/libs/formatCurrency'
+import { CartItem as CartItemProps } from '~/common/types/cart'
+
+import CartItemPromo from './ItemPromo'
+import CartItemAction from './ItemAction'
+import CartItemSelect from './ItemSelect'
+import { PROMO_CATEGORY } from '~/constants/promotion'
+import { InfoIcon } from 'lucide-react'
+
+type Props = {
+ item: CartItemProps
+ editable?: boolean
+}
+
+const CartItem = ({ item, editable = true }: Props) => {
+ const image = item?.image || item?.parent?.image
+
+ return (
+ <div className={style.wrapper}>
+ {item.cart_type === 'promotion' && (
+ <div className={style.header}>
+ {item.promotion_type?.value && (
+ <Tooltip label={PROMO_CATEGORY[item.promotion_type?.value].description} placement="top" bgColor='red.600' p={2} rounded={6}>
+ <div className={style.badgeType}>
+ Paket {PROMO_CATEGORY[item.promotion_type?.value].alias}
+ <InfoIcon size={14} />
+ </div>
+ </Tooltip>
+ )}
+ <div className='w-2' />
+ <div>
+ Selamat! Pembelian anda lebih hemat {' '}
+ <span className={style.savingAmt}>
+ Rp {formatCurrency((item.package_price || 0) - item.subtotal)}
+ </span>
+ </div>
+ </div>
+ )}
+
+ <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>
+
+ <div className={style.details}>
+ <div className={style.name}>{item.name}</div>
+ <div className='mt-2 flex justify-between w-full'>
+ <div className='flex flex-col gap-y-1'>
+ {item.cart_type === 'promotion' && (
+ <div className={style.discPriceSection}>
+ <span className={style.priceBefore}>
+ Rp {formatCurrency((item.package_price || 0))}
+ </span>
+ <span className={style.price}>
+ Rp {formatCurrency(item.subtotal)}
+ </span>
+ </div>
+ )}
+
+ {item.cart_type === 'product' && (
+ <>
+ <div className={style.price}>
+ Rp {formatCurrency(item.price.price)}
+ </div>
+ <div>{item.code}</div>
+ </>
+ )}
+
+ <div>
+ {item.weight} Kg
+ </div>
+ </div>
+
+ {editable && <CartItemAction item={item} />}
+ {!editable && <div className={style.quantity}>{item.quantity}</div>}
+ </div>
+ </div>
+
+ </div>
+
+ <div className="flex flex-col">
+ {item.products?.map((product) => <CartItemPromo key={product.id} product={product} />)}
+ {item.free_products?.map((product) => <CartItemPromo key={product.id} product={product} />)}
+ </div>
+ </div>
+ )
+}
+
+CartItem.Skeleton = function CartItemSkeleton(props: SkeletonProps & { count: number }) {
+ return Array.from({ length: props.count }).map((_, index) => (
+ <Skeleton key={index}
+ height='100px'
+ width='100%'
+ rounded='md'
+ {...props}
+ />
+ ))
+}
+
+export default CartItem \ No newline at end of file
diff --git a/src-migrate/modules/cart/components/CartItemAction.tsx b/src-migrate/modules/cart/components/ItemAction.tsx
index 742d1a39..3e264aef 100644
--- a/src-migrate/modules/cart/components/CartItemAction.tsx
+++ b/src-migrate/modules/cart/components/ItemAction.tsx
@@ -1,3 +1,5 @@
+import style from '../styles/item-action.module.css'
+
import React, { useEffect, useState } from 'react'
import { Spinner, Tooltip } from '@chakra-ui/react'
@@ -10,7 +12,6 @@ import { deleteUserCart, upsertUserCart } from '~/services/cart'
import { useDebounce } from 'usehooks-ts'
import { useCartStore } from '../stores/useCartStore'
-import style from '../styles/CartItemAction.module.css'
type Props = {
item: CartItem
diff --git a/src-migrate/modules/cart/components/ItemPromo.tsx b/src-migrate/modules/cart/components/ItemPromo.tsx
new file mode 100644
index 00000000..951d4d6a
--- /dev/null
+++ b/src-migrate/modules/cart/components/ItemPromo.tsx
@@ -0,0 +1,41 @@
+import style from '../styles/item-promo.module.css'
+
+import Image from 'next/image'
+import React from 'react'
+
+import { CartProduct } from '~/common/types/cart'
+
+
+type Props = {
+ product: CartProduct
+}
+
+const CartItemPromo = ({ product }: Props) => {
+ return (
+ <div key={product.id} className={style.wrapper}>
+ <div className={style.imageWrapper}>
+ {product?.image && <Image src={product.image} alt={product.name} width={128} height={128} className={style.image} />}
+ </div>
+
+ <div className={style.details}>
+ <div className={style.name}>{product.display_name}</div>
+ <div className='flex'>
+ <div className="flex flex-col">
+ <div className={style.code}>{product.code}</div>
+ <div>
+ <span className={style.weightLabel}>Berat Barang: </span>
+ <span>{product.package_weight} Kg</span>
+ </div>
+ </div>
+
+ <div className={style.quantity}>
+ {product.qty}
+ </div>
+ </div>
+ </div>
+
+ </div>
+ )
+}
+
+export default CartItemPromo \ No newline at end of file
diff --git a/src-migrate/modules/cart/components/CartItemSelect.tsx b/src-migrate/modules/cart/components/ItemSelect.tsx
index f44b0d7e..96e7c713 100644
--- a/src-migrate/modules/cart/components/CartItemSelect.tsx
+++ b/src-migrate/modules/cart/components/ItemSelect.tsx
@@ -1,8 +1,10 @@
import { Checkbox, Spinner } from '@chakra-ui/react'
import React, { useState } from 'react'
+
import { getAuth } from '~/common/libs/auth'
import { CartItem } from '~/common/types/cart'
import { upsertUserCart } from '~/services/cart'
+
import { useCartStore } from '../stores/useCartStore'
type Props = {
diff --git a/src-migrate/modules/cart/ui/CartSummary.tsx b/src-migrate/modules/cart/components/Summary.tsx
index 390c1c77..a835bca9 100644
--- a/src-migrate/modules/cart/ui/CartSummary.tsx
+++ b/src-migrate/modules/cart/components/Summary.tsx
@@ -1,5 +1,6 @@
+import style from '../styles/summary.module.css'
+
import React from 'react'
-import style from '../styles/CartSummary.module.css'
import formatCurrency from '~/common/libs/formatCurrency'
import clsxm from '~/common/libs/clsxm'
import { Skeleton } from '@chakra-ui/react'
diff --git a/src-migrate/modules/cart/stores/useCartStore.ts b/src-migrate/modules/cart/stores/useCartStore.ts
index 1963df53..d3eaadb7 100644
--- a/src-migrate/modules/cart/stores/useCartStore.ts
+++ b/src-migrate/modules/cart/stores/useCartStore.ts
@@ -1,6 +1,6 @@
import { create } from 'zustand';
import { CartProps } from '~/common/types/cart';
-import { deleteUserCart, getUserCart, upsertUserCart } from '~/services/cart';
+import { getUserCart } from '~/services/cart';
type State = {
cart: CartProps | null;
@@ -56,7 +56,7 @@ const computeSummary = (cart: CartProps) => {
discount += price - item.price.price_discount * item.quantity;
}
let total = subtotal - discount;
- let tax = total * 0.11;
+ let tax = Math.round(total * 0.11);
let grandTotal = total + tax;
return { subtotal, discount, total, tax, grandTotal };
diff --git a/src-migrate/modules/cart/styles/CartItem.module.css b/src-migrate/modules/cart/styles/CartItem.module.css
deleted file mode 100644
index 8ee3d3e9..00000000
--- a/src-migrate/modules/cart/styles/CartItem.module.css
+++ /dev/null
@@ -1,47 +0,0 @@
-.wrapper {
- @apply border-b border-gray-300 pb-8;
-}
-
-.mainProdWrapper {
- @apply flex;
-}
-
-.image {
- @apply h-32 w-32 rounded flex p-2 border border-gray-300;
-}
-
-.noImage {
- @apply m-auto font-semibold text-gray-400;
-}
-
-.details {
- @apply ml-4 flex flex-col gap-y-1;
-}
-
-.name {
- @apply font-medium;
-}
-
-.spacing2 {
- @apply h-2;
-}
-
-.discPriceSection {
- @apply flex gap-x-2.5;
-}
-
-.priceBefore {
- @apply line-through text-gray-500;
-}
-
-.price {
- @apply text-red-600 font-medium;
-}
-
-.savingAmt {
- @apply text-success-600;
-}
-
-.weightLabel {
- @apply text-gray-500;
-}
diff --git a/src-migrate/modules/cart/styles/ProductPromo.module.css b/src-migrate/modules/cart/styles/ProductPromo.module.css
deleted file mode 100644
index 3f6e7a05..00000000
--- a/src-migrate/modules/cart/styles/ProductPromo.module.css
+++ /dev/null
@@ -1,24 +0,0 @@
-.wrapper {
- @apply ml-16 mt-4 flex;
-}
-
-.imageWrapper {
- @apply h-24 w-24 border border-gray-300 rounded p-2.5;
-}
-
-.details {
- @apply ml-4 flex flex-col gap-y-1;
-}
-
-.name {
- @apply font-medium;
-}
-
-.code,
-.weightLabel {
- @apply text-gray-600;
-}
-
-.quantity {
- @apply py-2.5 bg-gray-100 border border-gray-300 h-fit my-auto rounded-md ml-auto font-medium w-12 text-center;
-}
diff --git a/src-migrate/modules/cart/styles/CartDetail.module.css b/src-migrate/modules/cart/styles/detail.module.css
index 42d492bb..42d492bb 100644
--- a/src-migrate/modules/cart/styles/CartDetail.module.css
+++ b/src-migrate/modules/cart/styles/detail.module.css
diff --git a/src-migrate/modules/cart/styles/CartItemAction.module.css b/src-migrate/modules/cart/styles/item-action.module.css
index e4db7fa5..e4db7fa5 100644
--- a/src-migrate/modules/cart/styles/CartItemAction.module.css
+++ b/src-migrate/modules/cart/styles/item-action.module.css
diff --git a/src-migrate/modules/cart/styles/item-promo.module.css b/src-migrate/modules/cart/styles/item-promo.module.css
new file mode 100644
index 00000000..17dbf1c7
--- /dev/null
+++ b/src-migrate/modules/cart/styles/item-promo.module.css
@@ -0,0 +1,31 @@
+.wrapper {
+ @apply md:ml-16 ml-12 mt-4 flex;
+}
+
+.imageWrapper {
+ @apply md:h-24 md:w-24 md:min-w-[96px]
+ h-20 w-20 min-w-[80px]
+ border border-gray-300 rounded
+ p-2.5;
+}
+
+.image {
+ @apply w-full h-full object-contain;
+}
+
+.details {
+ @apply ml-4 flex flex-col gap-y-1;
+}
+
+.name {
+ @apply font-medium;
+}
+
+.code,
+.weightLabel {
+ @apply text-gray-600;
+}
+
+.quantity {
+ @apply w-12 min-w-[48px] py-2.5 bg-gray-100 border border-gray-300 h-fit my-auto rounded-md ml-auto font-medium text-center;
+}
diff --git a/src-migrate/modules/cart/styles/item.module.css b/src-migrate/modules/cart/styles/item.module.css
new file mode 100644
index 00000000..6380cdad
--- /dev/null
+++ b/src-migrate/modules/cart/styles/item.module.css
@@ -0,0 +1,60 @@
+.wrapper {
+ @apply border-b border-gray-300 pb-8;
+}
+
+.header {
+ @apply mb-4 flex items-center text-caption-1 leading-6;
+}
+
+.badgeType {
+ @apply min-w-fit p-2 flex gap-x-1.5 rounded-md border border-danger-500 text-danger-500;
+}
+
+.mainProdWrapper {
+ @apply flex;
+}
+
+.image {
+ @apply md:h-32 md:w-32 md:min-w-[128px]
+ w-24 h-24 min-w-[96px] rounded flex p-2 border border-gray-300;
+}
+
+.noImage {
+ @apply m-auto font-semibold text-gray-400;
+}
+
+.details {
+ @apply ml-4 flex flex-col gap-y-1 w-full;
+}
+
+.name {
+ @apply font-medium;
+}
+
+.spacing2 {
+ @apply h-2;
+}
+
+.discPriceSection {
+ @apply flex flex-col md:flex-row gap-x-2.5;
+}
+
+.priceBefore {
+ @apply line-through text-gray-500;
+}
+
+.price {
+ @apply text-red-600 font-medium;
+}
+
+.savingAmt {
+ @apply text-success-600;
+}
+
+.weightLabel {
+ @apply text-gray-500;
+}
+
+.quantity {
+ @apply py-2.5 bg-red-100 border border-red-300 text-red-800 h-fit my-auto rounded-md ml-auto font-medium w-12 text-center;
+}
diff --git a/src-migrate/modules/cart/styles/CartSummary.module.css b/src-migrate/modules/cart/styles/summary.module.css
index 48ccec28..48ccec28 100644
--- a/src-migrate/modules/cart/styles/CartSummary.module.css
+++ b/src-migrate/modules/cart/styles/summary.module.css
diff --git a/src-migrate/modules/cart/ui/CartItem.tsx b/src-migrate/modules/cart/ui/CartItem.tsx
deleted file mode 100644
index 70d50bff..00000000
--- a/src-migrate/modules/cart/ui/CartItem.tsx
+++ /dev/null
@@ -1,80 +0,0 @@
-import Image from 'next/image'
-import React from 'react'
-import formatCurrency from '~/common/libs/formatCurrency'
-import { CartItem as CartItemProps } from '~/common/types/cart'
-import ProductPromo from './ProductPromo'
-import { Skeleton, SkeletonProps } from '@chakra-ui/react'
-import style from '../styles/CartItem.module.css'
-import CartItemAction from '../components/CartItemAction'
-import CartItemSelect from '../components/CartItemSelect'
-
-type Props = {
- item: CartItemProps
-}
-
-const CartItem = ({ item }: Props) => {
- const image = item?.image || item?.parent?.image
-
- return (
- <div className={style.wrapper}>
- <div className={style.mainProdWrapper}>
- <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>
-
- <div className={style.details}>
- <div className={style.name}>{item.name}</div>
- <div className={style.spacing2} />
- {item.cart_type === 'promotion' && (
- <div className={style.discPriceSection}>
- <span className={style.priceBefore}>
- Rp {formatCurrency((item.package_price || 0))}
- </span>
- <span className={style.savingAmt}>
- Hemat Rp {formatCurrency((item.package_price || 0) - item.subtotal)}
- </span>
- <span className={style.price}>
- Rp {formatCurrency(item.subtotal)}
- </span>
- </div>
- )}
- {item.cart_type === 'product' && (
- <>
- <div className={style.price}>
- Rp {formatCurrency(item.price.price)}
- </div>
- <div>{item.code}</div>
- </>
- )}
- <div>
- <span className={style.weightLabel}>Berat barang: </span>
- {item.weight} Kg
- </div>
- </div>
-
- <CartItemAction item={item} />
- </div>
-
- <div className="flex flex-col">
- {item.products?.map((product) => <ProductPromo key={product.id} product={product} />)}
- {item.free_products?.map((product) => <ProductPromo key={product.id} product={product} />)}
- </div>
- </div>
- )
-}
-
-CartItem.Skeleton = function CartItemSkeleton(props: SkeletonProps & { count: number }) {
- return Array.from({ length: props.count }).map((_, index) => (
- <Skeleton key={index}
- height='100px'
- width='100%'
- rounded='md'
- {...props}
- />
- ))
-}
-
-export default CartItem \ No newline at end of file
diff --git a/src-migrate/modules/cart/ui/ProductPromo.tsx b/src-migrate/modules/cart/ui/ProductPromo.tsx
deleted file mode 100644
index a41afc97..00000000
--- a/src-migrate/modules/cart/ui/ProductPromo.tsx
+++ /dev/null
@@ -1,33 +0,0 @@
-import Image from 'next/image'
-import React from 'react'
-import { CartProduct } from '~/common/types/cart'
-import style from '../styles/ProductPromo.module.css'
-
-type Props = {
- product: CartProduct
-}
-
-const ProductPromo = ({ product }: Props) => {
- return (
- <div key={product.id} className={style.wrapper}>
- <div className={style.imageWrapper}>
- {product?.image && <Image src={product.image} alt={product.name} width={128} height={128} />}
- </div>
-
- <div className={style.details}>
- <div className={style.name}>{product.display_name}</div>
- <div className={style.code}>{product.code}</div>
- <div>
- <span className={style.weightLabel}>Berat Barang: </span>
- <span>{product.package_weight} Kg</span>
- </div>
- </div>
-
- <div className={style.quantity}>
- {product.qty}
- </div>
- </div>
- )
-}
-
-export default ProductPromo \ No newline at end of file