@burdenoff/website-sdk 2026.1101.1 → 2026.1101.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +42 -8
- package/dist/analytics/index.js +19 -69
- package/dist/analytics/index.js.map +1 -1
- package/dist/analytics/index.mjs +3 -69
- package/dist/analytics/index.mjs.map +1 -1
- package/dist/avatar-live/index.js +1 -0
- package/dist/avatar-live/index.js.map +1 -1
- package/dist/avatar-live/index.mjs +1 -0
- package/dist/avatar-live/index.mjs.map +1 -1
- package/dist/avatar-live-view/index.js +10 -30
- package/dist/avatar-live-view/index.js.map +1 -1
- package/dist/avatar-live-view/index.mjs +4 -24
- package/dist/avatar-live-view/index.mjs.map +1 -1
- package/dist/chunk-23H4JUL4.js +41 -0
- package/dist/chunk-23H4JUL4.js.map +1 -0
- package/dist/chunk-34RX5P75.mjs +25 -0
- package/dist/chunk-34RX5P75.mjs.map +1 -0
- package/dist/chunk-3LFFY7AZ.js +184 -0
- package/dist/chunk-3LFFY7AZ.js.map +1 -0
- package/dist/chunk-3X26GE4S.js +2794 -0
- package/dist/chunk-3X26GE4S.js.map +1 -0
- package/dist/chunk-45GCA4GG.js +85 -0
- package/dist/chunk-45GCA4GG.js.map +1 -0
- package/dist/chunk-4SAGVLHN.js +876 -0
- package/dist/chunk-4SAGVLHN.js.map +1 -0
- package/dist/chunk-4U6YAII5.js +218 -0
- package/dist/chunk-4U6YAII5.js.map +1 -0
- package/dist/chunk-5GMTBOO6.js +21 -0
- package/dist/chunk-5GMTBOO6.js.map +1 -0
- package/dist/chunk-5JRJ57CL.mjs +329 -0
- package/dist/chunk-5JRJ57CL.mjs.map +1 -0
- package/dist/chunk-6C2DKIC7.js +4 -0
- package/dist/chunk-6C2DKIC7.js.map +1 -0
- package/dist/chunk-6IBFBWC5.mjs +17 -0
- package/dist/chunk-6IBFBWC5.mjs.map +1 -0
- package/dist/chunk-6KY2ZRVI.js +116 -0
- package/dist/chunk-6KY2ZRVI.js.map +1 -0
- package/dist/chunk-6VJT3SM4.mjs +182 -0
- package/dist/chunk-6VJT3SM4.mjs.map +1 -0
- package/dist/chunk-6YZUFMK2.mjs +40 -0
- package/dist/chunk-6YZUFMK2.mjs.map +1 -0
- package/dist/chunk-7A6R7CGG.js +47 -0
- package/dist/chunk-7A6R7CGG.js.map +1 -0
- package/dist/chunk-7PWL4V2R.js +4 -0
- package/dist/chunk-7PWL4V2R.js.map +1 -0
- package/dist/chunk-AA33WDYS.js +161 -0
- package/dist/chunk-AA33WDYS.js.map +1 -0
- package/dist/chunk-AHRGFXV2.js +525 -0
- package/dist/chunk-AHRGFXV2.js.map +1 -0
- package/dist/chunk-B63XLDZH.mjs +109 -0
- package/dist/chunk-B63XLDZH.mjs.map +1 -0
- package/dist/chunk-BX2USEWF.mjs +35 -0
- package/dist/chunk-BX2USEWF.mjs.map +1 -0
- package/dist/chunk-BYSZT35R.js +150 -0
- package/dist/chunk-BYSZT35R.js.map +1 -0
- package/dist/chunk-C6OJIHNO.js +12 -0
- package/dist/chunk-C6OJIHNO.js.map +1 -0
- package/dist/chunk-COOELBX7.mjs +63 -0
- package/dist/chunk-COOELBX7.mjs.map +1 -0
- package/dist/chunk-D2TW7MNC.mjs +2771 -0
- package/dist/chunk-D2TW7MNC.mjs.map +1 -0
- package/dist/chunk-D5KEZ6V6.mjs +3 -0
- package/dist/chunk-D5KEZ6V6.mjs.map +1 -0
- package/dist/chunk-E3GUGJMY.js +46 -0
- package/dist/chunk-E3GUGJMY.js.map +1 -0
- package/dist/chunk-EBZ2HGJ2.mjs +52 -0
- package/dist/chunk-EBZ2HGJ2.mjs.map +1 -0
- package/dist/chunk-EDLTUOIA.mjs +210 -0
- package/dist/chunk-EDLTUOIA.mjs.map +1 -0
- package/dist/chunk-EJQSOT4X.js +4 -0
- package/dist/chunk-EJQSOT4X.js.map +1 -0
- package/dist/chunk-EUPFS6MZ.mjs +2019 -0
- package/dist/chunk-EUPFS6MZ.mjs.map +1 -0
- package/dist/chunk-F3XWDC3B.js +77 -0
- package/dist/chunk-F3XWDC3B.js.map +1 -0
- package/dist/chunk-FFADMVIK.mjs +5127 -0
- package/dist/chunk-FFADMVIK.mjs.map +1 -0
- package/dist/chunk-FJWS7BKT.mjs +3 -0
- package/dist/chunk-FJWS7BKT.mjs.map +1 -0
- package/dist/chunk-FJZJDUOR.mjs +3 -0
- package/dist/chunk-FJZJDUOR.mjs.map +1 -0
- package/dist/chunk-GCFLCO2Z.mjs +145 -0
- package/dist/chunk-GCFLCO2Z.mjs.map +1 -0
- package/dist/chunk-GEXC4LRP.js +61 -0
- package/dist/chunk-GEXC4LRP.js.map +1 -0
- package/dist/chunk-GTRAXQGC.mjs +3 -0
- package/dist/chunk-GTRAXQGC.mjs.map +1 -0
- package/dist/chunk-IKOIRUKW.js +270 -0
- package/dist/chunk-IKOIRUKW.js.map +1 -0
- package/dist/chunk-IXTWOPRN.js +45 -0
- package/dist/chunk-IXTWOPRN.js.map +1 -0
- package/dist/chunk-JDXOXGOK.js +547 -0
- package/dist/chunk-JDXOXGOK.js.map +1 -0
- package/dist/chunk-JSLDWYV7.mjs +558 -0
- package/dist/chunk-JSLDWYV7.mjs.map +1 -0
- package/dist/chunk-JXLSTVBK.js +336 -0
- package/dist/chunk-JXLSTVBK.js.map +1 -0
- package/dist/chunk-KHYXK7FG.mjs +49 -0
- package/dist/chunk-KHYXK7FG.mjs.map +1 -0
- package/dist/chunk-KSMBOWQQ.js +2034 -0
- package/dist/chunk-KSMBOWQQ.js.map +1 -0
- package/dist/chunk-KU2PXHGB.mjs +83 -0
- package/dist/chunk-KU2PXHGB.mjs.map +1 -0
- package/dist/chunk-KZANIV3S.mjs +37 -0
- package/dist/chunk-KZANIV3S.mjs.map +1 -0
- package/dist/chunk-L4BP6YOB.js +20 -0
- package/dist/chunk-L4BP6YOB.js.map +1 -0
- package/dist/chunk-MRKA2OAF.mjs +75 -0
- package/dist/chunk-MRKA2OAF.mjs.map +1 -0
- package/dist/chunk-N5EC53MH.mjs +80 -0
- package/dist/chunk-N5EC53MH.mjs.map +1 -0
- package/dist/chunk-NZANQGDM.mjs +34 -0
- package/dist/chunk-NZANQGDM.mjs.map +1 -0
- package/dist/chunk-O4GS3XPZ.js +10 -0
- package/dist/chunk-O4GS3XPZ.js.map +1 -0
- package/dist/chunk-O76QDGRM.js +5154 -0
- package/dist/chunk-O76QDGRM.js.map +1 -0
- package/dist/chunk-OYEUNZJY.js +114 -0
- package/dist/chunk-OYEUNZJY.js.map +1 -0
- package/dist/chunk-PHXAGQNB.js +74 -0
- package/dist/chunk-PHXAGQNB.js.map +1 -0
- package/dist/chunk-PIHHPP7J.mjs +16 -0
- package/dist/chunk-PIHHPP7J.mjs.map +1 -0
- package/dist/chunk-PXRHVVOU.mjs +499 -0
- package/dist/chunk-PXRHVVOU.mjs.map +1 -0
- package/dist/chunk-QMA6U6AU.js +36 -0
- package/dist/chunk-QMA6U6AU.js.map +1 -0
- package/dist/chunk-R6J7IULF.js +44 -0
- package/dist/chunk-R6J7IULF.js.map +1 -0
- package/dist/chunk-R7G6TWIS.mjs +10 -0
- package/dist/chunk-R7G6TWIS.mjs.map +1 -0
- package/dist/chunk-RUMGFI6L.mjs +544 -0
- package/dist/chunk-RUMGFI6L.mjs.map +1 -0
- package/dist/chunk-S54JWSJF.js +565 -0
- package/dist/chunk-S54JWSJF.js.map +1 -0
- package/dist/chunk-SK5UGG6A.js +2041 -0
- package/dist/chunk-SK5UGG6A.js.map +1 -0
- package/dist/chunk-SKIYDKIS.mjs +70 -0
- package/dist/chunk-SKIYDKIS.mjs.map +1 -0
- package/dist/chunk-SZNS5IK6.mjs +322 -0
- package/dist/chunk-SZNS5IK6.mjs.map +1 -0
- package/dist/chunk-T7JIPZAC.js +66 -0
- package/dist/chunk-T7JIPZAC.js.map +1 -0
- package/dist/chunk-TGYQHO2E.mjs +864 -0
- package/dist/chunk-TGYQHO2E.mjs.map +1 -0
- package/dist/chunk-TT3MHN42.mjs +8 -0
- package/dist/chunk-TT3MHN42.mjs.map +1 -0
- package/dist/chunk-UM55U65W.mjs +268 -0
- package/dist/chunk-UM55U65W.mjs.map +1 -0
- package/dist/chunk-UQ2HALUD.js +72 -0
- package/dist/chunk-UQ2HALUD.js.map +1 -0
- package/dist/chunk-UXWT7G77.js +82 -0
- package/dist/chunk-UXWT7G77.js.map +1 -0
- package/dist/chunk-VNS5WDWO.mjs +7 -0
- package/dist/chunk-VNS5WDWO.mjs.map +1 -0
- package/dist/chunk-VRWZLGR7.js +4 -0
- package/dist/chunk-VRWZLGR7.js.map +1 -0
- package/dist/chunk-VZLDSNH4.mjs +22 -0
- package/dist/chunk-VZLDSNH4.mjs.map +1 -0
- package/dist/chunk-W6P3YETJ.js +92 -0
- package/dist/chunk-W6P3YETJ.js.map +1 -0
- package/dist/chunk-WPKFFQCR.mjs +90 -0
- package/dist/chunk-WPKFFQCR.mjs.map +1 -0
- package/dist/chunk-WTVTI5TO.mjs +22 -0
- package/dist/chunk-WTVTI5TO.mjs.map +1 -0
- package/dist/chunk-XJOBZ4RJ.js +44 -0
- package/dist/chunk-XJOBZ4RJ.js.map +1 -0
- package/dist/chunk-XP2JDNDU.js +325 -0
- package/dist/chunk-XP2JDNDU.js.map +1 -0
- package/dist/chunk-Y4V5CEWD.mjs +112 -0
- package/dist/chunk-Y4V5CEWD.mjs.map +1 -0
- package/dist/chunk-YERN2UWM.js +116 -0
- package/dist/chunk-YERN2UWM.js.map +1 -0
- package/dist/chunk-ZKJQWFAA.mjs +114 -0
- package/dist/chunk-ZKJQWFAA.mjs.map +1 -0
- package/dist/chunk-ZOON3S3Y.mjs +138 -0
- package/dist/chunk-ZOON3S3Y.mjs.map +1 -0
- package/dist/chunk-ZP6QRAYC.mjs +2024 -0
- package/dist/chunk-ZP6QRAYC.mjs.map +1 -0
- package/dist/chunk-ZSTFX7FV.js +9 -0
- package/dist/chunk-ZSTFX7FV.js.map +1 -0
- package/dist/client/index.js +23 -331
- package/dist/client/index.js.map +1 -1
- package/dist/client/index.mjs +3 -330
- package/dist/client/index.mjs.map +1 -1
- package/dist/comparison/index.js +28 -111
- package/dist/comparison/index.js.map +1 -1
- package/dist/comparison/index.mjs +2 -107
- package/dist/comparison/index.mjs.map +1 -1
- package/dist/components/contact.js +21 -931
- package/dist/components/contact.js.map +1 -1
- package/dist/components/contact.mjs +12 -909
- package/dist/components/contact.mjs.map +1 -1
- package/dist/components/electron-download.js +12 -124
- package/dist/components/electron-download.js.map +1 -1
- package/dist/components/electron-download.mjs +4 -106
- package/dist/components/electron-download.mjs.map +1 -1
- package/dist/components/explore-cta.js +8 -112
- package/dist/components/explore-cta.js.map +1 -1
- package/dist/components/explore-cta.mjs +3 -114
- package/dist/components/explore-cta.mjs.map +1 -1
- package/dist/components/explore.js +62 -7833
- package/dist/components/explore.js.map +1 -1
- package/dist/components/explore.mjs +13 -7800
- package/dist/components/explore.mjs.map +1 -1
- package/dist/components/launch-countdown.js +8 -83
- package/dist/components/launch-countdown.js.map +1 -1
- package/dist/components/launch-countdown.mjs +3 -85
- package/dist/components/launch-countdown.mjs.map +1 -1
- package/dist/components/newsletter.js +20 -993
- package/dist/components/newsletter.js.map +1 -1
- package/dist/components/newsletter.mjs +11 -971
- package/dist/components/newsletter.mjs.map +1 -1
- package/dist/components/partners.js +24 -1302
- package/dist/components/partners.js.map +1 -1
- package/dist/components/partners.mjs +15 -1276
- package/dist/components/partners.mjs.map +1 -1
- package/dist/components/pricing.js +49 -1249
- package/dist/components/pricing.js.map +1 -1
- package/dist/components/pricing.mjs +8 -1226
- package/dist/components/pricing.mjs.map +1 -1
- package/dist/components/problems-solved.js +8 -150
- package/dist/components/problems-solved.js.map +1 -1
- package/dist/components/problems-solved.mjs +4 -133
- package/dist/components/problems-solved.mjs.map +1 -1
- package/dist/components/resource-links.js +8 -304
- package/dist/components/resource-links.js.map +1 -1
- package/dist/components/resource-links.mjs +5 -308
- package/dist/components/resource-links.mjs.map +1 -1
- package/dist/components/social-links.js +8 -343
- package/dist/components/social-links.js.map +1 -1
- package/dist/components/social-links.mjs +5 -347
- package/dist/components/social-links.mjs.map +1 -1
- package/dist/components/unsubscribe.js +10 -627
- package/dist/components/unsubscribe.js.map +1 -1
- package/dist/components/unsubscribe.mjs +6 -611
- package/dist/components/unsubscribe.mjs.map +1 -1
- package/dist/components/waitlist.js +21 -1001
- package/dist/components/waitlist.js.map +1 -1
- package/dist/components/waitlist.mjs +12 -982
- package/dist/components/waitlist.mjs.map +1 -1
- package/dist/components/website-switcher.js +12 -175
- package/dist/components/website-switcher.js.map +1 -1
- package/dist/components/website-switcher.mjs +4 -157
- package/dist/components/website-switcher.mjs.map +1 -1
- package/dist/content/index.js +118 -3616
- package/dist/content/index.js.map +1 -1
- package/dist/content/index.mjs +12 -3567
- package/dist/content/index.mjs.map +1 -1
- package/dist/hooks/index.js +37 -2321
- package/dist/hooks/index.js.map +1 -1
- package/dist/hooks/index.mjs +6 -2318
- package/dist/hooks/index.mjs.map +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +4145 -20599
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +3766 -20567
- package/dist/index.mjs.map +1 -1
- package/dist/product/index.js +20 -393
- package/dist/product/index.js.map +1 -1
- package/dist/product/index.mjs +5 -394
- package/dist/product/index.mjs.map +1 -1
- package/dist/seo/index.js +8 -76
- package/dist/seo/index.js.map +1 -1
- package/dist/seo/index.mjs +3 -78
- package/dist/seo/index.mjs.map +1 -1
- package/dist/store/index.js +51 -2650
- package/dist/store/index.js.map +1 -1
- package/dist/store/index.mjs +13 -2619
- package/dist/store/index.mjs.map +1 -1
- package/dist/utils/index.js +69 -134
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/index.mjs +5 -122
- package/dist/utils/index.mjs.map +1 -1
- package/package.json +2 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/analytics/rybbit.tsx"],"names":["useEffect"],"mappings":";;;;AAoDO,SAAS,eAAA,CAAgB;AAAA,EAC9B,MAAA;AAAA,EACA,SAAA,GAAY,+CAAA;AAAA,EACZ,OAAA,GAAU;AACZ,CAAA,EAAyB;AACvB,EAAAA,eAAA,CAAU,MAAM;AACd,IAAA,IAAI,CAAC,OAAA,IAAW,CAAC,MAAA,EAAQ;AAGzB,IAAA,MAAM,iBAAiB,QAAA,CAAS,aAAA;AAAA,MAC9B,wBAAwB,MAAM,CAAA,EAAA;AAAA,KAChC;AACA,IAAA,IAAI,cAAA,EAAgB;AAQpB,IAAA,MAAM,MAAA,GAAS,QAAA,CAAS,aAAA,CAAc,QAAQ,CAAA;AAC9C,IAAA,MAAA,CAAO,GAAA,GAAM,SAAA;AACb,IAAA,MAAA,CAAO,KAAA,GAAQ,IAAA;AACf,IAAA,MAAA,CAAO,WAAA,GAAc,WAAA;AACrB,IAAA,MAAA,CAAO,YAAA,CAAa,gBAAgB,MAAM,CAAA;AAC1C,IAAA,QAAA,CAAS,IAAA,CAAK,YAAY,MAAM,CAAA;AAGhC,IAAA,OAAO,MAAM;AACX,MAAA,MAAM,iBAAiB,QAAA,CAAS,aAAA;AAAA,QAC9B,wBAAwB,MAAM,CAAA,EAAA;AAAA,OAChC;AACA,MAAA,IAAI,cAAA,EAAgB;AAClB,QAAA,QAAA,CAAS,IAAA,CAAK,YAAY,cAAc,CAAA;AAAA,MAC1C;AAAA,IACF,CAAA;AAAA,EACF,CAAA,EAAG,CAAC,MAAA,EAAQ,SAAA,EAAW,OAAO,CAAC,CAAA;AAG/B,EAAA,OAAO,IAAA;AACT","file":"chunk-QMA6U6AU.js","sourcesContent":["/**\n * Rybbit Analytics Component\n *\n * Injects the Rybbit tracking script into the page head.\n * Works with both Vite (CSR) and Next.js (SSR/CSR) applications.\n *\n * @example\n * ```tsx\n * // In your app layout or root component\n * import { RybbitAnalytics } from '@burdenoff/website-sdk/analytics'\n *\n * function App() {\n * return (\n * <>\n * <RybbitAnalytics siteId=\"1\" />\n * <Router>...</Router>\n * </>\n * )\n * }\n * ```\n */\n\"use client\";\n\nimport { useEffect } from \"react\";\n\nexport interface RybbitAnalyticsProps {\n /**\n * Rybbit site ID (obtained from the Rybbit dashboard)\n */\n siteId: string;\n\n /**\n * Rybbit script URL (defaults to the self-hosted instance)\n * @default \"https://analytics.burdenoff.com/api/script.js\"\n */\n scriptUrl?: string;\n\n /**\n * Whether to enable tracking (useful for disabling in development)\n * @default true\n */\n enabled?: boolean;\n}\n\n/**\n * RybbitAnalytics - Embeds the Rybbit analytics tracking script.\n *\n * The script is loaded asynchronously with `defer` to avoid blocking page load.\n * It automatically tracks page views and user interactions.\n *\n * In development mode (when `enabled` is false), no script is loaded.\n */\nexport function RybbitAnalytics({\n siteId,\n scriptUrl = \"https://analytics.burdenoff.com/api/script.js\",\n enabled = true,\n}: RybbitAnalyticsProps) {\n useEffect(() => {\n if (!enabled || !siteId) return;\n\n // Check if script already exists\n const existingScript = document.querySelector(\n `script[data-site-id=\"${siteId}\"]`,\n );\n if (existingScript) return;\n\n // Create and inject the script. `crossOrigin=\"anonymous\"` puts the\n // request in CORS-no-credentials mode so the browser does not include\n // any third-party cookies the visitor may have on the analytics origin\n // (e.g. `app.rybbit.io`'s own dashboard session cookie). Without this,\n // Lighthouse `third-party-cookies` audit flags the page even though we\n // never read those cookies ourselves.\n const script = document.createElement(\"script\");\n script.src = scriptUrl;\n script.defer = true;\n script.crossOrigin = \"anonymous\";\n script.setAttribute(\"data-site-id\", siteId);\n document.head.appendChild(script);\n\n // Cleanup on unmount\n return () => {\n const scriptToRemove = document.querySelector(\n `script[data-site-id=\"${siteId}\"]`,\n );\n if (scriptToRemove) {\n document.head.removeChild(scriptToRemove);\n }\n };\n }, [siteId, scriptUrl, enabled]);\n\n // This component renders nothing - it only manages the script tag\n return null;\n}\n"]}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var chunkC6OJIHNO_js = require('./chunk-C6OJIHNO.js');
|
|
4
|
+
var React = require('react');
|
|
5
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
6
|
+
|
|
7
|
+
function _interopNamespace(e) {
|
|
8
|
+
if (e && e.__esModule) return e;
|
|
9
|
+
var n = Object.create(null);
|
|
10
|
+
if (e) {
|
|
11
|
+
Object.keys(e).forEach(function (k) {
|
|
12
|
+
if (k !== 'default') {
|
|
13
|
+
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
14
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
15
|
+
enumerable: true,
|
|
16
|
+
get: function () { return e[k]; }
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
n.default = e;
|
|
22
|
+
return Object.freeze(n);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
var React__namespace = /*#__PURE__*/_interopNamespace(React);
|
|
26
|
+
|
|
27
|
+
var Textarea = React__namespace.forwardRef(({ className, ...props }, ref) => {
|
|
28
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
29
|
+
"textarea",
|
|
30
|
+
{
|
|
31
|
+
className: chunkC6OJIHNO_js.cn(
|
|
32
|
+
"flex min-h-[60px] w-full rounded-md border border-input bg-transparent px-3 py-2 text-base shadow-sm placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
|
|
33
|
+
className
|
|
34
|
+
),
|
|
35
|
+
ref,
|
|
36
|
+
...props
|
|
37
|
+
}
|
|
38
|
+
);
|
|
39
|
+
});
|
|
40
|
+
Textarea.displayName = "Textarea";
|
|
41
|
+
|
|
42
|
+
exports.Textarea = Textarea;
|
|
43
|
+
//# sourceMappingURL=chunk-R6J7IULF.js.map
|
|
44
|
+
//# sourceMappingURL=chunk-R6J7IULF.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/ui/textarea.tsx"],"names":["React","jsx","cn"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAIA,IAAM,QAAA,GAAiBA,4BAGrB,CAAC,EAAE,WAAW,GAAG,KAAA,IAAS,GAAA,KAAQ;AAClC,EAAA,uBACEC,cAAA;AAAA,IAAC,UAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAWC,mBAAA;AAAA,QACT,2QAAA;AAAA,QACA;AAAA,OACF;AAAA,MACA,GAAA;AAAA,MACC,GAAG;AAAA;AAAA,GACN;AAEJ,CAAC;AACD,QAAA,CAAS,WAAA,GAAc,UAAA","file":"chunk-R6J7IULF.js","sourcesContent":["import * as React from \"react\";\n\nimport { cn } from \"../utils/cn\";\n\nconst Textarea = React.forwardRef<\n HTMLTextAreaElement,\n React.ComponentProps<\"textarea\">\n>(({ className, ...props }, ref) => {\n return (\n <textarea\n className={cn(\n \"flex min-h-[60px] w-full rounded-md border border-input bg-transparent px-3 py-2 text-base shadow-sm placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 md:text-sm\",\n className,\n )}\n ref={ref}\n {...props}\n />\n );\n});\nTextarea.displayName = \"Textarea\";\n\nexport { Textarea };\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/utils/cn.ts"],"names":[],"mappings":";;;AAmBO,SAAS,MAAM,MAAA,EAA8B;AAClD,EAAA,OAAO,OAAA,CAAQ,IAAA,CAAK,MAAM,CAAC,CAAA;AAC7B","file":"chunk-R7G6TWIS.mjs","sourcesContent":["/**\n * Utility function to merge Tailwind CSS classes\n * Combines clsx and tailwind-merge for optimal class handling\n */\n\nimport { type ClassValue, clsx } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\n/**\n * Merge multiple class names intelligently\n * - Handles conditional classes via clsx\n * - Deduplicates and resolves Tailwind conflicts via tailwind-merge\n *\n * @example\n * ```ts\n * cn('px-4 py-2', 'bg-blue-500', { 'text-white': isActive })\n * // => 'px-4 py-2 bg-blue-500 text-white' (if isActive is true)\n * ```\n */\nexport function cn(...inputs: ClassValue[]): string {\n return twMerge(clsx(inputs));\n}\n"]}
|
|
@@ -0,0 +1,544 @@
|
|
|
1
|
+
import { trackWebsiteEvent } from './chunk-6YZUFMK2.mjs';
|
|
2
|
+
import { Textarea } from './chunk-VZLDSNH4.mjs';
|
|
3
|
+
import { Label } from './chunk-WTVTI5TO.mjs';
|
|
4
|
+
import { Input } from './chunk-34RX5P75.mjs';
|
|
5
|
+
import { PageHead } from './chunk-N5EC53MH.mjs';
|
|
6
|
+
import { Button } from './chunk-KHYXK7FG.mjs';
|
|
7
|
+
import { useProduct } from './chunk-GCFLCO2Z.mjs';
|
|
8
|
+
import { useWebSDK, useWebSDKConfig } from './chunk-5JRJ57CL.mjs';
|
|
9
|
+
import { useState, useRef } from 'react';
|
|
10
|
+
import { zodResolver } from '@hookform/resolvers/zod';
|
|
11
|
+
import { useForm } from 'react-hook-form';
|
|
12
|
+
import { toast } from 'sonner';
|
|
13
|
+
import { z } from 'zod';
|
|
14
|
+
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
15
|
+
|
|
16
|
+
var waitlistPageSchema = z.object({
|
|
17
|
+
name: z.string().min(1, "Name is required"),
|
|
18
|
+
email: z.string().email("Please enter a valid email address"),
|
|
19
|
+
company: z.string().optional(),
|
|
20
|
+
reason: z.string().optional()
|
|
21
|
+
});
|
|
22
|
+
var JOIN_WAITLIST_MUTATION = (
|
|
23
|
+
/* GraphQL */
|
|
24
|
+
`
|
|
25
|
+
mutation JoinWaitlist($input: JoinWaitlistInput!) {
|
|
26
|
+
joinWaitlist(input: $input) {
|
|
27
|
+
id
|
|
28
|
+
email
|
|
29
|
+
name
|
|
30
|
+
status
|
|
31
|
+
createdAt
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
`
|
|
35
|
+
);
|
|
36
|
+
async function joinWaitlist(client, data, productId) {
|
|
37
|
+
try {
|
|
38
|
+
const result = await client.mutate(JOIN_WAITLIST_MUTATION, {
|
|
39
|
+
input: {
|
|
40
|
+
email: data.email.trim().toLowerCase(),
|
|
41
|
+
platformProductId: productId,
|
|
42
|
+
name: data.name?.trim() || void 0,
|
|
43
|
+
company: data.company?.trim() || void 0,
|
|
44
|
+
reason: data.reason?.trim() || void 0,
|
|
45
|
+
context: {
|
|
46
|
+
source: "website",
|
|
47
|
+
referrer: typeof window !== "undefined" ? window.location.href : "",
|
|
48
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
if (result.errors?.length) {
|
|
53
|
+
const errorMsg = result.errors[0]?.message ?? "Failed to join waitlist";
|
|
54
|
+
if (errorMsg.toLowerCase().includes("already")) {
|
|
55
|
+
return {
|
|
56
|
+
success: false,
|
|
57
|
+
message: "You are already on the waitlist!"
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
return { success: false, message: errorMsg };
|
|
61
|
+
}
|
|
62
|
+
return { success: true, message: "You have been added to the waitlist!" };
|
|
63
|
+
} catch (error) {
|
|
64
|
+
console.error("Waitlist signup error:", error);
|
|
65
|
+
return { success: false, message: "Network error. Please try again." };
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
function useRateLimit(maxAttempts, windowMinutes) {
|
|
69
|
+
const rateLimitRef = useRef(null);
|
|
70
|
+
const [isLimited, setIsLimited] = useState(false);
|
|
71
|
+
const [resetTime, setResetTime] = useState(null);
|
|
72
|
+
function recordAttempt() {
|
|
73
|
+
const now = Date.now();
|
|
74
|
+
const state = rateLimitRef.current;
|
|
75
|
+
if (state && now > state.resetTime) {
|
|
76
|
+
rateLimitRef.current = null;
|
|
77
|
+
}
|
|
78
|
+
const current = rateLimitRef.current;
|
|
79
|
+
if (!current) {
|
|
80
|
+
rateLimitRef.current = {
|
|
81
|
+
attempts: 1,
|
|
82
|
+
resetTime: now + windowMinutes * 60 * 1e3
|
|
83
|
+
};
|
|
84
|
+
return false;
|
|
85
|
+
}
|
|
86
|
+
current.attempts += 1;
|
|
87
|
+
if (current.attempts >= maxAttempts) {
|
|
88
|
+
setIsLimited(true);
|
|
89
|
+
setResetTime(new Date(current.resetTime));
|
|
90
|
+
return true;
|
|
91
|
+
}
|
|
92
|
+
return false;
|
|
93
|
+
}
|
|
94
|
+
function checkLimit() {
|
|
95
|
+
const state = rateLimitRef.current;
|
|
96
|
+
if (!state) return false;
|
|
97
|
+
if (Date.now() > state.resetTime) {
|
|
98
|
+
rateLimitRef.current = null;
|
|
99
|
+
setIsLimited(false);
|
|
100
|
+
setResetTime(null);
|
|
101
|
+
return false;
|
|
102
|
+
}
|
|
103
|
+
return state.attempts >= maxAttempts;
|
|
104
|
+
}
|
|
105
|
+
return { isLimited, resetTime, recordAttempt, checkLimit };
|
|
106
|
+
}
|
|
107
|
+
function WaitlistPage({
|
|
108
|
+
productName,
|
|
109
|
+
heroTitle = "Join the Waitlist",
|
|
110
|
+
heroSubtitle = "Be among the first to experience what's coming next",
|
|
111
|
+
heroDescription,
|
|
112
|
+
successMessage = "You have been added to the waitlist!",
|
|
113
|
+
errorMessage = "Failed to join waitlist. Please try again.",
|
|
114
|
+
className,
|
|
115
|
+
seo
|
|
116
|
+
}) {
|
|
117
|
+
const client = useWebSDK();
|
|
118
|
+
const config = useWebSDKConfig();
|
|
119
|
+
const {
|
|
120
|
+
product,
|
|
121
|
+
loading: productLoading,
|
|
122
|
+
error: productError,
|
|
123
|
+
hasProvider
|
|
124
|
+
} = useProduct();
|
|
125
|
+
const displayName = productName ?? product?.name ?? config.productId;
|
|
126
|
+
const productStatus = product?.status;
|
|
127
|
+
const canCheckStatus = Boolean(config.productSlug);
|
|
128
|
+
const [isSubmitting, setIsSubmitting] = useState(false);
|
|
129
|
+
const { isLimited, resetTime, recordAttempt, checkLimit } = useRateLimit(
|
|
130
|
+
3,
|
|
131
|
+
15
|
|
132
|
+
);
|
|
133
|
+
const {
|
|
134
|
+
register,
|
|
135
|
+
handleSubmit,
|
|
136
|
+
formState: { errors },
|
|
137
|
+
reset
|
|
138
|
+
} = useForm({
|
|
139
|
+
resolver: zodResolver(waitlistPageSchema)
|
|
140
|
+
});
|
|
141
|
+
if (canCheckStatus && !hasProvider) {
|
|
142
|
+
return /* @__PURE__ */ jsxs("div", { className, children: [
|
|
143
|
+
seo && /* @__PURE__ */ jsx(
|
|
144
|
+
PageHead,
|
|
145
|
+
{
|
|
146
|
+
title: seo.title ?? "",
|
|
147
|
+
description: seo.description ?? "",
|
|
148
|
+
keywords: seo.keywords,
|
|
149
|
+
image: seo.image,
|
|
150
|
+
url: seo.url
|
|
151
|
+
}
|
|
152
|
+
),
|
|
153
|
+
/* @__PURE__ */ jsx("section", { className: "relative overflow-hidden py-24 lg:py-32", children: /* @__PURE__ */ jsxs("div", { className: "relative max-w-3xl mx-auto px-4 sm:px-6 lg:px-8 text-center space-y-6", children: [
|
|
154
|
+
/* @__PURE__ */ jsx("h1", { className: "text-4xl font-bold tracking-tight sm:text-5xl text-foreground", children: "Waitlist Unavailable" }),
|
|
155
|
+
/* @__PURE__ */ jsxs("p", { className: "text-lg text-muted-foreground", children: [
|
|
156
|
+
"Product status checks require ",
|
|
157
|
+
/* @__PURE__ */ jsx("code", { children: "ProductProvider" }),
|
|
158
|
+
" to be mounted. Please update your integration configuration."
|
|
159
|
+
] })
|
|
160
|
+
] }) })
|
|
161
|
+
] });
|
|
162
|
+
}
|
|
163
|
+
if (canCheckStatus && productLoading) {
|
|
164
|
+
return /* @__PURE__ */ jsxs("div", { className, children: [
|
|
165
|
+
seo && /* @__PURE__ */ jsx(
|
|
166
|
+
PageHead,
|
|
167
|
+
{
|
|
168
|
+
title: seo.title ?? "",
|
|
169
|
+
description: seo.description ?? "",
|
|
170
|
+
keywords: seo.keywords,
|
|
171
|
+
image: seo.image,
|
|
172
|
+
url: seo.url
|
|
173
|
+
}
|
|
174
|
+
),
|
|
175
|
+
/* @__PURE__ */ jsx("section", { className: "relative overflow-hidden py-24 lg:py-32", children: /* @__PURE__ */ jsxs("div", { className: "relative max-w-3xl mx-auto px-4 sm:px-6 lg:px-8 text-center space-y-6", children: [
|
|
176
|
+
/* @__PURE__ */ jsx("h1", { className: "text-4xl font-bold tracking-tight sm:text-5xl text-foreground", children: "Loading\u2026" }),
|
|
177
|
+
/* @__PURE__ */ jsx("p", { className: "text-lg text-muted-foreground", children: "Fetching product status." })
|
|
178
|
+
] }) })
|
|
179
|
+
] });
|
|
180
|
+
}
|
|
181
|
+
if (canCheckStatus && (productError || !productStatus)) {
|
|
182
|
+
return /* @__PURE__ */ jsxs("div", { className, children: [
|
|
183
|
+
seo && /* @__PURE__ */ jsx(
|
|
184
|
+
PageHead,
|
|
185
|
+
{
|
|
186
|
+
title: seo.title ?? "",
|
|
187
|
+
description: seo.description ?? "",
|
|
188
|
+
keywords: seo.keywords,
|
|
189
|
+
image: seo.image,
|
|
190
|
+
url: seo.url
|
|
191
|
+
}
|
|
192
|
+
),
|
|
193
|
+
/* @__PURE__ */ jsx("section", { className: "relative overflow-hidden py-24 lg:py-32", children: /* @__PURE__ */ jsxs("div", { className: "relative max-w-3xl mx-auto px-4 sm:px-6 lg:px-8 text-center space-y-6", children: [
|
|
194
|
+
/* @__PURE__ */ jsx("h1", { className: "text-4xl font-bold tracking-tight sm:text-5xl text-foreground", children: "Waitlist Unavailable" }),
|
|
195
|
+
/* @__PURE__ */ jsx("p", { className: "text-lg text-muted-foreground", children: "We can\u2019t confirm waitlist availability right now. Please try again later." })
|
|
196
|
+
] }) })
|
|
197
|
+
] });
|
|
198
|
+
}
|
|
199
|
+
if (canCheckStatus && (productStatus === "ACTIVE" || productStatus === "RELEASED")) {
|
|
200
|
+
const appUrl = product?.appUrl || product?.website || "#";
|
|
201
|
+
return /* @__PURE__ */ jsxs("div", { className, children: [
|
|
202
|
+
seo && /* @__PURE__ */ jsx(
|
|
203
|
+
PageHead,
|
|
204
|
+
{
|
|
205
|
+
title: seo.title ?? "",
|
|
206
|
+
description: seo.description ?? "",
|
|
207
|
+
keywords: seo.keywords,
|
|
208
|
+
image: seo.image,
|
|
209
|
+
url: seo.url
|
|
210
|
+
}
|
|
211
|
+
),
|
|
212
|
+
/* @__PURE__ */ jsx("section", { className: "relative overflow-hidden py-24 lg:py-32", children: /* @__PURE__ */ jsxs("div", { className: "relative max-w-3xl mx-auto px-4 sm:px-6 lg:px-8 text-center space-y-8", children: [
|
|
213
|
+
/* @__PURE__ */ jsxs("h1", { className: "text-4xl font-bold tracking-tight sm:text-5xl text-foreground", children: [
|
|
214
|
+
displayName,
|
|
215
|
+
" is now available!"
|
|
216
|
+
] }),
|
|
217
|
+
/* @__PURE__ */ jsxs("p", { className: "text-lg text-muted-foreground", children: [
|
|
218
|
+
"Great news \u2014 ",
|
|
219
|
+
displayName,
|
|
220
|
+
" is open to everyone. Sign up or log in to get started."
|
|
221
|
+
] }),
|
|
222
|
+
/* @__PURE__ */ jsx(Button, { size: "lg", asChild: true, children: /* @__PURE__ */ jsx("a", { href: appUrl, target: "_blank", rel: "noopener noreferrer", children: "Get Started" }) })
|
|
223
|
+
] }) })
|
|
224
|
+
] });
|
|
225
|
+
}
|
|
226
|
+
if (canCheckStatus && (productStatus === "DRAFT" || productStatus === "COMING_SOON")) {
|
|
227
|
+
return /* @__PURE__ */ jsxs("div", { className, children: [
|
|
228
|
+
seo && /* @__PURE__ */ jsx(
|
|
229
|
+
PageHead,
|
|
230
|
+
{
|
|
231
|
+
title: seo.title ?? "",
|
|
232
|
+
description: seo.description ?? "",
|
|
233
|
+
keywords: seo.keywords,
|
|
234
|
+
image: seo.image,
|
|
235
|
+
url: seo.url
|
|
236
|
+
}
|
|
237
|
+
),
|
|
238
|
+
/* @__PURE__ */ jsx("section", { className: "relative overflow-hidden py-24 lg:py-32", children: /* @__PURE__ */ jsxs("div", { className: "relative max-w-3xl mx-auto px-4 sm:px-6 lg:px-8 text-center space-y-8", children: [
|
|
239
|
+
/* @__PURE__ */ jsx("h1", { className: "text-4xl font-bold tracking-tight sm:text-5xl text-foreground", children: "Coming Soon" }),
|
|
240
|
+
/* @__PURE__ */ jsxs("p", { className: "text-lg text-muted-foreground", children: [
|
|
241
|
+
displayName,
|
|
242
|
+
" is not yet accepting waitlist signups. Check back soon!"
|
|
243
|
+
] })
|
|
244
|
+
] }) })
|
|
245
|
+
] });
|
|
246
|
+
}
|
|
247
|
+
if (canCheckStatus && productStatus !== "WAITLIST") {
|
|
248
|
+
return /* @__PURE__ */ jsxs("div", { className, children: [
|
|
249
|
+
seo && /* @__PURE__ */ jsx(
|
|
250
|
+
PageHead,
|
|
251
|
+
{
|
|
252
|
+
title: seo.title ?? "",
|
|
253
|
+
description: seo.description ?? "",
|
|
254
|
+
keywords: seo.keywords,
|
|
255
|
+
image: seo.image,
|
|
256
|
+
url: seo.url
|
|
257
|
+
}
|
|
258
|
+
),
|
|
259
|
+
/* @__PURE__ */ jsx("section", { className: "relative overflow-hidden py-24 lg:py-32", children: /* @__PURE__ */ jsxs("div", { className: "relative max-w-3xl mx-auto px-4 sm:px-6 lg:px-8 text-center space-y-6", children: [
|
|
260
|
+
/* @__PURE__ */ jsx("h1", { className: "text-4xl font-bold tracking-tight sm:text-5xl text-foreground", children: "Waitlist Unavailable" }),
|
|
261
|
+
/* @__PURE__ */ jsxs("p", { className: "text-lg text-muted-foreground", children: [
|
|
262
|
+
displayName,
|
|
263
|
+
" is not accepting waitlist signups right now."
|
|
264
|
+
] })
|
|
265
|
+
] }) })
|
|
266
|
+
] });
|
|
267
|
+
}
|
|
268
|
+
const onSubmit = async (data) => {
|
|
269
|
+
if (canCheckStatus && productStatus !== "WAITLIST") {
|
|
270
|
+
toast.error("This product is not accepting waitlist signups right now.");
|
|
271
|
+
return;
|
|
272
|
+
}
|
|
273
|
+
if (checkLimit()) {
|
|
274
|
+
toast.error(
|
|
275
|
+
`Too many attempts. Please try again after ${resetTime?.toLocaleTimeString()}`
|
|
276
|
+
);
|
|
277
|
+
return;
|
|
278
|
+
}
|
|
279
|
+
setIsSubmitting(true);
|
|
280
|
+
try {
|
|
281
|
+
const result = await joinWaitlist(
|
|
282
|
+
client,
|
|
283
|
+
data,
|
|
284
|
+
product?.id || config.productId
|
|
285
|
+
);
|
|
286
|
+
if (result.success) {
|
|
287
|
+
trackWebsiteEvent("waitlist.signed_up", { form: "page" });
|
|
288
|
+
toast.success(result.message ?? successMessage);
|
|
289
|
+
reset();
|
|
290
|
+
} else {
|
|
291
|
+
toast.error(result.message ?? errorMessage);
|
|
292
|
+
}
|
|
293
|
+
recordAttempt();
|
|
294
|
+
} catch (_error) {
|
|
295
|
+
toast.error(errorMessage);
|
|
296
|
+
} finally {
|
|
297
|
+
setIsSubmitting(false);
|
|
298
|
+
}
|
|
299
|
+
};
|
|
300
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
301
|
+
seo && /* @__PURE__ */ jsx(
|
|
302
|
+
PageHead,
|
|
303
|
+
{
|
|
304
|
+
title: seo.title ?? `Join the Waitlist - ${displayName}`,
|
|
305
|
+
description: seo.description ?? heroDescription ?? heroSubtitle,
|
|
306
|
+
productName: displayName,
|
|
307
|
+
keywords: seo.keywords,
|
|
308
|
+
image: seo.image,
|
|
309
|
+
url: seo.url
|
|
310
|
+
}
|
|
311
|
+
),
|
|
312
|
+
/* @__PURE__ */ jsx("div", { className, children: /* @__PURE__ */ jsx("div", { className: "min-h-screen flex items-center justify-center px-4 py-12", children: /* @__PURE__ */ jsxs("div", { className: "max-w-lg w-full space-y-8", children: [
|
|
313
|
+
/* @__PURE__ */ jsxs("div", { className: "text-center", children: [
|
|
314
|
+
/* @__PURE__ */ jsx("h1", { className: "text-4xl font-bold tracking-tight", children: heroTitle }),
|
|
315
|
+
/* @__PURE__ */ jsx("p", { className: "mt-2 text-lg text-muted-foreground", children: heroSubtitle }),
|
|
316
|
+
heroDescription && /* @__PURE__ */ jsx("p", { className: "mt-4 text-sm text-muted-foreground", children: heroDescription })
|
|
317
|
+
] }),
|
|
318
|
+
/* @__PURE__ */ jsxs("form", { onSubmit: handleSubmit(onSubmit), className: "space-y-5", children: [
|
|
319
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
320
|
+
/* @__PURE__ */ jsx(Label, { htmlFor: "waitlist-name", children: "Name *" }),
|
|
321
|
+
/* @__PURE__ */ jsx(
|
|
322
|
+
Input,
|
|
323
|
+
{
|
|
324
|
+
id: "waitlist-name",
|
|
325
|
+
type: "text",
|
|
326
|
+
placeholder: "Your name",
|
|
327
|
+
disabled: isSubmitting || isLimited,
|
|
328
|
+
...register("name")
|
|
329
|
+
}
|
|
330
|
+
),
|
|
331
|
+
errors.name && /* @__PURE__ */ jsx("p", { className: "text-sm text-destructive", children: errors.name.message })
|
|
332
|
+
] }),
|
|
333
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
334
|
+
/* @__PURE__ */ jsx(Label, { htmlFor: "waitlist-email", children: "Email *" }),
|
|
335
|
+
/* @__PURE__ */ jsx(
|
|
336
|
+
Input,
|
|
337
|
+
{
|
|
338
|
+
id: "waitlist-email",
|
|
339
|
+
type: "email",
|
|
340
|
+
placeholder: "you@example.com",
|
|
341
|
+
disabled: isSubmitting || isLimited,
|
|
342
|
+
...register("email")
|
|
343
|
+
}
|
|
344
|
+
),
|
|
345
|
+
errors.email && /* @__PURE__ */ jsx("p", { className: "text-sm text-destructive", children: errors.email.message })
|
|
346
|
+
] }),
|
|
347
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
348
|
+
/* @__PURE__ */ jsx(Label, { htmlFor: "waitlist-company", children: "Company" }),
|
|
349
|
+
/* @__PURE__ */ jsx(
|
|
350
|
+
Input,
|
|
351
|
+
{
|
|
352
|
+
id: "waitlist-company",
|
|
353
|
+
type: "text",
|
|
354
|
+
placeholder: "Your company (optional)",
|
|
355
|
+
disabled: isSubmitting || isLimited,
|
|
356
|
+
...register("company")
|
|
357
|
+
}
|
|
358
|
+
)
|
|
359
|
+
] }),
|
|
360
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
361
|
+
/* @__PURE__ */ jsx(Label, { htmlFor: "waitlist-reason", children: "Why are you interested?" }),
|
|
362
|
+
/* @__PURE__ */ jsx(
|
|
363
|
+
Textarea,
|
|
364
|
+
{
|
|
365
|
+
id: "waitlist-reason",
|
|
366
|
+
placeholder: "Tell us what excites you about the product (optional)",
|
|
367
|
+
rows: 3,
|
|
368
|
+
disabled: isSubmitting || isLimited,
|
|
369
|
+
className: "resize-y",
|
|
370
|
+
...register("reason")
|
|
371
|
+
}
|
|
372
|
+
)
|
|
373
|
+
] }),
|
|
374
|
+
/* @__PURE__ */ jsx(
|
|
375
|
+
Button,
|
|
376
|
+
{
|
|
377
|
+
type: "submit",
|
|
378
|
+
className: "w-full",
|
|
379
|
+
disabled: isSubmitting || isLimited,
|
|
380
|
+
children: isSubmitting ? "Joining..." : "Join Waitlist"
|
|
381
|
+
}
|
|
382
|
+
),
|
|
383
|
+
isLimited && resetTime && /* @__PURE__ */ jsxs("p", { className: "text-sm text-muted-foreground text-center", children: [
|
|
384
|
+
"Rate limit reached. Try again after",
|
|
385
|
+
" ",
|
|
386
|
+
resetTime.toLocaleTimeString()
|
|
387
|
+
] })
|
|
388
|
+
] }),
|
|
389
|
+
/* @__PURE__ */ jsxs("p", { className: "text-xs text-muted-foreground text-center", children: [
|
|
390
|
+
"By joining the waitlist, you agree to receive updates from",
|
|
391
|
+
" ",
|
|
392
|
+
displayName,
|
|
393
|
+
". We respect your privacy and will never share your information."
|
|
394
|
+
] })
|
|
395
|
+
] }) }) })
|
|
396
|
+
] });
|
|
397
|
+
}
|
|
398
|
+
function WaitlistForm({
|
|
399
|
+
variant = "inline",
|
|
400
|
+
showLabel = false,
|
|
401
|
+
showDescription = false,
|
|
402
|
+
showNameField = false,
|
|
403
|
+
description = "Join our waitlist to get early access",
|
|
404
|
+
buttonText = "Join Waitlist",
|
|
405
|
+
className = ""
|
|
406
|
+
}) {
|
|
407
|
+
const client = useWebSDK();
|
|
408
|
+
const config = useWebSDKConfig();
|
|
409
|
+
const {
|
|
410
|
+
product,
|
|
411
|
+
loading: productLoading,
|
|
412
|
+
error: productError,
|
|
413
|
+
hasProvider
|
|
414
|
+
} = useProduct();
|
|
415
|
+
const productStatus = product?.status;
|
|
416
|
+
const canCheckStatus = Boolean(config.productSlug);
|
|
417
|
+
const [email, setEmail] = useState("");
|
|
418
|
+
const [name, setName] = useState("");
|
|
419
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
420
|
+
const handleSubmit = async (e) => {
|
|
421
|
+
e.preventDefault();
|
|
422
|
+
if (canCheckStatus && productStatus !== "WAITLIST") {
|
|
423
|
+
toast.error("This product is not accepting waitlist signups right now.");
|
|
424
|
+
return;
|
|
425
|
+
}
|
|
426
|
+
if (!email || !email.includes("@")) {
|
|
427
|
+
toast.error("Please enter a valid email address");
|
|
428
|
+
return;
|
|
429
|
+
}
|
|
430
|
+
setIsLoading(true);
|
|
431
|
+
try {
|
|
432
|
+
const result = await joinWaitlist(
|
|
433
|
+
client,
|
|
434
|
+
{ email, name: name || void 0 },
|
|
435
|
+
product?.id || config.productId
|
|
436
|
+
);
|
|
437
|
+
if (result.success) {
|
|
438
|
+
trackWebsiteEvent("waitlist.signed_up", { form: "inline" });
|
|
439
|
+
toast.success(result.message ?? "You have been added to the waitlist!");
|
|
440
|
+
setEmail("");
|
|
441
|
+
setName("");
|
|
442
|
+
} else {
|
|
443
|
+
toast.error(result.message ?? "Failed to join waitlist");
|
|
444
|
+
}
|
|
445
|
+
} catch (_error) {
|
|
446
|
+
toast.error("An error occurred. Please try again.");
|
|
447
|
+
} finally {
|
|
448
|
+
setIsLoading(false);
|
|
449
|
+
}
|
|
450
|
+
};
|
|
451
|
+
const isInline = variant === "inline";
|
|
452
|
+
if (canCheckStatus && !hasProvider) {
|
|
453
|
+
return /* @__PURE__ */ jsxs("div", { className, children: [
|
|
454
|
+
showDescription && /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground mb-3", children: description }),
|
|
455
|
+
/* @__PURE__ */ jsxs("p", { className: "text-sm text-muted-foreground", children: [
|
|
456
|
+
"Product status checks require ",
|
|
457
|
+
/* @__PURE__ */ jsx("code", { children: "ProductProvider" }),
|
|
458
|
+
" to be mounted."
|
|
459
|
+
] })
|
|
460
|
+
] });
|
|
461
|
+
}
|
|
462
|
+
if (canCheckStatus && productLoading) {
|
|
463
|
+
return /* @__PURE__ */ jsxs("div", { className, children: [
|
|
464
|
+
showDescription && /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground mb-3", children: description }),
|
|
465
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: "Loading waitlist\u2026" })
|
|
466
|
+
] });
|
|
467
|
+
}
|
|
468
|
+
if (canCheckStatus && (productError || productStatus !== "WAITLIST")) {
|
|
469
|
+
return /* @__PURE__ */ jsxs("div", { className, children: [
|
|
470
|
+
showDescription && /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground mb-3", children: description }),
|
|
471
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: "Waitlist signups are not available right now." })
|
|
472
|
+
] });
|
|
473
|
+
}
|
|
474
|
+
return /* @__PURE__ */ jsxs("div", { className, children: [
|
|
475
|
+
showDescription && /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground mb-3", children: description }),
|
|
476
|
+
/* @__PURE__ */ jsxs(
|
|
477
|
+
"form",
|
|
478
|
+
{
|
|
479
|
+
onSubmit: handleSubmit,
|
|
480
|
+
className: isInline ? "flex gap-2" : "flex flex-col gap-2",
|
|
481
|
+
children: [
|
|
482
|
+
showNameField && /* @__PURE__ */ jsxs("div", { className: isInline ? "flex-1" : "w-full", children: [
|
|
483
|
+
showLabel && /* @__PURE__ */ jsx(
|
|
484
|
+
Label,
|
|
485
|
+
{
|
|
486
|
+
htmlFor: "waitlist-inline-name",
|
|
487
|
+
className: "text-sm mb-1 block",
|
|
488
|
+
children: "Name"
|
|
489
|
+
}
|
|
490
|
+
),
|
|
491
|
+
/* @__PURE__ */ jsx(
|
|
492
|
+
Input,
|
|
493
|
+
{
|
|
494
|
+
id: "waitlist-inline-name",
|
|
495
|
+
type: "text",
|
|
496
|
+
placeholder: "Your name",
|
|
497
|
+
value: name,
|
|
498
|
+
onChange: (e) => setName(e.target.value),
|
|
499
|
+
disabled: isLoading,
|
|
500
|
+
className: "w-full"
|
|
501
|
+
}
|
|
502
|
+
)
|
|
503
|
+
] }),
|
|
504
|
+
/* @__PURE__ */ jsxs("div", { className: isInline ? "flex-1" : "w-full", children: [
|
|
505
|
+
showLabel && /* @__PURE__ */ jsx(
|
|
506
|
+
Label,
|
|
507
|
+
{
|
|
508
|
+
htmlFor: "waitlist-inline-email",
|
|
509
|
+
className: "text-sm mb-1 block",
|
|
510
|
+
children: "Email"
|
|
511
|
+
}
|
|
512
|
+
),
|
|
513
|
+
/* @__PURE__ */ jsx(
|
|
514
|
+
Input,
|
|
515
|
+
{
|
|
516
|
+
id: "waitlist-inline-email",
|
|
517
|
+
type: "email",
|
|
518
|
+
placeholder: "Enter your email",
|
|
519
|
+
value: email,
|
|
520
|
+
onChange: (e) => setEmail(e.target.value),
|
|
521
|
+
disabled: isLoading,
|
|
522
|
+
required: true,
|
|
523
|
+
className: "w-full"
|
|
524
|
+
}
|
|
525
|
+
)
|
|
526
|
+
] }),
|
|
527
|
+
/* @__PURE__ */ jsx(
|
|
528
|
+
Button,
|
|
529
|
+
{
|
|
530
|
+
type: "submit",
|
|
531
|
+
disabled: isLoading,
|
|
532
|
+
className: isInline ? "whitespace-nowrap" : "w-full",
|
|
533
|
+
children: isLoading ? "Joining..." : buttonText
|
|
534
|
+
}
|
|
535
|
+
)
|
|
536
|
+
]
|
|
537
|
+
}
|
|
538
|
+
)
|
|
539
|
+
] });
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
export { WaitlistForm, WaitlistPage };
|
|
543
|
+
//# sourceMappingURL=chunk-RUMGFI6L.mjs.map
|
|
544
|
+
//# sourceMappingURL=chunk-RUMGFI6L.mjs.map
|