@luxfi/core 5.1.4 → 5.1.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (125) hide show
  1. package/commerce/{AUTO-GEN-bullion-by-family.json → data/AUTO-GEN-bullion-by-family.json} +33 -33
  2. package/commerce/{EDIT-ME-bullion-market-prices.ts → data/EDIT-ME-bullion-market-prices.ts} +11 -11
  3. package/commerce/{assign-prices.ts → data/assign-prices.ts} +49 -49
  4. package/commerce/{assign-videos-by-family-group.ts → data/assign-videos-by-family-group.ts} +14 -14
  5. package/commerce/{bullion-price-1oz.ts → data/bullion-price-1oz.ts} +5 -5
  6. package/commerce/{index.ts → data/index.ts} +18 -18
  7. package/commerce/ui/conf.ts +13 -0
  8. package/commerce/ui/context.tsx +102 -0
  9. package/commerce/ui/store.ts +277 -0
  10. package/components/access-code-input.tsx +71 -71
  11. package/components/auth/auth-listener.tsx +29 -29
  12. package/components/auth/auth-token/clear-auth-token.tsx +12 -12
  13. package/components/auth/auth-token/set-auth-token.tsx +16 -16
  14. package/components/auth/common-auth-domains.ts +16 -16
  15. package/components/auth/login-panel.tsx +107 -104
  16. package/components/chat-widget.tsx +85 -80
  17. package/components/commerce/add-widget.tsx +20 -0
  18. package/components/commerce/bag-button.tsx +98 -98
  19. package/components/commerce/buy-button.tsx +34 -0
  20. package/components/commerce/checkout-button.tsx +129 -116
  21. package/components/commerce/checkout-panel/close-button.tsx +26 -26
  22. package/components/commerce/checkout-panel/dt-bag-carousel.tsx +36 -36
  23. package/components/commerce/checkout-panel/dt-checkout-panel.tsx +66 -66
  24. package/components/commerce/checkout-panel/index.tsx +129 -124
  25. package/components/commerce/checkout-panel/links-row.tsx +21 -21
  26. package/components/commerce/checkout-panel/mb-checkout-panel.tsx +54 -54
  27. package/components/commerce/checkout-panel/steps-indicator.tsx +39 -39
  28. package/components/commerce/checkout-panel/thank-you.tsx +18 -18
  29. package/components/commerce/checkout-widget/const.ts +13 -13
  30. package/components/commerce/checkout-widget/index.tsx +192 -86
  31. package/components/commerce/checkout-widget/obs-string-set.ts +48 -48
  32. package/components/commerce/checkout-widget/use-anim-clx-set.ts +58 -56
  33. package/components/commerce/desktop-bag-popup.tsx +78 -78
  34. package/components/commerce/drawer/index.tsx +117 -0
  35. package/components/commerce/drawer/micro.tsx +136 -0
  36. package/components/commerce/drawer/shell.tsx +79 -0
  37. package/components/commerce/mobile-bag-drawer.tsx +51 -51
  38. package/components/commerce/mobile-login-button.tsx +100 -100
  39. package/components/commerce/mobile-menu-toggle-button.tsx +35 -35
  40. package/components/commerce/mobile-nav-menu-ai.tsx +97 -97
  41. package/components/commerce/mobile-nav-menu-item.tsx +45 -45
  42. package/components/commerce/mobile-nav-menu.tsx +80 -79
  43. package/components/contact-dialog/contact-form.tsx +113 -112
  44. package/components/contact-dialog/disclaimer.tsx +13 -13
  45. package/components/contact-dialog/index.tsx +64 -64
  46. package/components/copyright.tsx +21 -21
  47. package/components/drawer-margin.tsx +25 -0
  48. package/components/footer.tsx +77 -77
  49. package/components/header/desktop.tsx +54 -54
  50. package/components/header/index.tsx +40 -47
  51. package/components/header/mobile.tsx +165 -165
  52. package/components/header/theme-toggle.tsx +26 -26
  53. package/components/icons/avatar.tsx +11 -11
  54. package/components/icons/bag-icon.tsx +10 -10
  55. package/components/icons/github.tsx +14 -14
  56. package/components/icons/index.tsx +43 -43
  57. package/components/icons/left-arrow.tsx +11 -11
  58. package/components/icons/lux-logo.tsx +10 -10
  59. package/components/icons/right-arrow.tsx +10 -10
  60. package/components/icons/search.tsx +12 -12
  61. package/components/icons/secure-delivery.tsx +13 -13
  62. package/components/icons/social-icon.tsx +35 -35
  63. package/components/icons/social-svg.css +3 -3
  64. package/components/icons/youtube-logo.tsx +59 -59
  65. package/components/index.ts +25 -27
  66. package/components/logo.tsx +81 -81
  67. package/components/main.tsx +27 -0
  68. package/components/mini-chart/index.tsx +7 -7
  69. package/components/mini-chart/mini-chart-props.ts +43 -43
  70. package/components/mini-chart/mini-chart.tsx +85 -85
  71. package/components/mini-chart/wrapper.tsx +23 -23
  72. package/components/not-found/index.tsx +28 -27
  73. package/components/not-found/not-found-content.mdx +5 -5
  74. package/components/scripts.tsx +24 -24
  75. package/conf/index.ts +52 -50
  76. package/{commerce/lux-service-options.ts → conf/lux-commerce-options.ts} +6 -6
  77. package/environment.d.ts +5 -5
  78. package/next/analytics/fpixel.ts +15 -15
  79. package/next/analytics/google-analytics.ts +13 -13
  80. package/next/analytics/index.ts +3 -3
  81. package/next/analytics/pixel-analytics.tsx +54 -54
  82. package/next/font/get-app-router-font-classes.ts +12 -12
  83. package/next/font/load-and-return-lux-next-fonts-on-import.ts +68 -68
  84. package/next/font/next-font-desc.ts +27 -27
  85. package/next/font/pages-router-font-vars.tsx +18 -18
  86. package/next/head-metadata/from-next/metadata-types.ts +158 -158
  87. package/next/head-metadata/from-next/opengraph-types.ts +267 -267
  88. package/next/head-metadata/from-next/twitter-types.ts +92 -92
  89. package/next/head-metadata/index.tsx +208 -208
  90. package/next/middleware/determine-device-mw.ts +16 -16
  91. package/package.json +80 -73
  92. package/root-layout/WHY_THIS_IS_SEPARATE.txt +1 -1
  93. package/root-layout/index.tsx +118 -121
  94. package/server-actions/firebase-app.ts +14 -14
  95. package/server-actions/index.ts +5 -5
  96. package/server-actions/store-contact.ts +51 -51
  97. package/site-def/footer/community.tsx +67 -67
  98. package/site-def/footer/company.ts +37 -37
  99. package/site-def/footer/ecosystem.ts +37 -37
  100. package/site-def/footer/index.tsx +26 -26
  101. package/site-def/footer/legal.ts +28 -28
  102. package/site-def/footer/network.ts +45 -45
  103. package/site-def/footer/svg/warpcast-logo.svg +11 -11
  104. package/site-def/index.ts +2 -2
  105. package/site-def/main-nav.tsx +292 -292
  106. package/style/cart-animation.css +29 -29
  107. package/style/checkout-animation.css +23 -23
  108. package/style/drawer-handle-overrides.css +160 -0
  109. package/style/lux-colors.css +85 -85
  110. package/style/lux-global.css +30 -30
  111. package/tailwind/fontFamily.tailwind.lux.ts +18 -18
  112. package/tailwind/index.ts +2 -2
  113. package/tailwind/lux-tw-fonts.ts +39 -39
  114. package/tailwind/tailwind.config.lux-preset.ts +10 -10
  115. package/tsconfig.json +15 -10
  116. package/types/chatbot-config.ts +6 -6
  117. package/types/chatbot-suggested-question.ts +7 -7
  118. package/types/commerce-config.ts +10 -10
  119. package/types/contact-info.ts +10 -10
  120. package/types/index.ts +5 -5
  121. package/types/site-def.ts +45 -45
  122. package/components/commerce/buy-drawer/drawer.tsx +0 -44
  123. package/components/commerce/buy-drawer/index.tsx +0 -46
  124. package/components/commerce/checkout-widget/use-lagging-item-ref.ts +0 -30
  125. package/components/header/guts.tsx +0 -27
