@hanzo/commerce 1.1.0 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/components/cart.tsx
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
'use client'
|
|
2
|
-
import React, { type PropsWithChildren
|
|
2
|
+
import React, { type PropsWithChildren } from 'react'
|
|
3
3
|
import { useRouter } from 'next/navigation'
|
|
4
4
|
import { observer } from 'mobx-react-lite'
|
|
5
5
|
|
|
@@ -23,18 +23,9 @@ const Cart: React.FC<PropsWithChildren & {
|
|
|
23
23
|
isMobile=false,
|
|
24
24
|
hideCheckout=false
|
|
25
25
|
}) => {
|
|
26
|
-
const [loadingCheckout, setLoadingCheckout] = useState(false)
|
|
27
26
|
const cmmc = useCommerce()
|
|
28
27
|
const router = useRouter()
|
|
29
28
|
const auth = useAuth()
|
|
30
|
-
|
|
31
|
-
const checkout = async () => {
|
|
32
|
-
setLoadingCheckout(true)
|
|
33
|
-
if (auth.user) {
|
|
34
|
-
await cmmc.createOrder(auth.user.email)
|
|
35
|
-
}
|
|
36
|
-
router.push('/checkout')
|
|
37
|
-
}
|
|
38
29
|
|
|
39
30
|
return (
|
|
40
31
|
<div className={cn('border p-6 rounded-lg', className)}>
|
|
@@ -50,10 +41,10 @@ const Cart: React.FC<PropsWithChildren & {
|
|
|
50
41
|
</div>
|
|
51
42
|
{cmmc.cartItems.length > 0 && !hideCheckout && (
|
|
52
43
|
<>
|
|
53
|
-
{!auth.loggedIn ? (
|
|
44
|
+
{!(auth && auth.loggedIn) ? (
|
|
54
45
|
<Button size='sm' variant='secondary' rounded='lg' className='mt-12 mx-auto' onClick={() => router.push('/login?redirectUrl=checkout')}>Login to checkout</Button>
|
|
55
46
|
) : (
|
|
56
|
-
<Button size='lg' variant='secondary' rounded='lg' className='mt-12 mx-auto' onClick={checkout}
|
|
47
|
+
<Button size='lg' variant='secondary' rounded='lg' className='mt-12 mx-auto' onClick={() => router.push('/checkout')}>Checkout</Button>
|
|
57
48
|
)}
|
|
58
49
|
</>
|
|
59
50
|
)}
|
package/package.json
CHANGED
|
@@ -23,12 +23,52 @@ const getDBInstance = (name: string): Firestore => {
|
|
|
23
23
|
|
|
24
24
|
interface SavedOrder {
|
|
25
25
|
email: string
|
|
26
|
+
paymentMethod: string
|
|
27
|
+
status: string
|
|
26
28
|
timestamp: FieldValue
|
|
27
29
|
items: ActualLineItemSnapshot[]
|
|
28
30
|
}
|
|
29
31
|
|
|
30
32
|
const createOrder = async (
|
|
31
33
|
email: string,
|
|
34
|
+
paymentMethod: string,
|
|
35
|
+
items: ActualLineItemSnapshot[],
|
|
36
|
+
options: {
|
|
37
|
+
dbName: string
|
|
38
|
+
ordersTable: string
|
|
39
|
+
}
|
|
40
|
+
): Promise<{
|
|
41
|
+
success: boolean,
|
|
42
|
+
error: any,
|
|
43
|
+
id?: string
|
|
44
|
+
}> => {
|
|
45
|
+
|
|
46
|
+
let error: any | null = null
|
|
47
|
+
const ordersRef = collection(getDBInstance(options.dbName), options.ordersTable)
|
|
48
|
+
const orderId = `${email}-${new Date().toISOString()}`
|
|
49
|
+
|
|
50
|
+
try {
|
|
51
|
+
await setDoc(doc(ordersRef, orderId), {
|
|
52
|
+
email,
|
|
53
|
+
paymentMethod,
|
|
54
|
+
status: 'open',
|
|
55
|
+
timestamp: serverTimestamp(),
|
|
56
|
+
items,
|
|
57
|
+
} satisfies SavedOrder)
|
|
58
|
+
return { success: !error, error, id: orderId }
|
|
59
|
+
}
|
|
60
|
+
catch (e) {
|
|
61
|
+
console.error('Error writing item document: ', e)
|
|
62
|
+
error = e
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return { success: !error, error }
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const updateOrder = async (
|
|
69
|
+
orderId: string,
|
|
70
|
+
email: string,
|
|
71
|
+
paymentMethod: string,
|
|
32
72
|
items: ActualLineItemSnapshot[],
|
|
33
73
|
options: {
|
|
34
74
|
dbName: string
|
|
@@ -43,8 +83,10 @@ const createOrder = async (
|
|
|
43
83
|
const ordersRef = collection(getDBInstance(options.dbName), options.ordersTable)
|
|
44
84
|
|
|
45
85
|
try {
|
|
46
|
-
await setDoc(doc(ordersRef,
|
|
86
|
+
await setDoc(doc(ordersRef, orderId), {
|
|
47
87
|
email,
|
|
88
|
+
paymentMethod,
|
|
89
|
+
status: 'open',
|
|
48
90
|
timestamp: serverTimestamp(),
|
|
49
91
|
items,
|
|
50
92
|
} satisfies SavedOrder)
|
|
@@ -57,4 +99,4 @@ const createOrder = async (
|
|
|
57
99
|
return { success: !error, error }
|
|
58
100
|
}
|
|
59
101
|
|
|
60
|
-
export { createOrder }
|
|
102
|
+
export { createOrder, updateOrder }
|
|
@@ -15,7 +15,10 @@ import type {
|
|
|
15
15
|
FacetsDesc
|
|
16
16
|
} from '../../../types'
|
|
17
17
|
|
|
18
|
-
import {
|
|
18
|
+
import {
|
|
19
|
+
createOrder as createOrderHelper,
|
|
20
|
+
updateOrder as updateOrderHelper
|
|
21
|
+
} from './orders'
|
|
19
22
|
|
|
20
23
|
import ActualLineItem, { type ActualLineItemSnapshot } from './actual-line-item'
|
|
21
24
|
|
|
@@ -84,9 +87,15 @@ class StandaloneService
|
|
|
84
87
|
})
|
|
85
88
|
}
|
|
86
89
|
|
|
87
|
-
async createOrder(email: string): Promise<
|
|
90
|
+
async createOrder(email: string, paymentMethod: string): Promise<string | undefined> {
|
|
88
91
|
const snapshot = this.takeSnapshot()
|
|
89
|
-
createOrderHelper(email, snapshot.items, this._options) // didn't want to have two levels of 'items'
|
|
92
|
+
const order = await createOrderHelper(email, paymentMethod, snapshot.items, this._options) // didn't want to have two levels of 'items'
|
|
93
|
+
return order.id
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
async updateOrder(orderId: string, email: string, paymentMethod: string): Promise<void> {
|
|
97
|
+
const snapshot = this.takeSnapshot()
|
|
98
|
+
updateOrderHelper(orderId, email, paymentMethod, snapshot.items, this._options) // didn't want to have two levels of 'items'
|
|
90
99
|
}
|
|
91
100
|
|
|
92
101
|
takeSnapshot = (): StandaloneServiceSnapshot => ({
|
|
@@ -127,13 +136,14 @@ class StandaloneService
|
|
|
127
136
|
}
|
|
128
137
|
}
|
|
129
138
|
}
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
if (foundItem)
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
}
|
|
139
|
+
for( const [categoryId, category] of this._categoryMap.entries()) {
|
|
140
|
+
if (categoriesTried.includes(categoryId)) continue
|
|
141
|
+
const foundItem = category.products.find((p) => (p.sku === skuToFind)) as ActualLineItem | undefined
|
|
142
|
+
if (foundItem) {
|
|
143
|
+
return foundItem as ActualLineItem
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
return undefined
|
|
137
147
|
})();
|
|
138
148
|
|
|
139
149
|
return !!this._currentItem
|
|
@@ -8,7 +8,8 @@ interface CommerceService extends ObsLineItemRef {
|
|
|
8
8
|
get cartTotal(): number
|
|
9
9
|
getCartCategorySubtotal(categoryId: string): number
|
|
10
10
|
|
|
11
|
-
createOrder(email: string): Promise<
|
|
11
|
+
createOrder(email: string, paymentMethod: string): Promise<string | undefined>
|
|
12
|
+
updateOrder(orderId: string, email: string, paymentMethod: string): Promise<void>
|
|
12
13
|
|
|
13
14
|
/**
|
|
14
15
|
* Sets the tokens at each level supplied.
|
|
@@ -29,7 +30,7 @@ interface CommerceService extends ObsLineItemRef {
|
|
|
29
30
|
* "current" is unrelated to what is "specified",
|
|
30
31
|
* ie, facets' values
|
|
31
32
|
* */
|
|
32
|
-
setCurrentItem(sku: string | undefined): boolean //
|
|
33
|
+
setCurrentItem(sku: string | undefined): boolean // valid sku and was set.
|
|
33
34
|
/**
|
|
34
35
|
* For convenience, so widgets can share state.
|
|
35
36
|
* "current" is unrelated to what is "specified",
|
|
@@ -22,6 +22,7 @@ interface GetMutator {
|
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
const useSkuAndFacetParams = (
|
|
25
|
+
setMessage: (m: string | undefined) => void,
|
|
25
26
|
setLoading?: (l: boolean) => void
|
|
26
27
|
) => {
|
|
27
28
|
|
|
@@ -50,8 +51,6 @@ const useSkuAndFacetParams = (
|
|
|
50
51
|
parseAsBoolean.withDefault(false).withOptions({ clearOnDefault: true })
|
|
51
52
|
)
|
|
52
53
|
|
|
53
|
-
const [message, setMessage] = useState<string | undefined>(undefined)
|
|
54
|
-
|
|
55
54
|
const directMutator: GetMutator = (level: 1 | 2): StringMutator => {
|
|
56
55
|
|
|
57
56
|
const setLevel = (value: string, level: 1 | 2 ): void => {
|
|
@@ -84,6 +83,8 @@ const useSkuAndFacetParams = (
|
|
|
84
83
|
}
|
|
85
84
|
}
|
|
86
85
|
|
|
86
|
+
let message: string | undefined = undefined
|
|
87
|
+
|
|
87
88
|
useEffect(() => {
|
|
88
89
|
|
|
89
90
|
const setCurrentCategoryFromSku = (sku: string) => {
|
|
@@ -111,14 +112,14 @@ const useSkuAndFacetParams = (
|
|
|
111
112
|
}
|
|
112
113
|
})
|
|
113
114
|
}
|
|
114
|
-
setMessage(undefined)
|
|
115
115
|
encRef.current.usingSkuMode = true
|
|
116
116
|
}
|
|
117
117
|
else {
|
|
118
|
+
|
|
118
119
|
setSkuParam('')
|
|
119
120
|
// if sent here w an invalid sku,
|
|
120
121
|
// it will effectively put us in facet params mode
|
|
121
|
-
|
|
122
|
+
message = 'Invalid sku. ' + PLEASE_SELECT_FACETS
|
|
122
123
|
}
|
|
123
124
|
}
|
|
124
125
|
|
|
@@ -148,7 +149,6 @@ const useSkuAndFacetParams = (
|
|
|
148
149
|
const categories = cmmc.setFacets(facets)
|
|
149
150
|
if (categories && categories.length > 0) {
|
|
150
151
|
cmmc.setCurrentItem(categories[0].products[0].sku)
|
|
151
|
-
setMessage(undefined)
|
|
152
152
|
}
|
|
153
153
|
else {
|
|
154
154
|
cmmc.setCurrentItem(undefined)
|
|
@@ -156,17 +156,15 @@ const useSkuAndFacetParams = (
|
|
|
156
156
|
}
|
|
157
157
|
}
|
|
158
158
|
else {
|
|
159
|
-
setMessage(PLEASE_SELECT_FACETS)
|
|
159
|
+
setMessage(message ?? PLEASE_SELECT_FACETS)
|
|
160
160
|
}
|
|
161
161
|
setLoading && setLoading(false)
|
|
162
162
|
}, [level1 , level2])
|
|
163
163
|
|
|
164
164
|
return {
|
|
165
|
-
message,
|
|
166
165
|
getMutator: encRef.current.usingSkuMode ?
|
|
167
166
|
directMutator : paramsMutator
|
|
168
167
|
}
|
|
169
|
-
|
|
170
168
|
}
|
|
171
169
|
|
|
172
170
|
export default useSkuAndFacetParams
|