@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.
- package/commerce/AUTO-GEN-bullion-by-family.json +33 -33
- package/commerce/EDIT-ME-bullion-market-prices.ts +11 -11
- package/commerce/assign-prices.ts +49 -49
- package/commerce/assign-videos-by-family-group.ts +14 -14
- package/commerce/bullion-price-1oz.ts +5 -5
- package/commerce/index.ts +18 -18
- package/commerce/lux-service-options.ts +6 -6
- package/components/access-code-input.tsx +71 -71
- package/components/auth/auth-listener.tsx +29 -29
- package/components/auth/auth-token/clear-auth-token.tsx +12 -12
- package/components/auth/auth-token/set-auth-token.tsx +16 -16
- package/components/auth/common-auth-domains.ts +16 -16
- package/components/auth/login-panel.tsx +104 -104
- package/components/chat-widget.tsx +80 -80
- package/components/commerce/bag-button.tsx +98 -98
- package/components/commerce/buy-drawer/drawer.tsx +44 -44
- package/components/commerce/buy-drawer/index.tsx +46 -46
- package/components/commerce/checkout-button.tsx +116 -116
- package/components/commerce/checkout-panel/close-button.tsx +26 -26
- package/components/commerce/checkout-panel/dt-bag-carousel.tsx +36 -36
- package/components/commerce/checkout-panel/dt-checkout-panel.tsx +66 -66
- package/components/commerce/checkout-panel/index.tsx +123 -123
- package/components/commerce/checkout-panel/links-row.tsx +21 -21
- package/components/commerce/checkout-panel/mb-checkout-panel.tsx +54 -54
- package/components/commerce/checkout-panel/steps-indicator.tsx +39 -39
- package/components/commerce/checkout-panel/thank-you.tsx +18 -18
- package/components/commerce/checkout-widget/const.ts +13 -13
- package/components/commerce/checkout-widget/index.tsx +86 -86
- package/components/commerce/checkout-widget/obs-string-set.ts +48 -48
- package/components/commerce/checkout-widget/use-anim-clx-set.ts +56 -56
- package/components/commerce/checkout-widget/use-lagging-item-ref.ts +29 -29
- package/components/commerce/desktop-bag-popup.tsx +78 -78
- package/components/commerce/mobile-bag-drawer.tsx +51 -51
- package/components/commerce/mobile-login-button.tsx +101 -0
- package/components/commerce/mobile-menu-toggle-button.tsx +35 -35
- package/components/commerce/mobile-nav-menu-ai.tsx +98 -0
- package/components/commerce/mobile-nav-menu-item.tsx +46 -0
- package/components/commerce/mobile-nav-menu.tsx +79 -64
- package/components/contact-dialog/contact-form.tsx +112 -112
- package/components/contact-dialog/disclaimer.tsx +13 -13
- package/components/contact-dialog/index.tsx +64 -64
- package/components/copyright.tsx +21 -21
- package/components/footer.tsx +77 -77
- package/components/header/desktop.tsx +54 -54
- package/components/header/guts.tsx +27 -0
- package/components/header/index.tsx +47 -26
- package/components/header/mobile.tsx +165 -161
- package/components/header/theme-toggle.tsx +26 -26
- package/components/icons/avatar.tsx +11 -0
- package/components/icons/bag-icon.tsx +10 -10
- package/components/icons/github.tsx +14 -14
- package/components/icons/index.tsx +43 -35
- package/components/icons/left-arrow.tsx +11 -0
- package/components/icons/lux-logo.tsx +10 -10
- package/components/icons/right-arrow.tsx +10 -0
- package/components/icons/search.tsx +12 -0
- package/components/icons/secure-delivery.tsx +13 -13
- package/components/icons/social-icon.tsx +35 -35
- package/components/icons/social-svg.css +3 -3
- package/components/icons/youtube-logo.tsx +59 -59
- package/components/index.ts +27 -27
- package/components/logo.tsx +81 -81
- package/components/mini-chart/index.tsx +7 -7
- package/components/mini-chart/mini-chart-props.ts +43 -43
- package/components/mini-chart/mini-chart.tsx +85 -85
- package/components/mini-chart/wrapper.tsx +23 -23
- package/components/not-found/index.tsx +27 -27
- package/components/not-found/not-found-content.mdx +5 -5
- package/components/scripts.tsx +24 -24
- package/conf/index.ts +50 -50
- package/environment.d.ts +5 -5
- package/next/analytics/fpixel.ts +15 -15
- package/next/analytics/google-analytics.ts +13 -13
- package/next/analytics/index.ts +3 -3
- package/next/analytics/pixel-analytics.tsx +54 -54
- package/next/font/get-app-router-font-classes.ts +12 -12
- package/next/font/load-and-return-lux-next-fonts-on-import.ts +68 -68
- package/next/font/next-font-desc.ts +27 -27
- package/next/font/pages-router-font-vars.tsx +18 -18
- package/next/head-metadata/from-next/metadata-types.ts +158 -158
- package/next/head-metadata/from-next/opengraph-types.ts +267 -267
- package/next/head-metadata/from-next/twitter-types.ts +92 -92
- package/next/head-metadata/index.tsx +208 -208
- package/next/middleware/determine-device-mw.ts +16 -16
- package/package.json +73 -72
- package/root-layout/WHY_THIS_IS_SEPARATE.txt +1 -1
- package/root-layout/index.tsx +121 -120
- package/server-actions/firebase-app.ts +14 -14
- package/server-actions/index.ts +5 -5
- package/server-actions/store-contact.ts +51 -51
- package/site-def/footer/community.tsx +67 -67
- package/site-def/footer/company.ts +37 -37
- package/site-def/footer/ecosystem.ts +37 -37
- package/site-def/footer/index.tsx +26 -26
- package/site-def/footer/legal.ts +28 -28
- package/site-def/footer/network.ts +45 -45
- package/site-def/footer/svg/warpcast-logo.svg +11 -11
- package/site-def/index.ts +2 -2
- package/site-def/main-nav.tsx +292 -0
- package/style/cart-animation.css +29 -29
- package/style/checkout-animation.css +23 -23
- package/style/lux-colors.css +85 -85
- package/style/lux-global.css +30 -30
- package/tailwind/fontFamily.tailwind.lux.ts +18 -18
- package/tailwind/index.ts +2 -2
- package/tailwind/lux-tw-fonts.ts +39 -39
- package/tailwind/tailwind.config.lux-preset.ts +10 -10
- package/tsconfig.json +10 -28
- package/types/chatbot-config.ts +6 -6
- package/types/chatbot-suggested-question.ts +7 -7
- package/types/commerce-config.ts +10 -10
- package/types/contact-info.ts +10 -10
- package/types/index.ts +5 -5
- package/types/site-def.ts +45 -45
- 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
|