@hanzo/commerce 7.3.1 → 7.3.2
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/Icons.tsx +34 -34
- package/components/add-to-cart-widget.tsx +183 -183
- package/components/buy/buy-card.tsx +259 -259
- package/components/buy/carousel-buy-card.tsx +242 -242
- package/components/buy/multi-family/all-variants-carousel.tsx +261 -261
- package/components/buy/multi-family/family-carousel/index.tsx +77 -77
- package/components/buy/multi-family/family-carousel/slide.tsx +83 -83
- package/components/buy/multi-family/family-carousel/state.ts +87 -87
- package/components/buy/multi-family/index.ts +2 -2
- package/components/buy/single-family-selector.tsx +90 -90
- package/components/buy/title-and-byline.tsx +25 -25
- package/components/cart/cart-panel/cart-line-item.tsx +76 -76
- package/components/cart/cart-panel/index.tsx +154 -154
- package/components/cart/cart-panel/promo-code.tsx +106 -106
- package/components/cart/cart-panel/total-area.tsx +60 -60
- package/components/checkout/payment-step-form/card-icon-row.tsx +26 -26
- package/components/checkout/payment-step-form/card-icons/amex.tsx +32 -32
- package/components/checkout/payment-step-form/card-icons/diners-club.tsx +13 -13
- package/components/checkout/payment-step-form/card-icons/discover.tsx +25 -25
- package/components/checkout/payment-step-form/card-icons/jcb.tsx +26 -26
- package/components/checkout/payment-step-form/card-icons/mastercard.tsx +27 -27
- package/components/checkout/payment-step-form/card-icons/visa.tsx +25 -25
- package/components/checkout/payment-step-form/cc-button.tsx +17 -17
- package/components/checkout/payment-step-form/contact-form.tsx +49 -49
- package/components/checkout/payment-step-form/crypto-icons/btc.tsx +11 -11
- package/components/checkout/payment-step-form/crypto-icons/eth.tsx +20 -20
- package/components/checkout/payment-step-form/crypto-icons/usdt.tsx +13 -13
- package/components/checkout/payment-step-form/index.tsx +122 -122
- package/components/checkout/payment-step-form/methods/bank-transfer.tsx +79 -79
- package/components/checkout/payment-step-form/methods/card.tsx +232 -232
- package/components/checkout/payment-step-form/methods/crypto.tsx +227 -227
- package/components/checkout/payment-step-form/methods/index.ts +22 -22
- package/components/checkout/shipping-step-form.tsx +172 -172
- package/components/index.ts +11 -11
- package/components/item/product-card.tsx +48 -48
- package/components/item-selector/button.tsx +188 -188
- package/components/item-selector/carousel/index.tsx +197 -197
- package/components/item-selector/carousel/slider.tsx +40 -40
- package/components/item-selector/index.ts +5 -5
- package/components/item-selector/quantity-indicator.tsx +48 -48
- package/components/node-tabs/index.tsx +91 -91
- package/components/node-tabs/node-image.tsx +31 -31
- package/index.ts +12 -12
- package/package.json +60 -60
- package/service/context.tsx +45 -45
- package/service/debug.ts +41 -41
- package/service/impls/standalone/actual-line-item.ts +135 -135
- package/service/impls/standalone/get-instance.ts +64 -64
- package/service/impls/standalone/index.ts +579 -579
- package/service/impls/standalone/order/firebase.ts +14 -14
- package/service/impls/standalone/order/index.ts +128 -128
- package/service/impls/standalone/persistence.ts +33 -33
- package/service/path-utils.ts +25 -25
- package/service/sep.ts +6 -6
- package/tsconfig.json +10 -10
- package/types/README.md +1 -1
- package/types/category-node.ts +49 -49
- package/types/checkout.ts +46 -46
- package/types/commerce-config.ts +13 -13
- package/types/commerce-service.ts +127 -127
- package/types/family.ts +25 -25
- package/types/index.ts +15 -15
- package/types/item-selector.ts +96 -96
- package/types/line-item.ts +29 -29
- package/types/multi-family-selector-props.ts +19 -19
- package/types/product.ts +20 -20
- package/types/promo.ts +9 -9
- package/types/selection-ui-specifier.ts +51 -51
- package/types/string-mutator.ts +13 -13
- package/types/token-separators.ts +7 -7
- package/util/analytics.ts +20 -20
- package/util/countries.ts +195 -195
- package/util/error.ts +34 -34
- package/util/index.ts +70 -70
- package/util/item-selector-options-accessor.ts +34 -34
- package/util/line-item-ref.ts +23 -23
- package/util/multi-family-selector-options-accessor.ts +14 -14
- package/util/obs-string-mutator.ts +22 -22
- package/util/product-media-accessor.ts +58 -58
- package/util/promo-codes.ts +108 -108
- package/util/selection-ui-specifiers.ts +29 -29
- package/util/square-payment.ts +42 -42
- package/util/use-sync-sku-param-w-current-item.ts +88 -88
package/util/index.ts
CHANGED
|
@@ -1,71 +1,71 @@
|
|
|
1
|
-
import type { StringMutator, CommerceService } from '../types'
|
|
2
|
-
|
|
3
|
-
export function toTitleCase(str: string) {
|
|
4
|
-
return str.replace(
|
|
5
|
-
/\w\S*/g,
|
|
6
|
-
(txt) => txt.charAt(0).toUpperCase() + txt.slice(1).toLowerCase()
|
|
7
|
-
)
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export function slugify(str: string) {
|
|
11
|
-
return str
|
|
12
|
-
.toLowerCase()
|
|
13
|
-
.replace(/ /g, '-')
|
|
14
|
-
.replace(/[^\w-]+/g, '')
|
|
15
|
-
.replace(/--+/g, '-')
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export function unslugify(str: string) {
|
|
19
|
-
return str.replace(/-/g, ' ')
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
export function formatCurrencyValue(price: number): string {
|
|
24
|
-
const str = price.toLocaleString('en-US', {
|
|
25
|
-
style: 'currency',
|
|
26
|
-
currency: 'USD',
|
|
27
|
-
});
|
|
28
|
-
return (str.endsWith('.00')) ? str.replace('.00', '') : str
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export const getFacetValuesMutator = (level: number, cmmc: CommerceService): StringMutator => {
|
|
32
|
-
|
|
33
|
-
const setLevel = (value: string, level: number ): void => {
|
|
34
|
-
const facets = cmmc.selectedPaths
|
|
35
|
-
facets[level] = [value]
|
|
36
|
-
cmmc.selectPaths(facets)
|
|
37
|
-
const subFacets = cmmc.getSelectedNodesAtLevel(level)
|
|
38
|
-
if (subFacets) {
|
|
39
|
-
const facets = cmmc.selectedPaths
|
|
40
|
-
facets[level + 1] = [subFacets[0].skuToken]
|
|
41
|
-
cmmc.selectPaths(facets)
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
const getLevelValueSafe = (level: number): string | null => {
|
|
46
|
-
const facets = cmmc.selectedPaths
|
|
47
|
-
if (!(level in facets) || facets[level].length === 0 ) {
|
|
48
|
-
return null
|
|
49
|
-
}
|
|
50
|
-
return facets[level][0]
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
return {
|
|
54
|
-
get: (): string | null => (getLevelValueSafe(level)),
|
|
55
|
-
set: (v: string): void => {setLevel(v, level)}
|
|
56
|
-
} satisfies StringMutator
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
export { default as useSyncSkuParamWithCurrentItem } from './use-sync-sku-param-w-current-item'
|
|
60
|
-
export { default as processSquareCardPayment } from './square-payment'
|
|
61
|
-
export { default as ObsStringMutator } from './obs-string-mutator'
|
|
62
|
-
export { default as ProductMediaAccessor } from './product-media-accessor'
|
|
63
|
-
|
|
64
|
-
export * from './selection-ui-specifiers'
|
|
65
|
-
|
|
66
|
-
export { getErrorMessage } from './error'
|
|
67
|
-
|
|
68
|
-
export { default as accessItemOptions } from './item-selector-options-accessor'
|
|
69
|
-
export { default as accessMultiSelectorOptions } from './multi-family-selector-options-accessor'
|
|
70
|
-
|
|
1
|
+
import type { StringMutator, CommerceService } from '../types'
|
|
2
|
+
|
|
3
|
+
export function toTitleCase(str: string) {
|
|
4
|
+
return str.replace(
|
|
5
|
+
/\w\S*/g,
|
|
6
|
+
(txt) => txt.charAt(0).toUpperCase() + txt.slice(1).toLowerCase()
|
|
7
|
+
)
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export function slugify(str: string) {
|
|
11
|
+
return str
|
|
12
|
+
.toLowerCase()
|
|
13
|
+
.replace(/ /g, '-')
|
|
14
|
+
.replace(/[^\w-]+/g, '')
|
|
15
|
+
.replace(/--+/g, '-')
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function unslugify(str: string) {
|
|
19
|
+
return str.replace(/-/g, ' ')
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
export function formatCurrencyValue(price: number): string {
|
|
24
|
+
const str = price.toLocaleString('en-US', {
|
|
25
|
+
style: 'currency',
|
|
26
|
+
currency: 'USD',
|
|
27
|
+
});
|
|
28
|
+
return (str.endsWith('.00')) ? str.replace('.00', '') : str
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export const getFacetValuesMutator = (level: number, cmmc: CommerceService): StringMutator => {
|
|
32
|
+
|
|
33
|
+
const setLevel = (value: string, level: number ): void => {
|
|
34
|
+
const facets = cmmc.selectedPaths
|
|
35
|
+
facets[level] = [value]
|
|
36
|
+
cmmc.selectPaths(facets)
|
|
37
|
+
const subFacets = cmmc.getSelectedNodesAtLevel(level)
|
|
38
|
+
if (subFacets) {
|
|
39
|
+
const facets = cmmc.selectedPaths
|
|
40
|
+
facets[level + 1] = [subFacets[0].skuToken]
|
|
41
|
+
cmmc.selectPaths(facets)
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const getLevelValueSafe = (level: number): string | null => {
|
|
46
|
+
const facets = cmmc.selectedPaths
|
|
47
|
+
if (!(level in facets) || facets[level].length === 0 ) {
|
|
48
|
+
return null
|
|
49
|
+
}
|
|
50
|
+
return facets[level][0]
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return {
|
|
54
|
+
get: (): string | null => (getLevelValueSafe(level)),
|
|
55
|
+
set: (v: string): void => {setLevel(v, level)}
|
|
56
|
+
} satisfies StringMutator
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export { default as useSyncSkuParamWithCurrentItem } from './use-sync-sku-param-w-current-item'
|
|
60
|
+
export { default as processSquareCardPayment } from './square-payment'
|
|
61
|
+
export { default as ObsStringMutator } from './obs-string-mutator'
|
|
62
|
+
export { default as ProductMediaAccessor } from './product-media-accessor'
|
|
63
|
+
|
|
64
|
+
export * from './selection-ui-specifiers'
|
|
65
|
+
|
|
66
|
+
export { getErrorMessage } from './error'
|
|
67
|
+
|
|
68
|
+
export { default as accessItemOptions } from './item-selector-options-accessor'
|
|
69
|
+
export { default as accessMultiSelectorOptions } from './multi-family-selector-options-accessor'
|
|
70
|
+
|
|
71
71
|
export { default as LineItemRef} from './line-item-ref'
|
|
@@ -1,35 +1,35 @@
|
|
|
1
|
-
import type { ItemSelectorOptions } from '../types'
|
|
2
|
-
|
|
3
|
-
export default (options: ItemSelectorOptions | undefined = {}): Required<ItemSelectorOptions> => {
|
|
4
|
-
|
|
5
|
-
const familyTitle = 'familyTitle' in options ? options.familyTitle! : 'short'
|
|
6
|
-
const showFamilyByline = 'showFamilyByline' in options ? options.showFamilyByline! : false
|
|
7
|
-
|
|
8
|
-
const showFamilyInOption = 'showFamilyInOption' in options ? options.showFamilyInOption! : false
|
|
9
|
-
const showByline = 'showByline' in options ? options.showByline! : true
|
|
10
|
-
|
|
11
|
-
const showPrice = 'showPrice' in options ? options.showPrice! : true
|
|
12
|
-
const showQuantity = 'showQuantity' in options ? options.showQuantity! : false
|
|
13
|
-
|
|
14
|
-
const buttonType = 'buttonType' in options ? options.buttonType! : 'text'
|
|
15
|
-
const horizButtons = 'horizButtons' in options ? options.horizButtons! : false
|
|
16
|
-
const showSlider = 'showSlider' in options ? options.showSlider! : true
|
|
17
|
-
|
|
18
|
-
const showButtonIfOnlyOne = 'showButtonIfOnlyOne' in options ? options.showButtonIfOnlyOne! : true
|
|
19
|
-
|
|
20
|
-
const sort = 'sort' in options ? options.sort! : 'none'
|
|
21
|
-
|
|
22
|
-
return {
|
|
23
|
-
showFamilyInOption,
|
|
24
|
-
familyTitle,
|
|
25
|
-
showFamilyByline,
|
|
26
|
-
showByline,
|
|
27
|
-
showPrice,
|
|
28
|
-
showQuantity,
|
|
29
|
-
buttonType,
|
|
30
|
-
horizButtons,
|
|
31
|
-
showSlider,
|
|
32
|
-
showButtonIfOnlyOne,
|
|
33
|
-
sort,
|
|
34
|
-
}
|
|
1
|
+
import type { ItemSelectorOptions } from '../types'
|
|
2
|
+
|
|
3
|
+
export default (options: ItemSelectorOptions | undefined = {}): Required<ItemSelectorOptions> => {
|
|
4
|
+
|
|
5
|
+
const familyTitle = 'familyTitle' in options ? options.familyTitle! : 'short'
|
|
6
|
+
const showFamilyByline = 'showFamilyByline' in options ? options.showFamilyByline! : false
|
|
7
|
+
|
|
8
|
+
const showFamilyInOption = 'showFamilyInOption' in options ? options.showFamilyInOption! : false
|
|
9
|
+
const showByline = 'showByline' in options ? options.showByline! : true
|
|
10
|
+
|
|
11
|
+
const showPrice = 'showPrice' in options ? options.showPrice! : true
|
|
12
|
+
const showQuantity = 'showQuantity' in options ? options.showQuantity! : false
|
|
13
|
+
|
|
14
|
+
const buttonType = 'buttonType' in options ? options.buttonType! : 'text'
|
|
15
|
+
const horizButtons = 'horizButtons' in options ? options.horizButtons! : false
|
|
16
|
+
const showSlider = 'showSlider' in options ? options.showSlider! : true
|
|
17
|
+
|
|
18
|
+
const showButtonIfOnlyOne = 'showButtonIfOnlyOne' in options ? options.showButtonIfOnlyOne! : true
|
|
19
|
+
|
|
20
|
+
const sort = 'sort' in options ? options.sort! : 'none'
|
|
21
|
+
|
|
22
|
+
return {
|
|
23
|
+
showFamilyInOption,
|
|
24
|
+
familyTitle,
|
|
25
|
+
showFamilyByline,
|
|
26
|
+
showByline,
|
|
27
|
+
showPrice,
|
|
28
|
+
showQuantity,
|
|
29
|
+
buttonType,
|
|
30
|
+
horizButtons,
|
|
31
|
+
showSlider,
|
|
32
|
+
showButtonIfOnlyOne,
|
|
33
|
+
sort,
|
|
34
|
+
}
|
|
35
35
|
}
|
package/util/line-item-ref.ts
CHANGED
|
@@ -1,23 +1,23 @@
|
|
|
1
|
-
import { observable, action, computed, makeObservable } from 'mobx'
|
|
2
|
-
|
|
3
|
-
import type { LineItem, ObsLineItemRef } from '../types'
|
|
4
|
-
|
|
5
|
-
class LineItemRef implements ObsLineItemRef {
|
|
6
|
-
|
|
7
|
-
_item: LineItem | undefined = undefined
|
|
8
|
-
|
|
9
|
-
constructor() {
|
|
10
|
-
|
|
11
|
-
makeObservable(this, {
|
|
12
|
-
_item: observable,
|
|
13
|
-
item: computed,
|
|
14
|
-
set: action
|
|
15
|
-
})
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
get item(): LineItem | undefined { return this._item }
|
|
19
|
-
|
|
20
|
-
set = (v: LineItem | undefined): void => { this._item = v }
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export default LineItemRef
|
|
1
|
+
import { observable, action, computed, makeObservable } from 'mobx'
|
|
2
|
+
|
|
3
|
+
import type { LineItem, ObsLineItemRef } from '../types'
|
|
4
|
+
|
|
5
|
+
class LineItemRef implements ObsLineItemRef {
|
|
6
|
+
|
|
7
|
+
_item: LineItem | undefined = undefined
|
|
8
|
+
|
|
9
|
+
constructor() {
|
|
10
|
+
|
|
11
|
+
makeObservable(this, {
|
|
12
|
+
_item: observable,
|
|
13
|
+
item: computed,
|
|
14
|
+
set: action
|
|
15
|
+
})
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
get item(): LineItem | undefined { return this._item }
|
|
19
|
+
|
|
20
|
+
set = (v: LineItem | undefined): void => { this._item = v }
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export default LineItemRef
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import type { MultiFamilySelectorOptions } from '../types'
|
|
2
|
-
|
|
3
|
-
export default (options: MultiFamilySelectorOptions | undefined = {}): Required<MultiFamilySelectorOptions> => {
|
|
4
|
-
|
|
5
|
-
const showParentTitle = 'showParentTitle' in options ? options.showParentTitle! : true
|
|
6
|
-
const showItemSwatches = 'showItemSwatches' in options ? options.showItemSwatches! : true
|
|
7
|
-
|
|
8
|
-
const parentByline = 'parentByline' in options ? options.parentByline! : 'none'
|
|
9
|
-
|
|
10
|
-
return {
|
|
11
|
-
showParentTitle,
|
|
12
|
-
showItemSwatches,
|
|
13
|
-
parentByline,
|
|
14
|
-
}
|
|
1
|
+
import type { MultiFamilySelectorOptions } from '../types'
|
|
2
|
+
|
|
3
|
+
export default (options: MultiFamilySelectorOptions | undefined = {}): Required<MultiFamilySelectorOptions> => {
|
|
4
|
+
|
|
5
|
+
const showParentTitle = 'showParentTitle' in options ? options.showParentTitle! : true
|
|
6
|
+
const showItemSwatches = 'showItemSwatches' in options ? options.showItemSwatches! : true
|
|
7
|
+
|
|
8
|
+
const parentByline = 'parentByline' in options ? options.parentByline! : 'none'
|
|
9
|
+
|
|
10
|
+
return {
|
|
11
|
+
showParentTitle,
|
|
12
|
+
showItemSwatches,
|
|
13
|
+
parentByline,
|
|
14
|
+
}
|
|
15
15
|
}
|
|
@@ -1,22 +1,22 @@
|
|
|
1
|
-
import {makeObservable, observable, action} from 'mobx'
|
|
2
|
-
|
|
3
|
-
import type { StringMutator } from '../types'
|
|
4
|
-
|
|
5
|
-
class ObsStringMutator implements StringMutator {
|
|
6
|
-
|
|
7
|
-
_s: string | null
|
|
8
|
-
|
|
9
|
-
constructor(s: string) {
|
|
10
|
-
this._s = s
|
|
11
|
-
makeObservable(this, {
|
|
12
|
-
_s: observable,
|
|
13
|
-
set: action,
|
|
14
|
-
//get: computed .// no need
|
|
15
|
-
})
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
set(v: string | null): void { this._s = v }
|
|
19
|
-
get(): string | null { return this._s }
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export default ObsStringMutator
|
|
1
|
+
import {makeObservable, observable, action} from 'mobx'
|
|
2
|
+
|
|
3
|
+
import type { StringMutator } from '../types'
|
|
4
|
+
|
|
5
|
+
class ObsStringMutator implements StringMutator {
|
|
6
|
+
|
|
7
|
+
_s: string | null
|
|
8
|
+
|
|
9
|
+
constructor(s: string) {
|
|
10
|
+
this._s = s
|
|
11
|
+
makeObservable(this, {
|
|
12
|
+
_s: observable,
|
|
13
|
+
set: action,
|
|
14
|
+
//get: computed .// no need
|
|
15
|
+
})
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
set(v: string | null): void { this._s = v }
|
|
19
|
+
get(): string | null { return this._s }
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export default ObsStringMutator
|
|
@@ -1,58 +1,58 @@
|
|
|
1
|
-
import type { AnimationDef, ImageDef, MediaStackDef, VideoDef } from '@hanzo/ui/types'
|
|
2
|
-
|
|
3
|
-
interface FamilyMediaData {
|
|
4
|
-
img?: Record<string, ImageDef>
|
|
5
|
-
video?: Record<string, VideoDef>
|
|
6
|
-
anim?: Record<string, AnimationDef>
|
|
7
|
-
optionImg?: Record<string, ImageDef>
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
class ProductMediaAccessor {
|
|
11
|
-
|
|
12
|
-
_data: FamilyMediaData
|
|
13
|
-
|
|
14
|
-
constructor(data: FamilyMediaData) {
|
|
15
|
-
this._data = data
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
img = (key: string): ImageDef | undefined => (
|
|
19
|
-
(this._data.img) ? this._data.img[key] : undefined
|
|
20
|
-
)
|
|
21
|
-
|
|
22
|
-
spreadableImg = (key: string): { img?: ImageDef } => (
|
|
23
|
-
(this._data.img) ? {img: this._data.img[key]} : {}
|
|
24
|
-
)
|
|
25
|
-
|
|
26
|
-
video = (key: string): VideoDef | undefined => (
|
|
27
|
-
(this._data.video) ? this._data.video[key] : undefined
|
|
28
|
-
)
|
|
29
|
-
|
|
30
|
-
spreadableVideo = (key: string): { video?: VideoDef } => (
|
|
31
|
-
(this._data.video) ? {video: this._data.video[key]} : {}
|
|
32
|
-
)
|
|
33
|
-
|
|
34
|
-
anim = (key: string): AnimationDef | undefined => (
|
|
35
|
-
(this._data.anim) ? this._data.anim[key] : undefined
|
|
36
|
-
)
|
|
37
|
-
|
|
38
|
-
spreadableAnim = (key: string): { animation?: AnimationDef } => (
|
|
39
|
-
(this._data.anim) ? {animation: this._data.anim[key]} : {}
|
|
40
|
-
)
|
|
41
|
-
|
|
42
|
-
mediaStack = (key: string): MediaStackDef => ({
|
|
43
|
-
...this.spreadableImg(key),
|
|
44
|
-
...this.spreadableVideo(key),
|
|
45
|
-
...this.spreadableAnim(key)
|
|
46
|
-
})
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
optionImg = (key: string): ImageDef | undefined => (
|
|
50
|
-
(this._data.optionImg) ? this._data.optionImg[key] : undefined
|
|
51
|
-
)
|
|
52
|
-
|
|
53
|
-
spreadableOptionImg = (key: string): { optionImg?: ImageDef } => {
|
|
54
|
-
return (this._data.optionImg) ? { optionImg: this._data.optionImg[key]} : {}
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
export default ProductMediaAccessor
|
|
1
|
+
import type { AnimationDef, ImageDef, MediaStackDef, VideoDef } from '@hanzo/ui/types'
|
|
2
|
+
|
|
3
|
+
interface FamilyMediaData {
|
|
4
|
+
img?: Record<string, ImageDef>
|
|
5
|
+
video?: Record<string, VideoDef>
|
|
6
|
+
anim?: Record<string, AnimationDef>
|
|
7
|
+
optionImg?: Record<string, ImageDef>
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
class ProductMediaAccessor {
|
|
11
|
+
|
|
12
|
+
_data: FamilyMediaData
|
|
13
|
+
|
|
14
|
+
constructor(data: FamilyMediaData) {
|
|
15
|
+
this._data = data
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
img = (key: string): ImageDef | undefined => (
|
|
19
|
+
(this._data.img) ? this._data.img[key] : undefined
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
spreadableImg = (key: string): { img?: ImageDef } => (
|
|
23
|
+
(this._data.img) ? {img: this._data.img[key]} : {}
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
video = (key: string): VideoDef | undefined => (
|
|
27
|
+
(this._data.video) ? this._data.video[key] : undefined
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
spreadableVideo = (key: string): { video?: VideoDef } => (
|
|
31
|
+
(this._data.video) ? {video: this._data.video[key]} : {}
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
anim = (key: string): AnimationDef | undefined => (
|
|
35
|
+
(this._data.anim) ? this._data.anim[key] : undefined
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
spreadableAnim = (key: string): { animation?: AnimationDef } => (
|
|
39
|
+
(this._data.anim) ? {animation: this._data.anim[key]} : {}
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
mediaStack = (key: string): MediaStackDef => ({
|
|
43
|
+
...this.spreadableImg(key),
|
|
44
|
+
...this.spreadableVideo(key),
|
|
45
|
+
...this.spreadableAnim(key)
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
optionImg = (key: string): ImageDef | undefined => (
|
|
50
|
+
(this._data.optionImg) ? this._data.optionImg[key] : undefined
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
spreadableOptionImg = (key: string): { optionImg?: ImageDef } => {
|
|
54
|
+
return (this._data.optionImg) ? { optionImg: this._data.optionImg[key]} : {}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export default ProductMediaAccessor
|
package/util/promo-codes.ts
CHANGED
|
@@ -1,108 +1,108 @@
|
|
|
1
|
-
'use server'
|
|
2
|
-
|
|
3
|
-
import type { Promo } from '../types'
|
|
4
|
-
|
|
5
|
-
const referallCodeDiscountedSkus = [
|
|
6
|
-
'LXM-CR-B-ABT', 'LXM-CR-B-GM', 'LXM-CR-F-CC', 'LXM-CR-F-IC', 'LXM-CR-E-24G', 'LXM-CR-E-SS', 'LXM-CR-S-RT', // credit cards
|
|
7
|
-
'LXM-VL-GN', 'LXM-VL-VL', 'LXM-VL-MI', 'LXM-VL-NA', // validators
|
|
8
|
-
'LXM-PS-PS', // pass
|
|
9
|
-
'LXM-AG-B-1_OZ', // silver
|
|
10
|
-
]
|
|
11
|
-
|
|
12
|
-
const PROMO_CODES: Promo[] = [
|
|
13
|
-
{
|
|
14
|
-
type: 'percent',
|
|
15
|
-
code: 'ANGEL',
|
|
16
|
-
value: 22
|
|
17
|
-
},
|
|
18
|
-
{
|
|
19
|
-
type: 'percent',
|
|
20
|
-
code: 'NASSER',
|
|
21
|
-
value: 11.11
|
|
22
|
-
},
|
|
23
|
-
{
|
|
24
|
-
type: 'percent',
|
|
25
|
-
code: 'ROSEY',
|
|
26
|
-
value: 20
|
|
27
|
-
},
|
|
28
|
-
{
|
|
29
|
-
type: 'percent',
|
|
30
|
-
code: 'IYKYK',
|
|
31
|
-
value: 11.1
|
|
32
|
-
},
|
|
33
|
-
{
|
|
34
|
-
type: 'percent',
|
|
35
|
-
code: 'GENESIS',
|
|
36
|
-
value: 99,
|
|
37
|
-
skus: ['LXM-PS-PS']
|
|
38
|
-
},
|
|
39
|
-
{
|
|
40
|
-
type: 'percent',
|
|
41
|
-
code: 'ANTJE',
|
|
42
|
-
value: 33.3,
|
|
43
|
-
skus: referallCodeDiscountedSkus
|
|
44
|
-
},
|
|
45
|
-
{
|
|
46
|
-
type: 'percent',
|
|
47
|
-
code: 'ASHLEY',
|
|
48
|
-
value: 33.3,
|
|
49
|
-
skus: referallCodeDiscountedSkus
|
|
50
|
-
},
|
|
51
|
-
{
|
|
52
|
-
type: 'percent',
|
|
53
|
-
code: 'CALE',
|
|
54
|
-
value: 33.3,
|
|
55
|
-
skus: referallCodeDiscountedSkus
|
|
56
|
-
},
|
|
57
|
-
{
|
|
58
|
-
type: 'percent',
|
|
59
|
-
code: 'DARA',
|
|
60
|
-
value: 33.3,
|
|
61
|
-
skus: referallCodeDiscountedSkus
|
|
62
|
-
},
|
|
63
|
-
{
|
|
64
|
-
type: 'percent',
|
|
65
|
-
code: 'KENJI',
|
|
66
|
-
value: 33.3,
|
|
67
|
-
skus: referallCodeDiscountedSkus
|
|
68
|
-
},
|
|
69
|
-
{
|
|
70
|
-
type: 'percent',
|
|
71
|
-
code: 'MAJOR',
|
|
72
|
-
value: 33.3,
|
|
73
|
-
skus: referallCodeDiscountedSkus
|
|
74
|
-
},
|
|
75
|
-
{
|
|
76
|
-
type: 'percent',
|
|
77
|
-
code: 'CYRUS',
|
|
78
|
-
value: 33.3,
|
|
79
|
-
skus: referallCodeDiscountedSkus
|
|
80
|
-
},
|
|
81
|
-
{
|
|
82
|
-
type: 'percent',
|
|
83
|
-
code: 'STOBIE',
|
|
84
|
-
value: 33.3,
|
|
85
|
-
skus: referallCodeDiscountedSkus
|
|
86
|
-
},
|
|
87
|
-
{
|
|
88
|
-
type: 'percent',
|
|
89
|
-
code: 'SKYLER',
|
|
90
|
-
value: 33.3,
|
|
91
|
-
skus: referallCodeDiscountedSkus
|
|
92
|
-
},
|
|
93
|
-
{
|
|
94
|
-
type: 'percent',
|
|
95
|
-
code: 'ZEEKAY',
|
|
96
|
-
value: 33.3,
|
|
97
|
-
skus: referallCodeDiscountedSkus
|
|
98
|
-
}
|
|
99
|
-
]
|
|
100
|
-
|
|
101
|
-
// TODO: implement a real API call
|
|
102
|
-
const getPromoFromApi = async (code: string) => {
|
|
103
|
-
return PROMO_CODES.find(promo => promo.code === code)
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
export {
|
|
107
|
-
getPromoFromApi as default
|
|
108
|
-
}
|
|
1
|
+
'use server'
|
|
2
|
+
|
|
3
|
+
import type { Promo } from '../types'
|
|
4
|
+
|
|
5
|
+
const referallCodeDiscountedSkus = [
|
|
6
|
+
'LXM-CR-B-ABT', 'LXM-CR-B-GM', 'LXM-CR-F-CC', 'LXM-CR-F-IC', 'LXM-CR-E-24G', 'LXM-CR-E-SS', 'LXM-CR-S-RT', // credit cards
|
|
7
|
+
'LXM-VL-GN', 'LXM-VL-VL', 'LXM-VL-MI', 'LXM-VL-NA', // validators
|
|
8
|
+
'LXM-PS-PS', // pass
|
|
9
|
+
'LXM-AG-B-1_OZ', // silver
|
|
10
|
+
]
|
|
11
|
+
|
|
12
|
+
const PROMO_CODES: Promo[] = [
|
|
13
|
+
{
|
|
14
|
+
type: 'percent',
|
|
15
|
+
code: 'ANGEL',
|
|
16
|
+
value: 22
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
type: 'percent',
|
|
20
|
+
code: 'NASSER',
|
|
21
|
+
value: 11.11
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
type: 'percent',
|
|
25
|
+
code: 'ROSEY',
|
|
26
|
+
value: 20
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
type: 'percent',
|
|
30
|
+
code: 'IYKYK',
|
|
31
|
+
value: 11.1
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
type: 'percent',
|
|
35
|
+
code: 'GENESIS',
|
|
36
|
+
value: 99,
|
|
37
|
+
skus: ['LXM-PS-PS']
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
type: 'percent',
|
|
41
|
+
code: 'ANTJE',
|
|
42
|
+
value: 33.3,
|
|
43
|
+
skus: referallCodeDiscountedSkus
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
type: 'percent',
|
|
47
|
+
code: 'ASHLEY',
|
|
48
|
+
value: 33.3,
|
|
49
|
+
skus: referallCodeDiscountedSkus
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
type: 'percent',
|
|
53
|
+
code: 'CALE',
|
|
54
|
+
value: 33.3,
|
|
55
|
+
skus: referallCodeDiscountedSkus
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
type: 'percent',
|
|
59
|
+
code: 'DARA',
|
|
60
|
+
value: 33.3,
|
|
61
|
+
skus: referallCodeDiscountedSkus
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
type: 'percent',
|
|
65
|
+
code: 'KENJI',
|
|
66
|
+
value: 33.3,
|
|
67
|
+
skus: referallCodeDiscountedSkus
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
type: 'percent',
|
|
71
|
+
code: 'MAJOR',
|
|
72
|
+
value: 33.3,
|
|
73
|
+
skus: referallCodeDiscountedSkus
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
type: 'percent',
|
|
77
|
+
code: 'CYRUS',
|
|
78
|
+
value: 33.3,
|
|
79
|
+
skus: referallCodeDiscountedSkus
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
type: 'percent',
|
|
83
|
+
code: 'STOBIE',
|
|
84
|
+
value: 33.3,
|
|
85
|
+
skus: referallCodeDiscountedSkus
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
type: 'percent',
|
|
89
|
+
code: 'SKYLER',
|
|
90
|
+
value: 33.3,
|
|
91
|
+
skus: referallCodeDiscountedSkus
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
type: 'percent',
|
|
95
|
+
code: 'ZEEKAY',
|
|
96
|
+
value: 33.3,
|
|
97
|
+
skus: referallCodeDiscountedSkus
|
|
98
|
+
}
|
|
99
|
+
]
|
|
100
|
+
|
|
101
|
+
// TODO: implement a real API call
|
|
102
|
+
const getPromoFromApi = async (code: string) => {
|
|
103
|
+
return PROMO_CODES.find(promo => promo.code === code)
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export {
|
|
107
|
+
getPromoFromApi as default
|
|
108
|
+
}
|