From c9366090153e8aba3a673b2b77cbc8acc24e59a5 Mon Sep 17 00:00:00 2001
From: Rafi Zadanly <zadanlyr@gmail.com>
Date: Fri, 15 Dec 2023 17:15:32 +0700
Subject: Update promotion program feature

---
 .../modules/cart/components/CartItemAction.tsx     | 104 +++++++++++++++++++++
 1 file changed, 104 insertions(+)
 create mode 100644 src-migrate/modules/cart/components/CartItemAction.tsx

(limited to 'src-migrate/modules/cart/components/CartItemAction.tsx')

diff --git a/src-migrate/modules/cart/components/CartItemAction.tsx b/src-migrate/modules/cart/components/CartItemAction.tsx
new file mode 100644
index 00000000..742d1a39
--- /dev/null
+++ b/src-migrate/modules/cart/components/CartItemAction.tsx
@@ -0,0 +1,104 @@
+import React, { useEffect, useState } from 'react'
+
+import { Spinner, Tooltip } from '@chakra-ui/react'
+import { MinusIcon, PlusIcon, Trash2Icon } from 'lucide-react'
+
+import { CartItem } from '~/common/types/cart'
+import { getAuth } from '~/common/libs/auth'
+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
+}
+
+const CartItemAction = ({ item }: Props) => {
+  const auth = getAuth()
+
+  const [isLoadDelete, setIsLoadDelete] = useState<boolean>(false)
+  const [isLoadQuantity, setIsLoadQuantity] = useState<boolean>(false)
+
+  const [quantity, setQuantity] = useState<number>(item.quantity)
+
+  const { loadCart } = useCartStore()
+
+  const limitQty = item.limit_qty?.transaction || 0
+
+  const handleDelete = async () => {
+    if (typeof auth !== 'object') return
+
+    setIsLoadDelete(true)
+    await deleteUserCart(auth.id, [item.cart_id])
+    await loadCart(auth.id)
+    setIsLoadDelete(false)
+  }
+
+  const decreaseQty = () => { setQuantity((quantity) => quantity -= 1) }
+  const increaseQty = () => { setQuantity((quantity) => quantity += 1) }
+  const debounceQty = useDebounce(quantity, 1000)
+  useEffect(() => {
+    if (isNaN(debounceQty)) setQuantity(1)
+    if (limitQty > 0 && debounceQty > limitQty) setQuantity(limitQty)
+  }, [debounceQty, limitQty])
+
+  useEffect(() => {
+    const updateCart = async () => {
+      if (typeof auth !== 'object' || isNaN(debounceQty)) return
+
+      setIsLoadQuantity(true)
+      await upsertUserCart(auth.id, item.cart_type, item.id, debounceQty, item.selected)
+      await loadCart(auth.id)
+      setIsLoadQuantity(false)
+    }
+    updateCart()
+    //eslint-disable-next-line react-hooks/exhaustive-deps
+  }, [debounceQty])
+
+  return (
+    <div className={style.actionSection}>
+      <button className={style.deleteButton} onClick={handleDelete} disabled={isLoadDelete}>
+        {isLoadDelete && <Spinner size='xs' />}
+        {!isLoadDelete && <Trash2Icon size={16} />}
+      </button>
+
+      <div className={style.quantitySection}>
+        {isLoadQuantity && (
+          <div className={style.quantityLoading}>
+            <Spinner size='sm' />
+          </div>
+        )}
+
+        <button
+          className={style.quantityControl}
+          onClick={decreaseQty}
+          disabled={quantity <= 1}
+        >
+          <MinusIcon size={16} />
+        </button>
+
+        <input
+          type='number'
+          className={style.quantity.toString()}
+          onChange={(e) => setQuantity(parseInt(e.target.value))}
+          value={quantity}
+        />
+
+        <Tooltip label={limitQty > 0 ? `Max. ${limitQty}` : ''}>
+          <button
+            className={style.quantityControl}
+            onClick={increaseQty}
+            disabled={limitQty > 0 && quantity >= limitQty}
+          >
+            <PlusIcon size={16} />
+          </button>
+        </Tooltip>
+      </div>
+    </div>
+  )
+}
+
+export default CartItemAction
\ No newline at end of file
-- 
cgit v1.2.3