package/package.json CHANGED
@@ -1,73 +1,80 @@
1
- {
2
- "name": "@luxfi/core",
3
- "version": "5.1.4",
4
- "description": "Library that contains shared UI primitives, support for a common design system, and other boilerplate support.",
5
- "publishConfig": {
6
- "registry": "https://registry.npmjs.org/",
7
- "access": "public",
8
- "scope": "@luxfi"
9
- },
10
- "repository": {
11
- "type": "git",
12
- "url": "git+https://github.com/luxfi/web.git",
13
- "directory": "packages/core"
14
- },
15
- "keywords": [
16
- "components",
17
- "radix-ui",
18
- "hanzo",
19
- "luxdefi"
20
- ],
21
- "scripts": {
22
- "lat": "npm show @luxfi/core version",
23
- "pub": "npm publish",
24
- "build": "tsc",
25
- "tc": "tsc",
26
- "clean": "rm -rf node_modules"
27
- },
28
- "exports": {
29
- ".": "./components/index.ts",
30
- "./commerce": "./commerce/index.ts",
31
- "./root-layout": "./root-layout/index.tsx",
32
- "./server-actions": "./server-actions/index.ts",
33
- "./next": "./next/index.ts",
34
- "./style/": "./style/",
35
- "./site-def": "./site-def/index.ts",
36
- "./tailwind": "./tailwind/index.ts",
37
- "./conf": "./conf/index.ts"
38
- },
39
- "dependencies": {
40
- "@hanzo/auth": "2.4.6",
41
- "@hanzo/commerce": "7.0.2",
42
- "@hanzo/ui": "3.7.0",
43
- "@next/third-parties": "^14.1.0",
44
- "@types/node": "^20.12.12",
45
- "cookies-next": "^4.1.1",
46
- "date-fns": "^3.6.0",
47
- "embla-carousel-autoplay": "^8.0.1",
48
- "react-device-detect": "^2.2.3",
49
- "react-social-icons": "^6.4.0"
50
- },
51
- "peerDependencies": {
52
- "@hookform/resolvers": "^3.3.2",
53
- "lucide-react": "^0.344.0",
54
- "next": "14.1.3",
55
- "next-themes": "^0.2.1",
56
- "react": "^18.2.0",
57
- "react-dom": "^18.2.0",
58
- "react-hook-form": "^7.44.2",
59
- "validator": "^13.11.0",
60
- "zod": "3.21.4"
61
- },
62
- "devDependencies": {
63
- "@mdx-js/loader": "^3.0.0",
64
- "@mdx-js/react": "^3.0.0",
65
- "@types/facebook-pixel": "^0.0.30",
66
- "@types/gtag.js": "^0.0.19",
67
- "@types/mdx": "^2.0.9",
68
- "@types/react": "^18.2.64",
69
- "@types/react-dom": "^18.2.18",
70
- "tailwindcss": "^3.4.2",
71
- "typescript": "5.3.3"
72
- }
73
- }
1
+ {
2
+ "name": "@luxfi/core",
3
+ "version": "5.1.6",
4
+ "description": "Library that contains shared UI primitives, support for a common design system, and other boilerplate support.",
5
+ "publishConfig": {
6
+ "registry": "https://registry.npmjs.org/",
7
+ "access": "public",
8
+ "scope": "@luxfi"
9
+ },
10
+ "repository": {
11
+ "type": "git",
12
+ "url": "git+https://github.com/luxfi/web.git",
13
+ "directory": "packages/core"
14
+ },
15
+ "keywords": [
16
+ "components",
17
+ "radix-ui",
18
+ "hanzo",
19
+ "luxdefi"
20
+ ],
21
+ "scripts": {
22
+ "lat": "npm show @luxfi/core version",
23
+ "pub": "npm publish",
24
+ "build": "tsc",
25
+ "tc": "tsc",
26
+ "clean": "rm -rf node_modules"
27
+ },
28
+ "exports": {
29
+ ".": "./components/index.ts",
30
+ "./commerce-data": "./commerce/data/index.ts",
31
+ "./commerce": "./commerce/ui/context.tsx",
32
+ "./root-layout": "./root-layout/index.tsx",
33
+ "./server-actions": "./server-actions/index.ts",
34
+ "./next": "./next/index.ts",
35
+ "./style/": "./style/",
36
+ "./site-def": "./site-def/index.ts",
37
+ "./tailwind": "./tailwind/index.ts",
38
+ "./conf": "./conf/index.ts"
39
+ },
40
+ "dependencies": {
41
+ "@next/third-parties": "^14.1.0",
42
+ "@types/node": "^20.12.12",
43
+ "cookies-next": "^4.1.1",
44
+ "date-fns": "^3.6.0",
45
+ "embla-carousel-autoplay": "^8.1.1",
46
+ "firebase": "10.12.0",
47
+ "react-device-detect": "^2.2.3",
48
+ "react-social-icons": "^6.4.0",
49
+ "request": "^2.88.2",
50
+ "usehooks-ts": "^3.1.0"
51
+ },
52
+ "peerDependencies": {
53
+ "@hanzo/auth": "*",
54
+ "@hanzo/commerce": "*",
55
+ "@hanzo/ui": "*",
56
+ "@hookform/resolvers": "^3.3.2",
57
+ "lucide-react": "^0.344.0",
58
+ "mobx": "^6.12.3",
59
+ "mobx-react-lite": "^4.0.7",
60
+ "next": "14.2.3",
61
+ "next-themes": "^0.2.1",
62
+ "react": "*",
63
+ "react-dom": "*",
64
+ "react-hook-form": "^7.51.4",
65
+ "validator": "^13.11.0",
66
+ "zod": "3.23.8"
67
+ },
68
+ "devDependencies": {
69
+ "@mdx-js/loader": "^3.0.0",
70
+ "@mdx-js/react": "^3.0.0",
71
+ "@types/facebook-pixel": "^0.0.30",
72
+ "@types/gtag.js": "^0.0.19",
73
+ "@types/mdx": "^2.0.9",
74
+ "@types/node": "^20.11.24",
75
+ "@types/react": "*",
76
+ "@types/react-dom": "*",
77
+ "tailwindcss": "^3.4.3",
78
+ "typescript": "5.4.5"
79
+ }
80
+ }
@@ -1,2 +1,2 @@
1
- Unwise to have this in a barrel / index file that is mostly imported by a Client Component.
1
+ Unwise to have this in a barrel / index file that is mostly imported by a Client Component.
2
2
  Creates Next / SSR issues
