@burdenoff/website-sdk 2026.1101.1 → 2026.1101.3
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 +52 -11
- 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 +25 -30
- package/dist/avatar-live-view/index.js.map +1 -1
- package/dist/avatar-live-view/index.mjs +20 -25
- 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,499 @@
|
|
|
1
|
+
import { useDeferredRecaptcha, RECAPTCHA_WIDGET_HEIGHT } from './chunk-6IBFBWC5.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 { cn } from './chunk-R7G6TWIS.mjs';
|
|
8
|
+
import { useProduct } from './chunk-GCFLCO2Z.mjs';
|
|
9
|
+
import { useWebSDK, useWebSDKConfig } from './chunk-5JRJ57CL.mjs';
|
|
10
|
+
import * as React from 'react';
|
|
11
|
+
import { useRef, useState } from 'react';
|
|
12
|
+
import { Mail, Phone, MapPin, Clock, Send } from 'lucide-react';
|
|
13
|
+
import ReCAPTCHA from 'react-google-recaptcha';
|
|
14
|
+
import { toast } from 'sonner';
|
|
15
|
+
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
16
|
+
|
|
17
|
+
var Select = React.forwardRef(({ className, children, ...props }, ref) => {
|
|
18
|
+
return /* @__PURE__ */ jsx(
|
|
19
|
+
"select",
|
|
20
|
+
{
|
|
21
|
+
className: cn(
|
|
22
|
+
"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",
|
|
23
|
+
// Inline SVG chevron: SVG inside a `background-image: url(data:…)`
|
|
24
|
+
// does NOT inherit `currentColor` from the host element (the SVG is
|
|
25
|
+
// its own document with no parent CSS context), so the stroke is
|
|
26
|
+
// hardcoded to a muted slate-400 (#94a3b8). Matches the muted
|
|
27
|
+
// foreground token visually in both light and dark themes well
|
|
28
|
+
// enough for a passive chevron — addresses #9 review feedback.
|
|
29
|
+
`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>")]`,
|
|
30
|
+
className
|
|
31
|
+
),
|
|
32
|
+
ref,
|
|
33
|
+
...props,
|
|
34
|
+
children
|
|
35
|
+
}
|
|
36
|
+
);
|
|
37
|
+
});
|
|
38
|
+
Select.displayName = "Select";
|
|
39
|
+
var DEFAULT_CONTACT_CATEGORIES = [
|
|
40
|
+
{ value: "general", label: "General enquiry" },
|
|
41
|
+
{ value: "sales", label: "Sales" },
|
|
42
|
+
{ value: "support", label: "Support" },
|
|
43
|
+
{ value: "partnership", label: "Partnership" },
|
|
44
|
+
{ value: "press", label: "Press / media" },
|
|
45
|
+
{ value: "careers", label: "Careers" },
|
|
46
|
+
{ value: "security", label: "Security disclosure" }
|
|
47
|
+
];
|
|
48
|
+
var SUBMIT_CONTACT_INQUIRY_MUTATION = (
|
|
49
|
+
/* GraphQL */
|
|
50
|
+
`
|
|
51
|
+
mutation SubmitContactInquiry($input: SubmitContactInquiryInput!) {
|
|
52
|
+
submitContactInquiry(input: $input) {
|
|
53
|
+
success
|
|
54
|
+
message
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
`
|
|
58
|
+
);
|
|
59
|
+
async function submitContactForm(client, data, productId) {
|
|
60
|
+
try {
|
|
61
|
+
const result = await client.mutate(SUBMIT_CONTACT_INQUIRY_MUTATION, {
|
|
62
|
+
input: {
|
|
63
|
+
name: `${data.firstName} ${data.lastName}`,
|
|
64
|
+
email: data.email.trim().toLowerCase(),
|
|
65
|
+
company: data.company || void 0,
|
|
66
|
+
subject: data.subject,
|
|
67
|
+
message: data.message,
|
|
68
|
+
productId,
|
|
69
|
+
// Send `category` only when the user actually picked one. Older
|
|
70
|
+
// backend deployments without the `category` field in the
|
|
71
|
+
// `SubmitContactInquiryInput` schema would reject any unknown
|
|
72
|
+
// field; spreading conditionally keeps the SDK forward-
|
|
73
|
+
// compatible.
|
|
74
|
+
...data.category ? { category: data.category } : {},
|
|
75
|
+
...data.recaptchaToken ? { recaptchaToken: data.recaptchaToken } : {}
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
if (result.errors?.length) {
|
|
79
|
+
const errorMsg = result.errors[0]?.message ?? "Failed to send message";
|
|
80
|
+
return { success: false, message: errorMsg };
|
|
81
|
+
}
|
|
82
|
+
const response = result.data?.submitContactInquiry;
|
|
83
|
+
if (response?.success) {
|
|
84
|
+
return {
|
|
85
|
+
success: true,
|
|
86
|
+
message: response.message || "Message sent successfully!"
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
return {
|
|
90
|
+
success: false,
|
|
91
|
+
message: response?.message || "Failed to send message"
|
|
92
|
+
};
|
|
93
|
+
} catch (error) {
|
|
94
|
+
console.error("Contact form submission error:", error);
|
|
95
|
+
return {
|
|
96
|
+
success: false,
|
|
97
|
+
message: "Network error. Please try again."
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
function replacePlaceholders(text, productName, email) {
|
|
102
|
+
return text.replace(/{productName}/g, productName).replace(/{email}/g, email);
|
|
103
|
+
}
|
|
104
|
+
function ContactPage({
|
|
105
|
+
productName,
|
|
106
|
+
recaptchaSiteKey,
|
|
107
|
+
contactEmail,
|
|
108
|
+
contactPhone,
|
|
109
|
+
officeAddress,
|
|
110
|
+
responseTime = "We typically respond within 24 hours",
|
|
111
|
+
heroTitle = "Get in Touch",
|
|
112
|
+
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.",
|
|
113
|
+
headingLevel = 1,
|
|
114
|
+
// Backward-compatibility: default to `[]` so existing consumers
|
|
115
|
+
// (fluidgrids/burdenoff/algoshred websites) that don't pass
|
|
116
|
+
// `categories` continue to render with NO dropdown — same behavior
|
|
117
|
+
// they had before this SDK version. To opt in, pass an explicit
|
|
118
|
+
// `categories={…}` array (or the exported `DEFAULT_CONTACT_CATEGORIES`
|
|
119
|
+
// constant for the sane Burdenoff-generic vocabulary).
|
|
120
|
+
categories = [],
|
|
121
|
+
categoryLabel = "Category",
|
|
122
|
+
categoryPlaceholder = "Select a category",
|
|
123
|
+
categoryRequired = true,
|
|
124
|
+
additionalOptions = [
|
|
125
|
+
{
|
|
126
|
+
title: "Sales Inquiries",
|
|
127
|
+
description: "Ready to see {productName} in action? Our sales team is here to help.",
|
|
128
|
+
buttonText: "Contact Sales",
|
|
129
|
+
buttonLink: `mailto:${contactEmail}`
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
title: "Technical Support",
|
|
133
|
+
description: "Need help with your {productName} setup? Our support team is ready.",
|
|
134
|
+
buttonText: "Get Support",
|
|
135
|
+
buttonLink: `mailto:${contactEmail}`
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
title: "Partnership",
|
|
139
|
+
description: "Interested in partnering with {productName}? Let's explore opportunities.",
|
|
140
|
+
buttonText: "Partner With Us",
|
|
141
|
+
buttonLink: `mailto:${contactEmail}`
|
|
142
|
+
}
|
|
143
|
+
],
|
|
144
|
+
seo
|
|
145
|
+
}) {
|
|
146
|
+
const client = useWebSDK();
|
|
147
|
+
const config = useWebSDKConfig();
|
|
148
|
+
const { product } = useProduct();
|
|
149
|
+
const resolvedProductId = product?.id || config.productId;
|
|
150
|
+
const displayName = productName ?? product?.name ?? config.productId;
|
|
151
|
+
const effectiveRecaptchaSiteKey = recaptchaSiteKey ?? product?.recaptchaSiteKey ?? config.recaptchaSiteKey ?? "";
|
|
152
|
+
const recaptchaRef = useRef(null);
|
|
153
|
+
const recaptchaGate = useDeferredRecaptcha(effectiveRecaptchaSiteKey);
|
|
154
|
+
const [isSubmitting, setIsSubmitting] = useState(false);
|
|
155
|
+
const [submitStatus, setSubmitStatus] = useState("idle");
|
|
156
|
+
const handleSubmit = async (e) => {
|
|
157
|
+
e.preventDefault();
|
|
158
|
+
const recaptchaToken = recaptchaRef.current?.getValue() ?? "";
|
|
159
|
+
if (effectiveRecaptchaSiteKey && !recaptchaToken) {
|
|
160
|
+
recaptchaGate.arm();
|
|
161
|
+
toast.error("Please complete the reCAPTCHA verification");
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
setIsSubmitting(true);
|
|
165
|
+
setSubmitStatus("idle");
|
|
166
|
+
const form = e.currentTarget;
|
|
167
|
+
try {
|
|
168
|
+
const formData = new FormData(form);
|
|
169
|
+
const showCategory = categories.length > 0;
|
|
170
|
+
const rawCategory = showCategory ? (formData.get("category") ?? "").trim() : "";
|
|
171
|
+
if (showCategory && categoryRequired && !rawCategory) {
|
|
172
|
+
toast.error("Please select a category");
|
|
173
|
+
setIsSubmitting(false);
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
const contactData = {
|
|
177
|
+
firstName: formData.get("firstName"),
|
|
178
|
+
lastName: formData.get("lastName"),
|
|
179
|
+
email: formData.get("email"),
|
|
180
|
+
company: formData.get("company"),
|
|
181
|
+
category: rawCategory || void 0,
|
|
182
|
+
subject: formData.get("subject"),
|
|
183
|
+
message: formData.get("message"),
|
|
184
|
+
recaptchaToken
|
|
185
|
+
};
|
|
186
|
+
const result = await submitContactForm(
|
|
187
|
+
client,
|
|
188
|
+
contactData,
|
|
189
|
+
resolvedProductId
|
|
190
|
+
);
|
|
191
|
+
if (result.success) {
|
|
192
|
+
setSubmitStatus("success");
|
|
193
|
+
toast.success(
|
|
194
|
+
result.message ?? `Thank you for contacting ${displayName}. We'll get back to you within 24 hours.`
|
|
195
|
+
);
|
|
196
|
+
if (form) {
|
|
197
|
+
form.reset();
|
|
198
|
+
}
|
|
199
|
+
recaptchaRef.current?.reset();
|
|
200
|
+
} else {
|
|
201
|
+
setSubmitStatus("error");
|
|
202
|
+
toast.error(
|
|
203
|
+
result.message ?? "Failed to send message. Please try again."
|
|
204
|
+
);
|
|
205
|
+
recaptchaRef.current?.reset();
|
|
206
|
+
}
|
|
207
|
+
} catch (error) {
|
|
208
|
+
console.error("Error submitting form:", error);
|
|
209
|
+
setSubmitStatus("error");
|
|
210
|
+
toast.error("Failed to send message. Please try again later.");
|
|
211
|
+
recaptchaRef.current?.reset();
|
|
212
|
+
} finally {
|
|
213
|
+
setIsSubmitting(false);
|
|
214
|
+
}
|
|
215
|
+
};
|
|
216
|
+
const heroDescriptionText = replacePlaceholders(
|
|
217
|
+
heroDescription,
|
|
218
|
+
displayName,
|
|
219
|
+
contactEmail
|
|
220
|
+
).trim();
|
|
221
|
+
const hasHero = heroTitle.trim() !== "" || heroDescriptionText !== "";
|
|
222
|
+
return /* @__PURE__ */ jsxs("div", { className: "w-full", children: [
|
|
223
|
+
seo && /* @__PURE__ */ jsx(
|
|
224
|
+
PageHead,
|
|
225
|
+
{
|
|
226
|
+
title: seo.title ?? `Contact ${displayName} - Get in Touch With Our Team`,
|
|
227
|
+
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.`,
|
|
228
|
+
productName: displayName,
|
|
229
|
+
keywords: seo.keywords ?? `contact ${displayName.toLowerCase()}, sales inquiries, customer support, technical support, partnership opportunities, get in touch`,
|
|
230
|
+
image: seo.image ?? "/og-image-contact.png",
|
|
231
|
+
url: seo.url
|
|
232
|
+
}
|
|
233
|
+
),
|
|
234
|
+
hasHero && /* @__PURE__ */ jsx(
|
|
235
|
+
"section",
|
|
236
|
+
{
|
|
237
|
+
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",
|
|
238
|
+
children: /* @__PURE__ */ jsx("div", { className: "max-w-7xl mx-auto px-4 sm:px-6 lg:px-8", children: /* @__PURE__ */ jsxs("div", { className: "text-center max-w-3xl mx-auto", children: [
|
|
239
|
+
!heroTitle.trim() ? null : headingLevel === 2 ? /* @__PURE__ */ jsx("h2", { className: "text-2xl md:text-3xl font-bold mb-3", children: heroTitle }) : /* @__PURE__ */ jsx("h1", { className: "text-3xl sm:text-4xl md:text-5xl font-bold mb-4 sm:mb-6", children: heroTitle }),
|
|
240
|
+
heroDescriptionText && /* @__PURE__ */ jsx("p", { className: "text-lg sm:text-xl text-muted-foreground leading-relaxed", children: heroDescriptionText })
|
|
241
|
+
] }) })
|
|
242
|
+
}
|
|
243
|
+
),
|
|
244
|
+
/* @__PURE__ */ jsx("section", { className: "py-12 sm:py-16 md:py-20 lg:py-24", children: /* @__PURE__ */ jsx("div", { className: "max-w-7xl mx-auto px-4 sm:px-6 lg:px-8", children: /* @__PURE__ */ jsxs("div", { className: "grid sm:grid-cols-1 lg:grid-cols-3 gap-8 sm:gap-10 lg:gap-12", children: [
|
|
245
|
+
/* @__PURE__ */ jsxs("div", { className: "lg:col-span-1 order-2 lg:order-1", children: [
|
|
246
|
+
/* @__PURE__ */ jsx("h2", { className: "text-xl sm:text-2xl font-bold mb-4 sm:mb-6", children: "Contact Information" }),
|
|
247
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-4 sm:space-y-6", children: [
|
|
248
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-start space-x-3 sm:space-x-4", children: [
|
|
249
|
+
/* @__PURE__ */ 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__ */ jsx(Mail, { className: "h-4 w-4 sm:h-5 sm:w-5 text-primary" }) }),
|
|
250
|
+
/* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
|
|
251
|
+
/* @__PURE__ */ jsx("h3", { className: "font-semibold mb-1 text-sm sm:text-base", children: "Email" }),
|
|
252
|
+
/* @__PURE__ */ jsx("p", { className: "text-muted-foreground text-sm sm:text-base break-all", children: contactEmail })
|
|
253
|
+
] })
|
|
254
|
+
] }),
|
|
255
|
+
contactPhone && /* @__PURE__ */ jsxs("div", { className: "flex items-start space-x-3 sm:space-x-4", children: [
|
|
256
|
+
/* @__PURE__ */ 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__ */ jsx(Phone, { className: "h-4 w-4 sm:h-5 sm:w-5 text-primary" }) }),
|
|
257
|
+
/* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
|
|
258
|
+
/* @__PURE__ */ jsx("h3", { className: "font-semibold mb-1 text-sm sm:text-base", children: "Phone" }),
|
|
259
|
+
/* @__PURE__ */ jsx("p", { className: "text-muted-foreground text-sm sm:text-base", children: contactPhone })
|
|
260
|
+
] })
|
|
261
|
+
] }),
|
|
262
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-start space-x-3 sm:space-x-4", children: [
|
|
263
|
+
/* @__PURE__ */ 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__ */ jsx(MapPin, { className: "h-4 w-4 sm:h-5 sm:w-5 text-primary" }) }),
|
|
264
|
+
/* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
|
|
265
|
+
/* @__PURE__ */ jsx("h3", { className: "font-semibold mb-1 text-sm sm:text-base", children: "Office" }),
|
|
266
|
+
/* @__PURE__ */ jsxs("p", { className: "text-muted-foreground text-sm sm:text-base leading-relaxed", children: [
|
|
267
|
+
officeAddress.line1,
|
|
268
|
+
/* @__PURE__ */ jsx("br", {}),
|
|
269
|
+
officeAddress.line2,
|
|
270
|
+
/* @__PURE__ */ jsx("br", {}),
|
|
271
|
+
officeAddress.line3,
|
|
272
|
+
/* @__PURE__ */ jsx("br", {}),
|
|
273
|
+
officeAddress.country
|
|
274
|
+
] })
|
|
275
|
+
] })
|
|
276
|
+
] }),
|
|
277
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-start space-x-3 sm:space-x-4", children: [
|
|
278
|
+
/* @__PURE__ */ 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__ */ jsx(Clock, { className: "h-4 w-4 sm:h-5 sm:w-5 text-primary" }) }),
|
|
279
|
+
/* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
|
|
280
|
+
/* @__PURE__ */ jsx("h3", { className: "font-semibold mb-1 text-sm sm:text-base", children: "Response Time" }),
|
|
281
|
+
/* @__PURE__ */ jsx("p", { className: "text-muted-foreground text-sm sm:text-base", children: responseTime })
|
|
282
|
+
] })
|
|
283
|
+
] })
|
|
284
|
+
] })
|
|
285
|
+
] }),
|
|
286
|
+
/* @__PURE__ */ jsx("div", { className: "lg:col-span-2 order-1 lg:order-2", children: /* @__PURE__ */ jsxs("div", { className: "bg-card border rounded-lg p-4 sm:p-6 md:p-8", children: [
|
|
287
|
+
/* @__PURE__ */ jsx("h2", { className: "text-xl sm:text-2xl font-bold mb-4 sm:mb-6", children: "Send us a Message" }),
|
|
288
|
+
/* @__PURE__ */ jsxs(
|
|
289
|
+
"form",
|
|
290
|
+
{
|
|
291
|
+
onSubmit: handleSubmit,
|
|
292
|
+
className: "space-y-4 sm:space-y-6",
|
|
293
|
+
...recaptchaGate.formProps,
|
|
294
|
+
children: [
|
|
295
|
+
/* @__PURE__ */ jsxs("div", { className: "grid sm:grid-cols-2 gap-4 sm:gap-6", children: [
|
|
296
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
297
|
+
/* @__PURE__ */ jsx(
|
|
298
|
+
Label,
|
|
299
|
+
{
|
|
300
|
+
htmlFor: "firstName",
|
|
301
|
+
className: "text-sm sm:text-base",
|
|
302
|
+
children: "First Name *"
|
|
303
|
+
}
|
|
304
|
+
),
|
|
305
|
+
/* @__PURE__ */ jsx(
|
|
306
|
+
Input,
|
|
307
|
+
{
|
|
308
|
+
id: "firstName",
|
|
309
|
+
name: "firstName",
|
|
310
|
+
required: true,
|
|
311
|
+
placeholder: "John",
|
|
312
|
+
className: "text-sm sm:text-base"
|
|
313
|
+
}
|
|
314
|
+
)
|
|
315
|
+
] }),
|
|
316
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
317
|
+
/* @__PURE__ */ jsx(
|
|
318
|
+
Label,
|
|
319
|
+
{
|
|
320
|
+
htmlFor: "lastName",
|
|
321
|
+
className: "text-sm sm:text-base",
|
|
322
|
+
children: "Last Name *"
|
|
323
|
+
}
|
|
324
|
+
),
|
|
325
|
+
/* @__PURE__ */ jsx(
|
|
326
|
+
Input,
|
|
327
|
+
{
|
|
328
|
+
id: "lastName",
|
|
329
|
+
name: "lastName",
|
|
330
|
+
required: true,
|
|
331
|
+
placeholder: "Doe",
|
|
332
|
+
className: "text-sm sm:text-base"
|
|
333
|
+
}
|
|
334
|
+
)
|
|
335
|
+
] })
|
|
336
|
+
] }),
|
|
337
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
338
|
+
/* @__PURE__ */ jsx(Label, { htmlFor: "email", className: "text-sm sm:text-base", children: "Email *" }),
|
|
339
|
+
/* @__PURE__ */ jsx(
|
|
340
|
+
Input,
|
|
341
|
+
{
|
|
342
|
+
id: "email",
|
|
343
|
+
name: "email",
|
|
344
|
+
type: "email",
|
|
345
|
+
required: true,
|
|
346
|
+
placeholder: "john@company.com",
|
|
347
|
+
className: "text-sm sm:text-base"
|
|
348
|
+
}
|
|
349
|
+
)
|
|
350
|
+
] }),
|
|
351
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
352
|
+
/* @__PURE__ */ jsx(Label, { htmlFor: "company", className: "text-sm sm:text-base", children: "Company" }),
|
|
353
|
+
/* @__PURE__ */ jsx(
|
|
354
|
+
Input,
|
|
355
|
+
{
|
|
356
|
+
id: "company",
|
|
357
|
+
name: "company",
|
|
358
|
+
placeholder: "Acme Inc.",
|
|
359
|
+
className: "text-sm sm:text-base"
|
|
360
|
+
}
|
|
361
|
+
)
|
|
362
|
+
] }),
|
|
363
|
+
categories.length > 0 && /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
364
|
+
/* @__PURE__ */ jsxs(
|
|
365
|
+
Label,
|
|
366
|
+
{
|
|
367
|
+
htmlFor: "category",
|
|
368
|
+
className: "text-sm sm:text-base",
|
|
369
|
+
children: [
|
|
370
|
+
categoryLabel,
|
|
371
|
+
categoryRequired ? " *" : ""
|
|
372
|
+
]
|
|
373
|
+
}
|
|
374
|
+
),
|
|
375
|
+
/* @__PURE__ */ jsxs(
|
|
376
|
+
Select,
|
|
377
|
+
{
|
|
378
|
+
id: "category",
|
|
379
|
+
name: "category",
|
|
380
|
+
required: categoryRequired,
|
|
381
|
+
defaultValue: "",
|
|
382
|
+
className: "text-sm sm:text-base",
|
|
383
|
+
children: [
|
|
384
|
+
/* @__PURE__ */ jsx("option", { value: "", disabled: categoryRequired, children: categoryPlaceholder }),
|
|
385
|
+
categories.map((c) => /* @__PURE__ */ jsx("option", { value: c.value, children: c.label }, c.value))
|
|
386
|
+
]
|
|
387
|
+
}
|
|
388
|
+
)
|
|
389
|
+
] }),
|
|
390
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
391
|
+
/* @__PURE__ */ jsx(Label, { htmlFor: "subject", className: "text-sm sm:text-base", children: "Subject *" }),
|
|
392
|
+
/* @__PURE__ */ jsx(
|
|
393
|
+
Input,
|
|
394
|
+
{
|
|
395
|
+
id: "subject",
|
|
396
|
+
name: "subject",
|
|
397
|
+
required: true,
|
|
398
|
+
placeholder: "How can we help you?",
|
|
399
|
+
className: "text-sm sm:text-base"
|
|
400
|
+
}
|
|
401
|
+
)
|
|
402
|
+
] }),
|
|
403
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
404
|
+
/* @__PURE__ */ jsx(Label, { htmlFor: "message", className: "text-sm sm:text-base", children: "Message *" }),
|
|
405
|
+
/* @__PURE__ */ jsx(
|
|
406
|
+
Textarea,
|
|
407
|
+
{
|
|
408
|
+
id: "message",
|
|
409
|
+
name: "message",
|
|
410
|
+
required: true,
|
|
411
|
+
placeholder: "Tell us more about your needs...",
|
|
412
|
+
rows: 5,
|
|
413
|
+
className: "text-sm sm:text-base min-h-[120px] sm:min-h-[150px] resize-y"
|
|
414
|
+
}
|
|
415
|
+
)
|
|
416
|
+
] }),
|
|
417
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
|
|
418
|
+
effectiveRecaptchaSiteKey && /* @__PURE__ */ jsx(
|
|
419
|
+
"div",
|
|
420
|
+
{
|
|
421
|
+
className: "flex justify-center sm:justify-start",
|
|
422
|
+
style: { minHeight: RECAPTCHA_WIDGET_HEIGHT },
|
|
423
|
+
children: recaptchaGate.armed && /* @__PURE__ */ jsx(
|
|
424
|
+
ReCAPTCHA,
|
|
425
|
+
{
|
|
426
|
+
ref: recaptchaRef,
|
|
427
|
+
sitekey: effectiveRecaptchaSiteKey
|
|
428
|
+
}
|
|
429
|
+
)
|
|
430
|
+
}
|
|
431
|
+
),
|
|
432
|
+
/* @__PURE__ */ jsx(
|
|
433
|
+
Button,
|
|
434
|
+
{
|
|
435
|
+
type: "submit",
|
|
436
|
+
size: "lg",
|
|
437
|
+
disabled: isSubmitting,
|
|
438
|
+
className: "w-full sm:w-auto min-w-[200px]",
|
|
439
|
+
children: isSubmitting ? "Sending..." : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
440
|
+
"Send Message ",
|
|
441
|
+
/* @__PURE__ */ jsx(Send, { className: "ml-2 h-4 w-4" })
|
|
442
|
+
] })
|
|
443
|
+
}
|
|
444
|
+
)
|
|
445
|
+
] }),
|
|
446
|
+
submitStatus === "success" && /* @__PURE__ */ jsxs("div", { className: "p-3 sm:p-4 bg-green-50 border border-green-200 rounded-lg text-green-800 mt-4", children: [
|
|
447
|
+
/* @__PURE__ */ jsx("p", { className: "font-medium text-sm sm:text-base", children: "Message sent successfully!" }),
|
|
448
|
+
/* @__PURE__ */ jsxs("p", { className: "text-xs sm:text-sm mt-1", children: [
|
|
449
|
+
"Thank you for contacting ",
|
|
450
|
+
displayName,
|
|
451
|
+
". We'll get back to you within 24 hours."
|
|
452
|
+
] })
|
|
453
|
+
] }),
|
|
454
|
+
submitStatus === "error" && /* @__PURE__ */ jsxs("div", { className: "p-3 sm:p-4 bg-red-50 border border-red-200 rounded-lg text-red-800 mt-4", children: [
|
|
455
|
+
/* @__PURE__ */ jsx("p", { className: "font-medium text-sm sm:text-base", children: "Failed to send message" }),
|
|
456
|
+
/* @__PURE__ */ jsxs("p", { className: "text-xs sm:text-sm mt-1", children: [
|
|
457
|
+
"Please try again later or contact us directly at",
|
|
458
|
+
" ",
|
|
459
|
+
contactEmail
|
|
460
|
+
] })
|
|
461
|
+
] })
|
|
462
|
+
]
|
|
463
|
+
}
|
|
464
|
+
)
|
|
465
|
+
] }) })
|
|
466
|
+
] }) }) }),
|
|
467
|
+
additionalOptions.length > 0 && /* @__PURE__ */ jsx("section", { className: "py-12 sm:py-16 md:py-20 lg:py-24 bg-muted/30", children: /* @__PURE__ */ jsxs("div", { className: "max-w-7xl mx-auto px-4 sm:px-6 lg:px-8", children: [
|
|
468
|
+
/* @__PURE__ */ jsx("h2", { className: "text-2xl sm:text-3xl font-bold text-center mb-8 sm:mb-12", children: "More Ways to Connect" }),
|
|
469
|
+
/* @__PURE__ */ 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__ */ jsxs(
|
|
470
|
+
"div",
|
|
471
|
+
{
|
|
472
|
+
className: "text-center p-4 sm:p-6 bg-card border rounded-lg",
|
|
473
|
+
children: [
|
|
474
|
+
/* @__PURE__ */ jsx("h3", { className: "font-semibold text-base sm:text-lg mb-2", children: option.title }),
|
|
475
|
+
/* @__PURE__ */ jsx("p", { className: "text-muted-foreground text-sm sm:text-base mb-4 leading-relaxed", children: replacePlaceholders(
|
|
476
|
+
option.description,
|
|
477
|
+
displayName,
|
|
478
|
+
contactEmail
|
|
479
|
+
) }),
|
|
480
|
+
/* @__PURE__ */ jsx(
|
|
481
|
+
Button,
|
|
482
|
+
{
|
|
483
|
+
variant: "outline",
|
|
484
|
+
asChild: true,
|
|
485
|
+
className: "text-sm sm:text-base",
|
|
486
|
+
children: /* @__PURE__ */ jsx("a", { href: option.buttonLink, children: option.buttonText })
|
|
487
|
+
}
|
|
488
|
+
)
|
|
489
|
+
]
|
|
490
|
+
},
|
|
491
|
+
index
|
|
492
|
+
)) })
|
|
493
|
+
] }) })
|
|
494
|
+
] });
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
export { ContactPage, DEFAULT_CONTACT_CATEGORIES, Select };
|
|
498
|
+
//# sourceMappingURL=chunk-PXRHVVOU.mjs.map
|
|
499
|
+
//# sourceMappingURL=chunk-PXRHVVOU.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/ui/select.tsx","../src/components/contact.tsx"],"names":["jsx"],"mappings":"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","file":"chunk-PXRHVVOU.mjs","sourcesContent":["import * as React from \"react\";\n\nimport { cn } from \"../utils/cn\";\n\n/** Native `<select>` wrapper matching the `Input` design tokens. */\nconst Select = React.forwardRef<\n HTMLSelectElement,\n React.ComponentProps<\"select\">\n>(({ className, children, ...props }, ref) => {\n return (\n <select\n className={cn(\n \"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\",\n // Inline SVG chevron: SVG inside a `background-image: url(data:…)`\n // does NOT inherit `currentColor` from the host element (the SVG is\n // its own document with no parent CSS context), so the stroke is\n // hardcoded to a muted slate-400 (#94a3b8). Matches the muted\n // foreground token visually in both light and dark themes well\n // enough for a passive chevron — addresses #9 review feedback.\n \"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>\\\")]\",\n className,\n )}\n ref={ref}\n {...props}\n >\n {children}\n </select>\n );\n});\nSelect.displayName = \"Select\";\n\nexport { Select };\n","/**\n * Contact Page Component\n * Complete contact page with form submission via GraphQL, reCAPTCHA validation,\n * contact information display, and additional contact options.\n * Uses the WebSDKClient provider for API calls.\n *\n * @example\n * ```tsx\n * import { ContactPage } from '@burdenoff/website-sdk/components/contact'\n *\n * <ContactPage\n * productName=\"MyProduct\"\n * recaptchaSiteKey=\"your-recaptcha-key\"\n * contactEmail=\"contact@myproduct.com\"\n * contactPhone=\"+1-234-567-8900\"\n * officeAddress={{\n * line1: \"123 Main St\",\n * line2: \"Suite 100\",\n * line3: \"City, State 12345\",\n * country: \"USA\"\n * }}\n * />\n * ```\n */\n\n\"use client\";\n\nimport { useState, useRef } from \"react\";\n\nimport { Mail, MapPin, Phone, Clock, Send } from \"lucide-react\";\nimport ReCAPTCHA from \"react-google-recaptcha\";\nimport { toast } from \"sonner\";\n\nimport { useWebSDK, useWebSDKConfig } from \"../client/provider\";\nimport {\n RECAPTCHA_WIDGET_HEIGHT,\n useDeferredRecaptcha,\n} from \"../hooks/use-deferred-recaptcha\";\nimport { useProduct } from \"../product/product-provider\";\nimport { PageHead } from \"../seo/page-head\";\nimport { Button } from \"../ui/button\";\nimport { Input } from \"../ui/input\";\nimport { Label } from \"../ui/label\";\nimport { Select } from \"../ui/select\";\nimport { Textarea } from \"../ui/textarea\";\n\nimport type { WebSDKClient } from \"../client/graphql-client\";\n\n// ============================================================================\n// TYPES & INTERFACES\n// ============================================================================\n\ninterface OfficeAddress {\n line1: string;\n line2: string;\n line3: string;\n country: string;\n}\n\ninterface ContactOption {\n title: string;\n description: string;\n buttonText: string;\n buttonLink: string;\n}\n\n/**\n * One entry in the contact-form Category dropdown. Each product website\n * supplies its own allow-list via the `categories` prop so the\n * vocabulary stays product-appropriate (e.g. VibeControls uses\n * `plugin-developer`, a manufacturing site uses `dealer`). The backend\n * accepts whatever `value` string is sent and persists it directly.\n *\n * `value` flows to the backend; `label` is what the user sees.\n */\nexport interface ContactCategory {\n /** Stored on the server. Short, kebab-case is conventional. */\n value: string;\n /** Human-readable label shown in the dropdown. */\n label: string;\n}\n\n/**\n * Conservative starter category list — Burdenoff-generic vocabulary\n * (General / Sales / Support / Partnership / Press / Careers / Security).\n *\n * **Not** applied by default: pass it explicitly to opt in:\n *\n * ```tsx\n * <ContactPage\n * …\n * categories={DEFAULT_CONTACT_CATEGORIES}\n * />\n * ```\n *\n * The component default for `categories` is `[]` (no dropdown) so this\n * SDK release is backward-compatible with existing consumers that\n * don't yet know about the field — see the prop docs.\n */\nexport const DEFAULT_CONTACT_CATEGORIES: ContactCategory[] = [\n { value: \"general\", label: \"General enquiry\" },\n { value: \"sales\", label: \"Sales\" },\n { value: \"support\", label: \"Support\" },\n { value: \"partnership\", label: \"Partnership\" },\n { value: \"press\", label: \"Press / media\" },\n { value: \"careers\", label: \"Careers\" },\n { value: \"security\", label: \"Security disclosure\" },\n];\n\ninterface ContactFormData {\n firstName: string;\n lastName: string;\n email: string;\n company?: string;\n category?: string;\n subject: string;\n message: string;\n recaptchaToken: string;\n}\n\ntype SubmitStatus = \"idle\" | \"success\" | \"error\";\n\nexport interface ContactPageProps {\n /** Product name. Falls back to SDK config productId if not provided. */\n productName?: string;\n /** reCAPTCHA site key (optional, falls back to SDK config) */\n recaptchaSiteKey?: string;\n /** Contact email */\n contactEmail: string;\n /** Contact phone number */\n contactPhone: string;\n /** Office address */\n officeAddress: OfficeAddress;\n /** Response time message */\n responseTime?: string;\n /** Hero title */\n heroTitle?: string;\n /** Hero description */\n heroDescription?: string;\n /**\n * Heading level for the hero title. Defaults to `1` (a full page hero,\n * `<h1>`). Pass `2` when embedding ContactPage inside another page that\n * already owns the page `<h1>` (e.g. `PartnersPage`) — renders a compact\n * `<h2>` section header instead of a competing hero, keeping one `<h1>`\n * per page for SEO and a clean visual hierarchy.\n */\n headingLevel?: 1 | 2;\n /** Additional contact options */\n additionalOptions?: ContactOption[];\n /**\n * Inquiry-type dropdown allow-list. **Defaults to `[]`** — the\n * dropdown does not render unless the consumer explicitly opts in.\n *\n * Two ways to opt in:\n *\n * ```tsx\n * // 1. Provide a product-specific list\n * <ContactPage categories={[{ value: 'sales', label: 'Sales' }, …]} />\n *\n * // 2. Or use the conservative SDK starter list\n * <ContactPage categories={DEFAULT_CONTACT_CATEGORIES} />\n * ```\n *\n * Default is intentionally empty (not `DEFAULT_CONTACT_CATEGORIES`)\n * to keep this SDK release backward-compatible with existing\n * consumers that don't yet wire `categories` — they get zero\n * behavior change.\n *\n * Typed `readonly` because the component never mutates the array;\n * lets product sites pass an `as const`-frozen config without an\n * extra `[...spread]` at the call site.\n */\n categories?: readonly ContactCategory[];\n /** Label shown above the category dropdown. */\n categoryLabel?: string;\n /** Placeholder text for the unselected state of the dropdown. */\n categoryPlaceholder?: string;\n /**\n * Whether selecting a category is required to submit. Defaults to\n * `true` — the whole point of the dropdown is routing, so users\n * self-triage instead of pushing that work onto support.\n */\n categoryRequired?: boolean;\n /** SEO metadata */\n seo?: {\n title?: string;\n description?: string;\n keywords?: string;\n image?: string;\n url?: string;\n };\n}\n\n// ============================================================================\n// GRAPHQL MUTATION\n// ============================================================================\n\nconst SUBMIT_CONTACT_INQUIRY_MUTATION = /* GraphQL */ `\n mutation SubmitContactInquiry($input: SubmitContactInquiryInput!) {\n submitContactInquiry(input: $input) {\n success\n message\n }\n }\n`;\n\n// ============================================================================\n// API SERVICE\n// ============================================================================\n\nasync function submitContactForm(\n client: WebSDKClient,\n data: ContactFormData,\n productId: string,\n): Promise<{ success: boolean; message?: string }> {\n try {\n const result = await client.mutate<{\n submitContactInquiry: {\n success: boolean;\n message: string;\n };\n }>(SUBMIT_CONTACT_INQUIRY_MUTATION, {\n input: {\n name: `${data.firstName} ${data.lastName}`,\n email: data.email.trim().toLowerCase(),\n company: data.company || undefined,\n subject: data.subject,\n message: data.message,\n productId,\n // Send `category` only when the user actually picked one. Older\n // backend deployments without the `category` field in the\n // `SubmitContactInquiryInput` schema would reject any unknown\n // field; spreading conditionally keeps the SDK forward-\n // compatible.\n ...(data.category ? { category: data.category } : {}),\n ...(data.recaptchaToken ? { recaptchaToken: data.recaptchaToken } : {}),\n },\n });\n\n if (result.errors?.length) {\n const errorMsg = result.errors[0]?.message ?? \"Failed to send message\";\n return { success: false, message: errorMsg };\n }\n\n const response = result.data?.submitContactInquiry;\n if (response?.success) {\n return {\n success: true,\n message: response.message || \"Message sent successfully!\",\n };\n }\n\n return {\n success: false,\n message: response?.message || \"Failed to send message\",\n };\n } catch (error) {\n console.error(\"Contact form submission error:\", error);\n return {\n success: false,\n message: \"Network error. Please try again.\",\n };\n }\n}\n\n// ============================================================================\n// HELPER\n// ============================================================================\n\nfunction replacePlaceholders(\n text: string,\n productName: string,\n email: string,\n): string {\n return text.replace(/{productName}/g, productName).replace(/{email}/g, email);\n}\n\n// ============================================================================\n// MAIN COMPONENT\n// ============================================================================\n\nexport function ContactPage({\n productName,\n recaptchaSiteKey,\n contactEmail,\n contactPhone,\n officeAddress,\n responseTime = \"We typically respond within 24 hours\",\n heroTitle = \"Get in Touch\",\n 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.\",\n headingLevel = 1,\n // Backward-compatibility: default to `[]` so existing consumers\n // (fluidgrids/burdenoff/algoshred websites) that don't pass\n // `categories` continue to render with NO dropdown — same behavior\n // they had before this SDK version. To opt in, pass an explicit\n // `categories={…}` array (or the exported `DEFAULT_CONTACT_CATEGORIES`\n // constant for the sane Burdenoff-generic vocabulary).\n categories = [],\n categoryLabel = \"Category\",\n categoryPlaceholder = \"Select a category\",\n categoryRequired = true,\n additionalOptions = [\n {\n title: \"Sales Inquiries\",\n description:\n \"Ready to see {productName} in action? Our sales team is here to help.\",\n buttonText: \"Contact Sales\",\n buttonLink: `mailto:${contactEmail}`,\n },\n {\n title: \"Technical Support\",\n description:\n \"Need help with your {productName} setup? Our support team is ready.\",\n buttonText: \"Get Support\",\n buttonLink: `mailto:${contactEmail}`,\n },\n {\n title: \"Partnership\",\n description:\n \"Interested in partnering with {productName}? Let's explore opportunities.\",\n buttonText: \"Partner With Us\",\n buttonLink: `mailto:${contactEmail}`,\n },\n ],\n seo,\n}: ContactPageProps) {\n const client = useWebSDK();\n const config = useWebSDKConfig();\n const { product } = useProduct();\n const resolvedProductId = product?.id || config.productId;\n const displayName = productName ?? product?.name ?? config.productId;\n // Resolution order: explicit prop → product CMS (publicProduct.recaptchaSiteKey)\n // → SDK config/env. Lets the key be managed per-product in the CMS without\n // any env wiring on the consuming site.\n const effectiveRecaptchaSiteKey =\n recaptchaSiteKey ??\n product?.recaptchaSiteKey ??\n config.recaptchaSiteKey ??\n \"\";\n\n const recaptchaRef = useRef<ReCAPTCHA>(null);\n const recaptchaGate = useDeferredRecaptcha(effectiveRecaptchaSiteKey);\n const [isSubmitting, setIsSubmitting] = useState(false);\n const [submitStatus, setSubmitStatus] = useState<SubmitStatus>(\"idle\");\n\n const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {\n e.preventDefault();\n\n // Get reCAPTCHA token (skip validation when no site key is configured)\n const recaptchaToken = recaptchaRef.current?.getValue() ?? \"\";\n\n if (effectiveRecaptchaSiteKey && !recaptchaToken) {\n recaptchaGate.arm();\n toast.error(\"Please complete the reCAPTCHA verification\");\n return;\n }\n\n setIsSubmitting(true);\n setSubmitStatus(\"idle\");\n\n // Store form reference before async operations\n const form = e.currentTarget;\n\n try {\n const formData = new FormData(form);\n\n // Category is rendered only when `categories` is non-empty. Read\n // it conditionally so an opt-out site (`categories={[]}`) never\n // sends an empty-string `category` on the wire.\n const showCategory = categories.length > 0;\n const rawCategory = showCategory\n ? ((formData.get(\"category\") as string | null) ?? \"\").trim()\n : \"\";\n if (showCategory && categoryRequired && !rawCategory) {\n // Belt-and-braces validation. Browsers already enforce the\n // `required` attribute, but the form-data path runs even when\n // the native check is bypassed by a custom client.\n //\n // Message is hardcoded (not derived from `categoryPlaceholder`)\n // so a placeholder like \"Department type\" doesn't produce\n // ungrammatical output like \"Please department type\" —\n // addresses #9 review feedback.\n toast.error(\"Please select a category\");\n setIsSubmitting(false);\n return;\n }\n\n const contactData: ContactFormData = {\n firstName: formData.get(\"firstName\") as string,\n lastName: formData.get(\"lastName\") as string,\n email: formData.get(\"email\") as string,\n company: formData.get(\"company\") as string,\n category: rawCategory || undefined,\n subject: formData.get(\"subject\") as string,\n message: formData.get(\"message\") as string,\n recaptchaToken,\n };\n\n const result = await submitContactForm(\n client,\n contactData,\n resolvedProductId,\n );\n\n if (result.success) {\n setSubmitStatus(\"success\");\n toast.success(\n result.message ??\n `Thank you for contacting ${displayName}. We'll get back to you within 24 hours.`,\n );\n\n // Reset form\n if (form) {\n form.reset();\n }\n // Reset reCAPTCHA\n recaptchaRef.current?.reset();\n } else {\n setSubmitStatus(\"error\");\n toast.error(\n result.message ?? \"Failed to send message. Please try again.\",\n );\n recaptchaRef.current?.reset();\n }\n } catch (error) {\n console.error(\"Error submitting form:\", error);\n setSubmitStatus(\"error\");\n toast.error(\"Failed to send message. Please try again later.\");\n recaptchaRef.current?.reset();\n } finally {\n setIsSubmitting(false);\n }\n };\n\n const heroDescriptionText = replacePlaceholders(\n heroDescription,\n displayName,\n contactEmail,\n ).trim();\n const hasHero = heroTitle.trim() !== \"\" || heroDescriptionText !== \"\";\n\n return (\n <div className=\"w-full\">\n {seo && (\n <PageHead\n title={\n seo.title ?? `Contact ${displayName} - Get in Touch With Our Team`\n }\n description={\n seo.description ??\n `Ready to transform your business? Contact our team for sales inquiries, technical support, or partnership opportunities. We're here to help you succeed.`\n }\n productName={displayName}\n keywords={\n seo.keywords ??\n `contact ${displayName.toLowerCase()}, sales inquiries, customer support, technical support, partnership opportunities, get in touch`\n }\n image={seo.image ?? \"/og-image-contact.png\"}\n url={seo.url}\n />\n )}\n\n {/* Hero Section — full page hero (h1) by default; compact section\n header (h2) when embedded in a page that already owns the <h1>.\n An embedding page may blank both the title and the description to\n drop the header entirely; rendering an empty heading would be\n announced by screen readers as a nameless heading (axe\n \"empty-heading\"), so the section is skipped instead. */}\n {hasHero && (\n <section\n className={\n headingLevel === 2\n ? \"py-12 md:py-16\"\n : \"bg-gradient-to-b from-background to-muted/20 py-12 sm:py-16 md:py-20 lg:py-24\"\n }\n >\n <div className=\"max-w-7xl mx-auto px-4 sm:px-6 lg:px-8\">\n <div className=\"text-center max-w-3xl mx-auto\">\n {!heroTitle.trim() ? null : headingLevel === 2 ? (\n <h2 className=\"text-2xl md:text-3xl font-bold mb-3\">\n {heroTitle}\n </h2>\n ) : (\n <h1 className=\"text-3xl sm:text-4xl md:text-5xl font-bold mb-4 sm:mb-6\">\n {heroTitle}\n </h1>\n )}\n {heroDescriptionText && (\n <p className=\"text-lg sm:text-xl text-muted-foreground leading-relaxed\">\n {heroDescriptionText}\n </p>\n )}\n </div>\n </div>\n </section>\n )}\n\n {/* Contact Form and Info */}\n <section className=\"py-12 sm:py-16 md:py-20 lg:py-24\">\n <div className=\"max-w-7xl mx-auto px-4 sm:px-6 lg:px-8\">\n <div className=\"grid sm:grid-cols-1 lg:grid-cols-3 gap-8 sm:gap-10 lg:gap-12\">\n {/* Contact Information */}\n <div className=\"lg:col-span-1 order-2 lg:order-1\">\n <h2 className=\"text-xl sm:text-2xl font-bold mb-4 sm:mb-6\">\n Contact Information\n </h2>\n\n <div className=\"space-y-4 sm:space-y-6\">\n <div className=\"flex items-start space-x-3 sm:space-x-4\">\n <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\">\n <Mail className=\"h-4 w-4 sm:h-5 sm:w-5 text-primary\" />\n </div>\n <div className=\"min-w-0 flex-1\">\n <h3 className=\"font-semibold mb-1 text-sm sm:text-base\">\n Email\n </h3>\n <p className=\"text-muted-foreground text-sm sm:text-base break-all\">\n {contactEmail}\n </p>\n </div>\n </div>\n\n {contactPhone && (\n <div className=\"flex items-start space-x-3 sm:space-x-4\">\n <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\">\n <Phone className=\"h-4 w-4 sm:h-5 sm:w-5 text-primary\" />\n </div>\n <div className=\"min-w-0 flex-1\">\n <h3 className=\"font-semibold mb-1 text-sm sm:text-base\">\n Phone\n </h3>\n <p className=\"text-muted-foreground text-sm sm:text-base\">\n {contactPhone}\n </p>\n </div>\n </div>\n )}\n\n <div className=\"flex items-start space-x-3 sm:space-x-4\">\n <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\">\n <MapPin className=\"h-4 w-4 sm:h-5 sm:w-5 text-primary\" />\n </div>\n <div className=\"min-w-0 flex-1\">\n <h3 className=\"font-semibold mb-1 text-sm sm:text-base\">\n Office\n </h3>\n <p className=\"text-muted-foreground text-sm sm:text-base leading-relaxed\">\n {officeAddress.line1}\n <br />\n {officeAddress.line2}\n <br />\n {officeAddress.line3}\n <br />\n {officeAddress.country}\n </p>\n </div>\n </div>\n\n <div className=\"flex items-start space-x-3 sm:space-x-4\">\n <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\">\n <Clock className=\"h-4 w-4 sm:h-5 sm:w-5 text-primary\" />\n </div>\n <div className=\"min-w-0 flex-1\">\n <h3 className=\"font-semibold mb-1 text-sm sm:text-base\">\n Response Time\n </h3>\n <p className=\"text-muted-foreground text-sm sm:text-base\">\n {responseTime}\n </p>\n </div>\n </div>\n </div>\n </div>\n\n {/* Contact Form */}\n <div className=\"lg:col-span-2 order-1 lg:order-2\">\n <div className=\"bg-card border rounded-lg p-4 sm:p-6 md:p-8\">\n <h2 className=\"text-xl sm:text-2xl font-bold mb-4 sm:mb-6\">\n Send us a Message\n </h2>\n\n <form\n onSubmit={handleSubmit}\n className=\"space-y-4 sm:space-y-6\"\n {...recaptchaGate.formProps}\n >\n <div className=\"grid sm:grid-cols-2 gap-4 sm:gap-6\">\n <div className=\"space-y-2\">\n <Label\n htmlFor=\"firstName\"\n className=\"text-sm sm:text-base\"\n >\n First Name *\n </Label>\n <Input\n id=\"firstName\"\n name=\"firstName\"\n required\n placeholder=\"John\"\n className=\"text-sm sm:text-base\"\n />\n </div>\n\n <div className=\"space-y-2\">\n <Label\n htmlFor=\"lastName\"\n className=\"text-sm sm:text-base\"\n >\n Last Name *\n </Label>\n <Input\n id=\"lastName\"\n name=\"lastName\"\n required\n placeholder=\"Doe\"\n className=\"text-sm sm:text-base\"\n />\n </div>\n </div>\n\n <div className=\"space-y-2\">\n <Label htmlFor=\"email\" className=\"text-sm sm:text-base\">\n Email *\n </Label>\n <Input\n id=\"email\"\n name=\"email\"\n type=\"email\"\n required\n placeholder=\"john@company.com\"\n className=\"text-sm sm:text-base\"\n />\n </div>\n\n <div className=\"space-y-2\">\n <Label htmlFor=\"company\" className=\"text-sm sm:text-base\">\n Company\n </Label>\n <Input\n id=\"company\"\n name=\"company\"\n placeholder=\"Acme Inc.\"\n className=\"text-sm sm:text-base\"\n />\n </div>\n\n {categories.length > 0 && (\n <div className=\"space-y-2\">\n <Label\n htmlFor=\"category\"\n className=\"text-sm sm:text-base\"\n >\n {categoryLabel}\n {categoryRequired ? \" *\" : \"\"}\n </Label>\n <Select\n id=\"category\"\n name=\"category\"\n required={categoryRequired}\n defaultValue=\"\"\n className=\"text-sm sm:text-base\"\n >\n {/*\n * `disabled` is tied to `categoryRequired` on\n * purpose. When required, the placeholder is\n * locked out so the native form-validation can\n * enforce that the user picks a real value;\n * when optional, leaving it enabled lets the\n * user clear an accidental selection back to\n * the empty / uncategorized state (otherwise\n * an optional dropdown becomes effectively\n * sticky after any click). The form-submit\n * handler treats `category === ''` as\n * `undefined` on the wire so unselected\n * submissions don't carry a category at all.\n */}\n <option value=\"\" disabled={categoryRequired}>\n {categoryPlaceholder}\n </option>\n {categories.map((c) => (\n <option key={c.value} value={c.value}>\n {c.label}\n </option>\n ))}\n </Select>\n </div>\n )}\n\n <div className=\"space-y-2\">\n <Label htmlFor=\"subject\" className=\"text-sm sm:text-base\">\n Subject *\n </Label>\n <Input\n id=\"subject\"\n name=\"subject\"\n required\n placeholder=\"How can we help you?\"\n className=\"text-sm sm:text-base\"\n />\n </div>\n\n <div className=\"space-y-2\">\n <Label htmlFor=\"message\" className=\"text-sm sm:text-base\">\n Message *\n </Label>\n <Textarea\n id=\"message\"\n name=\"message\"\n required\n placeholder=\"Tell us more about your needs...\"\n rows={5}\n className=\"text-sm sm:text-base min-h-[120px] sm:min-h-[150px] resize-y\"\n />\n </div>\n\n <div className=\"space-y-4\">\n {effectiveRecaptchaSiteKey && (\n <div\n className=\"flex justify-center sm:justify-start\"\n style={{ minHeight: RECAPTCHA_WIDGET_HEIGHT }}\n >\n {/* Mounted on first engagement — see useDeferredRecaptcha. */}\n {recaptchaGate.armed && (\n <ReCAPTCHA\n ref={recaptchaRef}\n sitekey={effectiveRecaptchaSiteKey}\n />\n )}\n </div>\n )}\n\n <Button\n type=\"submit\"\n size=\"lg\"\n disabled={isSubmitting}\n className=\"w-full sm:w-auto min-w-[200px]\"\n >\n {isSubmitting ? (\n \"Sending...\"\n ) : (\n <>\n Send Message <Send className=\"ml-2 h-4 w-4\" />\n </>\n )}\n </Button>\n </div>\n\n {submitStatus === \"success\" && (\n <div className=\"p-3 sm:p-4 bg-green-50 border border-green-200 rounded-lg text-green-800 mt-4\">\n <p className=\"font-medium text-sm sm:text-base\">\n Message sent successfully!\n </p>\n <p className=\"text-xs sm:text-sm mt-1\">\n Thank you for contacting {displayName}. We'll get\n back to you within 24 hours.\n </p>\n </div>\n )}\n\n {submitStatus === \"error\" && (\n <div className=\"p-3 sm:p-4 bg-red-50 border border-red-200 rounded-lg text-red-800 mt-4\">\n <p className=\"font-medium text-sm sm:text-base\">\n Failed to send message\n </p>\n <p className=\"text-xs sm:text-sm mt-1\">\n Please try again later or contact us directly at{\" \"}\n {contactEmail}\n </p>\n </div>\n )}\n </form>\n </div>\n </div>\n </div>\n </div>\n </section>\n\n {/* Additional Contact Options — hidden when additionalOptions is empty */}\n {additionalOptions.length > 0 && (\n <section className=\"py-12 sm:py-16 md:py-20 lg:py-24 bg-muted/30\">\n <div className=\"max-w-7xl mx-auto px-4 sm:px-6 lg:px-8\">\n <h2 className=\"text-2xl sm:text-3xl font-bold text-center mb-8 sm:mb-12\">\n More Ways to Connect\n </h2>\n\n <div className=\"grid sm:grid-cols-2 lg:grid-cols-3 gap-6 sm:gap-8 max-w-5xl mx-auto\">\n {additionalOptions.map((option, index) => (\n <div\n key={index}\n className=\"text-center p-4 sm:p-6 bg-card border rounded-lg\"\n >\n <h3 className=\"font-semibold text-base sm:text-lg mb-2\">\n {option.title}\n </h3>\n <p className=\"text-muted-foreground text-sm sm:text-base mb-4 leading-relaxed\">\n {replacePlaceholders(\n option.description,\n displayName,\n contactEmail,\n )}\n </p>\n <Button\n variant=\"outline\"\n asChild\n className=\"text-sm sm:text-base\"\n >\n <a href={option.buttonLink}>{option.buttonText}</a>\n </Button>\n </div>\n ))}\n </div>\n </div>\n </section>\n )}\n </div>\n );\n}\n"]}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var react = require('react');
|
|
4
|
+
|
|
5
|
+
function RybbitAnalytics({
|
|
6
|
+
siteId,
|
|
7
|
+
scriptUrl = "https://analytics.burdenoff.com/api/script.js",
|
|
8
|
+
enabled = true
|
|
9
|
+
}) {
|
|
10
|
+
react.useEffect(() => {
|
|
11
|
+
if (!enabled || !siteId) return;
|
|
12
|
+
const existingScript = document.querySelector(
|
|
13
|
+
`script[data-site-id="${siteId}"]`
|
|
14
|
+
);
|
|
15
|
+
if (existingScript) return;
|
|
16
|
+
const script = document.createElement("script");
|
|
17
|
+
script.src = scriptUrl;
|
|
18
|
+
script.defer = true;
|
|
19
|
+
script.crossOrigin = "anonymous";
|
|
20
|
+
script.setAttribute("data-site-id", siteId);
|
|
21
|
+
document.head.appendChild(script);
|
|
22
|
+
return () => {
|
|
23
|
+
const scriptToRemove = document.querySelector(
|
|
24
|
+
`script[data-site-id="${siteId}"]`
|
|
25
|
+
);
|
|
26
|
+
if (scriptToRemove) {
|
|
27
|
+
document.head.removeChild(scriptToRemove);
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
}, [siteId, scriptUrl, enabled]);
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
exports.RybbitAnalytics = RybbitAnalytics;
|
|
35
|
+
//# sourceMappingURL=chunk-QMA6U6AU.js.map
|
|
36
|
+
//# sourceMappingURL=chunk-QMA6U6AU.js.map
|