@marvalt/madapter 2.1.1 → 2.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -2346,13 +2346,90 @@ const useMauticRemoveFromSegment = () => {
2346
2346
  });
2347
2347
  };
2348
2348
 
2349
+ const TurnstileWidget = ({ siteKey, onSuccess, onError, onExpire, theme = 'auto', size = 'normal', tabIndex, }) => {
2350
+ const widgetRef = React.useRef(null);
2351
+ const widgetId = React.useRef(null);
2352
+ const scriptLoaded = React.useRef(false);
2353
+ React.useEffect(() => {
2354
+ if (!widgetRef.current || !siteKey)
2355
+ return;
2356
+ const loadTurnstile = () => {
2357
+ if (window.turnstile && widgetRef.current && !widgetId.current) {
2358
+ try {
2359
+ widgetId.current = window.turnstile.render(widgetRef.current, {
2360
+ sitekey: siteKey,
2361
+ callback: onSuccess,
2362
+ 'error-callback': onError,
2363
+ 'expired-callback': onExpire,
2364
+ theme,
2365
+ size,
2366
+ tabindex: tabIndex,
2367
+ });
2368
+ }
2369
+ catch (error) {
2370
+ console.error('Failed to render Turnstile widget:', error);
2371
+ onError?.();
2372
+ }
2373
+ }
2374
+ };
2375
+ // Check if Turnstile is already loaded
2376
+ if (window.turnstile) {
2377
+ loadTurnstile();
2378
+ }
2379
+ else if (!scriptLoaded.current) {
2380
+ // Load Turnstile script
2381
+ scriptLoaded.current = true;
2382
+ const script = document.createElement('script');
2383
+ script.src = 'https://challenges.cloudflare.com/turnstile/v0/api.js';
2384
+ script.async = true;
2385
+ script.defer = true;
2386
+ script.onload = loadTurnstile;
2387
+ script.onerror = () => {
2388
+ console.error('Failed to load Turnstile script');
2389
+ onError?.();
2390
+ };
2391
+ document.head.appendChild(script);
2392
+ }
2393
+ return () => {
2394
+ if (widgetId.current && window.turnstile) {
2395
+ try {
2396
+ window.turnstile.remove(widgetId.current);
2397
+ }
2398
+ catch (error) {
2399
+ console.error('Failed to remove Turnstile widget:', error);
2400
+ }
2401
+ widgetId.current = null;
2402
+ }
2403
+ };
2404
+ }, [siteKey, onSuccess, onError, onExpire, theme, size, tabIndex]);
2405
+ return jsxRuntimeExports.jsx("div", { ref: widgetRef, className: "cf-turnstile" });
2406
+ };
2407
+
2349
2408
  const MauticForm = ({ formId, title, description, className = '', form, onSubmit, onSuccess, onError, }) => {
2350
2409
  const [formData, setFormData] = React.useState({});
2351
2410
  const [errors, setErrors] = React.useState({});
2352
2411
  const [isSubmitting, setIsSubmitting] = React.useState(false);
2353
2412
  const [isSubmitted, setIsSubmitted] = React.useState(false);
2354
2413
  const [showSuccessMessage, setShowSuccessMessage] = React.useState(false);
2414
+ const [turnstileToken, setTurnstileToken] = React.useState(null);
2355
2415
  const submitMutation = useMauticFormSubmission();
2416
+ // Get Turnstile site key from environment
2417
+ const getTurnstilesiteKey = () => {
2418
+ try {
2419
+ // @ts-ignore - import.meta is a Vite-specific global
2420
+ if (typeof ({ url: (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href)) }) !== 'undefined' && undefined) {
2421
+ // @ts-ignore
2422
+ const key = undefined.VITE_TURNSTILE_SITE_KEY;
2423
+ // Ensure we return a string or undefined, not an object
2424
+ return typeof key === 'string' ? key : undefined;
2425
+ }
2426
+ }
2427
+ catch (e) {
2428
+ // import.meta not available
2429
+ }
2430
+ return undefined;
2431
+ };
2432
+ const turnstilesiteKey = getTurnstilesiteKey();
2356
2433
  React.useEffect(() => {
2357
2434
  if (!form) {
2358
2435
  console.warn(`Form ${formId} not found`);
@@ -2411,6 +2488,11 @@ const MauticForm = ({ formId, title, description, className = '', form, onSubmit
2411
2488
  if (!validateForm()) {
2412
2489
  return;
2413
2490
  }
2491
+ // Check Turnstile token if enabled
2492
+ if (turnstilesiteKey && !turnstileToken) {
2493
+ setErrors(prev => ({ ...prev, _turnstile: 'Please complete the verification' }));
2494
+ return;
2495
+ }
2414
2496
  setIsSubmitting(true);
2415
2497
  setErrors({});
2416
2498
  try {
@@ -2426,7 +2508,12 @@ const MauticForm = ({ formId, title, description, className = '', form, onSubmit
2426
2508
  formId: parseInt(formId),
2427
2509
  fields: formData,
2428
2510
  returnUrl: window.location.href,
2429
- ...(derivedFormName ? { formName: derivedFormName } : {})
2511
+ ...(derivedFormName ? { formName: derivedFormName } : {}),
2512
+ ...(turnstileToken ? {
2513
+ headers: {
2514
+ 'cf-turnstile-response': turnstileToken
2515
+ }
2516
+ } : {})
2430
2517
  };
2431
2518
  // Call custom onSubmit if provided
2432
2519
  if (onSubmit) {
@@ -2515,7 +2602,23 @@ const MauticForm = ({ formId, title, description, className = '', form, onSubmit
2515
2602
  return (jsxRuntimeExports.jsxs("form", { className: `mautic-form ${className}`, onSubmit: handleSubmit, children: [(title || form.name) && (jsxRuntimeExports.jsxs("div", { className: "form-header", children: [jsxRuntimeExports.jsx("h3", { children: title || form.name }), (description || form.description) && (jsxRuntimeExports.jsx("p", { className: "form-description", children: description || form.description }))] })), jsxRuntimeExports.jsx("div", { className: "form-fields", children: form.fields
2516
2603
  // Filter out button/submit from field group; render them in actions
2517
2604
  .filter((field) => field.type !== 'button' && field.alias !== 'submit')
2518
- .map((field) => (jsxRuntimeExports.jsxs("div", { className: `form-field form-field-${field.type}`, children: [field.showLabel !== false && (jsxRuntimeExports.jsxs("label", { htmlFor: field.alias, className: "field-label", children: [field.label, field.isRequired && jsxRuntimeExports.jsx("span", { className: "required", children: "*" })] })), renderField(field), field.properties?.helpText && (jsxRuntimeExports.jsx("p", { className: "field-help", children: field.properties.helpText })), errors[field.alias] && (jsxRuntimeExports.jsx("p", { className: "field-error", children: errors[field.alias] }))] }, field.id))) }), jsxRuntimeExports.jsx("div", { className: "form-actions", children: jsxRuntimeExports.jsx("button", { type: "submit", disabled: isSubmitting, className: "submit-button", children: isSubmitting ? 'Submitting...' : 'Submit' }) }), submitMutation.error && (jsxRuntimeExports.jsx("div", { className: "form-error", children: jsxRuntimeExports.jsx("p", { children: "There was an error submitting the form. Please try again." }) }))] }));
2605
+ .map((field) => (jsxRuntimeExports.jsxs("div", { className: `form-field form-field-${field.type}`, children: [field.showLabel !== false && (jsxRuntimeExports.jsxs("label", { htmlFor: field.alias, className: "field-label", children: [field.label, field.isRequired && jsxRuntimeExports.jsx("span", { className: "required", children: "*" })] })), renderField(field), field.properties?.helpText && (jsxRuntimeExports.jsx("p", { className: "field-help", children: field.properties.helpText })), errors[field.alias] && (jsxRuntimeExports.jsx("p", { className: "field-error", children: errors[field.alias] }))] }, field.id))) }), turnstilesiteKey && (jsxRuntimeExports.jsxs("div", { className: "form-turnstile", children: [jsxRuntimeExports.jsx(TurnstileWidget, { siteKey: turnstilesiteKey, onSuccess: (token) => {
2606
+ setTurnstileToken(token);
2607
+ // Clear any turnstile error
2608
+ if (errors._turnstile) {
2609
+ setErrors(prev => {
2610
+ const next = { ...prev };
2611
+ delete next._turnstile;
2612
+ return next;
2613
+ });
2614
+ }
2615
+ }, onError: () => {
2616
+ setTurnstileToken(null);
2617
+ setErrors(prev => ({ ...prev, _turnstile: 'Verification failed. Please try again.' }));
2618
+ }, onExpire: () => {
2619
+ setTurnstileToken(null);
2620
+ setErrors(prev => ({ ...prev, _turnstile: 'Verification expired. Please verify again.' }));
2621
+ }, theme: "auto", size: "normal" }), errors._turnstile && (jsxRuntimeExports.jsx("p", { className: "field-error turnstile-error", children: errors._turnstile }))] })), jsxRuntimeExports.jsx("div", { className: "form-actions", children: jsxRuntimeExports.jsx("button", { type: "submit", disabled: isSubmitting || (!!turnstilesiteKey && !turnstileToken), className: "submit-button", children: isSubmitting ? 'Submitting...' : 'Submit' }) }), submitMutation.error && (jsxRuntimeExports.jsx("div", { className: "form-error", children: jsxRuntimeExports.jsx("p", { children: "There was an error submitting the form. Please try again." }) }))] }));
2519
2622
  };
2520
2623
 
2521
2624
  const MauticTracking = ({ enabled, mauticUrl, proxyUrl, children }) => {
@@ -2658,65 +2761,6 @@ const useMauticEvent = () => {
2658
2761
  };
2659
2762
  };
2660
2763
 
2661
- const TurnstileWidget = ({ siteKey, onSuccess, onError, onExpire, theme = 'auto', size = 'normal', tabIndex, }) => {
2662
- const widgetRef = React.useRef(null);
2663
- const widgetId = React.useRef(null);
2664
- const scriptLoaded = React.useRef(false);
2665
- React.useEffect(() => {
2666
- if (!widgetRef.current || !siteKey)
2667
- return;
2668
- const loadTurnstile = () => {
2669
- if (window.turnstile && widgetRef.current && !widgetId.current) {
2670
- try {
2671
- widgetId.current = window.turnstile.render(widgetRef.current, {
2672
- sitekey: siteKey,
2673
- callback: onSuccess,
2674
- 'error-callback': onError,
2675
- 'expired-callback': onExpire,
2676
- theme,
2677
- size,
2678
- tabindex: tabIndex,
2679
- });
2680
- }
2681
- catch (error) {
2682
- console.error('Failed to render Turnstile widget:', error);
2683
- onError?.();
2684
- }
2685
- }
2686
- };
2687
- // Check if Turnstile is already loaded
2688
- if (window.turnstile) {
2689
- loadTurnstile();
2690
- }
2691
- else if (!scriptLoaded.current) {
2692
- // Load Turnstile script
2693
- scriptLoaded.current = true;
2694
- const script = document.createElement('script');
2695
- script.src = 'https://challenges.cloudflare.com/turnstile/v0/api.js';
2696
- script.async = true;
2697
- script.defer = true;
2698
- script.onload = loadTurnstile;
2699
- script.onerror = () => {
2700
- console.error('Failed to load Turnstile script');
2701
- onError?.();
2702
- };
2703
- document.head.appendChild(script);
2704
- }
2705
- return () => {
2706
- if (widgetId.current && window.turnstile) {
2707
- try {
2708
- window.turnstile.remove(widgetId.current);
2709
- }
2710
- catch (error) {
2711
- console.error('Failed to remove Turnstile widget:', error);
2712
- }
2713
- widgetId.current = null;
2714
- }
2715
- };
2716
- }, [siteKey, onSuccess, onError, onExpire, theme, size, tabIndex]);
2717
- return jsxRuntimeExports.jsx("div", { ref: widgetRef, className: "cf-turnstile" });
2718
- };
2719
-
2720
2764
  const MauticContext = React.createContext(null);
2721
2765
  const MauticProvider = ({ config, children }) => {
2722
2766
  const client = React.useMemo(() => {