@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.
Files changed (276) hide show
  1. package/README.md +42 -8
  2. package/dist/analytics/index.js +19 -69
  3. package/dist/analytics/index.js.map +1 -1
  4. package/dist/analytics/index.mjs +3 -69
  5. package/dist/analytics/index.mjs.map +1 -1
  6. package/dist/avatar-live/index.js +1 -0
  7. package/dist/avatar-live/index.js.map +1 -1
  8. package/dist/avatar-live/index.mjs +1 -0
  9. package/dist/avatar-live/index.mjs.map +1 -1
  10. package/dist/avatar-live-view/index.js +10 -30
  11. package/dist/avatar-live-view/index.js.map +1 -1
  12. package/dist/avatar-live-view/index.mjs +4 -24
  13. package/dist/avatar-live-view/index.mjs.map +1 -1
  14. package/dist/chunk-23H4JUL4.js +41 -0
  15. package/dist/chunk-23H4JUL4.js.map +1 -0
  16. package/dist/chunk-34RX5P75.mjs +25 -0
  17. package/dist/chunk-34RX5P75.mjs.map +1 -0
  18. package/dist/chunk-3LFFY7AZ.js +184 -0
  19. package/dist/chunk-3LFFY7AZ.js.map +1 -0
  20. package/dist/chunk-3X26GE4S.js +2794 -0
  21. package/dist/chunk-3X26GE4S.js.map +1 -0
  22. package/dist/chunk-45GCA4GG.js +85 -0
  23. package/dist/chunk-45GCA4GG.js.map +1 -0
  24. package/dist/chunk-4SAGVLHN.js +876 -0
  25. package/dist/chunk-4SAGVLHN.js.map +1 -0
  26. package/dist/chunk-4U6YAII5.js +218 -0
  27. package/dist/chunk-4U6YAII5.js.map +1 -0
  28. package/dist/chunk-5GMTBOO6.js +21 -0
  29. package/dist/chunk-5GMTBOO6.js.map +1 -0
  30. package/dist/chunk-5JRJ57CL.mjs +329 -0
  31. package/dist/chunk-5JRJ57CL.mjs.map +1 -0
  32. package/dist/chunk-6C2DKIC7.js +4 -0
  33. package/dist/chunk-6C2DKIC7.js.map +1 -0
  34. package/dist/chunk-6IBFBWC5.mjs +17 -0
  35. package/dist/chunk-6IBFBWC5.mjs.map +1 -0
  36. package/dist/chunk-6KY2ZRVI.js +116 -0
  37. package/dist/chunk-6KY2ZRVI.js.map +1 -0
  38. package/dist/chunk-6VJT3SM4.mjs +182 -0
  39. package/dist/chunk-6VJT3SM4.mjs.map +1 -0
  40. package/dist/chunk-6YZUFMK2.mjs +40 -0
  41. package/dist/chunk-6YZUFMK2.mjs.map +1 -0
  42. package/dist/chunk-7A6R7CGG.js +47 -0
  43. package/dist/chunk-7A6R7CGG.js.map +1 -0
  44. package/dist/chunk-7PWL4V2R.js +4 -0
  45. package/dist/chunk-7PWL4V2R.js.map +1 -0
  46. package/dist/chunk-AA33WDYS.js +161 -0
  47. package/dist/chunk-AA33WDYS.js.map +1 -0
  48. package/dist/chunk-AHRGFXV2.js +525 -0
  49. package/dist/chunk-AHRGFXV2.js.map +1 -0
  50. package/dist/chunk-B63XLDZH.mjs +109 -0
  51. package/dist/chunk-B63XLDZH.mjs.map +1 -0
  52. package/dist/chunk-BX2USEWF.mjs +35 -0
  53. package/dist/chunk-BX2USEWF.mjs.map +1 -0
  54. package/dist/chunk-BYSZT35R.js +150 -0
  55. package/dist/chunk-BYSZT35R.js.map +1 -0
  56. package/dist/chunk-C6OJIHNO.js +12 -0
  57. package/dist/chunk-C6OJIHNO.js.map +1 -0
  58. package/dist/chunk-COOELBX7.mjs +63 -0
  59. package/dist/chunk-COOELBX7.mjs.map +1 -0
  60. package/dist/chunk-D2TW7MNC.mjs +2771 -0
  61. package/dist/chunk-D2TW7MNC.mjs.map +1 -0
  62. package/dist/chunk-D5KEZ6V6.mjs +3 -0
  63. package/dist/chunk-D5KEZ6V6.mjs.map +1 -0
  64. package/dist/chunk-E3GUGJMY.js +46 -0
  65. package/dist/chunk-E3GUGJMY.js.map +1 -0
  66. package/dist/chunk-EBZ2HGJ2.mjs +52 -0
  67. package/dist/chunk-EBZ2HGJ2.mjs.map +1 -0
  68. package/dist/chunk-EDLTUOIA.mjs +210 -0
  69. package/dist/chunk-EDLTUOIA.mjs.map +1 -0
  70. package/dist/chunk-EJQSOT4X.js +4 -0
  71. package/dist/chunk-EJQSOT4X.js.map +1 -0
  72. package/dist/chunk-EUPFS6MZ.mjs +2019 -0
  73. package/dist/chunk-EUPFS6MZ.mjs.map +1 -0
  74. package/dist/chunk-F3XWDC3B.js +77 -0
  75. package/dist/chunk-F3XWDC3B.js.map +1 -0
  76. package/dist/chunk-FFADMVIK.mjs +5127 -0
  77. package/dist/chunk-FFADMVIK.mjs.map +1 -0
  78. package/dist/chunk-FJWS7BKT.mjs +3 -0
  79. package/dist/chunk-FJWS7BKT.mjs.map +1 -0
  80. package/dist/chunk-FJZJDUOR.mjs +3 -0
  81. package/dist/chunk-FJZJDUOR.mjs.map +1 -0
  82. package/dist/chunk-GCFLCO2Z.mjs +145 -0
  83. package/dist/chunk-GCFLCO2Z.mjs.map +1 -0
  84. package/dist/chunk-GEXC4LRP.js +61 -0
  85. package/dist/chunk-GEXC4LRP.js.map +1 -0
  86. package/dist/chunk-GTRAXQGC.mjs +3 -0
  87. package/dist/chunk-GTRAXQGC.mjs.map +1 -0
  88. package/dist/chunk-IKOIRUKW.js +270 -0
  89. package/dist/chunk-IKOIRUKW.js.map +1 -0
  90. package/dist/chunk-IXTWOPRN.js +45 -0
  91. package/dist/chunk-IXTWOPRN.js.map +1 -0
  92. package/dist/chunk-JDXOXGOK.js +547 -0
  93. package/dist/chunk-JDXOXGOK.js.map +1 -0
  94. package/dist/chunk-JSLDWYV7.mjs +558 -0
  95. package/dist/chunk-JSLDWYV7.mjs.map +1 -0
  96. package/dist/chunk-JXLSTVBK.js +336 -0
  97. package/dist/chunk-JXLSTVBK.js.map +1 -0
  98. package/dist/chunk-KHYXK7FG.mjs +49 -0
  99. package/dist/chunk-KHYXK7FG.mjs.map +1 -0
  100. package/dist/chunk-KSMBOWQQ.js +2034 -0
  101. package/dist/chunk-KSMBOWQQ.js.map +1 -0
  102. package/dist/chunk-KU2PXHGB.mjs +83 -0
  103. package/dist/chunk-KU2PXHGB.mjs.map +1 -0
  104. package/dist/chunk-KZANIV3S.mjs +37 -0
  105. package/dist/chunk-KZANIV3S.mjs.map +1 -0
  106. package/dist/chunk-L4BP6YOB.js +20 -0
  107. package/dist/chunk-L4BP6YOB.js.map +1 -0
  108. package/dist/chunk-MRKA2OAF.mjs +75 -0
  109. package/dist/chunk-MRKA2OAF.mjs.map +1 -0
  110. package/dist/chunk-N5EC53MH.mjs +80 -0
  111. package/dist/chunk-N5EC53MH.mjs.map +1 -0
  112. package/dist/chunk-NZANQGDM.mjs +34 -0
  113. package/dist/chunk-NZANQGDM.mjs.map +1 -0
  114. package/dist/chunk-O4GS3XPZ.js +10 -0
  115. package/dist/chunk-O4GS3XPZ.js.map +1 -0
  116. package/dist/chunk-O76QDGRM.js +5154 -0
  117. package/dist/chunk-O76QDGRM.js.map +1 -0
  118. package/dist/chunk-OYEUNZJY.js +114 -0
  119. package/dist/chunk-OYEUNZJY.js.map +1 -0
  120. package/dist/chunk-PHXAGQNB.js +74 -0
  121. package/dist/chunk-PHXAGQNB.js.map +1 -0
  122. package/dist/chunk-PIHHPP7J.mjs +16 -0
  123. package/dist/chunk-PIHHPP7J.mjs.map +1 -0
  124. package/dist/chunk-PXRHVVOU.mjs +499 -0
  125. package/dist/chunk-PXRHVVOU.mjs.map +1 -0
  126. package/dist/chunk-QMA6U6AU.js +36 -0
  127. package/dist/chunk-QMA6U6AU.js.map +1 -0
  128. package/dist/chunk-R6J7IULF.js +44 -0
  129. package/dist/chunk-R6J7IULF.js.map +1 -0
  130. package/dist/chunk-R7G6TWIS.mjs +10 -0
  131. package/dist/chunk-R7G6TWIS.mjs.map +1 -0
  132. package/dist/chunk-RUMGFI6L.mjs +544 -0
  133. package/dist/chunk-RUMGFI6L.mjs.map +1 -0
  134. package/dist/chunk-S54JWSJF.js +565 -0
  135. package/dist/chunk-S54JWSJF.js.map +1 -0
  136. package/dist/chunk-SK5UGG6A.js +2041 -0
  137. package/dist/chunk-SK5UGG6A.js.map +1 -0
  138. package/dist/chunk-SKIYDKIS.mjs +70 -0
  139. package/dist/chunk-SKIYDKIS.mjs.map +1 -0
  140. package/dist/chunk-SZNS5IK6.mjs +322 -0
  141. package/dist/chunk-SZNS5IK6.mjs.map +1 -0
  142. package/dist/chunk-T7JIPZAC.js +66 -0
  143. package/dist/chunk-T7JIPZAC.js.map +1 -0
  144. package/dist/chunk-TGYQHO2E.mjs +864 -0
  145. package/dist/chunk-TGYQHO2E.mjs.map +1 -0
  146. package/dist/chunk-TT3MHN42.mjs +8 -0
  147. package/dist/chunk-TT3MHN42.mjs.map +1 -0
  148. package/dist/chunk-UM55U65W.mjs +268 -0
  149. package/dist/chunk-UM55U65W.mjs.map +1 -0
  150. package/dist/chunk-UQ2HALUD.js +72 -0
  151. package/dist/chunk-UQ2HALUD.js.map +1 -0
  152. package/dist/chunk-UXWT7G77.js +82 -0
  153. package/dist/chunk-UXWT7G77.js.map +1 -0
  154. package/dist/chunk-VNS5WDWO.mjs +7 -0
  155. package/dist/chunk-VNS5WDWO.mjs.map +1 -0
  156. package/dist/chunk-VRWZLGR7.js +4 -0
  157. package/dist/chunk-VRWZLGR7.js.map +1 -0
  158. package/dist/chunk-VZLDSNH4.mjs +22 -0
  159. package/dist/chunk-VZLDSNH4.mjs.map +1 -0
  160. package/dist/chunk-W6P3YETJ.js +92 -0
  161. package/dist/chunk-W6P3YETJ.js.map +1 -0
  162. package/dist/chunk-WPKFFQCR.mjs +90 -0
  163. package/dist/chunk-WPKFFQCR.mjs.map +1 -0
  164. package/dist/chunk-WTVTI5TO.mjs +22 -0
  165. package/dist/chunk-WTVTI5TO.mjs.map +1 -0
  166. package/dist/chunk-XJOBZ4RJ.js +44 -0
  167. package/dist/chunk-XJOBZ4RJ.js.map +1 -0
  168. package/dist/chunk-XP2JDNDU.js +325 -0
  169. package/dist/chunk-XP2JDNDU.js.map +1 -0
  170. package/dist/chunk-Y4V5CEWD.mjs +112 -0
  171. package/dist/chunk-Y4V5CEWD.mjs.map +1 -0
  172. package/dist/chunk-YERN2UWM.js +116 -0
  173. package/dist/chunk-YERN2UWM.js.map +1 -0
  174. package/dist/chunk-ZKJQWFAA.mjs +114 -0
  175. package/dist/chunk-ZKJQWFAA.mjs.map +1 -0
  176. package/dist/chunk-ZOON3S3Y.mjs +138 -0
  177. package/dist/chunk-ZOON3S3Y.mjs.map +1 -0
  178. package/dist/chunk-ZP6QRAYC.mjs +2024 -0
  179. package/dist/chunk-ZP6QRAYC.mjs.map +1 -0
  180. package/dist/chunk-ZSTFX7FV.js +9 -0
  181. package/dist/chunk-ZSTFX7FV.js.map +1 -0
  182. package/dist/client/index.js +23 -331
  183. package/dist/client/index.js.map +1 -1
  184. package/dist/client/index.mjs +3 -330
  185. package/dist/client/index.mjs.map +1 -1
  186. package/dist/comparison/index.js +28 -111
  187. package/dist/comparison/index.js.map +1 -1
  188. package/dist/comparison/index.mjs +2 -107
  189. package/dist/comparison/index.mjs.map +1 -1
  190. package/dist/components/contact.js +21 -931
  191. package/dist/components/contact.js.map +1 -1
  192. package/dist/components/contact.mjs +12 -909
  193. package/dist/components/contact.mjs.map +1 -1
  194. package/dist/components/electron-download.js +12 -124
  195. package/dist/components/electron-download.js.map +1 -1
  196. package/dist/components/electron-download.mjs +4 -106
  197. package/dist/components/electron-download.mjs.map +1 -1
  198. package/dist/components/explore-cta.js +8 -112
  199. package/dist/components/explore-cta.js.map +1 -1
  200. package/dist/components/explore-cta.mjs +3 -114
  201. package/dist/components/explore-cta.mjs.map +1 -1
  202. package/dist/components/explore.js +62 -7833
  203. package/dist/components/explore.js.map +1 -1
  204. package/dist/components/explore.mjs +13 -7800
  205. package/dist/components/explore.mjs.map +1 -1
  206. package/dist/components/launch-countdown.js +8 -83
  207. package/dist/components/launch-countdown.js.map +1 -1
  208. package/dist/components/launch-countdown.mjs +3 -85
  209. package/dist/components/launch-countdown.mjs.map +1 -1
  210. package/dist/components/newsletter.js +20 -993
  211. package/dist/components/newsletter.js.map +1 -1
  212. package/dist/components/newsletter.mjs +11 -971
  213. package/dist/components/newsletter.mjs.map +1 -1
  214. package/dist/components/partners.js +24 -1302
  215. package/dist/components/partners.js.map +1 -1
  216. package/dist/components/partners.mjs +15 -1276
  217. package/dist/components/partners.mjs.map +1 -1
  218. package/dist/components/pricing.js +49 -1249
  219. package/dist/components/pricing.js.map +1 -1
  220. package/dist/components/pricing.mjs +8 -1226
  221. package/dist/components/pricing.mjs.map +1 -1
  222. package/dist/components/problems-solved.js +8 -150
  223. package/dist/components/problems-solved.js.map +1 -1
  224. package/dist/components/problems-solved.mjs +4 -133
  225. package/dist/components/problems-solved.mjs.map +1 -1
  226. package/dist/components/resource-links.js +8 -304
  227. package/dist/components/resource-links.js.map +1 -1
  228. package/dist/components/resource-links.mjs +5 -308
  229. package/dist/components/resource-links.mjs.map +1 -1
  230. package/dist/components/social-links.js +8 -343
  231. package/dist/components/social-links.js.map +1 -1
  232. package/dist/components/social-links.mjs +5 -347
  233. package/dist/components/social-links.mjs.map +1 -1
  234. package/dist/components/unsubscribe.js +10 -627
  235. package/dist/components/unsubscribe.js.map +1 -1
  236. package/dist/components/unsubscribe.mjs +6 -611
  237. package/dist/components/unsubscribe.mjs.map +1 -1
  238. package/dist/components/waitlist.js +21 -1001
  239. package/dist/components/waitlist.js.map +1 -1
  240. package/dist/components/waitlist.mjs +12 -982
  241. package/dist/components/waitlist.mjs.map +1 -1
  242. package/dist/components/website-switcher.js +12 -175
  243. package/dist/components/website-switcher.js.map +1 -1
  244. package/dist/components/website-switcher.mjs +4 -157
  245. package/dist/components/website-switcher.mjs.map +1 -1
  246. package/dist/content/index.js +118 -3616
  247. package/dist/content/index.js.map +1 -1
  248. package/dist/content/index.mjs +12 -3567
  249. package/dist/content/index.mjs.map +1 -1
  250. package/dist/hooks/index.js +37 -2321
  251. package/dist/hooks/index.js.map +1 -1
  252. package/dist/hooks/index.mjs +6 -2318
  253. package/dist/hooks/index.mjs.map +1 -1
  254. package/dist/index.d.mts +1 -1
  255. package/dist/index.d.ts +1 -1
  256. package/dist/index.js +4145 -20599
  257. package/dist/index.js.map +1 -1
  258. package/dist/index.mjs +3766 -20567
  259. package/dist/index.mjs.map +1 -1
  260. package/dist/product/index.js +20 -393
  261. package/dist/product/index.js.map +1 -1
  262. package/dist/product/index.mjs +5 -394
  263. package/dist/product/index.mjs.map +1 -1
  264. package/dist/seo/index.js +8 -76
  265. package/dist/seo/index.js.map +1 -1
  266. package/dist/seo/index.mjs +3 -78
  267. package/dist/seo/index.mjs.map +1 -1
  268. package/dist/store/index.js +51 -2650
  269. package/dist/store/index.js.map +1 -1
  270. package/dist/store/index.mjs +13 -2619
  271. package/dist/store/index.mjs.map +1 -1
  272. package/dist/utils/index.js +69 -134
  273. package/dist/utils/index.js.map +1 -1
  274. package/dist/utils/index.mjs +5 -122
  275. package/dist/utils/index.mjs.map +1 -1
  276. package/package.json +2 -1
