@luxfi/core 5.3.7 → 10.0.0

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