@luxfi/core 4.4.10 → 4.4.12
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/components/access-code-input.tsx +71 -71
- package/components/auth/auth-listener.tsx +23 -41
- package/components/auth/auth-token/clear-auth-token.tsx +12 -0
- package/components/auth/auth-token/set-auth-token.tsx +16 -0
- package/components/auth/common-auth-domains.ts +16 -15
- package/components/auth/login-panel.tsx +119 -117
- package/components/chat-widget.tsx +77 -77
- package/components/commerce/bag-button.tsx +67 -67
- 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 +55 -55
- package/components/commerce/checkout-panel/steps-indicator.tsx +39 -39
- package/components/commerce/checkout-panel/thank-you.tsx +18 -18
- package/components/commerce/desktop-bag-popup.tsx +78 -78
- package/components/commerce/mobile-bag-drawer.tsx +51 -51
- package/components/commerce/mobile-menu-toggle-button.tsx +35 -35
- package/components/commerce/mobile-nav-menu.tsx +64 -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/index.tsx +26 -26
- package/components/header/mobile.tsx +161 -161
- package/components/header/theme-toggle.tsx +26 -26
- package/components/icons/bag-icon.tsx +10 -10
- package/components/icons/github.tsx +14 -14
- package/components/icons/index.tsx +35 -35
- package/components/icons/lux-logo.tsx +10 -10
- 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/root-layout.tsx +71 -71
- package/components/scripts.tsx +23 -23
- 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/determine-device-mw.ts +16 -16
- 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/package.json +73 -73
- 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.ts +35 -35
- package/site-def/site-def.ts +36 -36
- 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 -10
- package/types/contact-info.ts +10 -10
@@ -1,54 +1,54 @@
|
|
1
|
-
import React from 'react'
|
2
|
-
|
3
|
-
import { NavItems } from '@hanzo/ui/primitives'
|
4
|
-
import { cn } from '@hanzo/ui/util'
|
5
|
-
import { AuthWidget } from '@hanzo/auth/components'
|
6
|
-
|
7
|
-
import { Logo } from '..'
|
8
|
-
|
9
|
-
import DesktopBagPopup from '../commerce/desktop-bag-popup'
|
10
|
-
import BagButton from '../commerce/bag-button'
|
11
|
-
|
12
|
-
|
13
|
-
import type { LinkDef } from '@hanzo/ui/types'
|
14
|
-
|
15
|
-
const DesktopHeader: React.FC<{
|
16
|
-
currentAs: string | undefined
|
17
|
-
links: LinkDef[]
|
18
|
-
className?: string
|
19
|
-
}> = ({
|
20
|
-
currentAs,
|
21
|
-
links,
|
22
|
-
className = ''
|
23
|
-
}) => {
|
24
|
-
|
25
|
-
// TODO move 13px into a size class and configure twMerge to recognize say, 'text-size-nav'
|
26
|
-
// (vs be beat out by 'text-color-nav')
|
27
|
-
return (
|
28
|
-
<header className={cn('bg-background sticky z-header top-0 ', className)} >
|
29
|
-
{/* md or larger */}
|
30
|
-
<div className={
|
31
|
-
'flex flex-row h-[80px] items-center justify-between ' +
|
32
|
-
'px-[32px] w-full 2xl:mx-auto max-w-screen-2xl'
|
33
|
-
}>
|
34
|
-
<Logo size='md' href='/' className='hidden lg:flex' key='two' layout='text-only'/>
|
35
|
-
<Logo size='sm' href='/' className='hidden md:flex lg:hidden' key='one' layout='text-only'/>
|
36
|
-
{/* md or larger */}
|
37
|
-
<div className='flex gap-4 items-center'>
|
38
|
-
<NavItems
|
39
|
-
currentAs={currentAs}
|
40
|
-
items={links}
|
41
|
-
className='flex md:gap-4 lg:justify-between lg:gap-7'
|
42
|
-
itemClx='font-nav h-8'
|
43
|
-
key='three'
|
44
|
-
/>
|
45
|
-
<DesktopBagPopup popupClx='w-[340px]' trigger={<BagButton className='text-primary -mr-[3px] lg:min-w-0' />} />
|
46
|
-
<AuthWidget/>
|
47
|
-
</div>
|
48
|
-
</div>
|
49
|
-
</header>
|
50
|
-
)
|
51
|
-
}
|
52
|
-
|
53
|
-
export default DesktopHeader
|
54
|
-
|
1
|
+
import React from 'react'
|
2
|
+
|
3
|
+
import { NavItems } from '@hanzo/ui/primitives'
|
4
|
+
import { cn } from '@hanzo/ui/util'
|
5
|
+
import { AuthWidget } from '@hanzo/auth/components'
|
6
|
+
|
7
|
+
import { Logo } from '..'
|
8
|
+
|
9
|
+
import DesktopBagPopup from '../commerce/desktop-bag-popup'
|
10
|
+
import BagButton from '../commerce/bag-button'
|
11
|
+
|
12
|
+
|
13
|
+
import type { LinkDef } from '@hanzo/ui/types'
|
14
|
+
|
15
|
+
const DesktopHeader: React.FC<{
|
16
|
+
currentAs: string | undefined
|
17
|
+
links: LinkDef[]
|
18
|
+
className?: string
|
19
|
+
}> = ({
|
20
|
+
currentAs,
|
21
|
+
links,
|
22
|
+
className = ''
|
23
|
+
}) => {
|
24
|
+
|
25
|
+
// TODO move 13px into a size class and configure twMerge to recognize say, 'text-size-nav'
|
26
|
+
// (vs be beat out by 'text-color-nav')
|
27
|
+
return (
|
28
|
+
<header className={cn('bg-background sticky z-header top-0 ', className)} >
|
29
|
+
{/* md or larger */}
|
30
|
+
<div className={
|
31
|
+
'flex flex-row h-[80px] items-center justify-between ' +
|
32
|
+
'px-[32px] w-full 2xl:mx-auto max-w-screen-2xl'
|
33
|
+
}>
|
34
|
+
<Logo size='md' href='/' className='hidden lg:flex' key='two' layout='text-only'/>
|
35
|
+
<Logo size='sm' href='/' className='hidden md:flex lg:hidden' key='one' layout='text-only'/>
|
36
|
+
{/* md or larger */}
|
37
|
+
<div className='flex gap-4 items-center'>
|
38
|
+
<NavItems
|
39
|
+
currentAs={currentAs}
|
40
|
+
items={links}
|
41
|
+
className='flex md:gap-4 lg:justify-between lg:gap-7'
|
42
|
+
itemClx='font-nav h-8'
|
43
|
+
key='three'
|
44
|
+
/>
|
45
|
+
<DesktopBagPopup popupClx='w-[340px]' trigger={<BagButton className='text-primary -mr-[3px] lg:min-w-0' />} />
|
46
|
+
<AuthWidget/>
|
47
|
+
</div>
|
48
|
+
</div>
|
49
|
+
</header>
|
50
|
+
)
|
51
|
+
}
|
52
|
+
|
53
|
+
export default DesktopHeader
|
54
|
+
|
@@ -1,26 +1,26 @@
|
|
1
|
-
import React from 'react'
|
2
|
-
|
3
|
-
import type { SiteDef } from '../../site-def'
|
4
|
-
|
5
|
-
import DesktopHeader from './desktop'
|
6
|
-
import MobileHeader from './mobile'
|
7
|
-
import { cn } from '@hanzo/ui/util'
|
8
|
-
|
9
|
-
const Header: React.FC<{
|
10
|
-
siteDef: SiteDef
|
11
|
-
className?: string
|
12
|
-
}> = ({
|
13
|
-
siteDef,
|
14
|
-
className = ''
|
15
|
-
}) => {
|
16
|
-
|
17
|
-
const { nav: { common, featured }, currentAs } = siteDef
|
18
|
-
const links = (featured) ? [...common, ...featured] : common
|
19
|
-
|
20
|
-
return (<>
|
21
|
-
<DesktopHeader className={cn(className, 'hidden md:flex')} links={links} currentAs={currentAs} />
|
22
|
-
<MobileHeader className={cn(className, 'md:hidden')} links={links} currentAs={currentAs} />
|
23
|
-
</>)
|
24
|
-
}
|
25
|
-
|
26
|
-
export default Header
|
1
|
+
import React from 'react'
|
2
|
+
|
3
|
+
import type { SiteDef } from '../../site-def'
|
4
|
+
|
5
|
+
import DesktopHeader from './desktop'
|
6
|
+
import MobileHeader from './mobile'
|
7
|
+
import { cn } from '@hanzo/ui/util'
|
8
|
+
|
9
|
+
const Header: React.FC<{
|
10
|
+
siteDef: SiteDef
|
11
|
+
className?: string
|
12
|
+
}> = ({
|
13
|
+
siteDef,
|
14
|
+
className = ''
|
15
|
+
}) => {
|
16
|
+
|
17
|
+
const { nav: { common, featured }, currentAs } = siteDef
|
18
|
+
const links = (featured) ? [...common, ...featured] : common
|
19
|
+
|
20
|
+
return (<>
|
21
|
+
<DesktopHeader className={cn(className, 'hidden md:flex')} links={links} currentAs={currentAs} />
|
22
|
+
<MobileHeader className={cn(className, 'md:hidden')} links={links} currentAs={currentAs} />
|
23
|
+
</>)
|
24
|
+
}
|
25
|
+
|
26
|
+
export default Header
|
@@ -1,161 +1,161 @@
|
|
1
|
-
'use client'
|
2
|
-
import React, { useState, useEffect } from 'react'
|
3
|
-
import { useRouter } from 'next/navigation'
|
4
|
-
|
5
|
-
import type { LinkDef } from '@hanzo/ui/types'
|
6
|
-
import { cn } from '@hanzo/ui/util'
|
7
|
-
|
8
|
-
import { CartPanel, useCommerce } from '@hanzo/commerce'
|
9
|
-
import { AuthWidget, LoginPanel } from '@hanzo/auth/components'
|
10
|
-
|
11
|
-
import sendGAEvent from '../../next/analytics/google-analytics'
|
12
|
-
import * as Icons from '../icons'
|
13
|
-
|
14
|
-
import { Logo } from '..'
|
15
|
-
|
16
|
-
import MenuToggleButton from '../commerce/mobile-menu-toggle-button'
|
17
|
-
import BagButton from '../commerce/bag-button'
|
18
|
-
import MobileBagDrawer from '../commerce/mobile-bag-drawer'
|
19
|
-
import NavMenu from '../commerce/mobile-nav-menu'
|
20
|
-
|
21
|
-
const bagClx = 'mt-4 mb-8 border-none py-0 px-4 w-full ' +
|
22
|
-
'sm:min-w-[350px] sm:max-w-[500px] sm:mx-auto min-h-[60vh] max-h-[70vh] ' +
|
23
|
-
'sm:animate-in sm:zoom-in-90 '
|
24
|
-
|
25
|
-
const MobileHeader: React.FC<{
|
26
|
-
currentAs: string | undefined
|
27
|
-
links: LinkDef[]
|
28
|
-
className?: string
|
29
|
-
}> = ({
|
30
|
-
currentAs,
|
31
|
-
links,
|
32
|
-
className = ''
|
33
|
-
}) => {
|
34
|
-
|
35
|
-
const cmmc = useCommerce()
|
36
|
-
const [menuState, setMenuState] = useState<'closed' | 'nav' | 'login' | 'bag'>('closed')
|
37
|
-
const [bagDrawerOpen, setBagDrawerOpen] = useState<boolean>(false)
|
38
|
-
const router = useRouter()
|
39
|
-
|
40
|
-
useEffect(() => {
|
41
|
-
if (menuState === 'bag' || bagDrawerOpen) {
|
42
|
-
sendGAEvent('view_cart', {
|
43
|
-
items: cmmc.cartItems.map((item) => ({
|
44
|
-
item_id: item.sku,
|
45
|
-
item_name: item.title,
|
46
|
-
item_category: item.familyId,
|
47
|
-
price: item.price,
|
48
|
-
quantity: item.quantity
|
49
|
-
})),
|
50
|
-
value: cmmc.cartTotal,
|
51
|
-
currency: 'USD',
|
52
|
-
})
|
53
|
-
}
|
54
|
-
}, [menuState, bagDrawerOpen])
|
55
|
-
|
56
|
-
const menuOpen = () => (menuState !== 'closed')
|
57
|
-
|
58
|
-
const onLoginChanged = (token: string) => {
|
59
|
-
// by def, menu was in state 'login'
|
60
|
-
if (!!token) { setMenuState('nav') }
|
61
|
-
}
|
62
|
-
|
63
|
-
const setMenuOpen = (open: boolean) => {
|
64
|
-
if (!open) {
|
65
|
-
setMenuState('closed')
|
66
|
-
}
|
67
|
-
else {
|
68
|
-
setMenuState('nav')
|
69
|
-
}
|
70
|
-
}
|
71
|
-
|
72
|
-
const handleCheckout = () => {
|
73
|
-
setMenuState('closed')
|
74
|
-
setBagDrawerOpen(false)
|
75
|
-
router.push('/checkout')
|
76
|
-
}
|
77
|
-
|
78
|
-
const openBag = () => {
|
79
|
-
if (menuOpen()) {
|
80
|
-
setMenuState('bag')
|
81
|
-
}
|
82
|
-
else {
|
83
|
-
setBagDrawerOpen(true)
|
84
|
-
}
|
85
|
-
}
|
86
|
-
// header element MUST be fixed, and NOT sticky. Or else drawer breaks on mobile browsers
|
87
|
-
return (<>
|
88
|
-
<header className={cn(
|
89
|
-
'bg-background fixed z-header top-0 left-0 w-full',
|
90
|
-
className
|
91
|
-
)}>
|
92
|
-
{/* smaller than md: mobile style drawer menu; h-11 is 44px, the standard mobile header height */}
|
93
|
-
<div className="flex h-11 items-center justify-between pl-6 pr-4">
|
94
|
-
<div className='relative h-full w-200 flex flex-row'>
|
95
|
-
<Logo href='/' size='sm' className={'top-[3px] h-full'} layout='text-only'/>
|
96
|
-
{/* Not that key to the cross-fade effect
|
97
|
-
is that this is **on top of** the logo. */}
|
98
|
-
{menuOpen() && (
|
99
|
-
<div className={'absolute left-0 top-0 bottom-0 right-0 ' +
|
100
|
-
'flex flex-col justify-center ' +
|
101
|
-
'bg-background animate-mobile-menu-open'
|
102
|
-
}>
|
103
|
-
<AuthWidget className='' handleLogin={() => {setMenuState('login')}}/>
|
104
|
-
</div>
|
105
|
-
)}
|
106
|
-
</div>
|
107
|
-
<div className='flex gap-0 '>
|
108
|
-
<BagButton className='text-primary -mr-[3px]' onClick={openBag}/>
|
109
|
-
<MenuToggleButton className='text-foreground' open={menuOpen()} setOpen={setMenuOpen} />
|
110
|
-
</div>
|
111
|
-
</div>
|
112
|
-
</header>
|
113
|
-
<MobileBagDrawer
|
114
|
-
className=''
|
115
|
-
open={bagDrawerOpen}
|
116
|
-
setOpen={setBagDrawerOpen}
|
117
|
-
handleCheckout={handleCheckout}
|
118
|
-
/>
|
119
|
-
{menuOpen() && (
|
120
|
-
<div className={
|
121
|
-
'fixed top-0 left-0 w-full h-full ' +
|
122
|
-
// z must below header itself
|
123
|
-
'flex flex-column p-6 pt-15 bg-background z-below-header animate-mobile-menu-open'
|
124
|
-
}>
|
125
|
-
{menuState === 'login' ? (
|
126
|
-
<LoginPanel noHeading onLoginChanged={onLoginChanged} className='sm:animate-in sm:zoom-in-90' />
|
127
|
-
) : (
|
128
|
-
menuState === 'bag' ? (
|
129
|
-
|
130
|
-
<CartPanel
|
131
|
-
handleCheckout={() => {router.push('/checkout')}}
|
132
|
-
className={bagClx}
|
133
|
-
listClx='rounded-sm'
|
134
|
-
scrollAfter={6}
|
135
|
-
scrollHeightClx='h-[80vh]'
|
136
|
-
itemClx='mt-2'
|
137
|
-
totalClx='sticky px-1 pr-2 border rounded-sm -bottom-[1px] bg-level-1'
|
138
|
-
buttonClx='max-w-[220px] flex-none'
|
139
|
-
>
|
140
|
-
<div className='flex flex-row items-center flex-none justify-center '>
|
141
|
-
<Icons.bag className='mr-2 relative w-4 h-5 fill-foreground ' />
|
142
|
-
<p className='font-heading text-foreground text-default'>Your Bag</p>
|
143
|
-
</div>
|
144
|
-
<div className='h-[1px] w-pr-80 bg-muted-3 mx-auto mt-1.5 flex-none'/>
|
145
|
-
</CartPanel>
|
146
|
-
|
147
|
-
) : ( /* menuState === 'nav' */
|
148
|
-
<NavMenu
|
149
|
-
currentAs={currentAs}
|
150
|
-
links={links}
|
151
|
-
className='sm:animate-in sm:zoom-in-90'
|
152
|
-
commonItemClx='px-0 text-xl h-16 justify-start '
|
153
|
-
/>
|
154
|
-
)
|
155
|
-
)}
|
156
|
-
</div>
|
157
|
-
) /* menuOpen */}
|
158
|
-
</>)
|
159
|
-
}
|
160
|
-
|
161
|
-
export default MobileHeader
|
1
|
+
'use client'
|
2
|
+
import React, { useState, useEffect } from 'react'
|
3
|
+
import { useRouter } from 'next/navigation'
|
4
|
+
|
5
|
+
import type { LinkDef } from '@hanzo/ui/types'
|
6
|
+
import { cn } from '@hanzo/ui/util'
|
7
|
+
|
8
|
+
import { CartPanel, useCommerce } from '@hanzo/commerce'
|
9
|
+
import { AuthWidget, LoginPanel } from '@hanzo/auth/components'
|
10
|
+
|
11
|
+
import sendGAEvent from '../../next/analytics/google-analytics'
|
12
|
+
import * as Icons from '../icons'
|
13
|
+
|
14
|
+
import { Logo } from '..'
|
15
|
+
|
16
|
+
import MenuToggleButton from '../commerce/mobile-menu-toggle-button'
|
17
|
+
import BagButton from '../commerce/bag-button'
|
18
|
+
import MobileBagDrawer from '../commerce/mobile-bag-drawer'
|
19
|
+
import NavMenu from '../commerce/mobile-nav-menu'
|
20
|
+
|
21
|
+
const bagClx = 'mt-4 mb-8 border-none py-0 px-4 w-full ' +
|
22
|
+
'sm:min-w-[350px] sm:max-w-[500px] sm:mx-auto min-h-[60vh] max-h-[70vh] ' +
|
23
|
+
'sm:animate-in sm:zoom-in-90 '
|
24
|
+
|
25
|
+
const MobileHeader: React.FC<{
|
26
|
+
currentAs: string | undefined
|
27
|
+
links: LinkDef[]
|
28
|
+
className?: string
|
29
|
+
}> = ({
|
30
|
+
currentAs,
|
31
|
+
links,
|
32
|
+
className = ''
|
33
|
+
}) => {
|
34
|
+
|
35
|
+
const cmmc = useCommerce()
|
36
|
+
const [menuState, setMenuState] = useState<'closed' | 'nav' | 'login' | 'bag'>('closed')
|
37
|
+
const [bagDrawerOpen, setBagDrawerOpen] = useState<boolean>(false)
|
38
|
+
const router = useRouter()
|
39
|
+
|
40
|
+
useEffect(() => {
|
41
|
+
if (menuState === 'bag' || bagDrawerOpen) {
|
42
|
+
sendGAEvent('view_cart', {
|
43
|
+
items: cmmc.cartItems.map((item) => ({
|
44
|
+
item_id: item.sku,
|
45
|
+
item_name: item.title,
|
46
|
+
item_category: item.familyId,
|
47
|
+
price: item.price,
|
48
|
+
quantity: item.quantity
|
49
|
+
})),
|
50
|
+
value: cmmc.cartTotal,
|
51
|
+
currency: 'USD',
|
52
|
+
})
|
53
|
+
}
|
54
|
+
}, [menuState, bagDrawerOpen])
|
55
|
+
|
56
|
+
const menuOpen = () => (menuState !== 'closed')
|
57
|
+
|
58
|
+
const onLoginChanged = (token: string) => {
|
59
|
+
// by def, menu was in state 'login'
|
60
|
+
if (!!token) { setMenuState('nav') }
|
61
|
+
}
|
62
|
+
|
63
|
+
const setMenuOpen = (open: boolean) => {
|
64
|
+
if (!open) {
|
65
|
+
setMenuState('closed')
|
66
|
+
}
|
67
|
+
else {
|
68
|
+
setMenuState('nav')
|
69
|
+
}
|
70
|
+
}
|
71
|
+
|
72
|
+
const handleCheckout = () => {
|
73
|
+
setMenuState('closed')
|
74
|
+
setBagDrawerOpen(false)
|
75
|
+
router.push('/checkout')
|
76
|
+
}
|
77
|
+
|
78
|
+
const openBag = () => {
|
79
|
+
if (menuOpen()) {
|
80
|
+
setMenuState('bag')
|
81
|
+
}
|
82
|
+
else {
|
83
|
+
setBagDrawerOpen(true)
|
84
|
+
}
|
85
|
+
}
|
86
|
+
// header element MUST be fixed, and NOT sticky. Or else drawer breaks on mobile browsers
|
87
|
+
return (<>
|
88
|
+
<header className={cn(
|
89
|
+
'bg-background fixed z-header top-0 left-0 w-full',
|
90
|
+
className
|
91
|
+
)}>
|
92
|
+
{/* smaller than md: mobile style drawer menu; h-11 is 44px, the standard mobile header height */}
|
93
|
+
<div className="flex h-11 items-center justify-between pl-6 pr-4">
|
94
|
+
<div className='relative h-full w-200 flex flex-row'>
|
95
|
+
<Logo href='/' size='sm' className={'top-[3px] h-full'} layout='text-only'/>
|
96
|
+
{/* Not that key to the cross-fade effect
|
97
|
+
is that this is **on top of** the logo. */}
|
98
|
+
{menuOpen() && (
|
99
|
+
<div className={'absolute left-0 top-0 bottom-0 right-0 ' +
|
100
|
+
'flex flex-col justify-center ' +
|
101
|
+
'bg-background animate-mobile-menu-open'
|
102
|
+
}>
|
103
|
+
<AuthWidget className='' handleLogin={() => {setMenuState('login')}}/>
|
104
|
+
</div>
|
105
|
+
)}
|
106
|
+
</div>
|
107
|
+
<div className='flex gap-0 '>
|
108
|
+
<BagButton className='text-primary -mr-[3px]' onClick={openBag}/>
|
109
|
+
<MenuToggleButton className='text-foreground' open={menuOpen()} setOpen={setMenuOpen} />
|
110
|
+
</div>
|
111
|
+
</div>
|
112
|
+
</header>
|
113
|
+
<MobileBagDrawer
|
114
|
+
className=''
|
115
|
+
open={bagDrawerOpen}
|
116
|
+
setOpen={setBagDrawerOpen}
|
117
|
+
handleCheckout={handleCheckout}
|
118
|
+
/>
|
119
|
+
{menuOpen() && (
|
120
|
+
<div className={
|
121
|
+
'fixed top-0 left-0 w-full h-full ' +
|
122
|
+
// z must below header itself
|
123
|
+
'flex flex-column p-6 pt-15 bg-background z-below-header animate-mobile-menu-open'
|
124
|
+
}>
|
125
|
+
{menuState === 'login' ? (
|
126
|
+
<LoginPanel noHeading onLoginChanged={onLoginChanged} className='sm:animate-in sm:zoom-in-90' />
|
127
|
+
) : (
|
128
|
+
menuState === 'bag' ? (
|
129
|
+
|
130
|
+
<CartPanel
|
131
|
+
handleCheckout={() => {router.push('/checkout')}}
|
132
|
+
className={bagClx}
|
133
|
+
listClx='rounded-sm'
|
134
|
+
scrollAfter={6}
|
135
|
+
scrollHeightClx='h-[80vh]'
|
136
|
+
itemClx='mt-2'
|
137
|
+
totalClx='sticky px-1 pr-2 border rounded-sm -bottom-[1px] bg-level-1'
|
138
|
+
buttonClx='max-w-[220px] flex-none'
|
139
|
+
>
|
140
|
+
<div className='flex flex-row items-center flex-none justify-center '>
|
141
|
+
<Icons.bag className='mr-2 relative w-4 h-5 fill-foreground ' />
|
142
|
+
<p className='font-heading text-foreground text-default'>Your Bag</p>
|
143
|
+
</div>
|
144
|
+
<div className='h-[1px] w-pr-80 bg-muted-3 mx-auto mt-1.5 flex-none'/>
|
145
|
+
</CartPanel>
|
146
|
+
|
147
|
+
) : ( /* menuState === 'nav' */
|
148
|
+
<NavMenu
|
149
|
+
currentAs={currentAs}
|
150
|
+
links={links}
|
151
|
+
className='sm:animate-in sm:zoom-in-90'
|
152
|
+
commonItemClx='px-0 text-xl h-16 justify-start '
|
153
|
+
/>
|
154
|
+
)
|
155
|
+
)}
|
156
|
+
</div>
|
157
|
+
) /* menuOpen */}
|
158
|
+
</>)
|
159
|
+
}
|
160
|
+
|
161
|
+
export default MobileHeader
|
@@ -1,26 +1,26 @@
|
|
1
|
-
'use client'
|
2
|
-
|
3
|
-
import React from 'react'
|
4
|
-
import { Moon, Sun } from 'lucide-react'
|
5
|
-
import { useTheme } from 'next-themes'
|
6
|
-
|
7
|
-
import { Button } from '@hanzo/ui/primitives'
|
8
|
-
|
9
|
-
const ThemeToggle: React.FC = () => {
|
10
|
-
|
11
|
-
const { setTheme, theme } = useTheme()
|
12
|
-
|
13
|
-
return (
|
14
|
-
<Button
|
15
|
-
variant='ghost'
|
16
|
-
size='icon'
|
17
|
-
onClick={() => {setTheme(theme === 'light' ? 'dark' : 'light')}}
|
18
|
-
>
|
19
|
-
<Sun className='h-[1.5rem] w-[1.3rem] dark:hidden' />
|
20
|
-
<Moon className='hidden h-5 w-5 dark:block' />
|
21
|
-
<span className='sr-only'>Toggle theme</span>
|
22
|
-
</Button>
|
23
|
-
)
|
24
|
-
}
|
25
|
-
|
26
|
-
export default ThemeToggle
|
1
|
+
'use client'
|
2
|
+
|
3
|
+
import React from 'react'
|
4
|
+
import { Moon, Sun } from 'lucide-react'
|
5
|
+
import { useTheme } from 'next-themes'
|
6
|
+
|
7
|
+
import { Button } from '@hanzo/ui/primitives'
|
8
|
+
|
9
|
+
const ThemeToggle: React.FC = () => {
|
10
|
+
|
11
|
+
const { setTheme, theme } = useTheme()
|
12
|
+
|
13
|
+
return (
|
14
|
+
<Button
|
15
|
+
variant='ghost'
|
16
|
+
size='icon'
|
17
|
+
onClick={() => {setTheme(theme === 'light' ? 'dark' : 'light')}}
|
18
|
+
>
|
19
|
+
<Sun className='h-[1.5rem] w-[1.3rem] dark:hidden' />
|
20
|
+
<Moon className='hidden h-5 w-5 dark:block' />
|
21
|
+
<span className='sr-only'>Toggle theme</span>
|
22
|
+
</Button>
|
23
|
+
)
|
24
|
+
}
|
25
|
+
|
26
|
+
export default ThemeToggle
|
@@ -1,10 +1,10 @@
|
|
1
|
-
import React from 'react'
|
2
|
-
import { type LucideProps } from 'lucide-react'
|
3
|
-
|
4
|
-
const BagIcon: React.FC<LucideProps> = (props: LucideProps) => (
|
5
|
-
<svg fill="none" viewBox="0 0 1019 1281" {...props}>
|
6
|
-
<path d="m977.243 365.553h-175.407v-90.629c0-151.923-131.968-274.924-292.334-274.924-160.367 0-292.337 123.002-292.337 274.924v90.629h-175.4023c-23.3886 0-41.7627 17.051-41.7627 38.756v775.121c0 55.8 48.4456 100.76 108.582 100.76h801.84c60.138 0 108.578-44.96 108.578-100.76v-775.121c0-21.705-18.37-38.756-41.757-38.756zm-676.553-90.629c0-108.517 93.546-196.9408 208.812-196.9408 115.265 0 208.813 88.4218 208.813 196.9408v89.08h-417.625z" fill="currentColor"/>
|
7
|
-
</svg>
|
8
|
-
)
|
9
|
-
|
10
|
-
export default BagIcon
|
1
|
+
import React from 'react'
|
2
|
+
import { type LucideProps } from 'lucide-react'
|
3
|
+
|
4
|
+
const BagIcon: React.FC<LucideProps> = (props: LucideProps) => (
|
5
|
+
<svg fill="none" viewBox="0 0 1019 1281" {...props}>
|
6
|
+
<path d="m977.243 365.553h-175.407v-90.629c0-151.923-131.968-274.924-292.334-274.924-160.367 0-292.337 123.002-292.337 274.924v90.629h-175.4023c-23.3886 0-41.7627 17.051-41.7627 38.756v775.121c0 55.8 48.4456 100.76 108.582 100.76h801.84c60.138 0 108.578-44.96 108.578-100.76v-775.121c0-21.705-18.37-38.756-41.757-38.756zm-676.553-90.629c0-108.517 93.546-196.9408 208.812-196.9408 115.265 0 208.813 88.4218 208.813 196.9408v89.08h-417.625z" fill="currentColor"/>
|
7
|
+
</svg>
|
8
|
+
)
|
9
|
+
|
10
|
+
export default BagIcon
|
@@ -1,14 +1,14 @@
|
|
1
|
-
import React from 'react'
|
2
|
-
import { type LucideProps } from 'lucide-react'
|
3
|
-
|
4
|
-
|
5
|
-
const GitHub: React.FC<LucideProps> = (props: LucideProps) => (
|
6
|
-
<svg viewBox="0 0 438.549 438.549" {...props}>
|
7
|
-
<path
|
8
|
-
fill="currentColor"
|
9
|
-
d="M409.132 114.573c-19.608-33.596-46.205-60.194-79.798-79.8-33.598-19.607-70.277-29.408-110.063-29.408-39.781 0-76.472 9.804-110.063 29.408-33.596 19.605-60.192 46.204-79.8 79.8C9.803 148.168 0 184.854 0 224.63c0 47.78 13.94 90.745 41.827 128.906 27.884 38.164 63.906 64.572 108.063 79.227 5.14.954 8.945.283 11.419-1.996 2.475-2.282 3.711-5.14 3.711-8.562 0-.571-.049-5.708-.144-15.417a2549.81 2549.81 0 01-.144-25.406l-6.567 1.136c-4.187.767-9.469 1.092-15.846 1-6.374-.089-12.991-.757-19.842-1.999-6.854-1.231-13.229-4.086-19.13-8.559-5.898-4.473-10.085-10.328-12.56-17.556l-2.855-6.57c-1.903-4.374-4.899-9.233-8.992-14.559-4.093-5.331-8.232-8.945-12.419-10.848l-1.999-1.431c-1.332-.951-2.568-2.098-3.711-3.429-1.142-1.331-1.997-2.663-2.568-3.997-.572-1.335-.098-2.43 1.427-3.289 1.525-.859 4.281-1.276 8.28-1.276l5.708.853c3.807.763 8.516 3.042 14.133 6.851 5.614 3.806 10.229 8.754 13.846 14.842 4.38 7.806 9.657 13.754 15.846 17.847 6.184 4.093 12.419 6.136 18.699 6.136 6.28 0 11.704-.476 16.274-1.423 4.565-.952 8.848-2.383 12.847-4.285 1.713-12.758 6.377-22.559 13.988-29.41-10.848-1.14-20.601-2.857-29.264-5.14-8.658-2.286-17.605-5.996-26.835-11.14-9.235-5.137-16.896-11.516-22.985-19.126-6.09-7.614-11.088-17.61-14.987-29.979-3.901-12.374-5.852-26.648-5.852-42.826 0-23.035 7.52-42.637 22.557-58.817-7.044-17.318-6.379-36.732 1.997-58.24 5.52-1.715 13.706-.428 24.554 3.853 10.85 4.283 18.794 7.952 23.84 10.994 5.046 3.041 9.089 5.618 12.135 7.708 17.705-4.947 35.976-7.421 54.818-7.421s37.117 2.474 54.823 7.421l10.849-6.849c7.419-4.57 16.18-8.758 26.262-12.565 10.088-3.805 17.802-4.853 23.134-3.138 8.562 21.509 9.325 40.922 2.279 58.24 15.036 16.18 22.559 35.787 22.559 58.817 0 16.178-1.958 30.497-5.853 42.966-3.9 12.471-8.941 22.457-15.125 29.979-6.191 7.521-13.901 13.85-23.131 18.986-9.232 5.14-18.182 8.85-26.84 11.136-8.662 2.286-18.415 4.004-29.263 5.146 9.894 8.562 14.842 22.077 14.842 40.539v60.237c0 3.422 1.19 6.279 3.572 8.562 2.379 2.279 6.136 2.95 11.276 1.995 44.163-14.653 80.185-41.062 108.068-79.226 27.88-38.161 41.825-81.126 41.825-128.906-.01-39.771-9.818-76.454-29.414-110.049z"
|
10
|
-
></path>
|
11
|
-
</svg>
|
12
|
-
)
|
13
|
-
|
14
|
-
export default GitHub
|
1
|
+
import React from 'react'
|
2
|
+
import { type LucideProps } from 'lucide-react'
|
3
|
+
|
4
|
+
|
5
|
+
const GitHub: React.FC<LucideProps> = (props: LucideProps) => (
|
6
|
+
<svg viewBox="0 0 438.549 438.549" {...props}>
|
7
|
+
<path
|
8
|
+
fill="currentColor"
|
9
|
+
d="M409.132 114.573c-19.608-33.596-46.205-60.194-79.798-79.8-33.598-19.607-70.277-29.408-110.063-29.408-39.781 0-76.472 9.804-110.063 29.408-33.596 19.605-60.192 46.204-79.8 79.8C9.803 148.168 0 184.854 0 224.63c0 47.78 13.94 90.745 41.827 128.906 27.884 38.164 63.906 64.572 108.063 79.227 5.14.954 8.945.283 11.419-1.996 2.475-2.282 3.711-5.14 3.711-8.562 0-.571-.049-5.708-.144-15.417a2549.81 2549.81 0 01-.144-25.406l-6.567 1.136c-4.187.767-9.469 1.092-15.846 1-6.374-.089-12.991-.757-19.842-1.999-6.854-1.231-13.229-4.086-19.13-8.559-5.898-4.473-10.085-10.328-12.56-17.556l-2.855-6.57c-1.903-4.374-4.899-9.233-8.992-14.559-4.093-5.331-8.232-8.945-12.419-10.848l-1.999-1.431c-1.332-.951-2.568-2.098-3.711-3.429-1.142-1.331-1.997-2.663-2.568-3.997-.572-1.335-.098-2.43 1.427-3.289 1.525-.859 4.281-1.276 8.28-1.276l5.708.853c3.807.763 8.516 3.042 14.133 6.851 5.614 3.806 10.229 8.754 13.846 14.842 4.38 7.806 9.657 13.754 15.846 17.847 6.184 4.093 12.419 6.136 18.699 6.136 6.28 0 11.704-.476 16.274-1.423 4.565-.952 8.848-2.383 12.847-4.285 1.713-12.758 6.377-22.559 13.988-29.41-10.848-1.14-20.601-2.857-29.264-5.14-8.658-2.286-17.605-5.996-26.835-11.14-9.235-5.137-16.896-11.516-22.985-19.126-6.09-7.614-11.088-17.61-14.987-29.979-3.901-12.374-5.852-26.648-5.852-42.826 0-23.035 7.52-42.637 22.557-58.817-7.044-17.318-6.379-36.732 1.997-58.24 5.52-1.715 13.706-.428 24.554 3.853 10.85 4.283 18.794 7.952 23.84 10.994 5.046 3.041 9.089 5.618 12.135 7.708 17.705-4.947 35.976-7.421 54.818-7.421s37.117 2.474 54.823 7.421l10.849-6.849c7.419-4.57 16.18-8.758 26.262-12.565 10.088-3.805 17.802-4.853 23.134-3.138 8.562 21.509 9.325 40.922 2.279 58.24 15.036 16.18 22.559 35.787 22.559 58.817 0 16.178-1.958 30.497-5.853 42.966-3.9 12.471-8.941 22.457-15.125 29.979-6.191 7.521-13.901 13.85-23.131 18.986-9.232 5.14-18.182 8.85-26.84 11.136-8.662 2.286-18.415 4.004-29.263 5.146 9.894 8.562 14.842 22.077 14.842 40.539v60.237c0 3.422 1.19 6.279 3.572 8.562 2.379 2.279 6.136 2.95 11.276 1.995 44.163-14.653 80.185-41.062 108.068-79.226 27.88-38.161 41.825-81.126 41.825-128.906-.01-39.771-9.818-76.454-29.414-110.049z"
|
10
|
+
></path>
|
11
|
+
</svg>
|
12
|
+
)
|
13
|
+
|
14
|
+
export default GitHub
|