@luxfi/core 5.1.3 → 5.1.4

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 (115) hide show
  1. package/commerce/AUTO-GEN-bullion-by-family.json +33 -33
  2. package/commerce/EDIT-ME-bullion-market-prices.ts +11 -11
  3. package/commerce/assign-prices.ts +49 -49
  4. package/commerce/assign-videos-by-family-group.ts +14 -14
  5. package/commerce/bullion-price-1oz.ts +5 -5
  6. package/commerce/index.ts +18 -18
  7. package/commerce/lux-service-options.ts +6 -6
  8. package/components/access-code-input.tsx +71 -71
  9. package/components/auth/auth-listener.tsx +29 -29
  10. package/components/auth/auth-token/clear-auth-token.tsx +12 -12
  11. package/components/auth/auth-token/set-auth-token.tsx +16 -16
  12. package/components/auth/common-auth-domains.ts +16 -16
  13. package/components/auth/login-panel.tsx +104 -104
  14. package/components/chat-widget.tsx +80 -80
  15. package/components/commerce/bag-button.tsx +98 -98
  16. package/components/commerce/buy-drawer/drawer.tsx +44 -44
  17. package/components/commerce/buy-drawer/index.tsx +46 -46
  18. package/components/commerce/checkout-button.tsx +116 -116
  19. package/components/commerce/checkout-panel/close-button.tsx +26 -26
  20. package/components/commerce/checkout-panel/dt-bag-carousel.tsx +36 -36
  21. package/components/commerce/checkout-panel/dt-checkout-panel.tsx +66 -66
  22. package/components/commerce/checkout-panel/index.tsx +123 -123
  23. package/components/commerce/checkout-panel/links-row.tsx +21 -21
  24. package/components/commerce/checkout-panel/mb-checkout-panel.tsx +54 -54
  25. package/components/commerce/checkout-panel/steps-indicator.tsx +39 -39
  26. package/components/commerce/checkout-panel/thank-you.tsx +18 -18
  27. package/components/commerce/checkout-widget/const.ts +13 -13
  28. package/components/commerce/checkout-widget/index.tsx +86 -86
  29. package/components/commerce/checkout-widget/obs-string-set.ts +48 -48
  30. package/components/commerce/checkout-widget/use-anim-clx-set.ts +56 -56
  31. package/components/commerce/checkout-widget/use-lagging-item-ref.ts +29 -29
  32. package/components/commerce/desktop-bag-popup.tsx +78 -78
  33. package/components/commerce/mobile-bag-drawer.tsx +51 -51
  34. package/components/commerce/mobile-login-button.tsx +101 -0
  35. package/components/commerce/mobile-menu-toggle-button.tsx +35 -35
  36. package/components/commerce/mobile-nav-menu-ai.tsx +98 -0
  37. package/components/commerce/mobile-nav-menu-item.tsx +46 -0
  38. package/components/commerce/mobile-nav-menu.tsx +79 -64
  39. package/components/contact-dialog/contact-form.tsx +112 -112
  40. package/components/contact-dialog/disclaimer.tsx +13 -13
  41. package/components/contact-dialog/index.tsx +64 -64
  42. package/components/copyright.tsx +21 -21
  43. package/components/footer.tsx +77 -77
  44. package/components/header/desktop.tsx +54 -54
  45. package/components/header/guts.tsx +27 -0
  46. package/components/header/index.tsx +47 -26
  47. package/components/header/mobile.tsx +165 -161
  48. package/components/header/theme-toggle.tsx +26 -26
  49. package/components/icons/avatar.tsx +11 -0
  50. package/components/icons/bag-icon.tsx +10 -10
  51. package/components/icons/github.tsx +14 -14
  52. package/components/icons/index.tsx +43 -35
  53. package/components/icons/left-arrow.tsx +11 -0
  54. package/components/icons/lux-logo.tsx +10 -10
  55. package/components/icons/right-arrow.tsx +10 -0
  56. package/components/icons/search.tsx +12 -0
  57. package/components/icons/secure-delivery.tsx +13 -13
  58. package/components/icons/social-icon.tsx +35 -35
  59. package/components/icons/social-svg.css +3 -3
  60. package/components/icons/youtube-logo.tsx +59 -59
  61. package/components/index.ts +27 -27
  62. package/components/logo.tsx +81 -81
  63. package/components/mini-chart/index.tsx +7 -7
  64. package/components/mini-chart/mini-chart-props.ts +43 -43
  65. package/components/mini-chart/mini-chart.tsx +85 -85
  66. package/components/mini-chart/wrapper.tsx +23 -23
  67. package/components/not-found/index.tsx +27 -27
  68. package/components/not-found/not-found-content.mdx +5 -5
  69. package/components/scripts.tsx +24 -24
  70. package/conf/index.ts +50 -50
  71. package/environment.d.ts +5 -5
  72. package/next/analytics/fpixel.ts +15 -15
  73. package/next/analytics/google-analytics.ts +13 -13
  74. package/next/analytics/index.ts +3 -3
  75. package/next/analytics/pixel-analytics.tsx +54 -54
  76. package/next/font/get-app-router-font-classes.ts +12 -12
  77. package/next/font/load-and-return-lux-next-fonts-on-import.ts +68 -68
  78. package/next/font/next-font-desc.ts +27 -27
  79. package/next/font/pages-router-font-vars.tsx +18 -18
  80. package/next/head-metadata/from-next/metadata-types.ts +158 -158
  81. package/next/head-metadata/from-next/opengraph-types.ts +267 -267
  82. package/next/head-metadata/from-next/twitter-types.ts +92 -92
  83. package/next/head-metadata/index.tsx +208 -208
  84. package/next/middleware/determine-device-mw.ts +16 -16
  85. package/package.json +73 -72
  86. package/root-layout/WHY_THIS_IS_SEPARATE.txt +1 -1
  87. package/root-layout/index.tsx +121 -120
  88. package/server-actions/firebase-app.ts +14 -14
  89. package/server-actions/index.ts +5 -5
  90. package/server-actions/store-contact.ts +51 -51
  91. package/site-def/footer/community.tsx +67 -67
  92. package/site-def/footer/company.ts +37 -37
  93. package/site-def/footer/ecosystem.ts +37 -37
  94. package/site-def/footer/index.tsx +26 -26
  95. package/site-def/footer/legal.ts +28 -28
  96. package/site-def/footer/network.ts +45 -45
  97. package/site-def/footer/svg/warpcast-logo.svg +11 -11
  98. package/site-def/index.ts +2 -2
  99. package/site-def/main-nav.tsx +292 -0
  100. package/style/cart-animation.css +29 -29
  101. package/style/checkout-animation.css +23 -23
  102. package/style/lux-colors.css +85 -85
  103. package/style/lux-global.css +30 -30
  104. package/tailwind/fontFamily.tailwind.lux.ts +18 -18
  105. package/tailwind/index.ts +2 -2
  106. package/tailwind/lux-tw-fonts.ts +39 -39
  107. package/tailwind/tailwind.config.lux-preset.ts +10 -10
  108. package/tsconfig.json +10 -28
  109. package/types/chatbot-config.ts +6 -6
  110. package/types/chatbot-suggested-question.ts +7 -7
  111. package/types/commerce-config.ts +10 -10
  112. package/types/contact-info.ts +10 -10
  113. package/types/index.ts +5 -5
  114. package/types/site-def.ts +45 -45
  115. package/site-def/main-nav.ts +0 -35
