@hanzo/commerce 1.0.8 → 1.0.10
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/index.ts
CHANGED
|
@@ -2,10 +2,7 @@ export { default as AddToCartWidget } from './add-to-cart-widget'
|
|
|
2
2
|
export { default as Cart } from './cart'
|
|
3
3
|
export { default as CartLineItem } from './cart-line-item'
|
|
4
4
|
export { default as FacetsWidget } from './facets-widget'
|
|
5
|
-
export { default as FacetTogglesWidget
|
|
6
|
-
type FacetMutatorSingle,
|
|
7
|
-
type FacetMutatorMultiple
|
|
8
|
-
} from './facet-toggles-widget'
|
|
5
|
+
export { default as FacetTogglesWidget } from './facet-toggles-widget'
|
|
9
6
|
export { default as ProductCard } from './product-card'
|
|
10
7
|
export { default as ProductSelectionMobilePicker } from './product-selection-mobile-picker'
|
|
11
8
|
export { default as ProductSelectionRadioGroup } from './product-selection-radio-group'
|
|
@@ -44,19 +44,19 @@ const SelectCategoryAndItemWidget: React.FC<{
|
|
|
44
44
|
comm.setFacets(facets)
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
-
const currentFacetToken =
|
|
47
|
+
const currentFacetToken = (): string | null => {
|
|
48
48
|
if (comm.specifiedCategories.length === 0) return null
|
|
49
49
|
const skuPath = comm.specifiedCategories[0].id
|
|
50
50
|
const skuPathTokens = skuPath.split('-')
|
|
51
51
|
return skuPathTokens.length > 0 ? skuPathTokens[skuPathTokens.length - 1] : null
|
|
52
|
-
}
|
|
52
|
+
}
|
|
53
53
|
|
|
54
54
|
return (
|
|
55
55
|
<div className={cn('flex flex-col justify-start gap-4 items-start pt-3', className)}>
|
|
56
56
|
<FacetTogglesWidget
|
|
57
57
|
facetValues={categoryLevelValues}
|
|
58
58
|
mutator={{
|
|
59
|
-
|
|
59
|
+
get: currentFacetToken, // computed's are accessed through their get()
|
|
60
60
|
set: onFacetTokenChanged
|
|
61
61
|
}}
|
|
62
62
|
/>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hanzo/commerce",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.10",
|
|
4
4
|
"description": "Library with shopping cart components.",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"registry": "https://registry.npmjs.org/",
|
|
@@ -29,17 +29,18 @@
|
|
|
29
29
|
"dependencies": {
|
|
30
30
|
"@hookform/resolvers": "^3.3.2",
|
|
31
31
|
"lucide-react": "^0.307.0",
|
|
32
|
+
"next-usequerystate": "^1.17.0",
|
|
32
33
|
"react-mobile-picker": "^1.0.0"
|
|
33
34
|
},
|
|
34
35
|
"peerDependencies": {
|
|
35
|
-
"@hanzo/ui": "^1.0.8",
|
|
36
36
|
"@hanzo/auth": "^1.0.9",
|
|
37
|
-
"
|
|
38
|
-
"
|
|
39
|
-
"react-dom": "^18.2.0",
|
|
37
|
+
"@hanzo/ui": "^1.0.8",
|
|
38
|
+
"firebase": "^10.8.0",
|
|
40
39
|
"mobx": "^6.12.0",
|
|
41
40
|
"mobx-react-lite": "^4.0.5",
|
|
42
|
-
"
|
|
41
|
+
"next": "^14.1.0",
|
|
42
|
+
"react": "^18.2.0",
|
|
43
|
+
"react-dom": "^18.2.0"
|
|
43
44
|
},
|
|
44
45
|
"devDependencies": {
|
|
45
46
|
"@types/react": "^18.2.48",
|
|
@@ -64,7 +64,7 @@ class StandaloneCommerceService
|
|
|
64
64
|
currentItem: computed,
|
|
65
65
|
item: computed,
|
|
66
66
|
specifiedCategories: computed,
|
|
67
|
-
|
|
67
|
+
facetsValue: computed
|
|
68
68
|
/* NOT setFacets. It implements it's action mechanism */
|
|
69
69
|
})
|
|
70
70
|
|
|
@@ -130,8 +130,12 @@ class StandaloneCommerceService
|
|
|
130
130
|
return this.specifiedCategories
|
|
131
131
|
}
|
|
132
132
|
|
|
133
|
-
get
|
|
134
|
-
|
|
133
|
+
get facetsValue(): FacetsValue {
|
|
134
|
+
const result: FacetsValue = {}
|
|
135
|
+
for( let level in this._selectedFacets ) {
|
|
136
|
+
result[level] = [...this._selectedFacets[level]]
|
|
137
|
+
}
|
|
138
|
+
return result
|
|
135
139
|
}
|
|
136
140
|
|
|
137
141
|
get specifiedCategories(): Category[] {
|
package/util/index.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
|
|
1
2
|
export function toTitleCase(str: string) {
|
|
2
3
|
return str.replace(
|
|
3
4
|
/\w\S*/g,
|
|
@@ -23,3 +24,5 @@ export function formatPrice(price: number): string {
|
|
|
23
24
|
currency: 'USD',
|
|
24
25
|
});
|
|
25
26
|
}
|
|
27
|
+
|
|
28
|
+
export { default as useSkuAndFacetParams } from './use-sku-and-facet-params'
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import {
|
|
2
|
+
useEffect,
|
|
3
|
+
useRef,
|
|
4
|
+
} from 'react'
|
|
5
|
+
import { autorun, toJS, type IReactionDisposer } from 'mobx'
|
|
6
|
+
|
|
7
|
+
import {
|
|
8
|
+
useQueryState,
|
|
9
|
+
parseAsString,
|
|
10
|
+
parseAsBoolean,
|
|
11
|
+
} from 'next-usequerystate'
|
|
12
|
+
|
|
13
|
+
import type { Category, FacetsValue, StringMutator } from '../types'
|
|
14
|
+
import { useCommerce } from '../service'
|
|
15
|
+
|
|
16
|
+
interface GetMutator {
|
|
17
|
+
(level: 1 | 2): StringMutator
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const useSkuAndFacetParams = (
|
|
21
|
+
setLoading?: (l: boolean) => void
|
|
22
|
+
) => {
|
|
23
|
+
|
|
24
|
+
const cmmc = useCommerce()
|
|
25
|
+
|
|
26
|
+
const encRef = useRef<{
|
|
27
|
+
category: Category | undefined
|
|
28
|
+
usingSkuMode: boolean
|
|
29
|
+
autoRunDisposer: IReactionDisposer | undefined
|
|
30
|
+
}>({
|
|
31
|
+
category: undefined,
|
|
32
|
+
usingSkuMode: false,
|
|
33
|
+
autoRunDisposer: undefined,
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
const [level1, setLevel1] = useQueryState('lev1',
|
|
37
|
+
parseAsString.withDefault('').withOptions({ clearOnDefault: true })
|
|
38
|
+
)
|
|
39
|
+
const [level2, setLevel2] = useQueryState('lev2',
|
|
40
|
+
parseAsString.withDefault('').withOptions({ clearOnDefault: true })
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
const [skuParam, setSkuParam] = useQueryState('sku')
|
|
44
|
+
const [addParam, setAddParam] = useQueryState('add',
|
|
45
|
+
parseAsBoolean.withDefault(false).withOptions({ clearOnDefault: true })
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
let message = ''
|
|
49
|
+
|
|
50
|
+
const directMutator: GetMutator = (level: 1 | 2): StringMutator => {
|
|
51
|
+
|
|
52
|
+
const setLevel = (value: string, level: 1 | 2 ): void => {
|
|
53
|
+
const facets = cmmc.facetsValue
|
|
54
|
+
facets[level] = [value]
|
|
55
|
+
cmmc.setFacets(facets)
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const getLevelValueSafe = (level: 1 | 2): string | null => {
|
|
59
|
+
const facets = cmmc.facetsValue
|
|
60
|
+
if (!(level in facets) || facets[level].length === 0 ) {
|
|
61
|
+
return null
|
|
62
|
+
}
|
|
63
|
+
return facets[level][0]
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return {
|
|
67
|
+
get: () => (getLevelValueSafe(level)),
|
|
68
|
+
set: (v: string) => {setLevel(v, level)}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const paramsMutator: GetMutator = (level: 1 | 2): StringMutator => {
|
|
73
|
+
return level === 1 ? {
|
|
74
|
+
get: () => (level1),
|
|
75
|
+
set: setLevel1
|
|
76
|
+
} : {
|
|
77
|
+
get: () => (level2),
|
|
78
|
+
set: setLevel2
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
useEffect(() => {
|
|
83
|
+
|
|
84
|
+
const setCurrentCategoryFromSku = (sku: string) => {
|
|
85
|
+
const toks: string[] = sku.split('-')
|
|
86
|
+
const categories = cmmc.setFacets({
|
|
87
|
+
1: [toks[1]],
|
|
88
|
+
2: [toks[2]]
|
|
89
|
+
})
|
|
90
|
+
encRef.current.category = categories[0]
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
if (skuParam) {
|
|
94
|
+
cmmc.setCurrentItem(skuParam)
|
|
95
|
+
if (addParam && cmmc.currentItem!.quantity === 0) {
|
|
96
|
+
cmmc.currentItem!.increment()
|
|
97
|
+
setAddParam(false)
|
|
98
|
+
}
|
|
99
|
+
// Marks that we've been here so no need to
|
|
100
|
+
// create an autorun() instance twice.
|
|
101
|
+
if (!encRef.current.usingSkuMode) {
|
|
102
|
+
setCurrentCategoryFromSku(skuParam)
|
|
103
|
+
encRef.current.autoRunDisposer = autorun(() => {
|
|
104
|
+
if (cmmc.currentItem && cmmc.currentItem.sku !== skuParam) {
|
|
105
|
+
setSkuParam(cmmc.currentItem.sku)
|
|
106
|
+
}
|
|
107
|
+
})
|
|
108
|
+
}
|
|
109
|
+
encRef.current.usingSkuMode = true
|
|
110
|
+
}
|
|
111
|
+
else if (encRef.current.category) {
|
|
112
|
+
//const catMutators = [{val: level1, set: setLevel1} , {val: level2, set: setLevel2}]
|
|
113
|
+
cmmc.setCurrentItem(encRef.current.category.products[0].sku)
|
|
114
|
+
}
|
|
115
|
+
setLoading && setLoading(false)
|
|
116
|
+
}, [skuParam, encRef.current.category])
|
|
117
|
+
|
|
118
|
+
// supposed to be when component unmounts
|
|
119
|
+
useEffect(() => (() => {
|
|
120
|
+
if (encRef.current.autoRunDisposer) {
|
|
121
|
+
//encRef.current.autoRunDisposer() // no idea why this seems to be called prematurely and so many times <shrug>
|
|
122
|
+
}
|
|
123
|
+
}), [])
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
// Level Params Mode
|
|
127
|
+
useEffect(() => {
|
|
128
|
+
|
|
129
|
+
if (encRef.current.usingSkuMode) return
|
|
130
|
+
|
|
131
|
+
const facets: FacetsValue = { }
|
|
132
|
+
if (level1) { facets[1] = [level1] }
|
|
133
|
+
if (level2) { facets[2] = [level2] }
|
|
134
|
+
if (level1 && level2) {
|
|
135
|
+
const categories = cmmc.setFacets(facets)
|
|
136
|
+
if (categories.length > 1) {
|
|
137
|
+
console.error("CAT", categories.map((c) => (c.title)))
|
|
138
|
+
throw new Error ( "CategoryContents: More than one specified Category should never be possible with this UI!")
|
|
139
|
+
}
|
|
140
|
+
encRef.current.category = categories[0]
|
|
141
|
+
}
|
|
142
|
+
else {
|
|
143
|
+
message = 'Please select an option from each group above.'
|
|
144
|
+
}
|
|
145
|
+
setLoading && setLoading(false)
|
|
146
|
+
}, [level1 , level2])
|
|
147
|
+
|
|
148
|
+
return {
|
|
149
|
+
category: encRef.current.category,
|
|
150
|
+
message,
|
|
151
|
+
getMutator: encRef.current.usingSkuMode ?
|
|
152
|
+
directMutator : paramsMutator
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
export default useSkuAndFacetParams
|