@luxfi/core 5.1.5 → 5.1.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (125) hide show
  1. package/commerce/{AUTO-GEN-bullion-by-family.json → data/AUTO-GEN-bullion-by-family.json} +33 -33
  2. package/commerce/{EDIT-ME-bullion-market-prices.ts → data/EDIT-ME-bullion-market-prices.ts} +11 -11
  3. package/commerce/{assign-prices.ts → data/assign-prices.ts} +49 -49
  4. package/commerce/{assign-videos-by-family-group.ts → data/assign-videos-by-family-group.ts} +14 -14
  5. package/commerce/{bullion-price-1oz.ts → data/bullion-price-1oz.ts} +5 -5
  6. package/commerce/{index.ts → data/index.ts} +18 -18
  7. package/commerce/ui/conf.ts +13 -0
  8. package/commerce/ui/context.tsx +102 -0
  9. package/commerce/ui/store.ts +277 -0
  10. package/components/access-code-input.tsx +71 -71
  11. package/components/auth/auth-listener.tsx +29 -29
  12. package/components/auth/auth-token/clear-auth-token.tsx +12 -12
  13. package/components/auth/auth-token/set-auth-token.tsx +16 -16
  14. package/components/auth/common-auth-domains.ts +16 -16
  15. package/components/auth/login-panel.tsx +107 -104
  16. package/components/chat-widget.tsx +85 -80
  17. package/components/commerce/add-widget.tsx +20 -0
  18. package/components/commerce/bag-button.tsx +98 -98
  19. package/components/commerce/buy-button.tsx +34 -0
  20. package/components/commerce/checkout-button.tsx +129 -116
  21. package/components/commerce/checkout-panel/close-button.tsx +26 -26
  22. package/components/commerce/checkout-panel/dt-bag-carousel.tsx +36 -36
  23. package/components/commerce/checkout-panel/dt-checkout-panel.tsx +66 -66
  24. package/components/commerce/checkout-panel/index.tsx +129 -124
  25. package/components/commerce/checkout-panel/links-row.tsx +21 -21
  26. package/components/commerce/checkout-panel/mb-checkout-panel.tsx +54 -54
  27. package/components/commerce/checkout-panel/steps-indicator.tsx +39 -39
  28. package/components/commerce/checkout-panel/thank-you.tsx +18 -18
  29. package/components/commerce/checkout-widget/const.ts +13 -13
  30. package/components/commerce/checkout-widget/index.tsx +192 -86
  31. package/components/commerce/checkout-widget/obs-string-set.ts +48 -48
  32. package/components/commerce/checkout-widget/use-anim-clx-set.ts +58 -56
  33. package/components/commerce/desktop-bag-popup.tsx +78 -78
  34. package/components/commerce/drawer/index.tsx +115 -0
  35. package/components/commerce/drawer/micro.tsx +144 -0
  36. package/components/commerce/drawer/shell.tsx +83 -0
  37. package/components/commerce/mobile-bag-drawer.tsx +51 -51
  38. package/components/commerce/mobile-login-button.tsx +100 -100
  39. package/components/commerce/mobile-menu-toggle-button.tsx +35 -35
  40. package/components/commerce/mobile-nav-menu-ai.tsx +97 -97
  41. package/components/commerce/mobile-nav-menu-item.tsx +45 -45
  42. package/components/commerce/mobile-nav-menu.tsx +80 -79
  43. package/components/contact-dialog/contact-form.tsx +113 -112
  44. package/components/contact-dialog/disclaimer.tsx +13 -13
  45. package/components/contact-dialog/index.tsx +64 -64
  46. package/components/copyright.tsx +21 -21
  47. package/components/drawer-margin.tsx +25 -0
  48. package/components/footer.tsx +77 -77
  49. package/components/header/desktop.tsx +54 -54
  50. package/components/header/index.tsx +40 -47
  51. package/components/header/mobile.tsx +165 -165
  52. package/components/header/theme-toggle.tsx +26 -26
  53. package/components/icons/avatar.tsx +11 -11
  54. package/components/icons/bag-icon.tsx +10 -10
  55. package/components/icons/github.tsx +14 -14
  56. package/components/icons/index.tsx +43 -43
  57. package/components/icons/left-arrow.tsx +11 -11
  58. package/components/icons/lux-logo.tsx +10 -10
  59. package/components/icons/right-arrow.tsx +10 -10
  60. package/components/icons/search.tsx +12 -12
  61. package/components/icons/secure-delivery.tsx +13 -13
  62. package/components/icons/social-icon.tsx +35 -35
  63. package/components/icons/social-svg.css +3 -3
  64. package/components/icons/youtube-logo.tsx +59 -59
  65. package/components/index.ts +25 -27
  66. package/components/logo.tsx +81 -81
  67. package/components/main.tsx +27 -0
  68. package/components/mini-chart/index.tsx +7 -7
  69. package/components/mini-chart/mini-chart-props.ts +43 -43
  70. package/components/mini-chart/mini-chart.tsx +85 -85
  71. package/components/mini-chart/wrapper.tsx +23 -23
  72. package/components/not-found/index.tsx +28 -27
  73. package/components/not-found/not-found-content.mdx +5 -5
  74. package/components/scripts.tsx +24 -24
  75. package/conf/index.ts +52 -50
  76. package/{commerce/lux-service-options.ts → conf/lux-commerce-options.ts} +6 -6
  77. package/environment.d.ts +5 -5
  78. package/next/analytics/fpixel.ts +15 -15
  79. package/next/analytics/google-analytics.ts +13 -13
  80. package/next/analytics/index.ts +3 -3
  81. package/next/analytics/pixel-analytics.tsx +54 -54
  82. package/next/font/get-app-router-font-classes.ts +12 -12
  83. package/next/font/load-and-return-lux-next-fonts-on-import.ts +68 -68
  84. package/next/font/next-font-desc.ts +27 -27
  85. package/next/font/pages-router-font-vars.tsx +18 -18
  86. package/next/head-metadata/from-next/metadata-types.ts +158 -158
  87. package/next/head-metadata/from-next/opengraph-types.ts +267 -267
  88. package/next/head-metadata/from-next/twitter-types.ts +92 -92
  89. package/next/head-metadata/index.tsx +208 -208
  90. package/next/middleware/determine-device-mw.ts +16 -16
  91. package/package.json +80 -73
  92. package/root-layout/WHY_THIS_IS_SEPARATE.txt +1 -1
  93. package/root-layout/index.tsx +118 -121
  94. package/server-actions/firebase-app.ts +14 -14
  95. package/server-actions/index.ts +5 -5
  96. package/server-actions/store-contact.ts +51 -51
  97. package/site-def/footer/community.tsx +67 -67
  98. package/site-def/footer/company.ts +37 -37
  99. package/site-def/footer/ecosystem.ts +37 -37
  100. package/site-def/footer/index.tsx +26 -26
  101. package/site-def/footer/legal.ts +28 -28
  102. package/site-def/footer/network.ts +45 -45
  103. package/site-def/footer/svg/warpcast-logo.svg +11 -11
  104. package/site-def/index.ts +2 -2
  105. package/site-def/main-nav.tsx +292 -292
  106. package/style/cart-animation.css +29 -29
  107. package/style/checkout-animation.css +23 -23
  108. package/style/drawer-handle-overrides.css +160 -0
  109. package/style/lux-colors.css +85 -85
  110. package/style/lux-global.css +30 -30
  111. package/tailwind/fontFamily.tailwind.lux.ts +18 -18
  112. package/tailwind/index.ts +2 -2
  113. package/tailwind/lux-tw-fonts.ts +39 -39
  114. package/tailwind/tailwind.config.lux-preset.ts +10 -10
  115. package/tsconfig.json +15 -10
  116. package/types/chatbot-config.ts +6 -6
  117. package/types/chatbot-suggested-question.ts +7 -7
  118. package/types/commerce-config.ts +10 -10
  119. package/types/contact-info.ts +10 -10
  120. package/types/index.ts +5 -5
  121. package/types/site-def.ts +45 -45
  122. package/components/commerce/buy-drawer/drawer.tsx +0 -44
  123. package/components/commerce/buy-drawer/index.tsx +0 -46
  124. package/components/commerce/checkout-widget/use-lagging-item-ref.ts +0 -30
  125. package/components/header/guts.tsx +0 -27
