@hanzo/commerce 7.3.0 → 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.
Files changed (83) hide show
  1. package/components/Icons.tsx +34 -34
  2. package/components/add-to-cart-widget.tsx +183 -183
  3. package/components/buy/buy-card.tsx +259 -259
  4. package/components/buy/carousel-buy-card.tsx +242 -242
  5. package/components/buy/multi-family/all-variants-carousel.tsx +261 -261
  6. package/components/buy/multi-family/family-carousel/index.tsx +77 -77
  7. package/components/buy/multi-family/family-carousel/slide.tsx +83 -83
  8. package/components/buy/multi-family/family-carousel/state.ts +87 -87
  9. package/components/buy/multi-family/index.ts +2 -2
  10. package/components/buy/single-family-selector.tsx +90 -90
  11. package/components/buy/title-and-byline.tsx +25 -25
  12. package/components/cart/cart-panel/cart-line-item.tsx +76 -76
  13. package/components/cart/cart-panel/index.tsx +154 -154
  14. package/components/cart/cart-panel/promo-code.tsx +106 -106
  15. package/components/cart/cart-panel/total-area.tsx +60 -60
  16. package/components/checkout/payment-step-form/card-icon-row.tsx +26 -26
  17. package/components/checkout/payment-step-form/card-icons/amex.tsx +32 -32
  18. package/components/checkout/payment-step-form/card-icons/diners-club.tsx +13 -13
  19. package/components/checkout/payment-step-form/card-icons/discover.tsx +25 -25
  20. package/components/checkout/payment-step-form/card-icons/jcb.tsx +26 -26
  21. package/components/checkout/payment-step-form/card-icons/mastercard.tsx +27 -27
  22. package/components/checkout/payment-step-form/card-icons/visa.tsx +25 -25
  23. package/components/checkout/payment-step-form/cc-button.tsx +17 -17
  24. package/components/checkout/payment-step-form/contact-form.tsx +49 -49
  25. package/components/checkout/payment-step-form/crypto-icons/btc.tsx +11 -11
  26. package/components/checkout/payment-step-form/crypto-icons/eth.tsx +20 -20
  27. package/components/checkout/payment-step-form/crypto-icons/usdt.tsx +13 -13
  28. package/components/checkout/payment-step-form/index.tsx +122 -122
  29. package/components/checkout/payment-step-form/methods/bank-transfer.tsx +79 -79
  30. package/components/checkout/payment-step-form/methods/card.tsx +232 -232
  31. package/components/checkout/payment-step-form/methods/crypto.tsx +227 -227
  32. package/components/checkout/payment-step-form/methods/index.ts +22 -22
  33. package/components/checkout/shipping-step-form.tsx +172 -172
  34. package/components/index.ts +11 -11
  35. package/components/item/product-card.tsx +48 -48
  36. package/components/item-selector/button.tsx +188 -188
  37. package/components/item-selector/carousel/index.tsx +197 -197
  38. package/components/item-selector/carousel/slider.tsx +40 -40
  39. package/components/item-selector/index.ts +5 -5
  40. package/components/item-selector/quantity-indicator.tsx +48 -48
  41. package/components/node-tabs/index.tsx +91 -91
  42. package/components/node-tabs/node-image.tsx +31 -31
  43. package/index.ts +12 -12
  44. package/package.json +60 -60
  45. package/service/context.tsx +45 -45
  46. package/service/debug.ts +41 -41
  47. package/service/impls/standalone/actual-line-item.ts +135 -135
  48. package/service/impls/standalone/get-instance.ts +64 -64
  49. package/service/impls/standalone/index.ts +579 -579
  50. package/service/impls/standalone/order/firebase.ts +14 -14
  51. package/service/impls/standalone/order/index.ts +128 -128
  52. package/service/impls/standalone/persistence.ts +33 -33
  53. package/service/path-utils.ts +25 -25
  54. package/service/sep.ts +6 -6
  55. package/tsconfig.json +10 -10
  56. package/types/README.md +1 -1
  57. package/types/category-node.ts +49 -49
  58. package/types/checkout.ts +46 -46
  59. package/types/commerce-config.ts +13 -13
  60. package/types/commerce-service.ts +127 -127
  61. package/types/family.ts +25 -25
  62. package/types/index.ts +15 -15
  63. package/types/item-selector.ts +96 -96
  64. package/types/line-item.ts +29 -29
  65. package/types/multi-family-selector-props.ts +19 -19
  66. package/types/product.ts +20 -20
  67. package/types/promo.ts +9 -9
  68. package/types/selection-ui-specifier.ts +51 -51
  69. package/types/string-mutator.ts +13 -13
  70. package/types/token-separators.ts +7 -7
  71. package/util/analytics.ts +20 -20
  72. package/util/countries.ts +195 -195
  73. package/util/error.ts +34 -34
  74. package/util/index.ts +70 -70
  75. package/util/item-selector-options-accessor.ts +34 -34
  76. package/util/line-item-ref.ts +23 -23
  77. package/util/multi-family-selector-options-accessor.ts +14 -14
  78. package/util/obs-string-mutator.ts +22 -22
  79. package/util/product-media-accessor.ts +58 -58
  80. package/util/promo-codes.ts +108 -108
  81. package/util/selection-ui-specifiers.ts +29 -29
  82. package/util/square-payment.ts +42 -42
  83. package/util/use-sync-sku-param-w-current-item.ts +88 -88
