1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
|
import style from '../styles/item-action.module.css'
import React, { useEffect, useState } from 'react'
import { Spinner, Tooltip } from '@chakra-ui/react'
import { MinusIcon, PlusIcon, Trash2Icon } from 'lucide-react'
import { CartItem } from '~/types/cart'
import { getAuth } from '~/libs/auth'
import { deleteUserCart, upsertUserCart } from '~/services/cart'
import { useDebounce } from 'usehooks-ts'
import { useCartStore } from '../stores/useCartStore'
import { useProductCartContext } from '@/contexts/ProductCartContext'
type Props = {
item: CartItem
}
const CartItemAction = ({ item }: Props) => {
const auth = getAuth()
const { setRefreshCart } = useProductCartContext()
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)
setRefreshCart(true)
}
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({
userId: auth.id,
type: item.cart_type,
id: item.id,
qty: debounceQty,
selected: 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
|