@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.
Files changed (196) hide show
  1. package/package.json +9 -53
  2. package/tsconfig.json +3 -8
  3. package/types/asset.ts +28 -0
  4. package/types/contract.ts +13 -0
  5. package/types/deposit-address.ts +9 -0
  6. package/types/exchange.ts +25 -0
  7. package/types/index.ts +21 -4
  8. package/types/network-type.ts +16 -0
  9. package/types/network.ts +58 -0
  10. package/types/swap-status.ts +58 -0
  11. package/types/transaction-type.ts +5 -0
  12. package/types/utila.ts +36 -0
  13. package/commerce/ui/conf.ts +0 -13
  14. package/commerce/ui/context.tsx +0 -123
  15. package/commerce/ui/store.ts +0 -290
  16. package/components/access-code-input.tsx +0 -71
  17. package/components/auth/auth-listener.tsx +0 -29
  18. package/components/auth/auth-token/clear-auth-token.tsx +0 -12
  19. package/components/auth/auth-token/set-auth-token.tsx +0 -16
  20. package/components/auth/common-auth-domains.ts +0 -16
  21. package/components/auth/login-panel.tsx +0 -107
  22. package/components/back-button.tsx +0 -49
  23. package/components/chat-widget.tsx +0 -85
  24. package/components/commerce/_to_deprecate_checkout-widget/const.ts +0 -13
  25. package/components/commerce/_to_deprecate_checkout-widget/index.tsx_ +0 -188
  26. package/components/commerce/_to_deprecate_checkout-widget/obs-string-set.ts +0 -48
  27. package/components/commerce/_to_deprecate_checkout-widget/use-anim-clx-set.ts +0 -59
  28. package/components/commerce/bag-button.tsx +0 -98
  29. package/components/commerce/buy-button.tsx +0 -34
  30. package/components/commerce/checkout-button.tsx +0 -129
  31. package/components/commerce/checkout-panel/cart-accordian.tsx +0 -66
  32. package/components/commerce/checkout-panel/checkout-panel-props.ts +0 -10
  33. package/components/commerce/checkout-panel/desktop-bag-carousel.tsx +0 -36
  34. package/components/commerce/checkout-panel/desktop-cp.tsx +0 -83
  35. package/components/commerce/checkout-panel/index.tsx +0 -126
  36. package/components/commerce/checkout-panel/mobile-cp.tsx +0 -67
  37. package/components/commerce/checkout-panel/policy-links.tsx +0 -29
  38. package/components/commerce/checkout-panel/steps-indicator.tsx +0 -39
  39. package/components/commerce/checkout-panel/thank-you.tsx +0 -18
  40. package/components/commerce/desktop-bag-popup.tsx +0 -78
  41. package/components/commerce/desktop-nav-menu.tsx +0 -194
  42. package/components/commerce/drawer/index.tsx +0 -88
  43. package/components/commerce/drawer/micro.tsx +0 -145
  44. package/components/commerce/drawer/shell.tsx +0 -85
  45. package/components/commerce/mobile-bag-drawer.tsx +0 -51
  46. package/components/commerce/mobile-login-button.tsx +0 -108
  47. package/components/commerce/mobile-menu-toggle-button.tsx +0 -35
  48. package/components/commerce/mobile-nav-menu-ai.tsx +0 -51
  49. package/components/commerce/mobile-nav-menu-item.tsx +0 -50
  50. package/components/commerce/mobile-nav-menu.tsx +0 -102
  51. package/components/contact-dialog/contact-form.tsx +0 -113
  52. package/components/contact-dialog/disclaimer.tsx +0 -13
  53. package/components/contact-dialog/index.tsx +0 -64
  54. package/components/copyright.tsx +0 -21
  55. package/components/drawer-margin.tsx +0 -28
  56. package/components/footer.tsx +0 -78
  57. package/components/header/desktop.tsx +0 -51
  58. package/components/header/index.tsx +0 -50
  59. package/components/header/mobile.tsx +0 -163
  60. package/components/header/theme-toggle.tsx +0 -26
  61. package/components/icons/24k-gold-card.tsx +0 -43
  62. package/components/icons/ai-chat-act.tsx +0 -47
  63. package/components/icons/ai-chat.tsx +0 -29
  64. package/components/icons/anodized-titanium.tsx +0 -45
  65. package/components/icons/avatar.tsx +0 -11
  66. package/components/icons/bag-icon.tsx +0 -10
  67. package/components/icons/blog-act.tsx +0 -14
  68. package/components/icons/blog.tsx +0 -20
  69. package/components/icons/bridge-act.tsx +0 -18
  70. package/components/icons/bridge.tsx +0 -68
  71. package/components/icons/changelog-act.tsx +0 -15
  72. package/components/icons/changelog.tsx +0 -21
  73. package/components/icons/chrome.tsx +0 -45
  74. package/components/icons/coins-act.tsx +0 -29
  75. package/components/icons/coins.tsx +0 -20
  76. package/components/icons/compare-cards-act.tsx +0 -30
  77. package/components/icons/compare-cards.tsx +0 -21
  78. package/components/icons/credit-act.tsx +0 -29
  79. package/components/icons/credit.tsx +0 -20
  80. package/components/icons/customer-support-act.tsx +0 -27
  81. package/components/icons/customer-support.tsx +0 -21
  82. package/components/icons/customers-act.tsx +0 -65
  83. package/components/icons/customers.tsx +0 -33
  84. package/components/icons/developer-docs-act.tsx +0 -26
  85. package/components/icons/developer-docs.tsx +0 -20
  86. package/components/icons/exchange-act.tsx +0 -27
  87. package/components/icons/exchange.tsx +0 -21
  88. package/components/icons/explorer-act.tsx +0 -27
  89. package/components/icons/explorer.tsx +0 -22
  90. package/components/icons/faqs-act.tsx +0 -27
  91. package/components/icons/faqs.tsx +0 -21
  92. package/components/icons/github.tsx +0 -14
  93. package/components/icons/guides-act.tsx +0 -26
  94. package/components/icons/guides.tsx +0 -21
  95. package/components/icons/gun-metal.tsx +0 -44
  96. package/components/icons/index.tsx +0 -43
  97. package/components/icons/integrations-act.tsx +0 -41
  98. package/components/icons/integrations.tsx +0 -25
  99. package/components/icons/irradescent.tsx +0 -41
  100. package/components/icons/launch-subnet.tsx +0 -21
  101. package/components/icons/launchsubnet-act.tsx +0 -29
  102. package/components/icons/left-arrow.tsx +0 -11
  103. package/components/icons/lux-finance-act.tsx +0 -34
  104. package/components/icons/lux-finance.tsx +0 -23
  105. package/components/icons/lux-logo.tsx +0 -10
  106. package/components/icons/lux-pass-act.tsx +0 -41
  107. package/components/icons/lux-pass.tsx +0 -25
  108. package/components/icons/lux-quests-act.tsx +0 -15
  109. package/components/icons/lux-quests.tsx +0 -21
  110. package/components/icons/market-act.tsx +0 -39
  111. package/components/icons/market.tsx +0 -24
  112. package/components/icons/mirrored-titanium.tsx +0 -46
  113. package/components/icons/more-benefits-act.tsx +0 -29
  114. package/components/icons/more-benefits.tsx +0 -21
  115. package/components/icons/open-source-act.tsx +0 -41
  116. package/components/icons/open-source.tsx +0 -26
  117. package/components/icons/right-arrow.tsx +0 -10
  118. package/components/icons/safe-act.tsx +0 -77
  119. package/components/icons/safe.tsx +0 -37
  120. package/components/icons/search.tsx +0 -12
  121. package/components/icons/secure-delivery.tsx +0 -13
  122. package/components/icons/shop-act.tsx +0 -29
  123. package/components/icons/shop.tsx +0 -20
  124. package/components/icons/social-icon.tsx +0 -35
  125. package/components/icons/social-svg.css +0 -3
  126. package/components/icons/sterling-silver-card.tsx +0 -44
  127. package/components/icons/templates-act.tsx +0 -29
  128. package/components/icons/templates.tsx +0 -21
  129. package/components/icons/validators-act.tsx +0 -42
  130. package/components/icons/validators.tsx +0 -41
  131. package/components/icons/view-all-card-act.tsx +0 -28
  132. package/components/icons/view-all-card.tsx +0 -20
  133. package/components/icons/wallet-act.tsx +0 -29
  134. package/components/icons/wallet.tsx +0 -20
  135. package/components/icons/warpcast.tsx +0 -58
  136. package/components/icons/youtube-logo.tsx +0 -59
  137. package/components/index.ts +0 -25
  138. package/components/logo.tsx +0 -89
  139. package/components/main.tsx +0 -27
  140. package/components/mini-chart/index.tsx +0 -8
  141. package/components/mini-chart/mini-chart-props.ts +0 -44
  142. package/components/mini-chart/mini-chart.tsx +0 -85
  143. package/components/mini-chart/wrapper.tsx +0 -23
  144. package/components/not-found/index.tsx +0 -28
  145. package/components/not-found/not-found-content.mdx +0 -5
  146. package/components/scripts.tsx +0 -24
  147. package/components/tooltip.tsx +0 -31
  148. package/environment.d.ts +0 -6
  149. package/next/analytics/fpixel.ts +0 -16
  150. package/next/analytics/google-analytics.ts +0 -14
  151. package/next/analytics/index.ts +0 -3
  152. package/next/analytics/pixel-analytics.tsx +0 -55
  153. package/next/font/get-app-router-font-classes.ts +0 -12
  154. package/next/font/load-and-return-lux-next-fonts-on-import.ts +0 -68
  155. package/next/font/local/Druk-Wide-Bold.ttf +0 -0
  156. package/next/font/local/Druk-Wide-Medium.ttf +0 -0
  157. package/next/font/local/InterVariable-Italic.ttf +0 -0
  158. package/next/font/local/InterVariable-Italic.woff2 +0 -0
  159. package/next/font/local/InterVariable.ttf +0 -0
  160. package/next/font/local/InterVariable.woff2 +0 -0
  161. package/next/font/next-font-desc.ts +0 -28
  162. package/next/font/pages-router-font-vars.tsx +0 -18
  163. package/next/head-metadata/from-next/metadata-types.ts +0 -158
  164. package/next/head-metadata/from-next/opengraph-types.ts +0 -267
  165. package/next/head-metadata/from-next/twitter-types.ts +0 -92
  166. package/next/head-metadata/index.tsx +0 -208
  167. package/next/index.ts +0 -1
  168. package/next/middleware/determine-device-mw.ts +0 -16
  169. package/root-layout/WHY_THIS_IS_SEPARATE.txt +0 -2
  170. package/root-layout/index.tsx +0 -112
  171. package/server-actions/TO-DO.txt +0 -1
  172. package/server-actions/firebase-app.ts +0 -14
  173. package/server-actions/index.ts +0 -5
  174. package/server-actions/store-contact.ts +0 -51
  175. package/site-def/footer/community.tsx +0 -67
  176. package/site-def/footer/company.ts +0 -37
  177. package/site-def/footer/ecosystem.ts +0 -37
  178. package/site-def/footer/index.tsx +0 -26
  179. package/site-def/footer/legal.ts +0 -28
  180. package/site-def/footer/network.ts +0 -45
  181. package/site-def/footer/svg/warpcast-logo.svg +0 -12
  182. package/site-def/index.ts +0 -3
  183. package/site-def/main-nav.tsx +0 -458
  184. package/style/cart-animation.css +0 -29
  185. package/style/checkout-animation.css +0 -23
  186. package/style/drawer-handle-overrides.css +0 -160
  187. package/style/lux-colors.css +0 -85
  188. package/style/lux-global.css +0 -51
  189. package/tailwind/fontFamily.tailwind.lux.ts +0 -18
  190. package/tailwind/index.ts +0 -2
  191. package/tailwind/lux-tw-fonts.ts +0 -40
  192. package/tailwind/tailwind.config.lux-preset.ts +0 -10
  193. package/types/chatbot-config.ts +0 -7
  194. package/types/chatbot-suggested-question.ts +0 -7
  195. package/types/contact-info.ts +0 -11
  196. 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
@@ -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}`}&nbsp;<br className='sm:hidden'/>Lux Partners Limited.&nbsp;<br className='md:hidden'/>&nbsp;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
@@ -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