@@ -1,30 +1,30 @@
1
- import type { SelectionUISpecifier } from '../types'
2
- import sep from '../service/sep'
3
-
4
- const DEFAULT = {
5
- multiFamily: {
6
- type: 'all-variants-carousel'
7
- },
8
- singleFamily: { type: 'carousel' }
9
- } satisfies SelectionUISpecifier
10
-
11
- const map = new Map<string, SelectionUISpecifier>()
12
-
13
- // key: first two tokens of path
14
- export const initSelectionUI = (v: Record<string, SelectionUISpecifier>) => {
15
-
16
- // Might have multiple calls client and server side
17
- if (map.size > 0) {
18
- map.clear()
19
- }
20
-
21
- for (let [key, value] of Object.entries(v)) {
22
- map.set(key, value)
23
- }
24
- }
25
-
26
- export const getSelectionUISpecifier = (skuPath: string): SelectionUISpecifier => {
27
- const key = skuPath.split(sep.tok).slice(0, 2).join(sep.tok)
28
- const result = map.get(key)
29
- return result ?? DEFAULT
1
+ import type { SelectionUISpecifier } from '../types'
2
+ import sep from '../service/sep'
3
+
4
+ const DEFAULT = {
5
+ multiFamily: {
6
+ type: 'all-variants-carousel'
7
+ },
8
+ singleFamily: { type: 'carousel' }
9
+ } satisfies SelectionUISpecifier
10
+
11
+ const map = new Map<string, SelectionUISpecifier>()
12
+
13
+ // key: first two tokens of path
14
+ export const initSelectionUI = (v: Record<string, SelectionUISpecifier>) => {
15
+
16
+ // Might have multiple calls client and server side
17
+ if (map.size > 0) {
18
+ map.clear()
19
+ }
20
+
21
+ for (let [key, value] of Object.entries(v)) {
22
+ map.set(key, value)
23
+ }
24
+ }
25
+
26
+ export const getSelectionUISpecifier = (skuPath: string): SelectionUISpecifier => {
27
+ const key = skuPath.split(sep.tok).slice(0, 2).join(sep.tok)
28
+ const result = map.get(key)
29
+ return result ?? DEFAULT
30
30
  }
@@ -1,43 +1,43 @@
1
- 'use server'
2
-
3
- import { Client, Environment } from 'square'
4
- import { randomUUID } from 'crypto'
5
-
6
- // https://developer.squareup.com/blog/online-payments-with-square-and-react/
7
- declare global {
8
- interface BigInt {
9
- toJSON(): string;
10
- }
11
- }
12
-
13
- BigInt.prototype.toJSON = function() { return this.toString(); }
14
-
15
- const { paymentsApi } = new Client({
16
- accessToken: process.env.SQUARE_ACCESS_TOKEN,
17
- environment: process.env.SQUARE_ENVIRONMENT as Environment
18
- })
19
-
20
- const processPayment = async (sourceId: string, amount: number, verificationToken: string) => {
21
- // Square API accepts amount in cents
22
- const amountInCents = amount * 100
23
-
24
- try {
25
- const { result } = await paymentsApi.createPayment({
26
- idempotencyKey: randomUUID(),
27
- sourceId: sourceId,
28
- amountMoney: {
29
- currency: 'USD',
30
- amount: BigInt(amountInCents)
31
- },
32
- verificationToken
33
- })
34
- return result
35
- } catch (error) {
36
- console.error('Error processing payment:', error)
37
- return null
38
- }
39
- }
40
-
41
- export {
42
- processPayment as default
1
+ 'use server'
2
+
3
+ import { Client, Environment } from 'square'
4
+ import { randomUUID } from 'crypto'
5
+
6
+ // https://developer.squareup.com/blog/online-payments-with-square-and-react/
7
+ declare global {
8
+ interface BigInt {
9
+ toJSON(): string;
10
+ }
11
+ }
12
+
13
+ BigInt.prototype.toJSON = function() { return this.toString(); }
14
+
15
+ const { paymentsApi } = new Client({
16
+ accessToken: process.env.SQUARE_ACCESS_TOKEN,
17
+ environment: process.env.SQUARE_ENVIRONMENT as Environment
18
+ })
19
+
20
+ const processPayment = async (sourceId: string, amount: number, verificationToken: string) => {
21
+ // Square API accepts amount in cents
22
+ const amountInCents = amount * 100
23
+
24
+ try {
25
+ const { result } = await paymentsApi.createPayment({
26
+ idempotencyKey: randomUUID(),
27
+ sourceId: sourceId,
28
+ amountMoney: {
29
+ currency: 'USD',
30
+ amount: BigInt(amountInCents)
31
+ },
32
+ verificationToken
33
+ })
34
+ return result
35
+ } catch (error) {
36
+ console.error('Error processing payment:', error)
37
+ return null
38
+ }
39
+ }
40
+
41
+ export {
42
+ processPayment as default
43
43
  }
@@ -1,88 +1,88 @@
1
- "use client"
2
- import { useEffect } from 'react'
3
- import { reaction } from 'mobx'
4
-
5
- import {
6
- useQueryState,
7
- parseAsString,
8
- parseAsBoolean,
9
- } from 'next-usequerystate'
10
-
11
- import { useCommerce } from '../service/context'
12
- import type { SelectedPaths } from '../types'
13
- import sep from '../service/sep'
14
-
15
- const PLEASE_SELECT_FACETS = 'Please select an option from each group.'
16
-
17
- const useSyncSkuParamWithCurrentItem = (
18
- familyLevel: number,
19
- setMessage: (m: string | undefined) => void,
20
- setLoading?: (l: boolean) => void
21
- ) => {
22
-
23
- const cmmc = useCommerce()
24
-
25
- const [skuParam, setSkuParam] = useQueryState('sku',
26
- parseAsString.withDefault('').withOptions({ clearOnDefault: true })
27
- )
28
-
29
- const [addParam, setAddParam] = useQueryState('add',
30
- parseAsBoolean.withDefault(false).withOptions({ clearOnDefault: true })
31
- )
32
-
33
- useEffect(() => {
34
-
35
- return reaction(() => ({
36
- specifiedCat: cmmc.selectedFamilies.length === 1 ? cmmc.selectedFamilies[0] : undefined,
37
- currentItem: cmmc.currentItem
38
- }),
39
- ({specifiedCat, currentItem}) => {
40
- //console.log("REACTION: " + `CAT ID: ${family?.id} SKU: ${item?.sku}`)
41
- if (currentItem) {
42
- // if we set the currentItem w sku, then user selects other facets
43
- if (specifiedCat && currentItem.familyId != specifiedCat.id ) {
44
- cmmc.setCurrentItem(specifiedCat.products[0].sku)
45
- }
46
- setSkuParam(cmmc.currentItem!.sku)
47
- }
48
- else if (specifiedCat) {
49
- cmmc.setCurrentItem(specifiedCat.products[0].sku)
50
- setSkuParam(cmmc.currentItem!.sku)
51
- }
52
- })
53
- }, [])
54
-
55
- useEffect(() => {
56
-
57
- const setCurrentFamilyFromSku = (sku: string) => {
58
- const toks: string[] = sku.split(sep.tok)
59
- const fv: SelectedPaths = {}
60
- // TODO: confirm that extra trailing nonsense tokens won't break selectPaths()
61
- for (let i = 1; i < familyLevel; i++) {
62
- if (i in toks) {
63
- fv[i] = [toks[i]]
64
- }
65
- }
66
- cmmc.selectPaths(fv)
67
- }
68
-
69
- // setCI returns true if it's a recognized sku
70
- if (skuParam && cmmc.setCurrentItem(skuParam)) {
71
- if (addParam) {
72
- if (cmmc.currentItem!.quantity === 0) {
73
- cmmc.currentItem!.increment()
74
- }
75
- setAddParam(false)
76
- }
77
- setCurrentFamilyFromSku(skuParam)
78
- setMessage(undefined)
79
- }
80
- else {
81
- setMessage(PLEASE_SELECT_FACETS)
82
- }
83
-
84
- setLoading && setLoading(false)
85
- }, [skuParam])
86
- }
87
-
88
- export default useSyncSkuParamWithCurrentItem
1
+ "use client"
2
+ import { useEffect } from 'react'
3
+ import { reaction } from 'mobx'
4
+
5
+ import {
6
+ useQueryState,
7
+ parseAsString,
8
+ parseAsBoolean,
9
+ } from 'next-usequerystate'
10
+
11
+ import { useCommerce } from '../service/context'
12
+ import type { SelectedPaths } from '../types'
13
+ import sep from '../service/sep'
14
+
15
+ const PLEASE_SELECT_FACETS = 'Please select an option from each group.'
16
+
17
+ const useSyncSkuParamWithCurrentItem = (
18
+ familyLevel: number,
19
+ setMessage: (m: string | undefined) => void,
20
+ setLoading?: (l: boolean) => void
21
+ ) => {
22
+
23
+ const cmmc = useCommerce()
24
+
25
+ const [skuParam, setSkuParam] = useQueryState('sku',
26
+ parseAsString.withDefault('').withOptions({ clearOnDefault: true })
27
+ )
28
+
29
+ const [addParam, setAddParam] = useQueryState('add',
30
+ parseAsBoolean.withDefault(false).withOptions({ clearOnDefault: true })
31
+ )
32
+
33
+ useEffect(() => {
34
+
35
+ return reaction(() => ({
36
+ specifiedCat: cmmc.selectedFamilies.length === 1 ? cmmc.selectedFamilies[0] : undefined,
37
+ currentItem: cmmc.currentItem
38
+ }),
39
+ ({specifiedCat, currentItem}) => {
40
+ //console.log("REACTION: " + `CAT ID: ${family?.id} SKU: ${item?.sku}`)
41
+ if (currentItem) {
42
+ // if we set the currentItem w sku, then user selects other facets
43
+ if (specifiedCat && currentItem.familyId != specifiedCat.id ) {
44
+ cmmc.setCurrentItem(specifiedCat.products[0].sku)
45
+ }
46
+ setSkuParam(cmmc.currentItem!.sku)
47
+ }
48
+ else if (specifiedCat) {
49
+ cmmc.setCurrentItem(specifiedCat.products[0].sku)
50
+ setSkuParam(cmmc.currentItem!.sku)
51
+ }
52
+ })
53
+ }, [])
54
+
55
+ useEffect(() => {
56
+
57
+ const setCurrentFamilyFromSku = (sku: string) => {
58
+ const toks: string[] = sku.split(sep.tok)
59
+ const fv: SelectedPaths = {}
60
+ // TODO: confirm that extra trailing nonsense tokens won't break selectPaths()
61
+ for (let i = 1; i < familyLevel; i++) {
62
+ if (i in toks) {
63
+ fv[i] = [toks[i]]
64
+ }
65
+ }
66
+ cmmc.selectPaths(fv)
67
+ }
68
+
69
+ // setCI returns true if it's a recognized sku
70
+ if (skuParam && cmmc.setCurrentItem(skuParam)) {
71
+ if (addParam) {
72
+ if (cmmc.currentItem!.quantity === 0) {
73
+ cmmc.currentItem!.increment()
74
+ }
75
+ setAddParam(false)
76
+ }
77
+ setCurrentFamilyFromSku(skuParam)
78
+ setMessage(undefined)
79
+ }
80
+ else {
81
+ setMessage(PLEASE_SELECT_FACETS)
82
+ }
83
+
84
+ setLoading && setLoading(false)
85
+ }, [skuParam])
86
+ }
87
+
88
+ export default useSyncSkuParamWithCurrentItem