@luxfi/core 5.2.7 → 5.2.9
Sign up to get free protection for your applications and to get access to all the features.
- package/commerce/ui/context.tsx +41 -17
- package/commerce/ui/store.ts +40 -12
- package/components/auth/login-panel.tsx +1 -1
- package/components/back-button.tsx +42 -0
- package/components/commerce/checkout-panel/dt-checkout-panel.tsx +36 -18
- package/components/commerce/checkout-panel/mb-checkout-panel.tsx +2 -2
- package/components/commerce/desktop-nav-menu.tsx +46 -45
- package/components/commerce/drawer/index.tsx +0 -17
- package/components/commerce/drawer/shell.tsx +58 -56
- package/components/commerce/mobile-nav-menu-ai.tsx +12 -8
- package/components/commerce/mobile-nav-menu.tsx +68 -34
- package/components/footer.tsx +1 -1
- package/components/header/desktop.tsx +20 -19
- package/components/header/mobile.tsx +15 -18
- package/components/icons/24k-gold-card.tsx +43 -0
- package/components/icons/ai-chat.tsx +29 -0
- package/components/icons/anodized-titanium.tsx +45 -0
- package/components/icons/blog.tsx +20 -0
- package/components/icons/bridge.tsx +68 -0
- package/components/icons/changelog.tsx +21 -0
- package/components/icons/chrome.tsx +45 -0
- package/components/icons/coins.tsx +20 -0
- package/components/icons/compare-cards.tsx +21 -0
- package/components/icons/credit.tsx +20 -0
- package/components/icons/customer-support.tsx +21 -0
- package/components/icons/customers.tsx +33 -0
- package/components/icons/developer-docs.tsx +20 -0
- package/components/icons/exchange.tsx +21 -0
- package/components/icons/explorer.tsx +22 -0
- package/components/icons/faqs.tsx +21 -0
- package/components/icons/guides.tsx +21 -0
- package/components/icons/gun-metal.tsx +44 -0
- package/components/icons/integrations.tsx +25 -0
- package/components/icons/irradescent.tsx +41 -0
- package/components/icons/launch-subnet.tsx +21 -0
- package/components/icons/lux-finance.tsx +23 -0
- package/components/icons/lux-pass.tsx +25 -0
- package/components/icons/lux-quests.tsx +21 -0
- package/components/icons/market.tsx +24 -0
- package/components/icons/mirrored-titanium.tsx +46 -0
- package/components/icons/more-benefits.tsx +21 -0
- package/components/icons/open-source.tsx +26 -0
- package/components/icons/safe.tsx +37 -0
- package/components/icons/shop.tsx +20 -0
- package/components/icons/sterling-silver-card.tsx +44 -0
- package/components/icons/templates.tsx +21 -0
- package/components/icons/validators.tsx +41 -0
- package/components/icons/view-all-card.tsx +20 -0
- package/components/icons/wallet.tsx +20 -0
- package/components/index.ts +2 -0
- package/components/logo.tsx +48 -40
- package/components/tooltip.tsx +31 -0
- package/package.json +2 -1
- package/root-layout/index.tsx +1 -1
- package/site-def/main-nav.tsx +248 -194
- package/components/commerce/checkout-panel/close-button.tsx +0 -26
package/commerce/ui/context.tsx
CHANGED
@@ -19,6 +19,13 @@ import type { CommerceDrawer, SelectAndBuy, RecentActivity } from './store'
|
|
19
19
|
import { CommerceUIStore } from './store'
|
20
20
|
import conf from './conf'
|
21
21
|
|
22
|
+
const LOG = false ////////////////////
|
23
|
+
const log = (s: string) => {
|
24
|
+
if (LOG) {
|
25
|
+
console.log('CMMC UI CONTEXT ' + s)
|
26
|
+
}
|
27
|
+
}
|
28
|
+
|
22
29
|
// https://dev.to/ivandotv/mobx-server-side-rendering-with-next-js-4m18
|
23
30
|
enableStaticRendering(typeof window === "undefined")
|
24
31
|
|
@@ -41,13 +48,9 @@ const CommerceUIProvider: React.FC<PropsWithChildren> = ({
|
|
41
48
|
}) => {
|
42
49
|
|
43
50
|
const cmmc = useCommerce()
|
44
|
-
const
|
45
|
-
const
|
46
|
-
const
|
47
|
-
|
48
|
-
if (ref.current.checkingOut != isCheckout) {
|
49
|
-
ref.current.setCheckingOut(isCheckout)
|
50
|
-
}
|
51
|
+
const pathname = usePathname()
|
52
|
+
const storeRef = useRef<CommerceUIStore>(new CommerceUIStore(cmmc, conf))
|
53
|
+
const prevPathRef = useRef<string>('initial')
|
51
54
|
|
52
55
|
const onResize = () => {
|
53
56
|
const width = window.innerWidth
|
@@ -58,36 +61,57 @@ const CommerceUIProvider: React.FC<PropsWithChildren> = ({
|
|
58
61
|
desktopMin = parseInt(twConfig.theme?.screens.md)
|
59
62
|
}
|
60
63
|
if (width < desktopMin) {
|
61
|
-
if (!
|
62
|
-
|
64
|
+
if (!storeRef.current.isMobile) {
|
65
|
+
storeRef.current.setMobile(true)
|
63
66
|
}
|
64
67
|
}
|
65
|
-
else if (
|
66
|
-
|
68
|
+
else if (storeRef.current.isMobile) {
|
69
|
+
storeRef.current.setMobile(false)
|
67
70
|
}
|
68
71
|
}
|
69
|
-
|
72
|
+
storeRef.current.setViewportHeight(window.innerHeight)
|
70
73
|
}
|
71
74
|
|
72
75
|
const onResize_debounced = useDebounceCallback(onResize, 500)
|
73
76
|
|
74
77
|
useLayoutEffect(() => {
|
75
|
-
|
78
|
+
storeRef.current.initialize()
|
76
79
|
onResize()
|
77
80
|
window.addEventListener('resize', onResize_debounced);
|
78
81
|
return () => {
|
79
82
|
window.removeEventListener('resize', onResize_debounced)
|
80
|
-
|
83
|
+
storeRef.current.dispose()
|
81
84
|
}
|
82
85
|
}, [])
|
83
86
|
|
84
87
|
useEffect(() => {
|
85
|
-
|
86
|
-
|
88
|
+
const checkingOut = (pathname === '/checkout')
|
89
|
+
|
90
|
+
/////////////////////////////////////
|
91
|
+
log("useEffect: pathname: " + pathname)
|
92
|
+
log("useEffect: prev pathname: " + prevPathRef.current)
|
93
|
+
|
94
|
+
if (storeRef.current.checkingOut === undefined || storeRef.current._checkingOut!== checkingOut) {
|
95
|
+
log("useEffect: setting checkingOut to: " + checkingOut) /////////////////////////////////////
|
96
|
+
storeRef.current.setCheckingOut(checkingOut)
|
97
|
+
}
|
98
|
+
if ( prevPathRef.current === 'initial') {
|
99
|
+
prevPathRef.current = pathname
|
100
|
+
// no need to reset
|
101
|
+
}
|
102
|
+
else if (
|
103
|
+
!checkingOut
|
104
|
+
&&
|
105
|
+
prevPathRef.current !== pathname
|
106
|
+
) {
|
107
|
+
storeRef.current.reset()
|
108
|
+
prevPathRef.current = pathname
|
109
|
+
}
|
110
|
+
}, [pathname])
|
87
111
|
|
88
112
|
|
89
113
|
return (
|
90
|
-
<CommerceUIContext.Provider value={
|
114
|
+
<CommerceUIContext.Provider value={storeRef.current}>
|
91
115
|
{children}
|
92
116
|
</CommerceUIContext.Provider>
|
93
117
|
)
|
package/commerce/ui/store.ts
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
import {
|
2
2
|
action,
|
3
|
+
autorun,
|
3
4
|
computed,
|
4
5
|
makeObservable,
|
5
6
|
observable,
|
@@ -9,9 +10,10 @@ import {
|
|
9
10
|
|
10
11
|
import type { CommerceService, LineItem, ObsLineItemRef } from '@hanzo/commerce/types'
|
11
12
|
|
12
|
-
const
|
13
|
+
const LOG = false ////////////////////
|
14
|
+
|
13
15
|
const log = (s: string) => {
|
14
|
-
if (
|
16
|
+
if (LOG) {
|
15
17
|
console.log('COMMERCE_UI ' + s)
|
16
18
|
}
|
17
19
|
}
|
@@ -69,7 +71,7 @@ class CommerceUIStore implements
|
|
69
71
|
|
70
72
|
_currentSkuPath: string | undefined = undefined
|
71
73
|
_closedByUser: boolean = false
|
72
|
-
_checkingOut: boolean =
|
74
|
+
_checkingOut: boolean | undefined = undefined
|
73
75
|
_ignoreStateChange: boolean = false
|
74
76
|
_activePoint: SnapPoint | null = null
|
75
77
|
|
@@ -116,6 +118,7 @@ class CommerceUIStore implements
|
|
116
118
|
showCheckout: computed,
|
117
119
|
snapPointPx: computed,
|
118
120
|
state: computed,
|
121
|
+
open: computed
|
119
122
|
})
|
120
123
|
}
|
121
124
|
|
@@ -135,6 +138,16 @@ class CommerceUIStore implements
|
|
135
138
|
}
|
136
139
|
}
|
137
140
|
))
|
141
|
+
this._reactionDisposers.push(autorun(() => {
|
142
|
+
log('AUTORUN: OPEN: ' + this.open)
|
143
|
+
log('AUTORUN:' + // ===============
|
144
|
+
'[showCheckout: ' + this.showCheckout +
|
145
|
+
'], [showAdded: ' + this.showAdded +
|
146
|
+
'], [showBuy: ' + this.showBuy +
|
147
|
+
'], [closedByUser: ' + this._closedByUser +
|
148
|
+
'], [checkingOut: ' + this._checkingOut + ']'
|
149
|
+
) // ===========
|
150
|
+
}))
|
138
151
|
}
|
139
152
|
|
140
153
|
reset = () => {
|
@@ -191,7 +204,7 @@ class CommerceUIStore implements
|
|
191
204
|
get ignoreStateChange(): boolean { return this._ignoreStateChange }
|
192
205
|
setIgnoreStateChange = (b: boolean): void => { this._ignoreStateChange = b}
|
193
206
|
|
194
|
-
get checkingOut(): boolean { return this._checkingOut }
|
207
|
+
get checkingOut(): boolean | undefined { return this._checkingOut }
|
195
208
|
setCheckingOut = (b: boolean): void => { this._checkingOut = b }
|
196
209
|
|
197
210
|
get activePoint(): SnapPoint | null { return this._activePoint }
|
@@ -218,26 +231,41 @@ class CommerceUIStore implements
|
|
218
231
|
}
|
219
232
|
|
220
233
|
get open(): boolean {
|
234
|
+
|
235
|
+
log('open():' + // ===============
|
236
|
+
' showCheckout: ' + this.showCheckout +
|
237
|
+
' showAdded: ' + this.showAdded +
|
238
|
+
' showBuy: ' + this.showBuy
|
239
|
+
) // ===========
|
240
|
+
|
241
|
+
|
242
|
+
|
221
243
|
return (
|
222
|
-
|
244
|
+
this._checkingOut !== undefined
|
245
|
+
&&
|
246
|
+
!this._checkingOut
|
247
|
+
&&
|
248
|
+
!this.closedByUser
|
223
249
|
&&
|
224
250
|
(this.showCheckout || this.showAdded || this.showBuy)
|
225
251
|
)
|
226
252
|
}
|
227
253
|
|
228
254
|
get state(): DrawerState {
|
229
|
-
if (this.
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
255
|
+
if (!this.closedByUser && !this._checkingOut) {
|
256
|
+
if (this.showBuy) {
|
257
|
+
return 'full'
|
258
|
+
}
|
259
|
+
else if (this.showAdded || this.showCheckout) {
|
260
|
+
return 'micro'
|
261
|
+
}
|
234
262
|
}
|
235
263
|
return 'closed'
|
236
264
|
}
|
237
265
|
|
238
266
|
get showBuy(): boolean {return !!this.currentSkuPath}
|
239
|
-
get showAdded(): boolean { return
|
240
|
-
get showCheckout(): boolean { return !this.
|
267
|
+
get showAdded(): boolean { return !!this.item}
|
268
|
+
get showCheckout(): boolean { return !this._service.cartEmpty}
|
241
269
|
get modal(): boolean { return this.state !== 'micro'}
|
242
270
|
|
243
271
|
get microHeight(): SnapPoint {
|
@@ -58,7 +58,7 @@ const LoginPanel: React.FC<{
|
|
58
58
|
onClick={close}
|
59
59
|
className='w-fit !min-w-0 p-2'
|
60
60
|
>
|
61
|
-
<Logo size='md'
|
61
|
+
<Logo size='md' textClx='!cursor-pointer' variant='text-only'/>
|
62
62
|
</Button>
|
63
63
|
<Carousel
|
64
64
|
options={{ align: 'center', loop: true }}
|
@@ -0,0 +1,42 @@
|
|
1
|
+
'use client'
|
2
|
+
import React from 'react'
|
3
|
+
import { useRouter } from 'next/navigation'
|
4
|
+
|
5
|
+
import { ChevronLeft } from 'lucide-react'
|
6
|
+
|
7
|
+
|
8
|
+
import {
|
9
|
+
Button,
|
10
|
+
buttonVariants,
|
11
|
+
} from '@hanzo/ui/primitives'
|
12
|
+
|
13
|
+
import type { VariantProps } from '@hanzo/ui/util'
|
14
|
+
|
15
|
+
const BackButton: React.FC<{
|
16
|
+
variant?: VariantProps<typeof buttonVariants>['variant']
|
17
|
+
size?: VariantProps<typeof buttonVariants>['size']
|
18
|
+
clx?: string
|
19
|
+
iconClx?: string
|
20
|
+
}> = ({
|
21
|
+
variant='ghost',
|
22
|
+
size='default',
|
23
|
+
clx='',
|
24
|
+
iconClx='',
|
25
|
+
}) => {
|
26
|
+
|
27
|
+
const router = useRouter()
|
28
|
+
const back = () => {router.back()}
|
29
|
+
|
30
|
+
return (
|
31
|
+
<Button
|
32
|
+
variant={variant}
|
33
|
+
size={size}
|
34
|
+
onClick={back}
|
35
|
+
className={clx}
|
36
|
+
>
|
37
|
+
<ChevronLeft className={iconClx}/>
|
38
|
+
</Button>
|
39
|
+
)
|
40
|
+
}
|
41
|
+
|
42
|
+
export default BackButton
|
@@ -1,56 +1,73 @@
|
|
1
1
|
'use client'
|
2
2
|
import React, { type PropsWithChildren } from 'react'
|
3
|
+
import { observer } from 'mobx-react-lite'
|
3
4
|
|
4
5
|
import { ScrollArea, StepIndicator } from '@hanzo/ui/primitives'
|
5
6
|
import { AuthWidget } from '@hanzo/auth/components'
|
6
|
-
import { CartPanel } from '@hanzo/commerce'
|
7
|
+
import { CartPanel, useCommerce } from '@hanzo/commerce'
|
8
|
+
import { cn } from '@hanzo/ui/util'
|
7
9
|
|
8
|
-
import
|
10
|
+
import { BackButton, Logo, Tooltip } from '../..'
|
9
11
|
import DesktopBagCarousel from './dt-bag-carousel'
|
10
|
-
import CloseButton from './close-button'
|
11
|
-
import { cn } from '@hanzo/ui/util'
|
12
12
|
import LinksRow from './links-row'
|
13
13
|
|
14
14
|
const DesktopCheckoutPanel: React.FC<PropsWithChildren & {
|
15
15
|
index: number
|
16
16
|
stepNames: string[]
|
17
|
-
close:() => void
|
17
|
+
close: () => void
|
18
18
|
className?: string
|
19
|
-
}> = ({
|
19
|
+
}> = observer(({
|
20
20
|
index,
|
21
21
|
stepNames,
|
22
22
|
close,
|
23
23
|
className='',
|
24
24
|
children
|
25
|
-
}) =>
|
25
|
+
}) => {
|
26
26
|
|
27
|
+
const cmmc = useCommerce()
|
28
|
+
|
29
|
+
return (
|
27
30
|
<div /* id='CHECKOUT_PANEL' */ className={cn('grid grid-cols-2', className)}>
|
28
|
-
<div className='w-full h-full bg-background flex flex-row items-start justify-end'>
|
29
|
-
<div className='w-full max-w-[750px] relative flex flex-col items-
|
30
|
-
<
|
31
|
-
|
32
|
-
<
|
31
|
+
<div key={1} className='w-full h-full bg-background flex flex-row items-start justify-end'>
|
32
|
+
<div className='w-full h-full max-w-[750px] relative flex flex-col items-stretch justify-start px-8 pb-8'>
|
33
|
+
<div key={1} className='h-[80px] grow-0 flex flex-row items-center z-10' >
|
34
|
+
<Logo onClick={close} size='md' href='/' variant='text-only' outerClx='logo-outer-tooltip-class' />
|
35
|
+
<Tooltip select='.logo-outer-tooltip-class' text='home' position='right' offset={6}/>
|
36
|
+
</div>
|
37
|
+
<BackButton size='sm' clx={
|
38
|
+
'z-10 absolute top-14 left-6 !px-0 aspect-square ' +
|
39
|
+
'rounded-full hover:!bg-level-3 ' +
|
40
|
+
//'border border-transparent hover:border-muted-2 ' +
|
41
|
+
'back-button-tooltip-class '
|
42
|
+
}/>
|
43
|
+
<Tooltip select='.back-button-tooltip-class' text='back' position='right' offset={5}/>
|
44
|
+
<div key={2} className={cn(
|
45
|
+
'w-full grow min-h-0 max-w-[550px] mx-auto flex flex-col gap-3',
|
46
|
+
(cmmc.cartItems.length > 4 ? 'justify-between' : 'justify-start gap-10 pt-10')
|
47
|
+
)}>
|
48
|
+
<DesktopBagCarousel className='grow-0 h-[260px] w-[360px] lg:w-[420px] mx-auto -mt-8' constrainTo={{w: 250, h: 250}}/>
|
33
49
|
<CartPanel
|
34
50
|
className='w-full border-none p-0'
|
35
|
-
itemClx='mb-
|
36
|
-
totalClx='sticky
|
51
|
+
itemClx='mb-2'
|
52
|
+
totalClx='sticky bottom-0 bg-background'
|
37
53
|
listClx='pr-3'
|
38
54
|
scrollAfter={5}
|
39
|
-
scrollHeightClx='h-[50vh]'
|
55
|
+
scrollHeightClx='min-h-[50vh] grow'
|
40
56
|
showPromoCode
|
41
57
|
showShipping
|
58
|
+
selectItems
|
42
59
|
/>
|
43
60
|
</div>
|
44
61
|
</div>
|
45
62
|
</div>
|
46
|
-
<div className='w-full h-full flex flex-col bg-level-1 min-h-screen justify-between'>
|
63
|
+
<div key={2} className='w-full h-full flex flex-col bg-level-1 min-h-screen justify-between'>
|
47
64
|
<ScrollArea className='w-full flex flex-row items-start justify-start overflow-y-auto'>
|
48
65
|
<div className='h-full w-full max-w-[750px] relative flex flex-col items-center px-8 pt-0'>
|
49
|
-
<div className='bg-level-1 sticky h-30 pb-8 w-full top-0 flex justify-center items-end'>
|
66
|
+
<div key={1} className='bg-level-1 sticky h-30 pb-8 w-full top-0 flex justify-center items-end'>
|
50
67
|
<AuthWidget noLogin className='hidden md:flex absolute top-4 right-4 '/>
|
51
68
|
<StepIndicator dotSizeRem={1.5} steps={stepNames} currentStep={index} className='gap-2 text-base w-pr-70' />
|
52
69
|
</div>
|
53
|
-
<div className='w-full max-w-[550px] mx-auto pb-10'>
|
70
|
+
<div key={2} className='w-full max-w-[550px] mx-auto pb-10'>
|
54
71
|
{children}
|
55
72
|
</div>
|
56
73
|
</div>
|
@@ -63,5 +80,6 @@ const DesktopCheckoutPanel: React.FC<PropsWithChildren & {
|
|
63
80
|
</div>
|
64
81
|
</div>
|
65
82
|
)
|
83
|
+
})
|
66
84
|
|
67
85
|
export default DesktopCheckoutPanel
|
@@ -6,7 +6,7 @@ import { cn } from '@hanzo/ui/util'
|
|
6
6
|
import { AuthWidget } from '@hanzo/auth/components'
|
7
7
|
import { CartAccordian } from '@hanzo/commerce'
|
8
8
|
|
9
|
-
import
|
9
|
+
import { Logo } from '../..'
|
10
10
|
import BagButton from '../bag-button'
|
11
11
|
import LinksRow from './links-row'
|
12
12
|
|
@@ -25,7 +25,7 @@ const MobileCheckoutPanel: React.FC<PropsWithChildren & {
|
|
25
25
|
|
26
26
|
<div /* id='MOBILE_GRID' */ className={cn('bg-background flex flex-col justify-start px-4', className)}>
|
27
27
|
<div className='sticky top-0 w-full flex flex-row justify-between items-center bg-background'>
|
28
|
-
<
|
28
|
+
<Logo onClick={close} size='xs' href='/' />
|
29
29
|
{/* Need wrapper div since 'noLogin' returns null if no logged in user */}
|
30
30
|
<div className='w-10 h-10 flex items-center justify-center'><AuthWidget noLogin className=''/></div>
|
31
31
|
</div>
|
@@ -5,7 +5,7 @@ import * as React from "react"
|
|
5
5
|
import Link from "next/link"
|
6
6
|
import { cn } from '@hanzo/ui/util'
|
7
7
|
import type { LinkDef } from '@hanzo/ui/types'
|
8
|
-
import type { LinkDefExtended } from "../../site-def/main-nav"
|
8
|
+
import type { ChildMenu, LinkDefExtended } from "../../site-def/main-nav"
|
9
9
|
import {
|
10
10
|
NavigationMenu,
|
11
11
|
NavigationMenuContent,
|
@@ -38,59 +38,25 @@ const DesktopNav: React.FC<{
|
|
38
38
|
</Link>
|
39
39
|
</NavigationMenuItem>
|
40
40
|
)
|
41
|
-
} else if (el.title ==
|
41
|
+
} else if (el.title == "Credit") {
|
42
42
|
return (
|
43
43
|
<NavigationMenuItem key={index}>
|
44
44
|
<NavigationMenuTrigger>{el.title}</NavigationMenuTrigger>
|
45
|
-
<NavigationMenuContent>
|
46
|
-
<
|
47
|
-
|
48
|
-
|
49
|
-
<a
|
50
|
-
className="flex h-full w-full select-none flex-col justify-end rounded-md bg-gradient-to-b from-muted/50 to-muted p-6 no-underline outline-none focus:shadow-md"
|
51
|
-
href={el.href}
|
52
|
-
>
|
53
|
-
<Warpcast />
|
54
|
-
<div className="mb-2 mt-4 text-lg font-medium">
|
55
|
-
{el.title}
|
56
|
-
</div>
|
57
|
-
<p className="text-sm leading-tight text-muted-foreground">
|
58
|
-
{el.details}
|
59
|
-
</p>
|
60
|
-
</a>
|
61
|
-
</NavigationMenuLink>
|
62
|
-
</li>
|
63
|
-
{el.childMenu?.map((component, index) => (
|
64
|
-
<div className="relative flex items-center my-2" key={index}>
|
65
|
-
<div className="mr-2 mt-0">
|
66
|
-
{component.icon}
|
67
|
-
</div>
|
68
|
-
<ListItem href={component.href} title={component.title} key={index}>
|
69
|
-
{component.contents}
|
70
|
-
</ListItem>
|
71
|
-
</div>
|
72
|
-
))}
|
73
|
-
|
74
|
-
</ul>
|
45
|
+
<NavigationMenuContent className="!left-0">
|
46
|
+
<div className="grid grid-cols-3 w-[846px]">
|
47
|
+
{GroupChildMenu(el.childMenu)}
|
48
|
+
</div>
|
75
49
|
</NavigationMenuContent>
|
76
50
|
</NavigationMenuItem>
|
77
51
|
)
|
78
52
|
} else {
|
79
53
|
return (
|
80
54
|
<NavigationMenuItem key={index}>
|
81
|
-
<NavigationMenuTrigger>{el.title}</NavigationMenuTrigger>
|
82
|
-
<NavigationMenuContent>
|
83
|
-
<
|
84
|
-
{el.childMenu
|
85
|
-
|
86
|
-
key={index}
|
87
|
-
title={component.title}
|
88
|
-
href={component.href}
|
89
|
-
>
|
90
|
-
{component.contents}
|
91
|
-
</ListItem>
|
92
|
-
))}
|
93
|
-
</ul>
|
55
|
+
<NavigationMenuTrigger className=" !rounded-2xl">{el.title}</NavigationMenuTrigger>
|
56
|
+
<NavigationMenuContent className="!left-0">
|
57
|
+
<div className="flex flex-row">
|
58
|
+
{GroupChildMenu(el.childMenu)}
|
59
|
+
</div>
|
94
60
|
</NavigationMenuContent>
|
95
61
|
</NavigationMenuItem>
|
96
62
|
)
|
@@ -128,3 +94,38 @@ const ListItem = React.forwardRef<
|
|
128
94
|
)
|
129
95
|
})
|
130
96
|
ListItem.displayName = "ListItem"
|
97
|
+
|
98
|
+
const GroupChildMenu = (childs: ChildMenu[] | undefined) => {
|
99
|
+
// Initialize groupedChildMenus with the type specification
|
100
|
+
if (!childs) {
|
101
|
+
return null
|
102
|
+
}
|
103
|
+
let groupedChildMenus = childs.reduce((grouped: Record<string, ChildMenu[]>, childLink) => {
|
104
|
+
if (childLink.groupName) {
|
105
|
+
if (!grouped[childLink.groupName]) {
|
106
|
+
grouped[childLink.groupName] = []
|
107
|
+
}
|
108
|
+
grouped[childLink.groupName].push(childLink)
|
109
|
+
}
|
110
|
+
return grouped
|
111
|
+
}, {} as Record<string, ChildMenu[]>) // added explicit type here
|
112
|
+
|
113
|
+
// Convert groups object to array
|
114
|
+
return Object.entries(groupedChildMenus).map(([groupName, childLinks]: [string, ChildMenu[]]) => { // added type specification here
|
115
|
+
return (
|
116
|
+
<div key={groupName} className={` py-4 px-4 ${groupName === "Elite Card" || groupName === "Sovereign Card" ? " -mt-34" : ""}` }>
|
117
|
+
<h2 className="text-muted-1">{groupName}</h2>
|
118
|
+
<ul className=" w-[200px] gap-3 md:w-[250px] lg:w-[250px]">
|
119
|
+
{childLinks.map((link) => (
|
120
|
+
<div className={"flex items-center"} key={link.title}>
|
121
|
+
{link.icon}
|
122
|
+
<ListItem key={link.title} title={link.title} href={link.href} className="text-muted-1 hover:text-primary hover:bg-transparent">
|
123
|
+
{link.contents}
|
124
|
+
</ListItem>
|
125
|
+
</div>
|
126
|
+
))}
|
127
|
+
</ul>
|
128
|
+
</div>
|
129
|
+
)
|
130
|
+
})
|
131
|
+
}
|
@@ -27,14 +27,6 @@ const CommerceUIComponent: React.FC = observer(() => {
|
|
27
27
|
router.push('/checkout')
|
28
28
|
}
|
29
29
|
|
30
|
-
// see handleCloseGesture()
|
31
|
-
const setOpen = (b: boolean): void => {
|
32
|
-
if (!b) {
|
33
|
-
if (!drawer.closedByUser) {
|
34
|
-
drawer.setClosedByUser(true)
|
35
|
-
}
|
36
|
-
}
|
37
|
-
}
|
38
30
|
|
39
31
|
const handleHandleClicked = (): void => {
|
40
32
|
|
@@ -64,19 +56,10 @@ const CommerceUIComponent: React.FC = observer(() => {
|
|
64
56
|
return false
|
65
57
|
}
|
66
58
|
|
67
|
-
|
68
59
|
return (
|
69
60
|
<CommerceDrawer
|
70
|
-
open={drawer.open}
|
71
|
-
setOpen={setOpen}
|
72
|
-
snapPoints={drawer.points}
|
73
|
-
modal={drawer.modal}
|
74
|
-
activeSnapPoint={drawer.activePoint}
|
75
|
-
setActiveSnapPoint={drawer.onActivePointChanged.bind(drawer)}
|
76
61
|
handleHandleClicked={handleHandleClicked}
|
77
62
|
handleCloseGesture={handleCloseGesture}
|
78
|
-
micro={drawer.state === 'micro'}
|
79
|
-
mobile={drawer.isMobile}
|
80
63
|
drawerClx='flex flex-col'
|
81
64
|
>
|
82
65
|
{drawer.state === 'full' && (
|
@@ -1,5 +1,6 @@
|
|
1
1
|
'use client'
|
2
2
|
import React, {type PropsWithChildren } from 'react'
|
3
|
+
import { observer } from 'mobx-react-lite'
|
3
4
|
|
4
5
|
import {
|
5
6
|
Drawer,
|
@@ -10,74 +11,75 @@ import {
|
|
10
11
|
import { cn } from '@hanzo/ui/util'
|
11
12
|
|
12
13
|
import '../../../style/drawer-handle-overrides.css'
|
14
|
+
import { useCommerceDrawer } from '../../../commerce/ui/context'
|
13
15
|
|
14
16
|
const CommerceDrawer: React.FC<PropsWithChildren &
|
15
|
-
Omit<DrawerProps,
|
17
|
+
Omit<DrawerProps,
|
18
|
+
'onOpenChange' |
|
19
|
+
'open' |
|
20
|
+
'snapPoints' |
|
21
|
+
'modal' |
|
22
|
+
'setActiveSnapPoint' |
|
23
|
+
'activeSnapPoint'
|
24
|
+
> &
|
16
25
|
{
|
17
|
-
setOpen: (b: boolean) => void
|
18
26
|
handleHandleClicked: () => void
|
19
27
|
drawerClx?: string
|
20
|
-
mobile?: boolean
|
21
|
-
micro?: boolean
|
22
28
|
}
|
23
|
-
> = ({
|
29
|
+
> = observer(({
|
24
30
|
children,
|
25
|
-
open,
|
26
|
-
setOpen,
|
27
|
-
modal,
|
28
|
-
snapPoints,
|
29
|
-
setActiveSnapPoint,
|
30
|
-
activeSnapPoint,
|
31
31
|
handleHandleClicked,
|
32
32
|
drawerClx='',
|
33
|
-
mobile=false,
|
34
|
-
micro=false,
|
35
33
|
...rest
|
36
|
-
}) =>
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
className={cn(
|
55
|
-
'border-0',
|
56
|
-
//(micro ? (mobile ? 'mt-4 pt-1.5' : 'mt-5 pt-4') : 'mt-5 pt-5'),
|
57
|
-
mobile ? 'pt-5' : 'pt-6',
|
58
|
-
'w-full h-full',
|
59
|
-
)}
|
60
|
-
// https://github.com/radix-ui/primitives/discussions/935
|
61
|
-
onOpenAutoFocus={(e) => {e.preventDefault()}}
|
34
|
+
}) => {
|
35
|
+
|
36
|
+
const drawer = useCommerceDrawer()
|
37
|
+
|
38
|
+
return (
|
39
|
+
<Drawer
|
40
|
+
open={drawer.open}
|
41
|
+
onOpenChange={() => {}}
|
42
|
+
modal={drawer.modal}
|
43
|
+
snapPoints={drawer.points}
|
44
|
+
activeSnapPoint={drawer.activePoint}
|
45
|
+
setActiveSnapPoint={drawer.onActivePointChanged.bind(drawer)}
|
46
|
+
fastDragSkipsToEnd={false}
|
47
|
+
dragHandleOnly={true}
|
48
|
+
handleHandleClicked={handleHandleClicked}
|
49
|
+
extendHandleDragRegion={false}
|
50
|
+
// debugOutput
|
51
|
+
{...rest}
|
62
52
|
>
|
63
|
-
<
|
53
|
+
<DrawerContent
|
54
|
+
defaultHandle={false}
|
64
55
|
className={cn(
|
65
|
-
'
|
66
|
-
'
|
67
|
-
'
|
68
|
-
|
69
|
-
|
56
|
+
'border-0',
|
57
|
+
drawer.isMobile ? 'pt-5' : 'pt-6',
|
58
|
+
'w-full h-full',
|
59
|
+
)}
|
60
|
+
// https://github.com/radix-ui/primitives/discussions/935
|
61
|
+
onOpenAutoFocus={(e) => {e.preventDefault()}}
|
70
62
|
>
|
71
|
-
<
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
63
|
+
<DrawerHandle
|
64
|
+
className={cn(
|
65
|
+
'absolute top-0 left-0 right-0 mx-auto z-10',
|
66
|
+
'flex justify-center items-start',
|
67
|
+
'border-t rounded-t-lg border-muted-3',
|
68
|
+
drawer.isMobile ? 'h-5 touch-pan-y' : 'h-6',
|
69
|
+
)}
|
70
|
+
>
|
71
|
+
<div className={cn(
|
72
|
+
// pseudo-handle
|
73
|
+
'rounded-[3px] bg-level-3',
|
74
|
+
drawer.isMobile ? 'w-[155px] mt-[5px] h-1.5' : 'w-[180px] mt-[3px] h-2.5 hover:bg-level-4',
|
75
|
+
!drawer.isMobile ? 'cursor-grab active:cursor-grabbing' : '',
|
76
|
+
)} />
|
77
|
+
</DrawerHandle>
|
78
|
+
{children}
|
79
|
+
</DrawerContent>
|
80
|
+
</Drawer>
|
81
|
+
)
|
82
|
+
})
|
83
|
+
|
82
84
|
|
83
85
|
export default CommerceDrawer
|