@luxfi/core 5.1.4 → 5.1.6

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 (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
+ }