@@ -1,937 +1,27 @@
1
1
  'use strict';
2
2
 
3
- var React = require('react');
4
- var lucideReact = require('lucide-react');
5
- var ReCAPTCHA = require('react-google-recaptcha');
6
- var sonner = require('sonner');
7
- var jsxRuntime = require('react/jsx-runtime');
8
- var reactHelmetAsync = require('react-helmet-async');
9
- var reactSlot = require('@radix-ui/react-slot');
10
- var classVarianceAuthority = require('class-variance-authority');
11
- var clsx = require('clsx');
12
- var tailwindMerge = require('tailwind-merge');
13
- var LabelPrimitive = require('@radix-ui/react-label');
14
-
15
- function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
16
-
17
- function _interopNamespace(e) {
18
- if (e && e.__esModule) return e;
19
- var n = Object.create(null);
20
- if (e) {
21
- Object.keys(e).forEach(function (k) {
22
- if (k !== 'default') {
23
- var d = Object.getOwnPropertyDescriptor(e, k);
24
- Object.defineProperty(n, k, d.get ? d : {
25
- enumerable: true,
26
- get: function () { return e[k]; }
27
- });
28
- }
29
- });
30
- }
31
- n.default = e;
32
- return Object.freeze(n);
33
- }
34
-
35
- var React__namespace = /*#__PURE__*/_interopNamespace(React);
36
- var ReCAPTCHA__default = /*#__PURE__*/_interopDefault(ReCAPTCHA);
37
- var LabelPrimitive__namespace = /*#__PURE__*/_interopNamespace(LabelPrimitive);
38
-
39
- var __defProp = Object.defineProperty;
40
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
41
- var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
42
-
43
- // src/client/security.ts
44
- var LOOPBACK_HOSTS = /* @__PURE__ */ new Set(["localhost", "127.0.0.1", "::1"]);
45
- var RESERVED_HEADERS = /* @__PURE__ */ new Set([
46
- "authorization",
47
- "cookie",
48
- "x-actor-id",
49
- "x-actor-type",
50
- "x-consent-granted-by",
51
- "x-consent-scope",
52
- "x-consent-granted-at",
53
- "x-consent-expires-at"
54
- ]);
55
- function validateGatewayUrl(value) {
56
- let url;
57
- try {
58
- url = new URL(value);
59
- } catch {
60
- throw new Error("Gateway URL must be a valid absolute URL");
61
- }
62
- if (url.protocol === "https:") {
63
- return url.toString();
64
- }
65
- if (url.protocol === "http:" && LOOPBACK_HOSTS.has(url.hostname.toLowerCase())) {
66
- return url.toString();
67
- }
68
- throw new Error("Gateway URL must use HTTPS unless it targets localhost");
69
- }
70
- function sanitizeHeaders(headers) {
71
- if (!headers) return void 0;
72
- return Object.fromEntries(
73
- Object.entries(headers).filter(
74
- ([key]) => !RESERVED_HEADERS.has(key.toLowerCase())
75
- )
76
- );
77
- }
78
- var CF_ACCESS_GATED_HOSTS = /* @__PURE__ */ new Set([
79
- "alphagraphql.burdenoff.com",
80
- "alphagraphqlworkspaces.burdenoff.com"
81
- ]);
82
- function cfAccessHeaders(gatewayUrl, cfAccess) {
83
- const clientId = cfAccess?.clientId?.trim();
84
- const clientSecret = cfAccess?.clientSecret?.trim();
85
- if (!clientId || !clientSecret) return {};
86
- let host;
87
- try {
88
- host = new URL(gatewayUrl).hostname.toLowerCase();
89
- } catch {
90
- return {};
91
- }
92
- if (!CF_ACCESS_GATED_HOSTS.has(host)) return {};
93
- return {
94
- "CF-Access-Client-Id": clientId,
95
- "CF-Access-Client-Secret": clientSecret
96
- };
97
- }
98
-
99
- // src/client/graphql-client.ts
100
- var _WebSDKClient = class _WebSDKClient {
101
- constructor(config) {
102
- __publicField(this, "config");
103
- __publicField(this, "queryCache", /* @__PURE__ */ new Map());
104
- __publicField(this, "inflight", /* @__PURE__ */ new Map());
105
- this.config = {
106
- ...config,
107
- gatewayUrl: validateGatewayUrl(config.gatewayUrl),
108
- headers: sanitizeHeaders(config.headers)
109
- };
110
- }
111
- getConfig() {
112
- return this.config;
113
- }
114
- /**
115
- * Execute a GraphQL query (with deduplication and caching).
116
- *
117
- * Pass `{ cache: false }` to bypass the cache entirely — required for poll
118
- * loops, where every tick must reach the network.
119
- */
120
- async query(query, variables, options) {
121
- if (options?.cache === false) {
122
- return this.request(query, variables, true, options.timeoutMs);
123
- }
124
- const cacheKey = JSON.stringify({ query, variables });
125
- const cached = this.queryCache.get(cacheKey);
126
- if (cached) {
127
- if (Date.now() - cached.ts < _WebSDKClient.CACHE_TTL) {
128
- return cached.data;
129
- }
130
- this.queryCache.delete(cacheKey);
131
- }
132
- const existing = this.inflight.get(cacheKey);
133
- if (existing) {
134
- return existing;
135
- }
136
- const promise = this.request(query, variables, true, options?.timeoutMs).then((result) => {
137
- if (result.data && !result.errors?.length) {
138
- if (this.queryCache.size >= _WebSDKClient.MAX_CACHE_ENTRIES) {
139
- const oldestEntry = this.queryCache.keys().next().value;
140
- if (oldestEntry) {
141
- this.queryCache.delete(oldestEntry);
142
- }
143
- }
144
- this.queryCache.set(cacheKey, { data: result, ts: Date.now() });
145
- }
146
- return result;
147
- }).finally(() => {
148
- this.inflight.delete(cacheKey);
149
- });
150
- this.inflight.set(cacheKey, promise);
151
- return promise;
152
- }
153
- /**
154
- * Execute a GraphQL mutation
155
- */
156
- async mutate(mutation, variables, options) {
157
- return this.request(mutation, variables, false, options?.timeoutMs);
158
- }
159
- /** HTTP statuses worth another attempt — transient server/edge conditions. */
160
- static isRetriableStatus(status) {
161
- return status === 429 || status === 408 || status >= 500 && status < 600;
162
- }
163
- static sleep(ms) {
164
- return new Promise((resolve) => setTimeout(resolve, ms));
165
- }
166
- /**
167
- * Perform the HTTP call with a hard timeout. Every outcome resolves to a
168
- * GraphQLResponse — callers never hang, so a UI's `loading` state always
169
- * settles into data or a renderable error.
170
- */
171
- async attempt(query, variables, timeoutMs) {
172
- const controller = new AbortController();
173
- const timer = setTimeout(() => controller.abort(), timeoutMs);
174
- try {
175
- const response = await fetch(this.config.gatewayUrl, {
176
- method: "POST",
177
- headers: {
178
- "Content-Type": "application/json",
179
- "x-product-id": this.config.productId,
180
- ...this.config.headers,
181
- ...cfAccessHeaders(this.config.gatewayUrl, this.config.cfAccess)
182
- },
183
- body: JSON.stringify({ query, variables }),
184
- signal: controller.signal
185
- });
186
- if (!response.ok) {
187
- console.error(
188
- "[WebSDK] GraphQL request failed",
189
- response.status,
190
- response.statusText
191
- );
192
- return {
193
- res: {
194
- errors: [
195
- {
196
- message: `HTTP ${response.status}: ${response.statusText}`,
197
- extensions: { code: `HTTP_${response.status}` }
198
- }
199
- ]
200
- },
201
- retriable: _WebSDKClient.isRetriableStatus(response.status)
202
- };
203
- }
204
- return {
205
- res: await response.json(),
206
- retriable: false
207
- };
208
- } catch (error) {
209
- const aborted = error instanceof Error && (error.name === "AbortError" || controller.signal.aborted);
210
- const message = aborted ? `Request timed out after ${timeoutMs}ms` : error instanceof Error ? error.message : "Network error";
211
- console.error("[WebSDK] Network error", message);
212
- return {
213
- res: {
214
- errors: [
215
- {
216
- message,
217
- extensions: { code: aborted ? "TIMEOUT" : "NETWORK_ERROR" }
218
- }
219
- ]
220
- },
221
- // Transport-level failures are worth one more try; a genuine outage
222
- // just fails twice quickly and still renders an error state.
223
- retriable: true
224
- };
225
- } finally {
226
- clearTimeout(timer);
227
- }
228
- }
229
- async request(query, variables, retry = true, timeoutOverrideMs) {
230
- const timeoutMs = timeoutOverrideMs ?? this.config.timeoutMs ?? _WebSDKClient.DEFAULT_TIMEOUT_MS;
231
- const maxRetries = retry ? this.config.maxRetries ?? _WebSDKClient.DEFAULT_MAX_RETRIES : 0;
232
- let last;
233
- for (let i = 0; i <= maxRetries; i++) {
234
- const { res, retriable } = await this.attempt(
235
- query,
236
- variables,
237
- timeoutMs
238
- );
239
- if (!retriable || i === maxRetries) return res;
240
- last = res;
241
- await _WebSDKClient.sleep(
242
- _WebSDKClient.RETRY_BASE_DELAY_MS * (i + 1) + Math.random() * 200
243
- );
244
- }
245
- return last;
246
- }
247
- };
248
- __publicField(_WebSDKClient, "CACHE_TTL", 5 * 60 * 1e3);
249
- // 5 minutes
250
- __publicField(_WebSDKClient, "MAX_CACHE_ENTRIES", 100);
251
- __publicField(_WebSDKClient, "DEFAULT_TIMEOUT_MS", 12e3);
252
- __publicField(_WebSDKClient, "DEFAULT_MAX_RETRIES", 1);
253
- __publicField(_WebSDKClient, "RETRY_BASE_DELAY_MS", 400);
254
- var WebSDKContext = React.createContext(null);
255
- function useWebSDK() {
256
- const client = React.useContext(WebSDKContext);
257
- if (!client) {
258
- throw new Error("useWebSDK must be used within a WebSDKProvider");
259
- }
260
- return client;
261
- }
262
- function useWebSDKConfig() {
263
- const client = useWebSDK();
264
- return client.getConfig();
265
- }
266
- var RECAPTCHA_WIDGET_HEIGHT = 78;
267
- function useDeferredRecaptcha(siteKey) {
268
- const [engaged, setEngaged] = React.useState(false);
269
- const arm = React.useCallback(() => setEngaged(true), []);
270
- const enabled = siteKey.length > 0;
271
- return {
272
- armed: enabled && engaged,
273
- arm,
274
- formProps: enabled && !engaged ? { onFocus: arm, onPointerDown: arm } : {}
275
- };
276
- }
277
-
278
- // src/utils/product-slug.ts
279
- var PRODUCT_SLUG_RENAMES = Object.freeze(
280
- [Object.freeze({ legacy: "botlit", current: "botmanor" })]
281
- );
282
- Object.freeze(
283
- Object.fromEntries(PRODUCT_SLUG_RENAMES.map((r) => [r.legacy, r.current]))
284
- );
285
- var ProductContext = React.createContext({
286
- product: null,
287
- loading: true,
288
- error: null,
289
- hasProvider: false,
290
- refetch: () => {
291
- }
3
+ var chunkAHRGFXV2_js = require('../chunk-AHRGFXV2.js');
4
+ require('../chunk-L4BP6YOB.js');
5
+ require('../chunk-R6J7IULF.js');
6
+ require('../chunk-IXTWOPRN.js');
7
+ require('../chunk-7A6R7CGG.js');
8
+ require('../chunk-UXWT7G77.js');
9
+ require('../chunk-UQ2HALUD.js');
10
+ require('../chunk-C6OJIHNO.js');
11
+ require('../chunk-BYSZT35R.js');
12
+ require('../chunk-E3GUGJMY.js');
13
+ require('../chunk-JXLSTVBK.js');
14
+ require('../chunk-ZSTFX7FV.js');
15
+
16
+
17
+
18
+ Object.defineProperty(exports, "ContactPage", {
19
+ enumerable: true,
20
+ get: function () { return chunkAHRGFXV2_js.ContactPage; }
292
21
  });
293
- function useProduct() {
294
- return React.useContext(ProductContext);
295
- }
296
- function canonicalFromLocation() {
297
- if (typeof window === "undefined" || !window.location) return void 0;
298
- const { origin, pathname } = window.location;
299
- if (!origin || origin === "null") return void 0;
300
- const path = pathname === "/" ? "/" : pathname.replace(/\/+$/, "");
301
- return `${origin}${path}`;
302
- }
303
- function resolveImageUrl(image, base) {
304
- if (!image || /^https?:\/\//i.test(image)) return image;
305
- if (!base) return image;
306
- try {
307
- return new URL(image, base).toString();
308
- } catch {
309
- return image;
310
- }
311
- }
312
- function serializeJsonLd(data) {
313
- return JSON.stringify(data).replace(/</g, "\\u003c").replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029");
314
- }
315
- function PageHead({
316
- title,
317
- description,
318
- productName,
319
- keywords,
320
- image,
321
- url,
322
- favicon,
323
- robots = "index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1",
324
- locale = "en_US",
325
- twitterHandle,
326
- themeColor = "#000000",
327
- author,
328
- structuredData,
329
- additionalMeta
330
- }) {
331
- const fullTitle = productName && !title.includes(productName) ? `${title} | ${productName}` : title;
332
- const resolvedUrl = url ?? canonicalFromLocation();
333
- const fullImageUrl = resolveImageUrl(image, resolvedUrl);
334
- const structuredDataItems = structuredData ? Array.isArray(structuredData) ? structuredData : [structuredData] : [];
335
- return /* @__PURE__ */ jsxRuntime.jsxs(reactHelmetAsync.Helmet, { children: [
336
- /* @__PURE__ */ jsxRuntime.jsx("title", { children: fullTitle }),
337
- /* @__PURE__ */ jsxRuntime.jsx("meta", { name: "title", content: fullTitle }),
338
- description ? /* @__PURE__ */ jsxRuntime.jsx("meta", { name: "description", content: description }) : null,
339
- keywords ? /* @__PURE__ */ jsxRuntime.jsx("meta", { name: "keywords", content: keywords }) : null,
340
- author ? /* @__PURE__ */ jsxRuntime.jsx("meta", { name: "author", content: author }) : null,
341
- /* @__PURE__ */ jsxRuntime.jsx("meta", { name: "robots", content: robots }),
342
- resolvedUrl ? /* @__PURE__ */ jsxRuntime.jsx("link", { rel: "canonical", href: resolvedUrl }) : null,
343
- favicon ? /* @__PURE__ */ jsxRuntime.jsx("link", { rel: "icon", href: favicon }) : null,
344
- /* @__PURE__ */ jsxRuntime.jsx("meta", { property: "og:type", content: "website" }),
345
- /* @__PURE__ */ jsxRuntime.jsx("meta", { property: "og:title", content: fullTitle }),
346
- description ? /* @__PURE__ */ jsxRuntime.jsx("meta", { property: "og:description", content: description }) : null,
347
- fullImageUrl ? /* @__PURE__ */ jsxRuntime.jsx("meta", { property: "og:image", content: fullImageUrl }) : null,
348
- resolvedUrl ? /* @__PURE__ */ jsxRuntime.jsx("meta", { property: "og:url", content: resolvedUrl }) : null,
349
- /* @__PURE__ */ jsxRuntime.jsx("meta", { property: "og:locale", content: locale }),
350
- productName ? /* @__PURE__ */ jsxRuntime.jsx("meta", { property: "og:site_name", content: productName }) : null,
351
- /* @__PURE__ */ jsxRuntime.jsx("meta", { name: "twitter:card", content: "summary_large_image" }),
352
- /* @__PURE__ */ jsxRuntime.jsx("meta", { name: "twitter:title", content: fullTitle }),
353
- description ? /* @__PURE__ */ jsxRuntime.jsx("meta", { name: "twitter:description", content: description }) : null,
354
- fullImageUrl ? /* @__PURE__ */ jsxRuntime.jsx("meta", { name: "twitter:image", content: fullImageUrl }) : null,
355
- twitterHandle ? /* @__PURE__ */ jsxRuntime.jsx("meta", { name: "twitter:creator", content: twitterHandle }) : null,
356
- /* @__PURE__ */ jsxRuntime.jsx("meta", { name: "theme-color", content: themeColor }),
357
- structuredDataItems.map((data, index) => /* @__PURE__ */ jsxRuntime.jsx("script", { type: "application/ld+json", children: serializeJsonLd(data) }, `ld-${index}`)),
358
- additionalMeta?.map((meta, index) => /* @__PURE__ */ jsxRuntime.jsx(
359
- "meta",
360
- {
361
- ...meta.name ? { name: meta.name } : {},
362
- ...meta.property ? { property: meta.property } : {},
363
- content: meta.content
364
- },
365
- `meta-${index}`
366
- ))
367
- ] });
368
- }
369
- function cn(...inputs) {
370
- return tailwindMerge.twMerge(clsx.clsx(inputs));
371
- }
372
- var buttonVariants = classVarianceAuthority.cva(
373
- "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
374
- {
375
- variants: {
376
- variant: {
377
- default: "bg-primary text-primary-foreground shadow hover:bg-primary/90",
378
- destructive: "bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90",
379
- outline: "border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground",
380
- secondary: "bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80",
381
- ghost: "hover:bg-accent hover:text-accent-foreground",
382
- link: "text-primary underline-offset-4 hover:underline"
383
- },
384
- size: {
385
- default: "h-9 px-4 py-2",
386
- sm: "h-8 rounded-md px-3 text-xs",
387
- lg: "h-10 rounded-md px-8",
388
- icon: "h-9 w-9"
389
- }
390
- },
391
- defaultVariants: {
392
- variant: "default",
393
- size: "default"
394
- }
395
- }
396
- );
397
- var Button = React__namespace.forwardRef(
398
- ({ className, variant, size, asChild = false, ...props }, ref) => {
399
- const Comp = asChild ? reactSlot.Slot : "button";
400
- return /* @__PURE__ */ jsxRuntime.jsx(
401
- Comp,
402
- {
403
- className: cn(buttonVariants({ variant, size, className })),
404
- ref,
405
- ...props
406
- }
407
- );
408
- }
409
- );
410
- Button.displayName = "Button";
411
- var Input = React__namespace.forwardRef(
412
- ({ className, type, ...props }, ref) => {
413
- return /* @__PURE__ */ jsxRuntime.jsx(
414
- "input",
415
- {
416
- type,
417
- className: cn(
418
- "flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-base shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground 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",
419
- className
420
- ),
421
- ref,
422
- ...props
423
- }
424
- );
425
- }
426
- );
427
- Input.displayName = "Input";
428
- var labelVariants = classVarianceAuthority.cva(
429
- "text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
430
- );
431
- var Label = React__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
432
- LabelPrimitive__namespace.Root,
433
- {
434
- ref,
435
- className: cn(labelVariants(), className),
436
- ...props
437
- }
438
- ));
439
- Label.displayName = LabelPrimitive__namespace.Root.displayName;
440
- var Select = React__namespace.forwardRef(({ className, children, ...props }, ref) => {
441
- return /* @__PURE__ */ jsxRuntime.jsx(
442
- "select",
443
- {
444
- className: cn(
445
- "flex h-9 w-full appearance-none rounded-md border border-input bg-transparent bg-[length:1rem_1rem] bg-[right_0.75rem_center] bg-no-repeat px-3 py-1 pr-8 text-base shadow-sm transition-colors 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",
446
- // Inline SVG chevron: SVG inside a `background-image: url(data:…)`
447
- // does NOT inherit `currentColor` from the host element (the SVG is
448
- // its own document with no parent CSS context), so the stroke is
449
- // hardcoded to a muted slate-400 (#94a3b8). Matches the muted
450
- // foreground token visually in both light and dark themes well
451
- // enough for a passive chevron — addresses #9 review feedback.
452
- `bg-[url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%2394a3b8' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'/></svg>")]`,
453
- className
454
- ),
455
- ref,
456
- ...props,
457
- children
458
- }
459
- );
22
+ Object.defineProperty(exports, "DEFAULT_CONTACT_CATEGORIES", {
23
+ enumerable: true,
24
+ get: function () { return chunkAHRGFXV2_js.DEFAULT_CONTACT_CATEGORIES; }
460
25
  });
461
- Select.displayName = "Select";
462
- var Textarea = React__namespace.forwardRef(({ className, ...props }, ref) => {
463
- return /* @__PURE__ */ jsxRuntime.jsx(
464
- "textarea",
465
- {
466
- className: cn(
467
- "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",
468
- className
469
- ),
470
- ref,
471
- ...props
472
- }
473
- );
474
- });
475
- Textarea.displayName = "Textarea";
476
- var DEFAULT_CONTACT_CATEGORIES = [
477
- { value: "general", label: "General enquiry" },
478
- { value: "sales", label: "Sales" },
479
- { value: "support", label: "Support" },
480
- { value: "partnership", label: "Partnership" },
481
- { value: "press", label: "Press / media" },
482
- { value: "careers", label: "Careers" },
483
- { value: "security", label: "Security disclosure" }
484
- ];
485
- var SUBMIT_CONTACT_INQUIRY_MUTATION = (
486
- /* GraphQL */
487
- `
488
- mutation SubmitContactInquiry($input: SubmitContactInquiryInput!) {
489
- submitContactInquiry(input: $input) {
490
- success
491
- message
492
- }
493
- }
494
- `
495
- );
496
- async function submitContactForm(client, data, productId) {
497
- try {
498
- const result = await client.mutate(SUBMIT_CONTACT_INQUIRY_MUTATION, {
499
- input: {
500
- name: `${data.firstName} ${data.lastName}`,
501
- email: data.email.trim().toLowerCase(),
502
- company: data.company || void 0,
503
- subject: data.subject,
504
- message: data.message,
505
- productId,
506
- // Send `category` only when the user actually picked one. Older
507
- // backend deployments without the `category` field in the
508
- // `SubmitContactInquiryInput` schema would reject any unknown
509
- // field; spreading conditionally keeps the SDK forward-
510
- // compatible.
511
- ...data.category ? { category: data.category } : {},
512
- ...data.recaptchaToken ? { recaptchaToken: data.recaptchaToken } : {}
513
- }
514
- });
515
- if (result.errors?.length) {
516
- const errorMsg = result.errors[0]?.message ?? "Failed to send message";
517
- return { success: false, message: errorMsg };
518
- }
519
- const response = result.data?.submitContactInquiry;
520
- if (response?.success) {
521
- return {
522
- success: true,
523
- message: response.message || "Message sent successfully!"
524
- };
525
- }
526
- return {
527
- success: false,
528
- message: response?.message || "Failed to send message"
529
- };
530
- } catch (error) {
531
- console.error("Contact form submission error:", error);
532
- return {
533
- success: false,
534
- message: "Network error. Please try again."
535
- };
536
- }
537
- }
538
- function replacePlaceholders(text, productName, email) {
539
- return text.replace(/{productName}/g, productName).replace(/{email}/g, email);
540
- }
541
- function ContactPage({
542
- productName,
543
- recaptchaSiteKey,
544
- contactEmail,
545
- contactPhone,
546
- officeAddress,
547
- responseTime = "We typically respond within 24 hours",
548
- heroTitle = "Get in Touch",
549
- heroDescription = "Have questions about {productName}? We're here to help. Reach out to our team and we'll get back to you as soon as possible.",
550
- headingLevel = 1,
551
- // Backward-compatibility: default to `[]` so existing consumers
552
- // (fluidgrids/burdenoff/algoshred websites) that don't pass
553
- // `categories` continue to render with NO dropdown — same behavior
554
- // they had before this SDK version. To opt in, pass an explicit
555
- // `categories={…}` array (or the exported `DEFAULT_CONTACT_CATEGORIES`
556
- // constant for the sane Burdenoff-generic vocabulary).
557
- categories = [],
558
- categoryLabel = "Category",
559
- categoryPlaceholder = "Select a category",
560
- categoryRequired = true,
561
- additionalOptions = [
562
- {
563
- title: "Sales Inquiries",
564
- description: "Ready to see {productName} in action? Our sales team is here to help.",
565
- buttonText: "Contact Sales",
566
- buttonLink: `mailto:${contactEmail}`
567
- },
568
- {
569
- title: "Technical Support",
570
- description: "Need help with your {productName} setup? Our support team is ready.",
571
- buttonText: "Get Support",
572
- buttonLink: `mailto:${contactEmail}`
573
- },
574
- {
575
- title: "Partnership",
576
- description: "Interested in partnering with {productName}? Let's explore opportunities.",
577
- buttonText: "Partner With Us",
578
- buttonLink: `mailto:${contactEmail}`
579
- }
580
- ],
581
- seo
582
- }) {
583
- const client = useWebSDK();
584
- const config = useWebSDKConfig();
585
- const { product } = useProduct();
586
- const resolvedProductId = product?.id || config.productId;
587
- const displayName = productName ?? product?.name ?? config.productId;
588
- const effectiveRecaptchaSiteKey = recaptchaSiteKey ?? product?.recaptchaSiteKey ?? config.recaptchaSiteKey ?? "";
589
- const recaptchaRef = React.useRef(null);
590
- const recaptchaGate = useDeferredRecaptcha(effectiveRecaptchaSiteKey);
591
- const [isSubmitting, setIsSubmitting] = React.useState(false);
592
- const [submitStatus, setSubmitStatus] = React.useState("idle");
593
- const handleSubmit = async (e) => {
594
- e.preventDefault();
595
- const recaptchaToken = recaptchaRef.current?.getValue() ?? "";
596
- if (effectiveRecaptchaSiteKey && !recaptchaToken) {
597
- recaptchaGate.arm();
598
- sonner.toast.error("Please complete the reCAPTCHA verification");
599
- return;
600
- }
601
- setIsSubmitting(true);
602
- setSubmitStatus("idle");
603
- const form = e.currentTarget;
604
- try {
605
- const formData = new FormData(form);
606
- const showCategory = categories.length > 0;
607
- const rawCategory = showCategory ? (formData.get("category") ?? "").trim() : "";
608
- if (showCategory && categoryRequired && !rawCategory) {
609
- sonner.toast.error("Please select a category");
610
- setIsSubmitting(false);
611
- return;
612
- }
613
- const contactData = {
614
- firstName: formData.get("firstName"),
615
- lastName: formData.get("lastName"),
616
- email: formData.get("email"),
617
- company: formData.get("company"),
618
- category: rawCategory || void 0,
619
- subject: formData.get("subject"),
620
- message: formData.get("message"),
621
- recaptchaToken
622
- };
623
- const result = await submitContactForm(
624
- client,
625
- contactData,
626
- resolvedProductId
627
- );
628
- if (result.success) {
629
- setSubmitStatus("success");
630
- sonner.toast.success(
631
- result.message ?? `Thank you for contacting ${displayName}. We'll get back to you within 24 hours.`
632
- );
633
- if (form) {
634
- form.reset();
635
- }
636
- recaptchaRef.current?.reset();
637
- } else {
638
- setSubmitStatus("error");
639
- sonner.toast.error(
640
- result.message ?? "Failed to send message. Please try again."
641
- );
642
- recaptchaRef.current?.reset();
643
- }
644
- } catch (error) {
645
- console.error("Error submitting form:", error);
646
- setSubmitStatus("error");
647
- sonner.toast.error("Failed to send message. Please try again later.");
648
- recaptchaRef.current?.reset();
649
- } finally {
650
- setIsSubmitting(false);
651
- }
652
- };
653
- const heroDescriptionText = replacePlaceholders(
654
- heroDescription,
655
- displayName,
656
- contactEmail
657
- ).trim();
658
- const hasHero = heroTitle.trim() !== "" || heroDescriptionText !== "";
659
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-full", children: [
660
- seo && /* @__PURE__ */ jsxRuntime.jsx(
661
- PageHead,
662
- {
663
- title: seo.title ?? `Contact ${displayName} - Get in Touch With Our Team`,
664
- description: seo.description ?? `Ready to transform your business? Contact our team for sales inquiries, technical support, or partnership opportunities. We're here to help you succeed.`,
665
- productName: displayName,
666
- keywords: seo.keywords ?? `contact ${displayName.toLowerCase()}, sales inquiries, customer support, technical support, partnership opportunities, get in touch`,
667
- image: seo.image ?? "/og-image-contact.png",
668
- url: seo.url
669
- }
670
- ),
671
- hasHero && /* @__PURE__ */ jsxRuntime.jsx(
672
- "section",
673
- {
674
- className: headingLevel === 2 ? "py-12 md:py-16" : "bg-gradient-to-b from-background to-muted/20 py-12 sm:py-16 md:py-20 lg:py-24",
675
- children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "max-w-7xl mx-auto px-4 sm:px-6 lg:px-8", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-center max-w-3xl mx-auto", children: [
676
- !heroTitle.trim() ? null : headingLevel === 2 ? /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-2xl md:text-3xl font-bold mb-3", children: heroTitle }) : /* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-3xl sm:text-4xl md:text-5xl font-bold mb-4 sm:mb-6", children: heroTitle }),
677
- heroDescriptionText && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-lg sm:text-xl text-muted-foreground leading-relaxed", children: heroDescriptionText })
678
- ] }) })
679
- }
680
- ),
681
- /* @__PURE__ */ jsxRuntime.jsx("section", { className: "py-12 sm:py-16 md:py-20 lg:py-24", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "max-w-7xl mx-auto px-4 sm:px-6 lg:px-8", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid sm:grid-cols-1 lg:grid-cols-3 gap-8 sm:gap-10 lg:gap-12", children: [
682
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "lg:col-span-1 order-2 lg:order-1", children: [
683
- /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-xl sm:text-2xl font-bold mb-4 sm:mb-6", children: "Contact Information" }),
684
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-4 sm:space-y-6", children: [
685
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start space-x-3 sm:space-x-4", children: [
686
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-8 h-8 sm:w-10 sm:h-10 bg-primary/10 rounded-lg flex items-center justify-center flex-shrink-0", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Mail, { className: "h-4 w-4 sm:h-5 sm:w-5 text-primary" }) }),
687
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0 flex-1", children: [
688
- /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "font-semibold mb-1 text-sm sm:text-base", children: "Email" }),
689
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground text-sm sm:text-base break-all", children: contactEmail })
690
- ] })
691
- ] }),
692
- contactPhone && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start space-x-3 sm:space-x-4", children: [
693
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-8 h-8 sm:w-10 sm:h-10 bg-primary/10 rounded-lg flex items-center justify-center flex-shrink-0", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Phone, { className: "h-4 w-4 sm:h-5 sm:w-5 text-primary" }) }),
694
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0 flex-1", children: [
695
- /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "font-semibold mb-1 text-sm sm:text-base", children: "Phone" }),
696
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground text-sm sm:text-base", children: contactPhone })
697
- ] })
698
- ] }),
699
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start space-x-3 sm:space-x-4", children: [
700
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-8 h-8 sm:w-10 sm:h-10 bg-primary/10 rounded-lg flex items-center justify-center flex-shrink-0", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.MapPin, { className: "h-4 w-4 sm:h-5 sm:w-5 text-primary" }) }),
701
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0 flex-1", children: [
702
- /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "font-semibold mb-1 text-sm sm:text-base", children: "Office" }),
703
- /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-muted-foreground text-sm sm:text-base leading-relaxed", children: [
704
- officeAddress.line1,
705
- /* @__PURE__ */ jsxRuntime.jsx("br", {}),
706
- officeAddress.line2,
707
- /* @__PURE__ */ jsxRuntime.jsx("br", {}),
708
- officeAddress.line3,
709
- /* @__PURE__ */ jsxRuntime.jsx("br", {}),
710
- officeAddress.country
711
- ] })
712
- ] })
713
- ] }),
714
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start space-x-3 sm:space-x-4", children: [
715
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-8 h-8 sm:w-10 sm:h-10 bg-primary/10 rounded-lg flex items-center justify-center flex-shrink-0", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Clock, { className: "h-4 w-4 sm:h-5 sm:w-5 text-primary" }) }),
716
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0 flex-1", children: [
717
- /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "font-semibold mb-1 text-sm sm:text-base", children: "Response Time" }),
718
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground text-sm sm:text-base", children: responseTime })
719
- ] })
720
- ] })
721
- ] })
722
- ] }),
723
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "lg:col-span-2 order-1 lg:order-2", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-card border rounded-lg p-4 sm:p-6 md:p-8", children: [
724
- /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-xl sm:text-2xl font-bold mb-4 sm:mb-6", children: "Send us a Message" }),
725
- /* @__PURE__ */ jsxRuntime.jsxs(
726
- "form",
727
- {
728
- onSubmit: handleSubmit,
729
- className: "space-y-4 sm:space-y-6",
730
- ...recaptchaGate.formProps,
731
- children: [
732
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid sm:grid-cols-2 gap-4 sm:gap-6", children: [
733
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
734
- /* @__PURE__ */ jsxRuntime.jsx(
735
- Label,
736
- {
737
- htmlFor: "firstName",
738
- className: "text-sm sm:text-base",
739
- children: "First Name *"
740
- }
741
- ),
742
- /* @__PURE__ */ jsxRuntime.jsx(
743
- Input,
744
- {
745
- id: "firstName",
746
- name: "firstName",
747
- required: true,
748
- placeholder: "John",
749
- className: "text-sm sm:text-base"
750
- }
751
- )
752
- ] }),
753
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
754
- /* @__PURE__ */ jsxRuntime.jsx(
755
- Label,
756
- {
757
- htmlFor: "lastName",
758
- className: "text-sm sm:text-base",
759
- children: "Last Name *"
760
- }
761
- ),
762
- /* @__PURE__ */ jsxRuntime.jsx(
763
- Input,
764
- {
765
- id: "lastName",
766
- name: "lastName",
767
- required: true,
768
- placeholder: "Doe",
769
- className: "text-sm sm:text-base"
770
- }
771
- )
772
- ] })
773
- ] }),
774
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
775
- /* @__PURE__ */ jsxRuntime.jsx(Label, { htmlFor: "email", className: "text-sm sm:text-base", children: "Email *" }),
776
- /* @__PURE__ */ jsxRuntime.jsx(
777
- Input,
778
- {
779
- id: "email",
780
- name: "email",
781
- type: "email",
782
- required: true,
783
- placeholder: "john@company.com",
784
- className: "text-sm sm:text-base"
785
- }
786
- )
787
- ] }),
788
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
789
- /* @__PURE__ */ jsxRuntime.jsx(Label, { htmlFor: "company", className: "text-sm sm:text-base", children: "Company" }),
790
- /* @__PURE__ */ jsxRuntime.jsx(
791
- Input,
792
- {
793
- id: "company",
794
- name: "company",
795
- placeholder: "Acme Inc.",
796
- className: "text-sm sm:text-base"
797
- }
798
- )
799
- ] }),
800
- categories.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
801
- /* @__PURE__ */ jsxRuntime.jsxs(
802
- Label,
803
- {
804
- htmlFor: "category",
805
- className: "text-sm sm:text-base",
806
- children: [
807
- categoryLabel,
808
- categoryRequired ? " *" : ""
809
- ]
810
- }
811
- ),
812
- /* @__PURE__ */ jsxRuntime.jsxs(
813
- Select,
814
- {
815
- id: "category",
816
- name: "category",
817
- required: categoryRequired,
818
- defaultValue: "",
819
- className: "text-sm sm:text-base",
820
- children: [
821
- /* @__PURE__ */ jsxRuntime.jsx("option", { value: "", disabled: categoryRequired, children: categoryPlaceholder }),
822
- categories.map((c) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: c.value, children: c.label }, c.value))
823
- ]
824
- }
825
- )
826
- ] }),
827
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
828
- /* @__PURE__ */ jsxRuntime.jsx(Label, { htmlFor: "subject", className: "text-sm sm:text-base", children: "Subject *" }),
829
- /* @__PURE__ */ jsxRuntime.jsx(
830
- Input,
831
- {
832
- id: "subject",
833
- name: "subject",
834
- required: true,
835
- placeholder: "How can we help you?",
836
- className: "text-sm sm:text-base"
837
- }
838
- )
839
- ] }),
840
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
841
- /* @__PURE__ */ jsxRuntime.jsx(Label, { htmlFor: "message", className: "text-sm sm:text-base", children: "Message *" }),
842
- /* @__PURE__ */ jsxRuntime.jsx(
843
- Textarea,
844
- {
845
- id: "message",
846
- name: "message",
847
- required: true,
848
- placeholder: "Tell us more about your needs...",
849
- rows: 5,
850
- className: "text-sm sm:text-base min-h-[120px] sm:min-h-[150px] resize-y"
851
- }
852
- )
853
- ] }),
854
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-4", children: [
855
- effectiveRecaptchaSiteKey && /* @__PURE__ */ jsxRuntime.jsx(
856
- "div",
857
- {
858
- className: "flex justify-center sm:justify-start",
859
- style: { minHeight: RECAPTCHA_WIDGET_HEIGHT },
860
- children: recaptchaGate.armed && /* @__PURE__ */ jsxRuntime.jsx(
861
- ReCAPTCHA__default.default,
862
- {
863
- ref: recaptchaRef,
864
- sitekey: effectiveRecaptchaSiteKey
865
- }
866
- )
867
- }
868
- ),
869
- /* @__PURE__ */ jsxRuntime.jsx(
870
- Button,
871
- {
872
- type: "submit",
873
- size: "lg",
874
- disabled: isSubmitting,
875
- className: "w-full sm:w-auto min-w-[200px]",
876
- children: isSubmitting ? "Sending..." : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
877
- "Send Message ",
878
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Send, { className: "ml-2 h-4 w-4" })
879
- ] })
880
- }
881
- )
882
- ] }),
883
- submitStatus === "success" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-3 sm:p-4 bg-green-50 border border-green-200 rounded-lg text-green-800 mt-4", children: [
884
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "font-medium text-sm sm:text-base", children: "Message sent successfully!" }),
885
- /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-xs sm:text-sm mt-1", children: [
886
- "Thank you for contacting ",
887
- displayName,
888
- ". We'll get back to you within 24 hours."
889
- ] })
890
- ] }),
891
- submitStatus === "error" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-3 sm:p-4 bg-red-50 border border-red-200 rounded-lg text-red-800 mt-4", children: [
892
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "font-medium text-sm sm:text-base", children: "Failed to send message" }),
893
- /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-xs sm:text-sm mt-1", children: [
894
- "Please try again later or contact us directly at",
895
- " ",
896
- contactEmail
897
- ] })
898
- ] })
899
- ]
900
- }
901
- )
902
- ] }) })
903
- ] }) }) }),
904
- additionalOptions.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("section", { className: "py-12 sm:py-16 md:py-20 lg:py-24 bg-muted/30", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "max-w-7xl mx-auto px-4 sm:px-6 lg:px-8", children: [
905
- /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-2xl sm:text-3xl font-bold text-center mb-8 sm:mb-12", children: "More Ways to Connect" }),
906
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid sm:grid-cols-2 lg:grid-cols-3 gap-6 sm:gap-8 max-w-5xl mx-auto", children: additionalOptions.map((option, index) => /* @__PURE__ */ jsxRuntime.jsxs(
907
- "div",
908
- {
909
- className: "text-center p-4 sm:p-6 bg-card border rounded-lg",
910
- children: [
911
- /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "font-semibold text-base sm:text-lg mb-2", children: option.title }),
912
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground text-sm sm:text-base mb-4 leading-relaxed", children: replacePlaceholders(
913
- option.description,
914
- displayName,
915
- contactEmail
916
- ) }),
917
- /* @__PURE__ */ jsxRuntime.jsx(
918
- Button,
919
- {
920
- variant: "outline",
921
- asChild: true,
922
- className: "text-sm sm:text-base",
923
- children: /* @__PURE__ */ jsxRuntime.jsx("a", { href: option.buttonLink, children: option.buttonText })
924
- }
925
- )
926
- ]
927
- },
928
- index
929
- )) })
930
- ] }) })
931
- ] });
932
- }
933
-
934
- exports.ContactPage = ContactPage;
935
- exports.DEFAULT_CONTACT_CATEGORIES = DEFAULT_CONTACT_CATEGORIES;
936
26
  //# sourceMappingURL=contact.js.map
937
27
  //# sourceMappingURL=contact.js.map