@@ -1,121 +1,118 @@
1
- import React, { type PropsWithChildren } from 'react'
2
- import type { Viewport } from 'next'
3
-
4
- import { Toaster } from '@hanzo/ui/primitives'
5
- import { AuthServiceProvider } from '@hanzo/auth/service'
6
- import { getUserServerSide } from '@hanzo/auth/server'
7
- import type { AuthServiceConf } from '@hanzo/auth/types'
8
- import { CommerceProvider } from '@hanzo/commerce'
9
-
10
- import getAppRouterBodyFontClasses from '../next/font/get-app-router-font-classes'
11
- import { FacebookPixelHead } from '../next/analytics/pixel-analytics'
12
-
13
- import { AuthListener, ChatWidget, Header, Scripts } from '../components'
14
- import Guts from '../components/header/guts'
15
- import BuyDrawer from '../components/commerce/buy-drawer'
16
- import CheckoutWidget from '../components/commerce/checkout-widget'
17
-
18
- import { selectionUISpecifiers } from '../conf'
19
- import type SiteDef from '../types/site-def'
20
-
21
- import '../style/lux-global.css'
22
- import '../style/cart-animation.css'
23
- import '../style/checkout-animation.css'
24
-
25
-
26
- // Next 14: https://nextjs.org/docs/app/building-your-application/upgrading/codemods#use-viewport-export
27
- const viewport = {
28
- themeColor: [
29
- { media: '(prefers-color-scheme: light)', color: 'white' },
30
- { media: '(prefers-color-scheme: dark)', color: 'black' },
31
- ],
32
- } satisfies Viewport
33
-
34
- /*
35
- These '.variable' fields are actually autogenerate css classnames that *define* the actual
36
- css variables ('--<ugly-name>') that one asks for in the tailwind classes.
37
- They are what make them available in the global scope. So this MUST
38
- be done like this for the tailwind font classes to work.
39
-
40
- (...not to be confused with the css var itself. This field should be named something else!)
41
- */
42
-
43
- /*
44
- re body: overflow-y-hidden overflow-x-hidden, h-full
45
- We cannot have these on body tag for scroll-snap to work on iOS!
46
- */
47
- const bodyClasses =
48
- 'bg-background text-foreground flex flex-col min-h-full' +
49
- getAppRouterBodyFontClasses()
50
-
51
- const RootLayout: React.FC<PropsWithChildren & {
52
- siteDef: SiteDef
53
- showHeader?: boolean
54
- chatbot?: boolean
55
- }> = async ({
56
- showHeader = false,
57
- chatbot = false,
58
- siteDef,
59
- children,
60
- }) => {
61
-
62
- const currentUser = await getUserServerSide()
63
-
64
- return (
65
- <html lang='en' suppressHydrationWarning className='hanzo-ui-dark-theme' style={{backgroundColor: '#000'}}>
66
- <head >
67
- {/* https://stackoverflow.com/a/75716588/11645689 */ }
68
- <base target='_blank' />
69
- <FacebookPixelHead/>
70
- </head>
71
-
72
- <body className={bodyClasses} style={{
73
- // Not sure why these got added (by my commit)
74
-
75
- // As also noted above, 'overflow: hidden' on the <body> tag breaks scroll snap!
76
- //paddingRight: '0 !important',
77
- //maxWidth: '100vw',
78
- display: 'none', // see scripts.tsx
79
-
80
- }}>
81
- <Scripts/>
82
- <AuthServiceProvider user={currentUser} conf={{} as AuthServiceConf}>
83
- {siteDef?.commerce ? (
84
- <CommerceProvider
85
- rootNode={siteDef.commerce!.rootNode}
86
- families={siteDef.commerce!.families}
87
- options={siteDef.commerce!.options}
88
- uiSpecs={selectionUISpecifiers}
89
- >
90
- <Guts
91
- siteDef={siteDef}
92
- showHeader={showHeader}
93
- chatbot={chatbot}
94
- >
95
- {children}
96
- </Guts>
97
- <BuyDrawer />
98
- <CheckoutWidget />
99
- </CommerceProvider>
100
- ) : (
101
- <Guts
102
- siteDef={siteDef}
103
- showHeader={showHeader}
104
- chatbot={chatbot}
105
- >
106
- {children}
107
- </Guts>
108
-
109
- )}
110
- <AuthListener/>
111
- </AuthServiceProvider>
112
- <Toaster position='top-center' duration={3000}/>
113
- </body>
114
- </html>
115
- )
116
- }
117
-
118
- export {
119
- RootLayout,
120
- viewport
121
- }
1
+ import React, { type PropsWithChildren } from 'react'
2
+ import type { Viewport } from 'next'
3
+
4
+ import { Toaster } from '@hanzo/ui/primitives'
5
+ import { AuthServiceProvider } from '@hanzo/auth/service'
6
+ import { getUserServerSide } from '@hanzo/auth/server'
7
+ import type { AuthServiceConf } from '@hanzo/auth/types'
8
+ import { CommerceProvider } from '@hanzo/commerce'
9
+
10
+ import getAppRouterBodyFontClasses from '../next/font/get-app-router-font-classes'
11
+ import { FacebookPixelHead } from '../next/analytics/pixel-analytics'
12
+
13
+ import { CommerceUIProvider } from '../commerce/ui/context'
14
+ import { AuthListener, ChatWidget, Header, Scripts } from '../components'
15
+
16
+ import CommerceDrawer from '../components/commerce/drawer'
17
+
18
+ import { selectionUISpecifiers } from '../conf'
19
+ import type SiteDef from '../types/site-def'
20
+
21
+ import '../style/lux-global.css'
22
+ import '../style/cart-animation.css'
23
+ import '../style/checkout-animation.css'
24
+
25
+
26
+ // Next 14: https://nextjs.org/docs/app/building-your-application/upgrading/codemods#use-viewport-export
27
+ const viewport = {
28
+ themeColor: [
29
+ { media: '(prefers-color-scheme: light)', color: 'white' },
30
+ { media: '(prefers-color-scheme: dark)', color: 'black' },
31
+ ],
32
+ } satisfies Viewport
33
+
34
+ /*
35
+ These '.variable' fields are actually autogenerate css classnames that *define* the actual
36
+ css variables ('--<ugly-name>') that one asks for in the tailwind classes.
37
+ They are what make them available in the global scope. So this MUST
38
+ be done like this for the tailwind font classes to work.
39
+
40
+ (...not to be confused with the css var itself. This field should be named something else!)
41
+ */
42
+
43
+ /*
44
+ re body: overflow-y-hidden overflow-x-hidden, h-full
45
+ We cannot have these on body tag for scroll-snap to work on iOS!
46
+ */
47
+ const bodyClasses =
48
+ 'bg-background text-foreground flex flex-col min-h-full' +
49
+ getAppRouterBodyFontClasses()
50
+
51
+ async function RootLayout({
52
+ showHeader = false,
53
+ chatbot = false,
54
+ siteDef,
55
+ children,
56
+ } : {
57
+ siteDef: SiteDef
58
+ showHeader?: boolean
59
+ chatbot?: boolean
60
+ } & PropsWithChildren) {
61
+
62
+ const currentUser = await getUserServerSide()
63
+
64
+ const Guts: React.FC = () => (<>
65
+ {showHeader && <Header siteDef={siteDef}/>}
66
+ {children}
67
+ {chatbot && (<ChatWidget
68
+ title='LUX'
69
+ subtitle='AI'
70
+ chatbotUrl='https://lux.chat/?isIframe=true'
71
+ suggestedQuestions={siteDef.chatbot?.suggestedQuestions ?? []}
72
+ buttonClx='hidden md:block'
73
+ />)}
74
+ </>)
75
+
76
+ return (
77
+ <html lang='en' suppressHydrationWarning className='hanzo-ui-dark-theme' style={{backgroundColor: '#000'}}>
78
+ <head >
79
+ {/* https://stackoverflow.com/a/75716588/11645689 */ }
80
+ <base target='_blank' />
81
+ <FacebookPixelHead/>
82
+ </head>
83
+
84
+ <body className={bodyClasses} style={{
85
+
86
+ // As also noted above, 'overflow: hidden' on the <body> tag breaks scroll snap!
87
+ display: 'none', // see scripts.tsx // :aa concerned about this.
88
+
89
+ }}>
90
+ <Scripts/>
91
+ <AuthServiceProvider user={currentUser} conf={{} as AuthServiceConf}>
92
+ {siteDef?.commerce ? (
93
+ <CommerceProvider
94
+ rootNode={siteDef.commerce!.rootNode}
95
+ families={siteDef.commerce!.families}
96
+ options={siteDef.commerce!.options}
97
+ uiSpecs={selectionUISpecifiers}
98
+ >
99
+ <CommerceUIProvider >
100
+ <Guts />
101
+ <CommerceDrawer />
102
+ </CommerceUIProvider>
103
+ </CommerceProvider>
104
+ ) : (
105
+ <Guts />
106
+ )}
107
+ <AuthListener/>
108
+ </AuthServiceProvider>
109
+ <Toaster position='top-center' duration={3000}/>
110
+ </body>
111
+ </html>
112
+ )
113
+ }
114
+
115
+ export {
116
+ RootLayout,
117
+ viewport
118
+ }
@@ -1,14 +1,14 @@
1
- import { initializeApp, getApps } from 'firebase/app'
2
-
3
- const firebaseConfig = {
4
- apiKey: process.env.NEXT_PUBLIC_FIREBASE_API_KEY,
5
- authDomain: process.env.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN,
6
- projectId: process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID,
7
- storageBucket: process.env.NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET,
8
- messagingSenderId: process.env.NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID,
9
- appId: process.env.NEXT_PUBLIC_FIREBASE_APP_ID,
10
- measurementId: process.env.NEXT_PUBLIC_FIREBASE_MEASUREMENT_ID,
11
- }
12
-
13
- // Initialize Firebase instance if there isn't one already
14
- export default getApps().length === 0 ? initializeApp(firebaseConfig) : getApps()[0]
1
+ import { initializeApp, getApps } from 'firebase/app'
2
+
3
+ const firebaseConfig = {
4
+ apiKey: process.env.NEXT_PUBLIC_FIREBASE_API_KEY,
5
+ authDomain: process.env.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN,
6
+ projectId: process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID,
7
+ storageBucket: process.env.NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET,
8
+ messagingSenderId: process.env.NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID,
9
+ appId: process.env.NEXT_PUBLIC_FIREBASE_APP_ID,
10
+ measurementId: process.env.NEXT_PUBLIC_FIREBASE_MEASUREMENT_ID,
11
+ }
12
+
13
+ // Initialize Firebase instance if there isn't one already
14
+ export default getApps().length === 0 ? initializeApp(firebaseConfig) : getApps()[0]
@@ -1,5 +1,5 @@
1
- import storeContact from './store-contact'
2
-
3
- export {
4
- storeContact as default
5
- }
1
+ import storeContact from './store-contact'
2
+
3
+ export {
4
+ storeContact as default
5
+ }
@@ -1,51 +1,51 @@
1
- 'use server'
2
-
3
- import {
4
- getFirestore,
5
- collection,
6
- setDoc,
7
- doc,
8
- serverTimestamp,
9
- type Firestore,
10
- } from 'firebase/firestore'
11
-
12
- import firebaseApp from './firebase-app'
13
- import type { ContactInfo } from '../types'
14
-
15
- let dbInstance: Firestore | undefined = undefined
16
-
17
- const getDBInstance = (name: string): Firestore => {
18
- if (!dbInstance) {
19
- dbInstance = getFirestore(firebaseApp, name)
20
- }
21
- return dbInstance
22
- }
23
-
24
- const storeContact = async ( formData: ContactInfo, enclosure: any ) => {
25
- const email = formData.email
26
- const phone = formData.phone
27
- const dbName = enclosure?.dbId
28
- const tableName = enclosure?.listId
29
-
30
- let error: any | null = null
31
- const tableRef = collection(getDBInstance(dbName), tableName)
32
-
33
- try {
34
- await setDoc(doc(tableRef, email), {
35
- email,
36
- phone,
37
- timestamp: serverTimestamp(),
38
- })
39
- return { success: !error, error, id: email }
40
- }
41
- catch (e) {
42
- console.error('Error writing contact info to database: ', e)
43
- error = e
44
- }
45
-
46
- return { success: !error, error }
47
- }
48
-
49
- export {
50
- storeContact as default
51
- }
1
+ 'use server'
2
+
3
+ import {
4
+ getFirestore,
5
+ collection,
6
+ setDoc,
7
+ doc,
8
+ serverTimestamp,
9
+ type Firestore,
10
+ } from 'firebase/firestore'
11
+
12
+ import firebaseApp from './firebase-app'
13
+ import type { ContactInfo } from '../types'
14
+
15
+ let dbInstance: Firestore | undefined = undefined
16
+
17
+ const getDBInstance = (name: string): Firestore => {
18
+ if (!dbInstance) {
19
+ dbInstance = getFirestore(firebaseApp, name)
20
+ }
21
+ return dbInstance
22
+ }
23
+
24
+ const storeContact = async ( formData: ContactInfo, enclosure: any ) => {
25
+ const email = formData.email
26
+ const phone = formData.phone
27
+ const dbName = enclosure?.dbId
28
+ const tableName = enclosure?.listId
29
+
30
+ let error: any | null = null
31
+ const tableRef = collection(getDBInstance(dbName), tableName)
32
+
33
+ try {
34
+ await setDoc(doc(tableRef, email), {
35
+ email,
36
+ phone,
37
+ timestamp: serverTimestamp(),
38
+ })
39
+ return { success: !error, error, id: email }
40
+ }
41
+ catch (e) {
42
+ console.error('Error writing contact info to database: ', e)
43
+ error = e
44
+ }
45
+
46
+ return { success: !error, error }
47
+ }
48
+
49
+ export {
50
+ storeContact as default
51
+ }