@luxfi/core 5.3.7 → 10.0.1
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/package.json +9 -53
- package/tsconfig.json +3 -8
- package/types/asset.ts +28 -0
- package/types/contract.ts +13 -0
- package/types/deposit-address.ts +9 -0
- package/types/exchange.ts +25 -0
- package/types/index.ts +21 -4
- package/types/network-type.ts +16 -0
- package/types/network.ts +58 -0
- package/types/swap-status.ts +58 -0
- package/types/transaction-type.ts +5 -0
- package/types/utila.ts +36 -0
- package/commerce/ui/conf.ts +0 -13
- package/commerce/ui/context.tsx +0 -123
- package/commerce/ui/store.ts +0 -290
- package/components/access-code-input.tsx +0 -71
- package/components/auth/auth-listener.tsx +0 -29
- package/components/auth/auth-token/clear-auth-token.tsx +0 -12
- package/components/auth/auth-token/set-auth-token.tsx +0 -16
- package/components/auth/common-auth-domains.ts +0 -16
- package/components/auth/login-panel.tsx +0 -107
- package/components/back-button.tsx +0 -49
- package/components/chat-widget.tsx +0 -85
- package/components/commerce/_to_deprecate_checkout-widget/const.ts +0 -13
- package/components/commerce/_to_deprecate_checkout-widget/index.tsx_ +0 -188
- package/components/commerce/_to_deprecate_checkout-widget/obs-string-set.ts +0 -48
- package/components/commerce/_to_deprecate_checkout-widget/use-anim-clx-set.ts +0 -59
- package/components/commerce/bag-button.tsx +0 -98
- package/components/commerce/buy-button.tsx +0 -34
- package/components/commerce/checkout-button.tsx +0 -129
- package/components/commerce/checkout-panel/cart-accordian.tsx +0 -66
- package/components/commerce/checkout-panel/checkout-panel-props.ts +0 -10
- package/components/commerce/checkout-panel/desktop-bag-carousel.tsx +0 -36
- package/components/commerce/checkout-panel/desktop-cp.tsx +0 -83
- package/components/commerce/checkout-panel/index.tsx +0 -126
- package/components/commerce/checkout-panel/mobile-cp.tsx +0 -67
- package/components/commerce/checkout-panel/policy-links.tsx +0 -29
- package/components/commerce/checkout-panel/steps-indicator.tsx +0 -39
- package/components/commerce/checkout-panel/thank-you.tsx +0 -18
- package/components/commerce/desktop-bag-popup.tsx +0 -78
- package/components/commerce/desktop-nav-menu.tsx +0 -194
- package/components/commerce/drawer/index.tsx +0 -88
- package/components/commerce/drawer/micro.tsx +0 -145
- package/components/commerce/drawer/shell.tsx +0 -85
- package/components/commerce/mobile-bag-drawer.tsx +0 -51
- package/components/commerce/mobile-login-button.tsx +0 -108
- package/components/commerce/mobile-menu-toggle-button.tsx +0 -35
- package/components/commerce/mobile-nav-menu-ai.tsx +0 -51
- package/components/commerce/mobile-nav-menu-item.tsx +0 -50
- package/components/commerce/mobile-nav-menu.tsx +0 -102
- package/components/contact-dialog/contact-form.tsx +0 -113
- package/components/contact-dialog/disclaimer.tsx +0 -13
- package/components/contact-dialog/index.tsx +0 -64
- package/components/copyright.tsx +0 -21
- package/components/drawer-margin.tsx +0 -28
- package/components/footer.tsx +0 -78
- package/components/header/desktop.tsx +0 -51
- package/components/header/index.tsx +0 -50
- package/components/header/mobile.tsx +0 -163
- package/components/header/theme-toggle.tsx +0 -26
- package/components/icons/24k-gold-card.tsx +0 -43
- package/components/icons/ai-chat-act.tsx +0 -47
- package/components/icons/ai-chat.tsx +0 -29
- package/components/icons/anodized-titanium.tsx +0 -45
- package/components/icons/avatar.tsx +0 -11
- package/components/icons/bag-icon.tsx +0 -10
- package/components/icons/blog-act.tsx +0 -14
- package/components/icons/blog.tsx +0 -20
- package/components/icons/bridge-act.tsx +0 -18
- package/components/icons/bridge.tsx +0 -68
- package/components/icons/changelog-act.tsx +0 -15
- package/components/icons/changelog.tsx +0 -21
- package/components/icons/chrome.tsx +0 -45
- package/components/icons/coins-act.tsx +0 -29
- package/components/icons/coins.tsx +0 -20
- package/components/icons/compare-cards-act.tsx +0 -30
- package/components/icons/compare-cards.tsx +0 -21
- package/components/icons/credit-act.tsx +0 -29
- package/components/icons/credit.tsx +0 -20
- package/components/icons/customer-support-act.tsx +0 -27
- package/components/icons/customer-support.tsx +0 -21
- package/components/icons/customers-act.tsx +0 -65
- package/components/icons/customers.tsx +0 -33
- package/components/icons/developer-docs-act.tsx +0 -26
- package/components/icons/developer-docs.tsx +0 -20
- package/components/icons/exchange-act.tsx +0 -27
- package/components/icons/exchange.tsx +0 -21
- package/components/icons/explorer-act.tsx +0 -27
- package/components/icons/explorer.tsx +0 -22
- package/components/icons/faqs-act.tsx +0 -27
- package/components/icons/faqs.tsx +0 -21
- package/components/icons/github.tsx +0 -14
- package/components/icons/guides-act.tsx +0 -26
- package/components/icons/guides.tsx +0 -21
- package/components/icons/gun-metal.tsx +0 -44
- package/components/icons/index.tsx +0 -43
- package/components/icons/integrations-act.tsx +0 -41
- package/components/icons/integrations.tsx +0 -25
- package/components/icons/irradescent.tsx +0 -41
- package/components/icons/launch-subnet.tsx +0 -21
- package/components/icons/launchsubnet-act.tsx +0 -29
- package/components/icons/left-arrow.tsx +0 -11
- package/components/icons/lux-finance-act.tsx +0 -34
- package/components/icons/lux-finance.tsx +0 -23
- package/components/icons/lux-logo.tsx +0 -10
- package/components/icons/lux-pass-act.tsx +0 -41
- package/components/icons/lux-pass.tsx +0 -25
- package/components/icons/lux-quests-act.tsx +0 -15
- package/components/icons/lux-quests.tsx +0 -21
- package/components/icons/market-act.tsx +0 -39
- package/components/icons/market.tsx +0 -24
- package/components/icons/mirrored-titanium.tsx +0 -46
- package/components/icons/more-benefits-act.tsx +0 -29
- package/components/icons/more-benefits.tsx +0 -21
- package/components/icons/open-source-act.tsx +0 -41
- package/components/icons/open-source.tsx +0 -26
- package/components/icons/right-arrow.tsx +0 -10
- package/components/icons/safe-act.tsx +0 -77
- package/components/icons/safe.tsx +0 -37
- package/components/icons/search.tsx +0 -12
- package/components/icons/secure-delivery.tsx +0 -13
- package/components/icons/shop-act.tsx +0 -29
- package/components/icons/shop.tsx +0 -20
- package/components/icons/social-icon.tsx +0 -35
- package/components/icons/social-svg.css +0 -3
- package/components/icons/sterling-silver-card.tsx +0 -44
- package/components/icons/templates-act.tsx +0 -29
- package/components/icons/templates.tsx +0 -21
- package/components/icons/validators-act.tsx +0 -42
- package/components/icons/validators.tsx +0 -41
- package/components/icons/view-all-card-act.tsx +0 -28
- package/components/icons/view-all-card.tsx +0 -20
- package/components/icons/wallet-act.tsx +0 -29
- package/components/icons/wallet.tsx +0 -20
- package/components/icons/warpcast.tsx +0 -58
- package/components/icons/youtube-logo.tsx +0 -59
- package/components/index.ts +0 -25
- package/components/logo.tsx +0 -89
- package/components/main.tsx +0 -27
- package/components/mini-chart/index.tsx +0 -8
- package/components/mini-chart/mini-chart-props.ts +0 -44
- package/components/mini-chart/mini-chart.tsx +0 -85
- package/components/mini-chart/wrapper.tsx +0 -23
- package/components/not-found/index.tsx +0 -28
- package/components/not-found/not-found-content.mdx +0 -5
- package/components/scripts.tsx +0 -24
- package/components/tooltip.tsx +0 -31
- package/environment.d.ts +0 -6
- package/next/analytics/fpixel.ts +0 -16
- package/next/analytics/google-analytics.ts +0 -14
- package/next/analytics/index.ts +0 -3
- package/next/analytics/pixel-analytics.tsx +0 -55
- package/next/font/get-app-router-font-classes.ts +0 -12
- package/next/font/load-and-return-lux-next-fonts-on-import.ts +0 -68
- package/next/font/local/Druk-Wide-Bold.ttf +0 -0
- package/next/font/local/Druk-Wide-Medium.ttf +0 -0
- package/next/font/local/InterVariable-Italic.ttf +0 -0
- package/next/font/local/InterVariable-Italic.woff2 +0 -0
- package/next/font/local/InterVariable.ttf +0 -0
- package/next/font/local/InterVariable.woff2 +0 -0
- package/next/font/next-font-desc.ts +0 -28
- package/next/font/pages-router-font-vars.tsx +0 -18
- package/next/head-metadata/from-next/metadata-types.ts +0 -158
- package/next/head-metadata/from-next/opengraph-types.ts +0 -267
- package/next/head-metadata/from-next/twitter-types.ts +0 -92
- package/next/head-metadata/index.tsx +0 -208
- package/next/index.ts +0 -1
- package/next/middleware/determine-device-mw.ts +0 -16
- package/root-layout/WHY_THIS_IS_SEPARATE.txt +0 -2
- package/root-layout/index.tsx +0 -112
- package/server-actions/TO-DO.txt +0 -1
- package/server-actions/firebase-app.ts +0 -14
- package/server-actions/index.ts +0 -5
- package/server-actions/store-contact.ts +0 -51
- package/site-def/footer/community.tsx +0 -67
- package/site-def/footer/company.ts +0 -37
- package/site-def/footer/ecosystem.ts +0 -37
- package/site-def/footer/index.tsx +0 -26
- package/site-def/footer/legal.ts +0 -28
- package/site-def/footer/network.ts +0 -45
- package/site-def/footer/svg/warpcast-logo.svg +0 -12
- package/site-def/index.ts +0 -3
- package/site-def/main-nav.tsx +0 -458
- package/style/cart-animation.css +0 -29
- package/style/checkout-animation.css +0 -23
- package/style/drawer-handle-overrides.css +0 -160
- package/style/lux-colors.css +0 -85
- package/style/lux-global.css +0 -51
- package/tailwind/fontFamily.tailwind.lux.ts +0 -18
- package/tailwind/index.ts +0 -2
- package/tailwind/lux-tw-fonts.ts +0 -40
- package/tailwind/tailwind.config.lux-preset.ts +0 -10
- package/types/chatbot-config.ts +0 -7
- package/types/chatbot-suggested-question.ts +0 -7
- package/types/contact-info.ts +0 -11
- package/types/site-def.ts +0 -43
|
@@ -1,102 +0,0 @@
|
|
|
1
|
-
'use client'
|
|
2
|
-
import React from 'react'
|
|
3
|
-
import type { LinkDef } from '@hanzo/ui/types'
|
|
4
|
-
import { cn } from '@hanzo/ui/util'
|
|
5
|
-
import type { LinkDefExtended, ChildMenu } from '../../site-def/main-nav'
|
|
6
|
-
import MobileNavMenuAI from './mobile-nav-menu-ai'
|
|
7
|
-
import MobileNavMenuItem from './mobile-nav-menu-item'
|
|
8
|
-
import MobileAuthWidget from './mobile-login-button'
|
|
9
|
-
import { Accordion, AccordionItem, AccordionTrigger, AccordionContent } from '@hanzo/ui/primitives'
|
|
10
|
-
import { ChevronDown } from 'lucide-react'
|
|
11
|
-
import Link from 'next/link'
|
|
12
|
-
|
|
13
|
-
const MobileNav: React.FC<{
|
|
14
|
-
currentAs: string | undefined
|
|
15
|
-
links: LinkDefExtended[]
|
|
16
|
-
className?: string
|
|
17
|
-
commonItemClx?: string | ((def: LinkDef) => string)
|
|
18
|
-
setChatbotOpen: (open: boolean) => void
|
|
19
|
-
setMenuOpen: (open: boolean) => void
|
|
20
|
-
setMenuState: (arg: 'closed' | 'nav' | 'login' | 'bag') => void
|
|
21
|
-
}> = ({
|
|
22
|
-
currentAs,
|
|
23
|
-
links,
|
|
24
|
-
setMenuState,
|
|
25
|
-
className = '',
|
|
26
|
-
commonItemClx,
|
|
27
|
-
setChatbotOpen,
|
|
28
|
-
setMenuOpen
|
|
29
|
-
}) => (
|
|
30
|
-
links.length > 0 ? (
|
|
31
|
-
<div className={cn('flex flex-col h-full', className)}>
|
|
32
|
-
<MobileNavMenuAI setMenuOpen={setMenuOpen} />
|
|
33
|
-
<div className="flex flex-col flex-1 overflow-auto">
|
|
34
|
-
<Accordion type="single" collapsible className='w-full h-full'>
|
|
35
|
-
{links.map((el, index) => {
|
|
36
|
-
const itemClx = (commonItemClx) ? (typeof commonItemClx === 'string' ? commonItemClx : commonItemClx(el)) : ''
|
|
37
|
-
const variant = el.variant ?? 'link'
|
|
38
|
-
let internalClx = variant === 'link'
|
|
39
|
-
? ' text-muted hover:text-foreground active:text-accent rounded-none'
|
|
40
|
-
: ' min-w-0'
|
|
41
|
-
|
|
42
|
-
if (currentAs && currentAs === el.href) {
|
|
43
|
-
internalClx += ' pointer-events-none'
|
|
44
|
-
if (variant === 'link') {
|
|
45
|
-
internalClx += ' text-accent'
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
if (!el.isAIMenu) {
|
|
50
|
-
return (
|
|
51
|
-
<AccordionItem key={index} value={el.title ? el.title : ""} className='!no-underline !border-0 px-6'>
|
|
52
|
-
<AccordionTrigger className={cn(internalClx, itemClx, '')}>
|
|
53
|
-
<div className={cn(internalClx, itemClx, 'flex items-center justify-between w-full pl-3 text-base font-normal leading-6')}>
|
|
54
|
-
{el.title}
|
|
55
|
-
</div>
|
|
56
|
-
<ChevronDown className="w-4 h-4 mr-3" />
|
|
57
|
-
</AccordionTrigger>
|
|
58
|
-
<AccordionContent>
|
|
59
|
-
{el.childMenu && (
|
|
60
|
-
<div className="px-4">
|
|
61
|
-
{Object.entries(el.childMenu.reduce((acc, child) => {
|
|
62
|
-
const group = acc[child.groupName ? child.groupName : ""] || []
|
|
63
|
-
group.push(child)
|
|
64
|
-
acc[child.groupName ? child.groupName : ""] = group
|
|
65
|
-
return acc
|
|
66
|
-
}, {} as { [key: string]: ChildMenu[] })).map(([groupName, children]) => (
|
|
67
|
-
<div key={groupName}>
|
|
68
|
-
<div className="mt-4 mb-4 font-light text-muted-1">{groupName}</div>
|
|
69
|
-
{children.map((child, childIndex) => (
|
|
70
|
-
<div key={childIndex} className="m-2">
|
|
71
|
-
<div className="flex items-center py-1">
|
|
72
|
-
<span>
|
|
73
|
-
{child.icon && child.icon}
|
|
74
|
-
</span>
|
|
75
|
-
<Link
|
|
76
|
-
href={child.href}
|
|
77
|
-
className="text-muted-2 hover:underline ml-5 hover:text-primary"
|
|
78
|
-
target={child.newTab ? '_blank' : '_self'}
|
|
79
|
-
rel="noopener noreferrer"
|
|
80
|
-
>
|
|
81
|
-
{child.title}
|
|
82
|
-
</Link>
|
|
83
|
-
</div>
|
|
84
|
-
</div>
|
|
85
|
-
))}
|
|
86
|
-
</div>
|
|
87
|
-
))}
|
|
88
|
-
</div>
|
|
89
|
-
)}
|
|
90
|
-
</AccordionContent>
|
|
91
|
-
</AccordionItem>
|
|
92
|
-
)
|
|
93
|
-
}
|
|
94
|
-
})}
|
|
95
|
-
</Accordion>
|
|
96
|
-
</div>
|
|
97
|
-
<MobileAuthWidget className='text-2xl z-10' handleLogin={() => { setMenuState('login') }} />
|
|
98
|
-
</div>
|
|
99
|
-
) : null
|
|
100
|
-
);
|
|
101
|
-
|
|
102
|
-
export default MobileNav;
|
|
@@ -1,113 +0,0 @@
|
|
|
1
|
-
'use client'
|
|
2
|
-
|
|
3
|
-
import React, { useTransition } from 'react'
|
|
4
|
-
|
|
5
|
-
import { useForm, type SubmitHandler, type ControllerRenderProps } from 'react-hook-form'
|
|
6
|
-
import { z } from 'zod'
|
|
7
|
-
import { zodResolver } from '@hookform/resolvers/zod'
|
|
8
|
-
|
|
9
|
-
// @ts-ignore
|
|
10
|
-
import validator from 'validator'
|
|
11
|
-
|
|
12
|
-
import { Loader2 } from 'lucide-react'
|
|
13
|
-
|
|
14
|
-
import {
|
|
15
|
-
Button,
|
|
16
|
-
Input,
|
|
17
|
-
Form,
|
|
18
|
-
FormControl,
|
|
19
|
-
FormField,
|
|
20
|
-
FormItem,
|
|
21
|
-
FormMessage,
|
|
22
|
-
} from '@hanzo/ui/primitives'
|
|
23
|
-
|
|
24
|
-
import type { SubmitServerAction } from '@hanzo/ui/types'
|
|
25
|
-
import type { ContactInfo } from '../../types'
|
|
26
|
-
|
|
27
|
-
const ContactFormSchema = z.object({
|
|
28
|
-
email: z
|
|
29
|
-
.string()
|
|
30
|
-
.min(1, { message: "Email must be provided." })
|
|
31
|
-
.email("Invalid email."),
|
|
32
|
-
phone: z
|
|
33
|
-
.string()
|
|
34
|
-
.min(1, { message: "Telephone must be provided." })
|
|
35
|
-
.refine(validator.isMobilePhone, { message: "Invalid format." })
|
|
36
|
-
})
|
|
37
|
-
|
|
38
|
-
type ContactFormSchemaType = z.infer<typeof ContactFormSchema>
|
|
39
|
-
|
|
40
|
-
const ContactForm: React.FC<{
|
|
41
|
-
onSubmit: (data: ContactFormSchemaType, enc: any) => void
|
|
42
|
-
enclosure: any
|
|
43
|
-
}> = ({
|
|
44
|
-
onSubmit: _onSubmit,
|
|
45
|
-
enclosure
|
|
46
|
-
}) => {
|
|
47
|
-
|
|
48
|
-
const form = useForm<ContactFormSchemaType>({
|
|
49
|
-
resolver: zodResolver(ContactFormSchema),
|
|
50
|
-
defaultValues: {
|
|
51
|
-
email: '',
|
|
52
|
-
phone: '',
|
|
53
|
-
},
|
|
54
|
-
})
|
|
55
|
-
|
|
56
|
-
const [isPending, startTransition] = useTransition()
|
|
57
|
-
|
|
58
|
-
const onSubmit: SubmitHandler<ContactFormSchemaType> = (data) => {
|
|
59
|
-
// https://github.com/orgs/react-hook-form/discussions/10757#discussioncomment-6672403
|
|
60
|
-
// @ts-ignore
|
|
61
|
-
startTransition(async () => {
|
|
62
|
-
await _onSubmit(data, enclosure)
|
|
63
|
-
})
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
const MyFormItem: React.FC<{
|
|
67
|
-
field: ControllerRenderProps<ContactFormSchemaType, 'email'> | ControllerRenderProps<ContactFormSchemaType, 'phone'>
|
|
68
|
-
placeholder: string
|
|
69
|
-
}> = ({
|
|
70
|
-
field,
|
|
71
|
-
placeholder
|
|
72
|
-
}) => (
|
|
73
|
-
<FormItem className="space-y-0" >
|
|
74
|
-
<FormControl>
|
|
75
|
-
<Input placeholder={placeholder} {...field} className="mt-0 text-foreground"/>
|
|
76
|
-
</FormControl>
|
|
77
|
-
<div className="flex flex-row justify-start items-stretch gap-2">
|
|
78
|
-
<FormMessage />
|
|
79
|
-
</div>
|
|
80
|
-
</FormItem>
|
|
81
|
-
)
|
|
82
|
-
|
|
83
|
-
return (
|
|
84
|
-
<Form {...form}>
|
|
85
|
-
<form onSubmit={form.handleSubmit(onSubmit)} className="w-3/4">
|
|
86
|
-
<div className='flex flex-col justify-start items-stretch mt-4'>
|
|
87
|
-
<FormField
|
|
88
|
-
control={form.control}
|
|
89
|
-
name='email'
|
|
90
|
-
render={({ field }) => ( <MyFormItem field={field} placeholder='email'/> )}
|
|
91
|
-
/>
|
|
92
|
-
<FormField
|
|
93
|
-
control={form.control}
|
|
94
|
-
name='phone'
|
|
95
|
-
// @ts-ignore
|
|
96
|
-
render={({ field }) => ( <MyFormItem field={field} placeholder='phone'/> )}
|
|
97
|
-
/>
|
|
98
|
-
<Button disabled={isPending} type='submit' className='bg-primary text-primary-fg hover:bg-primary-hover'>
|
|
99
|
-
{isPending ? (<>
|
|
100
|
-
<Loader2 className="mr-2 h-4 w-4 animate-spin" />
|
|
101
|
-
Please wait
|
|
102
|
-
</>
|
|
103
|
-
) : (
|
|
104
|
-
<>Submit</>
|
|
105
|
-
)}
|
|
106
|
-
</Button>
|
|
107
|
-
</div>
|
|
108
|
-
</form>
|
|
109
|
-
</Form>
|
|
110
|
-
)
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
export default ContactForm
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import React from 'react'
|
|
2
|
-
|
|
3
|
-
const Disclaimer: React.FC = () => (
|
|
4
|
-
<div>
|
|
5
|
-
By entering your mobile number and submitting, you consent to receive text messages from Lux at the number provided.
|
|
6
|
-
Message and data rates may apply. Message frequency varies.
|
|
7
|
-
You can unsubscribe at any time by replying STOP.
|
|
8
|
-
View our <a href='/privacy'>Privacy Policy</a> and <a href='/terms'>Terms & conditions</a>.
|
|
9
|
-
</div>
|
|
10
|
-
)
|
|
11
|
-
|
|
12
|
-
export default Disclaimer
|
|
13
|
-
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
'use client'
|
|
2
|
-
|
|
3
|
-
import React, { useState } from 'react'
|
|
4
|
-
|
|
5
|
-
import type { ButtonModalProps} from '@hanzo/ui/types'
|
|
6
|
-
|
|
7
|
-
import {
|
|
8
|
-
Button,
|
|
9
|
-
Dialog,
|
|
10
|
-
DialogContent,
|
|
11
|
-
DialogDescription,
|
|
12
|
-
DialogHeader,
|
|
13
|
-
DialogTitle,
|
|
14
|
-
DialogTrigger,
|
|
15
|
-
} from '@hanzo/ui/primitives'
|
|
16
|
-
|
|
17
|
-
import ContactForm from './contact-form'
|
|
18
|
-
import Disclaimer from './disclaimer'
|
|
19
|
-
|
|
20
|
-
const ContactDialog: React.FC<ButtonModalProps> = ({
|
|
21
|
-
open,
|
|
22
|
-
onOpenChange,
|
|
23
|
-
buttonText,
|
|
24
|
-
buttonProps,
|
|
25
|
-
title,
|
|
26
|
-
byline,
|
|
27
|
-
action,
|
|
28
|
-
actionEnclosure
|
|
29
|
-
}) => {
|
|
30
|
-
const [success, setSuccess] = useState(false)
|
|
31
|
-
|
|
32
|
-
const onSubmit = async (formData: any, enclosure: any) => {
|
|
33
|
-
const result = await action(formData, enclosure)
|
|
34
|
-
if (result.success) {
|
|
35
|
-
setSuccess(true)
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
return (
|
|
40
|
-
<Dialog open={open} onOpenChange={onOpenChange} >
|
|
41
|
-
<DialogTrigger asChild>
|
|
42
|
-
<Button {...buttonProps} >{buttonText}</Button>
|
|
43
|
-
</DialogTrigger>
|
|
44
|
-
<DialogContent className="sm:max-w-[500px] p-0 gap-0 bg-background border">
|
|
45
|
-
<DialogHeader className='py-6 text-foreground'>
|
|
46
|
-
<DialogTitle className='text-4xl text-center text-inherit'>{title}</DialogTitle>
|
|
47
|
-
{byline && (<DialogDescription className='text-inherit text-lg text-center'>{byline} </DialogDescription>)}
|
|
48
|
-
</DialogHeader>
|
|
49
|
-
<div className='px-8 pb-8 rounded-e-lg flex flex-col justify-start items-center'>
|
|
50
|
-
{success ? (
|
|
51
|
-
<p>{actionEnclosure?.reply}</p>
|
|
52
|
-
) : (
|
|
53
|
-
<ContactForm onSubmit={onSubmit} enclosure={actionEnclosure}/>
|
|
54
|
-
)}
|
|
55
|
-
<div className='text-muted-1 text-xs mt-4' >
|
|
56
|
-
<Disclaimer />
|
|
57
|
-
</div>
|
|
58
|
-
</div>
|
|
59
|
-
</DialogContent>
|
|
60
|
-
</Dialog>
|
|
61
|
-
)
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
export default ContactDialog
|
package/components/copyright.tsx
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import React from 'react'
|
|
2
|
-
|
|
3
|
-
const FIRST = 2020
|
|
4
|
-
|
|
5
|
-
const Copyright: React.FC<{
|
|
6
|
-
className?: string
|
|
7
|
-
}> = ({
|
|
8
|
-
className=''
|
|
9
|
-
}) => {
|
|
10
|
-
|
|
11
|
-
const year = new Date().getFullYear()
|
|
12
|
-
const yearString = (year > FIRST) ? `${FIRST} - ${year}` : FIRST.toString()
|
|
13
|
-
|
|
14
|
-
return (
|
|
15
|
-
<div className={className}>
|
|
16
|
-
{`Copyright © ${yearString}`} <br className='sm:hidden'/>Lux Partners Limited. <br className='md:hidden'/> All rights reserved.
|
|
17
|
-
</div>
|
|
18
|
-
)
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export default Copyright
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
'use client'
|
|
2
|
-
import React from 'react'
|
|
3
|
-
|
|
4
|
-
import { cn } from '@hanzo/ui/util'
|
|
5
|
-
import { useCommerceDrawer } from '@luxfi/core/commerce'
|
|
6
|
-
import { observer } from 'mobx-react-lite'
|
|
7
|
-
|
|
8
|
-
const DrawerMargin: React.FC<{
|
|
9
|
-
clx?: string
|
|
10
|
-
}> = observer(({
|
|
11
|
-
clx=''
|
|
12
|
-
}) => {
|
|
13
|
-
|
|
14
|
-
const drawer = useCommerceDrawer()
|
|
15
|
-
if (!drawer) {
|
|
16
|
-
throw new Error("DrawerMargin must be used with a CommerceUIContext!")
|
|
17
|
-
}
|
|
18
|
-
return (
|
|
19
|
-
<div
|
|
20
|
-
className={cn('transition-height', clx)}
|
|
21
|
-
style={{
|
|
22
|
-
height: drawer.state === 'micro' ? drawer.microHeight : 0
|
|
23
|
-
}}
|
|
24
|
-
/>
|
|
25
|
-
)
|
|
26
|
-
})
|
|
27
|
-
|
|
28
|
-
export default DrawerMargin
|
package/components/footer.tsx
DELETED
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
import React from 'react'
|
|
2
|
-
|
|
3
|
-
import type { LinkDef } from '@hanzo/ui/types'
|
|
4
|
-
import { NavItems } from '@hanzo/ui/primitives'
|
|
5
|
-
import { cn } from '@hanzo/ui/util'
|
|
6
|
-
|
|
7
|
-
import Copyright from './copyright'
|
|
8
|
-
import type { SiteDef } from '../site-def'
|
|
9
|
-
import { legal } from '../site-def/footer/legal'
|
|
10
|
-
import Logo from './logo'
|
|
11
|
-
|
|
12
|
-
const Footer: React.FC<{
|
|
13
|
-
siteDef: SiteDef,
|
|
14
|
-
className?: string,
|
|
15
|
-
noHorizPadding?: boolean
|
|
16
|
-
}> = ({
|
|
17
|
-
siteDef,
|
|
18
|
-
className='',
|
|
19
|
-
noHorizPadding=false
|
|
20
|
-
}) => {
|
|
21
|
-
|
|
22
|
-
const { footer, aboveCopyright } = siteDef
|
|
23
|
-
const smGridCols = Math.floor(footer.length/2)
|
|
24
|
-
const smGridColsClx = `sm:grid-cols-${smGridCols} `
|
|
25
|
-
const _aboveCopyright = (typeof aboveCopyright === 'undefined') ? legal : aboveCopyright
|
|
26
|
-
|
|
27
|
-
return (
|
|
28
|
-
<footer className={cn('grow flex flex-col justify-between gap-6 pb-[2vh]', className)}>
|
|
29
|
-
<div className={
|
|
30
|
-
(noHorizPadding ? '' : 'px-5 md:px-8 ') +
|
|
31
|
-
'grid grid-cols-2 gap-4 gap-y-6 md:gap-x-6 lg:gap-8 ' + smGridColsClx +
|
|
32
|
-
'md:w-full sm:justify-items-center md:mx-0 lg:w-full ' +
|
|
33
|
-
'md:flex md:flex-row md:justify-between px-[24px]'
|
|
34
|
-
}>
|
|
35
|
-
<div className='hidden lg:flex flex-col' key={0}>
|
|
36
|
-
<Logo size='md' variant='text-only' />
|
|
37
|
-
</div>
|
|
38
|
-
{footer.map((defs: LinkDef[], index: number) => {
|
|
39
|
-
|
|
40
|
-
const xsColSpanClx = ((index === footer.length - 1) && (footer.length % 2 === 1)) ?
|
|
41
|
-
'xs:col-span-2 xs:mx-auto md:col-span-1 md:mx-0 ' : ''
|
|
42
|
-
|
|
43
|
-
return (
|
|
44
|
-
<NavItems
|
|
45
|
-
items={defs}
|
|
46
|
-
currentAs={siteDef.currentAs}
|
|
47
|
-
as='nav'
|
|
48
|
-
className={cn('sm:min-w-[150px] md:min-w-0 flex flex-col justify-start items-start ' +
|
|
49
|
-
'gap-[11px] sm:gap-[12px] md:gap-[15px] ',
|
|
50
|
-
xsColSpanClx
|
|
51
|
-
)}
|
|
52
|
-
key={index + 1}
|
|
53
|
-
itemClx={(def: LinkDef) => ((def.variant === 'linkFG') ?
|
|
54
|
-
'font-nav text-[15px]/[1.3] font-medium tracking-normal text-muted-1 sm:hover:text-foreground transition-color duration-500'
|
|
55
|
-
:
|
|
56
|
-
'text-[15px]/[1.1] font-normal tracking-[0.2px] text-muted-1 sm:hover:text-foreground transition-color duration-500'
|
|
57
|
-
)}
|
|
58
|
-
/>
|
|
59
|
-
)
|
|
60
|
-
})}
|
|
61
|
-
</div>
|
|
62
|
-
<div className='md:mt-[2vh]'>
|
|
63
|
-
{_aboveCopyright.length > 0 && (
|
|
64
|
-
<NavItems
|
|
65
|
-
items={_aboveCopyright}
|
|
66
|
-
as='div'
|
|
67
|
-
className={'flex flex-row justify-center gap-4 mb-2'}
|
|
68
|
-
itemClx={'text-sm text-center text-muted-2 underline hover:text-foreground'}
|
|
69
|
-
/>
|
|
70
|
-
)}
|
|
71
|
-
<Copyright className='text-sm text-center text-muted-3'/>
|
|
72
|
-
</div>
|
|
73
|
-
</footer>
|
|
74
|
-
)
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
export default Footer
|
|
78
|
-
// flex flex-col justify-between gap-6
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
import React from 'react'
|
|
2
|
-
|
|
3
|
-
import { cn } from '@hanzo/ui/util'
|
|
4
|
-
import { AuthWidget } from '@hanzo/auth/components'
|
|
5
|
-
|
|
6
|
-
import { Logo } from '..'
|
|
7
|
-
|
|
8
|
-
import DesktopBagPopup from '../commerce/desktop-bag-popup'
|
|
9
|
-
import BagButton from '../commerce/bag-button'
|
|
10
|
-
import DesktopNav from '../commerce/desktop-nav-menu'
|
|
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
|
-
links,
|
|
21
|
-
className = ''
|
|
22
|
-
}) => {
|
|
23
|
-
const [isMenuOpened, setIsMenuOpen] = React.useState(false);
|
|
24
|
-
const opendMenuClass = isMenuOpened ? " h-full" : ""
|
|
25
|
-
|
|
26
|
-
// TODO move 13px into a size class and configure twMerge to recognize say, 'text-size-nav'
|
|
27
|
-
// (vs be beat out by 'text-color-nav')
|
|
28
|
-
return (
|
|
29
|
-
<header className={cn('bg-[rgba(0, 0, 0, 0.5)] !backdrop-blur-3xl fixed z-header top-0 left-0 right-0', className, opendMenuClass)} >
|
|
30
|
-
{/* md or larger */}
|
|
31
|
-
<div className={
|
|
32
|
-
'flex flex-row h-[80px] items-center justify-between ' +
|
|
33
|
-
'mx-[24px] w-full max-w-screen'
|
|
34
|
-
}>
|
|
35
|
-
<Logo size='md' href='/' outerClx='hidden lg:flex' key='two' variant='text-only' />
|
|
36
|
-
<Logo size='sm' href='/' outerClx='hidden md:flex lg:hidden' key='one' variant='text-only' />
|
|
37
|
-
{/* md or larger */}
|
|
38
|
-
<div className='flex w-full gap-4 items-center justify-center'>
|
|
39
|
-
<DesktopNav links={links} isMenuOpened={isMenuOpened} setIsMenuOpen={setIsMenuOpen} />
|
|
40
|
-
</div>
|
|
41
|
-
<div className='flex items-center'>
|
|
42
|
-
<DesktopBagPopup popupClx='w-[340px]' trigger={<BagButton className='text-primary -mr-[3px] lg:min-w-0' />} />
|
|
43
|
-
<AuthWidget />
|
|
44
|
-
</div>
|
|
45
|
-
</div>
|
|
46
|
-
</header>
|
|
47
|
-
)
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
export default DesktopHeader
|
|
51
|
-
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
'use client'
|
|
2
|
-
import React from 'react'
|
|
3
|
-
|
|
4
|
-
import type { SiteDef } from '../../site-def'
|
|
5
|
-
|
|
6
|
-
import DesktopHeader from './desktop'
|
|
7
|
-
import MobileHeader from './mobile'
|
|
8
|
-
import { cn } from '@hanzo/ui/util'
|
|
9
|
-
import { ChatWidget } from '../../components'
|
|
10
|
-
|
|
11
|
-
const Header: React.FC<{
|
|
12
|
-
siteDef: SiteDef
|
|
13
|
-
className?: string
|
|
14
|
-
}> = ({
|
|
15
|
-
siteDef,
|
|
16
|
-
className = ''
|
|
17
|
-
}) => {
|
|
18
|
-
|
|
19
|
-
// TODO
|
|
20
|
-
const [open, setOpen] = React.useState<boolean>(false);
|
|
21
|
-
|
|
22
|
-
const { nav: { common, featured }, currentAs } = siteDef
|
|
23
|
-
const links = (featured) ? [...common, ...featured] : common
|
|
24
|
-
const isDesktopView = (): boolean => {
|
|
25
|
-
if (typeof window === 'undefined') return false
|
|
26
|
-
return window.innerWidth > 768
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
return (<>
|
|
30
|
-
<DesktopHeader
|
|
31
|
-
className={cn(className, 'hidden md:flex')}
|
|
32
|
-
links={links}
|
|
33
|
-
currentAs={currentAs}
|
|
34
|
-
/>
|
|
35
|
-
<MobileHeader
|
|
36
|
-
className={cn(className, 'md:hidden')}
|
|
37
|
-
links={links}
|
|
38
|
-
currentAs={currentAs}
|
|
39
|
-
setChatbotOpen={setOpen}
|
|
40
|
-
/>
|
|
41
|
-
<ChatWidget
|
|
42
|
-
title='LUX'
|
|
43
|
-
subtitle='AI'
|
|
44
|
-
chatbotUrl='https://lux.chat/iframe'
|
|
45
|
-
suggestedQuestions={siteDef.chatbot?.suggestedQuestions ?? []}
|
|
46
|
-
/>
|
|
47
|
-
</>)
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
export default Header
|
|
@@ -1,163 +0,0 @@
|
|
|
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
|
-
import sendGAEvent from '../../next/analytics/google-analytics'
|
|
11
|
-
import * as Icons from '../icons'
|
|
12
|
-
|
|
13
|
-
import { Logo } from '..'
|
|
14
|
-
|
|
15
|
-
import MenuToggleButton from '../commerce/mobile-menu-toggle-button'
|
|
16
|
-
import BagButton from '../commerce/bag-button'
|
|
17
|
-
import MobileBagDrawer from '../commerce/mobile-bag-drawer'
|
|
18
|
-
import NavMenu from '../commerce/mobile-nav-menu'
|
|
19
|
-
|
|
20
|
-
const bagClx = 'mt-4 mb-8 border-none py-0 px-4 w-full ' +
|
|
21
|
-
'sm:min-w-[350px] sm:max-w-[500px] sm:mx-auto min-h-[60vh] max-h-[70vh] ' +
|
|
22
|
-
'sm:animate-in sm:zoom-in-90 '
|
|
23
|
-
|
|
24
|
-
const MobileHeader: React.FC<{
|
|
25
|
-
currentAs: string | undefined
|
|
26
|
-
links: LinkDef[]
|
|
27
|
-
className?: string,
|
|
28
|
-
setChatbotOpen: (open: boolean) => void,
|
|
29
|
-
}> = ({
|
|
30
|
-
currentAs,
|
|
31
|
-
links,
|
|
32
|
-
className = '',
|
|
33
|
-
setChatbotOpen,
|
|
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 ${menuOpen() ? 'hidden' : 'block'}`,
|
|
90
|
-
className
|
|
91
|
-
)}>
|
|
92
|
-
{/* smaller than md: mobile style drawer menu; h-11 is 44px, the standard mobile header height */}
|
|
93
|
-
<div className='w-full h-full flex flex-row justify-between items-center font-bold pr-5'>
|
|
94
|
-
<Logo href='/' size='md' outerClx={'p-6 h-full'} variant='text-only' />
|
|
95
|
-
{/* Not that key to the cross-fade effect
|
|
96
|
-
is that this is **on top of** the logo. */}
|
|
97
|
-
{menuOpen() && (
|
|
98
|
-
<div className={'absolute left-0 top-0 bottom-0 right-0 pl-8 ' +
|
|
99
|
-
'flex flex-row ' +
|
|
100
|
-
'bg-background animate-mobile-menu-open'
|
|
101
|
-
}>
|
|
102
|
-
<Icons.Avatar className='self-center ' />
|
|
103
|
-
</div>
|
|
104
|
-
)}
|
|
105
|
-
<div className='flex gap-0 flex-row'>
|
|
106
|
-
<BagButton className='text-primary -mr-[3px]' onClick={openBag} />
|
|
107
|
-
<MenuToggleButton className='text-foreground' open={menuOpen()} setOpen={setMenuOpen} />
|
|
108
|
-
</div>
|
|
109
|
-
|
|
110
|
-
</div>
|
|
111
|
-
</header>
|
|
112
|
-
<MobileBagDrawer
|
|
113
|
-
className=''
|
|
114
|
-
open={bagDrawerOpen}
|
|
115
|
-
setOpen={setBagDrawerOpen}
|
|
116
|
-
handleCheckout={handleCheckout}
|
|
117
|
-
/>
|
|
118
|
-
{menuOpen() && (
|
|
119
|
-
<div className={
|
|
120
|
-
'fixed top-0 left-0 w-full h-full ' +
|
|
121
|
-
// z must below header itself
|
|
122
|
-
'flex flex-column bg-background z-below-header animate-mobile-menu-open'
|
|
123
|
-
}>
|
|
124
|
-
{menuState === 'login' ? (
|
|
125
|
-
<LoginPanel noHeading onLoginChanged={onLoginChanged} className='sm:animate-in sm:zoom-in-90' />
|
|
126
|
-
) : (
|
|
127
|
-
menuState === 'bag' ? (
|
|
128
|
-
|
|
129
|
-
<CartPanel
|
|
130
|
-
handleCheckout={() => { router.push('/checkout') }}
|
|
131
|
-
className={bagClx}
|
|
132
|
-
listClx='rounded-sm'
|
|
133
|
-
scrollAfter={6}
|
|
134
|
-
scrollHeightClx='h-[80vh]'
|
|
135
|
-
itemClx='mt-2'
|
|
136
|
-
totalClx='sticky px-1 pr-2 border rounded-sm -bottom-[1px] bg-level-1'
|
|
137
|
-
buttonClx='max-w-[220px] flex-none'
|
|
138
|
-
>
|
|
139
|
-
<div className='flex flex-row items-center flex-none justify-center '>
|
|
140
|
-
<Icons.bag className='mr-2 relative w-4 h-5 fill-foreground ' />
|
|
141
|
-
<p className='font-heading text-foreground text-default'>Your Bag</p>
|
|
142
|
-
</div>
|
|
143
|
-
<div className='h-[1px] w-pr-80 bg-muted-3 mx-auto mt-1.5 flex-none' />
|
|
144
|
-
</CartPanel>
|
|
145
|
-
|
|
146
|
-
) : ( /* menuState === 'nav' */
|
|
147
|
-
<NavMenu
|
|
148
|
-
currentAs={currentAs}
|
|
149
|
-
links={links}
|
|
150
|
-
className='sm:animate-in sm:zoom-in-90 w-full'
|
|
151
|
-
commonItemClx='px-0 text-xl h-16 justify-start '
|
|
152
|
-
setMenuState={setMenuState}
|
|
153
|
-
setChatbotOpen={setChatbotOpen}
|
|
154
|
-
setMenuOpen={setMenuOpen}
|
|
155
|
-
/>
|
|
156
|
-
)
|
|
157
|
-
)}
|
|
158
|
-
</div>
|
|
159
|
-
) /* menuOpen */}
|
|
160
|
-
</>)
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
export default MobileHeader
|