@@ -1,86 +1,192 @@
1
- 'use client'
2
- import React from 'react'
3
- import { createPortal } from 'react-dom'
4
- import { usePathname, useRouter } from 'next/navigation'
5
- import { observer } from 'mobx-react-lite'
6
-
7
- import { cn } from '@hanzo/ui/util'
8
- import { Image } from '@hanzo/ui/primitives'
9
-
10
- import { useCommerceUI } from '@hanzo/commerce'
11
-
12
- import CheckoutButton from '../checkout-button'
13
- import useAnimationClxSet from './use-anim-clx-set'
14
- import useLaggingItemRef from './use-lagging-item-ref'
15
- import CONST from './const'
16
-
17
- const CheckoutWidget: React.FC<{
18
- clx?: string
19
- }> = observer(({
20
- clx=''
21
- }) => {
22
-
23
- const router = useRouter()
24
-
25
- const isCheckout = usePathname() === '/checkout'
26
- const clxSet = useAnimationClxSet(isCheckout)
27
-
28
- const itemRef = useCommerceUI()
29
- const laggingRef = useLaggingItemRef(itemRef, CONST.animDurationMs)
30
-
31
- const handleCheckout = () => { router.push('/checkout')}
32
-
33
- return globalThis?.document?.body && createPortal(
34
- (<div
35
- className={cn(
36
- 'min-w-[160px] sm:max-w-[320px] w-[calc(100%-72px)] ml-2 !h-10',
37
- 'z-below-modal-2 fixed bottom-[20px] left-0 right-0',
38
- 'rounded-lg bg-background',
39
- 'flex',
40
- itemRef.item ? 'gap-2' : '',
41
- clxSet.asArray.join(' ')
42
- )}
43
- style={laggingRef.item ? {} : CONST.shadowStyle}
44
- >
45
- <div
46
- className={cn(
47
- 'flex flex-row justify-between items-center',
48
- itemRef.item ? CONST.compWidthClx.itemInfo : 'w-0',
49
- laggingRef.item ? 'px-3 border rounded-lg border-muted-3' : ''
50
- )}
51
- style={{
52
- transitionProperty: 'width',
53
- transitionTimingFunction: CONST.animTimingFn,
54
- transitionDuration: `${CONST.animDurationMs}ms`
55
- }}
56
- >
57
- {laggingRef.item?.img ? (
58
- <Image def={laggingRef.item.img} constrainTo={CONST.itemImgConstraint} preload className='grow-0 shrink-0'/>
59
- ) : ( // placeholder so things align
60
- <div style={{height: CONST.itemImgConstraint.h, width: CONST.itemImgConstraint.w}} className='bg-level-3 grow-0 shrink-0'/>
61
- )}
62
-
63
- <div className='text-muted grow ml-1'>
64
- {laggingRef.item && (<>
65
- <p className='whitespace-nowrap text-sm'>{laggingRef.item.title}</p>
66
- <p className='whitespace-nowrap text-xxs' >recently added...</p>
67
- </>)}
68
- </div>
69
- </div>
70
- <CheckoutButton
71
- handleCheckout={handleCheckout}
72
- centerText={!!!itemRef.item}
73
- variant='primary' rounded='lg'
74
- className={cn(itemRef.item ? CONST.compWidthClx.checkout : 'w-full')}
75
- style={{
76
- transitionProperty: 'width',
77
- transitionTimingFunction: CONST.animTimingFn,
78
- transitionDuration: `${CONST.animDurationMs}ms`
79
- }}
80
- />
81
- </div>),
82
- globalThis?.document?.body
83
- )
84
- })
85
-
86
- export default CheckoutWidget
1
+ 'use client'
2
+ import React, { useRef } from 'react'
3
+ import { createPortal } from 'react-dom'
4
+ import { usePathname, useRouter } from 'next/navigation'
5
+ import { observer } from 'mobx-react-lite'
6
+
7
+ import { cn } from '@hanzo/ui/util'
8
+ import { useStepAnimation } from '@hanzo/ui/util-client'
9
+
10
+ import { Image } from '@hanzo/ui/primitives'
11
+
12
+ import { useCommerceDrawer, useRecentActivity } from '../../../commerce/ui/context'
13
+
14
+ import CheckoutButton from '../checkout-button'
15
+ import useAnimationClxSet from './use-anim-clx-set'
16
+ import CONST from './const'
17
+ import type { LineItem } from '@hanzo/commerce/types'
18
+
19
+ const transStyle = (t: { transition: string, from : string, to: string } | undefined) : any => (
20
+ t ? {
21
+ transitionProperty: t.transition,
22
+ transitionTimingFunction: CONST.animTimingFn,
23
+ transitionDuration: `${CONST.animDurationMs}ms`
24
+ } : {}
25
+ )
26
+
27
+ const transClx = (on: boolean, t: { transition: string, from : string, to: string } | undefined) : string => (
28
+ on ? (t?.from ?? '') : (t?.to ?? '')
29
+ )
30
+
31
+ const VARS: any = {
32
+ BR: {
33
+ pos: 'bottom-[24px] right-[66px]',
34
+ width: 'w-initial',
35
+ centerText: false,
36
+ coClx: 'w-auto',
37
+ infoClx: 'w-auto',
38
+ activeItemAnim: {
39
+ co: {
40
+ transition: 'none',
41
+ from : 'px-3 gap-2.5',
42
+ to: ''
43
+ },
44
+ coText: {
45
+ transition: 'max-width',
46
+ from : 'max-w-[100px]',
47
+ to: 'max-w-[0px]'
48
+ },
49
+ info: {
50
+ transition: 'transform, opacity',
51
+ from : 'scale-x-100 opacity-100 origin-right',
52
+ to: 'scale-x-0 opacity-0 origin-right'
53
+ }
54
+ },
55
+ showArrow: true
56
+ },
57
+ TR: {
58
+ pos: 'top-[48px] md:top-[80px] right-[28px]',
59
+ width: 'w-initial',
60
+ centerText: false,
61
+ showQuantity: false,
62
+ showArrow: true,
63
+ coClx: 'w-auto px-3 gap-1',
64
+ infoClx: 'w-auto',
65
+ activeItemAnim: {
66
+ co: {
67
+ transition: 'none',
68
+ from : 'px-3 gap-2.5',
69
+ to: ''
70
+ },
71
+ coText: {
72
+ transition: 'max-width',
73
+ from : 'max-w-[100px]',
74
+ to: 'max-w-[0px]'
75
+ },
76
+ info: {
77
+ transition: 'transform',
78
+ from : 'scale-x-100 origin-right',
79
+ to: 'scale-x-0 origin-right'
80
+ }
81
+ },
82
+ },
83
+ TRIO: {
84
+ pos: 'top-[48px] md:top-[70px] right-[28px]',
85
+ centerText: false,
86
+ showQuantity: true,
87
+ showArrow: true,
88
+ width: 'w-initial',
89
+ coClx: 'hidden',
90
+ infoClx: 'w-auto',
91
+ activeItemAnim: {
92
+ info: {
93
+ transition: 'transform, opacity',
94
+ from : 'scale-x-100 opacity-100',
95
+ to: 'scale-x-50 opacity-0'
96
+ }
97
+ },
98
+ }
99
+ }
100
+
101
+ const v = 'TR'
102
+
103
+ const CheckoutWidget: React.FC<{
104
+ clx?: string
105
+ }> = observer(({
106
+ clx=''
107
+ }) => {
108
+
109
+ const router = useRouter()
110
+
111
+ const isCheckout = usePathname() === '/checkout'
112
+ const clxSet = useAnimationClxSet(isCheckout)
113
+
114
+ const recentActivity = useRecentActivity()
115
+
116
+ // for rendering content after recentActivity.item() would return false
117
+ const persistentRef = useRef<LineItem | undefined>(undefined)
118
+
119
+ // Doing double duty of being initial step fn for StepAnimation,
120
+ // and also capturing the item for persistentRef :)
121
+ const initialStepFn = (): boolean => {
122
+ if (!!recentActivity.item && !persistentRef.current) {
123
+ persistentRef.current = recentActivity.item
124
+ }
125
+ return !!recentActivity.item
126
+ }
127
+ const steps = useStepAnimation(initialStepFn, [CONST.animDurationMs, CONST.animDurationMs, CONST.animDurationMs])
128
+
129
+ const handleCheckout = () => { router.push('/checkout')}
130
+
131
+ return globalThis?.document?.body && createPortal(
132
+ (<div
133
+ className={cn(
134
+ VARS[v].width,
135
+ 'z-below-modal-2 fixed ',
136
+ VARS[v].pos,
137
+ 'rounded-lg',
138
+ 'flex',
139
+ steps.notPast(0) ? 'bg-background' : '',
140
+ steps.notPast(1) ? 'gap-2' : '',
141
+ clxSet.asArray.join(' ')
142
+ )}
143
+ style={steps.notPast(1) ? {} : VARS[v].coClx?.includes('hidden') ? {} : CONST.shadowStyle}
144
+ >
145
+ <div
146
+ className={cn(
147
+ 'flex flex-row justify-between items-center',
148
+ transClx(steps.notPast(0), VARS[v].activeItemAnim.info),
149
+ VARS[v].itemClx,
150
+ steps.notPast(1) ? 'px-3 border rounded-lg bg-level-1 border-muted-3' : ''
151
+ )}
152
+ style={transStyle(VARS[v].activeItemAnim.info)}
153
+ >
154
+ {steps.notPast(1) && persistentRef.current?.img && (
155
+ <Image def={persistentRef.current.img} constrainTo={CONST.itemImgConstraint} preload className='grow-0 shrink-0'/>
156
+ )}
157
+ {steps.notPast(1) && persistentRef.current && (<div className='text-foreground grow ml-1'>
158
+ <p className='whitespace-nowrap text-ellipsis text-sm'>{persistentRef.current.title}</p>
159
+ <p className='whitespace-nowrap text-clip text-xxs' >recently added...</p>
160
+ </div>)}
161
+ </div>
162
+ <CheckoutButton
163
+ handleCheckout={handleCheckout}
164
+ centerText={VARS[v].centerText ?? !steps.notPast(0)}
165
+ variant='primary'
166
+ rounded='lg'
167
+ showQuantity={VARS[v].showQuantity ?? true}
168
+ showArrow={VARS[v].showArrow ?? true}
169
+ className={cn(
170
+ // for setting and unsetting 'gap'
171
+ transClx((VARS[v].activeItemAnim.coText ? steps.notPast(3) : true), VARS[v].activeItemAnim.co),
172
+ VARS[v].coClx
173
+ )}
174
+ style={transStyle(VARS[v].activeItemAnim.co)}
175
+ >
176
+ <div
177
+ className={cn(
178
+ 'overflow-hidden',
179
+ 'flex justify-center items-center',
180
+ transClx(steps.notPast(2), VARS[v].activeItemAnim.coText),
181
+ )}
182
+ style={transStyle(VARS[v].activeItemAnim.coText)}
183
+ >
184
+ Checkout
185
+ </div>
186
+ </CheckoutButton>
187
+ </div>),
188
+ globalThis?.document?.body
189
+ )
190
+ })
191
+
192
+ export default CheckoutWidget
@@ -1,48 +1,48 @@
1
- import {
2
- action,
3
- computed,
4
- makeObservable,
5
- observable
6
- } from 'mobx'
7
-
8
- class ObsStringSet {
9
-
10
- private _set = observable.set(new Set<string>())
11
-
12
- constructor(initial: string[] = []) {
13
- initial.forEach((el) => {this._set.add(el)})
14
- makeObservable(this, {
15
- add: action,
16
- remove: action,
17
- asArray: computed
18
- })
19
- }
20
-
21
- add = (v: string | string[]): void => {
22
- if (Array.isArray(v)) {
23
- v.forEach((el) => {this._set.add(el)})
24
- }
25
- else {
26
- this._set.add(v)
27
- }
28
- }
29
-
30
- remove = (v: string | string[]): void => {
31
- if (Array.isArray(v)) {
32
- v.forEach((el) => {this._set.delete(el)})
33
- }
34
- else {
35
- this._set.delete(v)
36
- }
37
- }
38
-
39
- has = (v: string): boolean => (
40
- this._set.has(v)
41
- )
42
-
43
- get asArray() {
44
- return Array.from(this._set)
45
- }
46
- }
47
-
48
- export default ObsStringSet
1
+ import {
2
+ action,
3
+ computed,
4
+ makeObservable,
5
+ observable
6
+ } from 'mobx'
7
+
8
+ class ObsStringSet {
9
+
10
+ private _set = observable.set(new Set<string>())
11
+
12
+ constructor(initial: string[] = []) {
13
+ initial.forEach((el) => {this._set.add(el)})
14
+ makeObservable(this, {
15
+ add: action,
16
+ remove: action,
17
+ asArray: computed
18
+ })
19
+ }
20
+
21
+ add = (v: string | string[]): void => {
22
+ if (Array.isArray(v)) {
23
+ v.forEach((el) => {this._set.add(el)})
24
+ }
25
+ else {
26
+ this._set.add(v)
27
+ }
28
+ }
29
+
30
+ remove = (v: string | string[]): void => {
31
+ if (Array.isArray(v)) {
32
+ v.forEach((el) => {this._set.delete(el)})
33
+ }
34
+ else {
35
+ this._set.delete(v)
36
+ }
37
+ }
38
+
39
+ has = (v: string): boolean => (
40
+ this._set.has(v)
41
+ )
42
+
43
+ get asArray() {
44
+ return Array.from(this._set)
45
+ }
46
+ }
47
+
48
+ export default ObsStringSet
@@ -1,57 +1,59 @@
1
- import { useEffect, useRef } from 'react'
2
- import { reaction, runInAction} from 'mobx'
3
-
4
- import ObsStringSet from './obs-string-set'
5
- import { useCommerce, useCommerceUI } from '@hanzo/commerce'
6
-
7
- export default (isCheckout: boolean): ObsStringSet => {
8
-
9
- const ui = useCommerceUI()
10
- const cmmc = useCommerce()
11
-
12
- const clxSetRef = useRef<ObsStringSet>(new ObsStringSet(
13
- (cmmc.cartEmpty || ui.buyOptionsSkuPath || isCheckout) ? ['hidden'] : []
14
- ))
15
-
16
- useEffect(() => (
17
- reaction(
18
- () => ({
19
- microOpen: !(cmmc.cartEmpty || !!ui.buyOptionsSkuPath || isCheckout),
20
- buyOpen: !!ui.buyOptionsSkuPath
21
- }),
22
- (val, prev) => {
23
-
24
- runInAction(() => {
25
- if (!val.microOpen && prev.microOpen) {
26
- clxSetRef.current.add('checkout-widget-disappears')
27
- }
28
- else if (val.microOpen && !prev.microOpen) {
29
- clxSetRef.current.remove('hidden')
30
- clxSetRef.current.add('checkout-widget-appears')
31
- }
32
- if (!val.buyOpen && prev.buyOpen) {
33
- clxSetRef.current.add('checkout-widget-appears-after-buy-drawer-closes')
34
- }
35
- else {
36
- clxSetRef.current.remove('checkout-widget-appears-after-buy-drawer-closes')
37
- }
38
- })
39
-
40
- setTimeout(() => {runInAction(() => {
41
- clxSetRef.current.remove(['checkout-widget-appears', 'checkout-widget-appears-after-buy-drawer-closes'])
42
- if (clxSetRef.current.has('checkout-widget-disappears') ) {
43
- clxSetRef.current.remove('checkout-widget-disappears')
44
- clxSetRef.current.add('hidden')
45
- }
46
- })}, 800)
47
- },
48
- {equals: (val, prev) => (
49
- val.microOpen === prev.microOpen
50
- &&
51
- val.buyOpen === prev.buyOpen
52
- )}
53
- )
54
- ), [isCheckout])
55
-
56
- return clxSetRef.current
1
+ import { useEffect, useRef } from 'react'
2
+ import { reaction, runInAction} from 'mobx'
3
+
4
+ import { useCommerce } from '@hanzo/commerce'
5
+
6
+ import ObsStringSet from './obs-string-set'
7
+ import { useSelectAndBuy } from '../../../commerce/ui/context'
8
+
9
+ export default (isCheckout: boolean): ObsStringSet => {
10
+
11
+ const ui = useSelectAndBuy()
12
+ const cmmc = useCommerce()
13
+
14
+ const clxSetRef = useRef<ObsStringSet>(new ObsStringSet(
15
+ (cmmc.cartEmpty || ui.currentSkuPath || isCheckout) ? ['hidden'] : []
16
+ ))
17
+
18
+ useEffect(() => (
19
+ reaction(
20
+ () => ({
21
+ microOpen: !(cmmc.cartEmpty || !!ui.currentSkuPath || isCheckout),
22
+ buyOpen: !!ui.currentSkuPath
23
+ }),
24
+ (val, prev) => {
25
+
26
+ runInAction(() => {
27
+ if (!val.microOpen && prev.microOpen) {
28
+ clxSetRef.current.add('checkout-widget-disappears')
29
+ }
30
+ else if (val.microOpen && !prev.microOpen) {
31
+ clxSetRef.current.remove('hidden')
32
+ clxSetRef.current.add('checkout-widget-appears')
33
+ }
34
+ if (!val.buyOpen && prev.buyOpen) {
35
+ clxSetRef.current.add('checkout-widget-appears-after-buy-drawer-closes')
36
+ }
37
+ else {
38
+ clxSetRef.current.remove('checkout-widget-appears-after-buy-drawer-closes')
39
+ }
40
+ })
41
+
42
+ setTimeout(() => {runInAction(() => {
43
+ clxSetRef.current.remove(['checkout-widget-appears', 'checkout-widget-appears-after-buy-drawer-closes'])
44
+ if (clxSetRef.current.has('checkout-widget-disappears') ) {
45
+ clxSetRef.current.remove('checkout-widget-disappears')
46
+ clxSetRef.current.add('hidden')
47
+ }
48
+ })}, 800)
49
+ },
50
+ {equals: (val, prev) => (
51
+ val.microOpen === prev.microOpen
52
+ &&
53
+ val.buyOpen === prev.buyOpen
54
+ )}
55
+ )
56
+ ), [isCheckout])
57
+
58
+ return clxSetRef.current
57
59
  }
@@ -1,78 +1,78 @@
1
- 'use client'
2
- import React, { useState, useEffect } from 'react'
3
- import { useRouter } from 'next/navigation'
4
-
5
- import { X } from 'lucide-react'
6
-
7
- import {
8
- Popover,
9
- PopoverContent,
10
- PopoverTrigger,
11
- PopoverClose,
12
- } from "@hanzo/ui/primitives"
13
-
14
- import { cn } from '@hanzo/ui/util'
15
- import { CartPanel, useCommerce } from '@hanzo/commerce'
16
-
17
- import * as Icons from '../icons'
18
- import sendGAEvent from '../../next/analytics/google-analytics'
19
-
20
- const DesktopBagPopup: React.FC<{
21
- triggerClx?: string
22
- popupClx?: string
23
- trigger: React.ReactNode
24
- }> = ({
25
- triggerClx='',
26
- popupClx='',
27
- trigger
28
- }) => {
29
- const cmmc = useCommerce()
30
-
31
- const [bagOpen, setBagOpen] = useState<boolean>(false)
32
- const router = useRouter()
33
-
34
- useEffect(() => {
35
- if (bagOpen) {
36
- sendGAEvent('view_cart', {
37
- items: cmmc.cartItems.map((item) => ({
38
- item_id: item.sku,
39
- item_name: item.title,
40
- item_category: item.familyId,
41
- price: item.price,
42
- quantity: item.quantity
43
- })),
44
- value: cmmc.cartTotal,
45
- currency: 'USD',
46
- })
47
- }
48
- }, [bagOpen])
49
-
50
- return (
51
- <Popover open={bagOpen} onOpenChange={setBagOpen}>
52
- <PopoverTrigger className={triggerClx}>
53
- {trigger}
54
- </PopoverTrigger>
55
- <PopoverContent sideOffset={28} className={cn('relative flex flex-col p-0 px-4 pb-4 pt-2', popupClx)}>
56
- <PopoverClose className='absolute z-above-content right-2 top-2 self-end hover:bg-level-3 text-muted hover:text-accent p-1 rounded-full'><X className='w-5 h-5'/></PopoverClose>
57
- <CartPanel
58
- handleCheckout={() => {router.push('/checkout')}}
59
- className='mt-4 mb-4 border-none py-0 px-4'
60
- listClx='rounded-sm pr-3'
61
- scrollAfter={5}
62
- scrollHeightClx='h-[70vh]'
63
- itemClx='mt-3'
64
- totalClx='sticky px-1 pr-2 -bottom-[1px] bg-level-1'
65
- buttonClx='max-w-[220px] flex-none'
66
- >
67
- <div className='flex flex-row items-center flex-none justify-center '>
68
- <Icons.bag className='mr-2 relative w-6 h-7 fill-foreground ' />
69
- <p className='font-heading text-foreground text-default'>Your Bag</p>
70
- </div>
71
- <div className='h-[1px] w-pr-80 bg-muted-3 mx-auto mt-1.5 flex-none'/>
72
- </CartPanel>
73
- </PopoverContent>
74
- </Popover>
75
- )
76
- }
77
-
78
- export default DesktopBagPopup
1
+ 'use client'
2
+ import React, { useState, useEffect } from 'react'
3
+ import { useRouter } from 'next/navigation'
4
+
5
+ import { X } from 'lucide-react'
6
+
7
+ import {
8
+ Popover,
9
+ PopoverContent,
10
+ PopoverTrigger,
11
+ PopoverClose,
12
+ } from "@hanzo/ui/primitives"
13
+
14
+ import { cn } from '@hanzo/ui/util'
15
+ import { CartPanel, useCommerce } from '@hanzo/commerce'
16
+
17
+ import * as Icons from '../icons'
18
+ import sendGAEvent from '../../next/analytics/google-analytics'
19
+
20
+ const DesktopBagPopup: React.FC<{
21
+ triggerClx?: string
22
+ popupClx?: string
23
+ trigger: React.ReactNode
24
+ }> = ({
25
+ triggerClx='',
26
+ popupClx='',
27
+ trigger
28
+ }) => {
29
+ const cmmc = useCommerce()
30
+
31
+ const [bagOpen, setBagOpen] = useState<boolean>(false)
32
+ const router = useRouter()
33
+
34
+ useEffect(() => {
35
+ if (bagOpen) {
36
+ sendGAEvent('view_cart', {
37
+ items: cmmc.cartItems.map((item) => ({
38
+ item_id: item.sku,
39
+ item_name: item.title,
40
+ item_category: item.familyId,
41
+ price: item.price,
42
+ quantity: item.quantity
43
+ })),
44
+ value: cmmc.cartTotal,
45
+ currency: 'USD',
46
+ })
47
+ }
48
+ }, [bagOpen])
49
+
50
+ return (
51
+ <Popover open={bagOpen} onOpenChange={setBagOpen}>
52
+ <PopoverTrigger className={triggerClx}>
53
+ {trigger}
54
+ </PopoverTrigger>
55
+ <PopoverContent sideOffset={28} className={cn('relative flex flex-col p-0 px-4 pb-4 pt-2', popupClx)}>
56
+ <PopoverClose className='absolute z-above-content right-2 top-2 self-end hover:bg-level-3 text-muted hover:text-accent p-1 rounded-full'><X className='w-5 h-5'/></PopoverClose>
57
+ <CartPanel
58
+ handleCheckout={() => {router.push('/checkout')}}
59
+ className='mt-4 mb-4 border-none py-0 px-4'
60
+ listClx='rounded-sm pr-3'
61
+ scrollAfter={5}
62
+ scrollHeightClx='h-[70vh]'
63
+ itemClx='mt-3'
64
+ totalClx='sticky px-1 pr-2 -bottom-[1px] bg-level-1'
65
+ buttonClx='max-w-[220px] flex-none'
66
+ >
67
+ <div className='flex flex-row items-center flex-none justify-center '>
68
+ <Icons.bag className='mr-2 relative w-6 h-7 fill-foreground ' />
69
+ <p className='font-heading text-foreground text-default'>Your Bag</p>
70
+ </div>
71
+ <div className='h-[1px] w-pr-80 bg-muted-3 mx-auto mt-1.5 flex-none'/>
72
+ </CartPanel>
73
+ </PopoverContent>
74
+ </Popover>
75
+ )
76
+ }
77
+
78
+ export default DesktopBagPopup