@@ -1,86 +1,86 @@
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 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,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,57 @@
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 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
57
57
  }
@@ -1,30 +1,30 @@
1
- import { useEffect, useRef } from 'react'
2
- import { reaction } from 'mobx'
3
-
4
- import type { LineItem, ObsLineItemRef } from "@hanzo/commerce/types"
5
- import { LineItemRef } from '@hanzo/commerce'
6
-
7
- export default (orig: ObsLineItemRef, lagMs: number): ObsLineItemRef => {
8
-
9
- // a ref that is synced to 'orig', but persists for lagMs longer
10
- // so ui does not jump while animating out.
11
- // (Fascilitates for start and end states in animation)
12
- const laggingRef = useRef<LineItemRef>(new LineItemRef())
13
-
14
- useEffect(() => (
15
- reaction(
16
- () => (orig.item),
17
- (item: LineItem | undefined) => {
18
- if (item) {
19
- laggingRef.current.set(item)
20
- }
21
- else {
22
- setTimeout(() => { laggingRef.current.set(undefined) }, lagMs)
23
- }
24
- },
25
- {equals: (val, prev) => (val?.sku === prev?.sku)}
26
- )
27
- ), [])
28
-
29
- return laggingRef.current
1
+ import { useEffect, useRef } from 'react'
2
+ import { reaction } from 'mobx'
3
+
4
+ import type { LineItem, ObsLineItemRef } from "@hanzo/commerce/types"
5
+ import { LineItemRef } from '@hanzo/commerce'
6
+
7
+ export default (orig: ObsLineItemRef, lagMs: number): ObsLineItemRef => {
8
+
9
+ // a ref that is synced to 'orig', but persists for lagMs longer
10
+ // so ui does not jump while animating out.
11
+ // (Fascilitates for start and end states in animation)
12
+ const laggingRef = useRef<LineItemRef>(new LineItemRef())
13
+
14
+ useEffect(() => (
15
+ reaction(
16
+ () => (orig.item),
17
+ (item: LineItem | undefined) => {
18
+ if (item) {
19
+ laggingRef.current.set(item)
20
+ }
21
+ else {
22
+ setTimeout(() => { laggingRef.current.set(undefined) }, lagMs)
23
+ }
24
+ },
25
+ {equals: (val, prev) => (val?.sku === prev?.sku)}
26
+ )
27
+ ), [])
28
+
29
+ return laggingRef.current
30
30
  }
@@ -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