-
Notifications
You must be signed in to change notification settings - Fork 42
/
Copy pathCartContext.tsx
100 lines (88 loc) · 2.67 KB
/
CartContext.tsx
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
import { BigNumber } from '@ethersproject/bignumber'
import { useBatchPurchase } from '@liteflow/react'
import { FC, PropsWithChildren, useCallback, useEffect, useState } from 'react'
import useAccount from '../hooks/useAccount'
import { CartItem, CartContext as Context } from '../hooks/useCart'
import useSigner from '../hooks/useSigner'
const CartContext: FC<PropsWithChildren> = (props) => {
const [items, setItems] = useState<CartItem[]>()
const { address } = useAccount()
const signer = useSigner()
const [transactionHash, setTransactionHash] = useState<string>()
const [batchPurchase, { transactionHash: txHash, activeStep }] =
useBatchPurchase(signer)
const [onCheckoutCallbacks, setOnCheckoutCallbacks] = useState<
(() => void)[]
>([])
useEffect(() => {
if (!txHash) return
setTransactionHash(txHash)
}, [txHash])
const registerOnCheckout = useCallback((callback: () => void) => {
setOnCheckoutCallbacks((prev) => [
...prev.filter((x) => x !== callback),
callback,
])
}, [])
const unregisterOnCheckout = useCallback((callback: () => void) => {
setOnCheckoutCallbacks((prev) => prev.filter((x) => x !== callback))
}, [])
const addItem = useCallback(
(item: CartItem) => {
setItems([...(items || []), item])
},
[items],
)
const removeItem = useCallback((id: UUID) => {
setItems((prev) => (prev || []).filter((x) => x.offerId !== id))
}, [])
const clearCart = useCallback(() => {
setItems([])
}, [])
const hasItem = useCallback(
(id: UUID) => (items || []).some((x) => x.offerId === id),
[items],
)
const checkout = useCallback(
async (items: CartItem[]) => {
await batchPurchase(
items.map((x) => ({
offerId: x.offerId,
quantity: BigNumber.from(x.quantity || 1).toString(),
})),
)
for (const item of items) removeItem(item.offerId) // cleanup items in the cart
onCheckoutCallbacks.map((callback) => callback())
},
[batchPurchase, removeItem, onCheckoutCallbacks],
)
useEffect(() => {
if (!address) return
setItems(
JSON.parse(localStorage.getItem(`liteflow.cart.${address}`) || '[]'),
)
}, [address])
useEffect(() => {
if (!items) return
if (!address) return
localStorage.setItem(`liteflow.cart.${address}`, JSON.stringify(items))
}, [items, address])
return (
<Context.Provider
value={{
items: items || [],
addItem,
hasItem,
removeItem,
clearCart,
checkout,
activeStep,
transactionHash,
registerOnCheckout,
unregisterOnCheckout,
}}
{...props}
/>
)
}
export default CartContext