@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.esm.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import fs from 'fs';
2
2
  import path from 'path';
3
- import React, { useState, useEffect, useRef, createContext, useMemo, useContext } from 'react';
3
+ import React, { useRef, useEffect, useState, createContext, useMemo, useContext } from 'react';
4
4
  import { useQueryClient, useMutation, useQuery } from '@tanstack/react-query';
5
5
 
6
6
  /**
@@ -2343,13 +2343,90 @@ const useMauticRemoveFromSegment = () => {
2343
2343
  });
2344
2344
  };
2345
2345
 
2346
+ const TurnstileWidget = ({ siteKey, onSuccess, onError, onExpire, theme = 'auto', size = 'normal', tabIndex, }) => {
2347
+ const widgetRef = useRef(null);
2348
+ const widgetId = useRef(null);
2349
+ const scriptLoaded = useRef(false);
2350
+ useEffect(() => {
2351
+ if (!widgetRef.current || !siteKey)
2352
+ return;
2353
+ const loadTurnstile = () => {
2354
+ if (window.turnstile && widgetRef.current && !widgetId.current) {
2355
+ try {
2356
+ widgetId.current = window.turnstile.render(widgetRef.current, {
2357
+ sitekey: siteKey,
2358
+ callback: onSuccess,
2359
+ 'error-callback': onError,
2360
+ 'expired-callback': onExpire,
2361
+ theme,
2362
+ size,
2363
+ tabindex: tabIndex,
2364
+ });
2365
+ }
2366
+ catch (error) {
2367
+ console.error('Failed to render Turnstile widget:', error);
2368
+ onError?.();
2369
+ }
2370
+ }
2371
+ };
2372
+ // Check if Turnstile is already loaded
2373
+ if (window.turnstile) {
2374
+ loadTurnstile();
2375
+ }
2376
+ else if (!scriptLoaded.current) {
2377
+ // Load Turnstile script
2378
+ scriptLoaded.current = true;
2379
+ const script = document.createElement('script');
2380
+ script.src = 'https://challenges.cloudflare.com/turnstile/v0/api.js';
2381
+ script.async = true;
2382
+ script.defer = true;
2383
+ script.onload = loadTurnstile;
2384
+ script.onerror = () => {
2385
+ console.error('Failed to load Turnstile script');
2386
+ onError?.();
2387
+ };
2388
+ document.head.appendChild(script);
2389
+ }
2390
+ return () => {
2391
+ if (widgetId.current && window.turnstile) {
2392
+ try {
2393
+ window.turnstile.remove(widgetId.current);
2394
+ }
2395
+ catch (error) {
2396
+ console.error('Failed to remove Turnstile widget:', error);
2397
+ }
2398
+ widgetId.current = null;
2399
+ }
2400
+ };
2401
+ }, [siteKey, onSuccess, onError, onExpire, theme, size, tabIndex]);
2402
+ return jsxRuntimeExports.jsx("div", { ref: widgetRef, className: "cf-turnstile" });
2403
+ };
2404
+
2346
2405
  const MauticForm = ({ formId, title, description, className = '', form, onSubmit, onSuccess, onError, }) => {
2347
2406
  const [formData, setFormData] = useState({});
2348
2407
  const [errors, setErrors] = useState({});
2349
2408
  const [isSubmitting, setIsSubmitting] = useState(false);
2350
2409
  const [isSubmitted, setIsSubmitted] = useState(false);
2351
2410
  const [showSuccessMessage, setShowSuccessMessage] = useState(false);
2411
+ const [turnstileToken, setTurnstileToken] = useState(null);
2352
2412
  const submitMutation = useMauticFormSubmission();
2413
+ // Get Turnstile site key from environment
2414
+ const getTurnstilesiteKey = () => {
2415
+ try {
2416
+ // @ts-ignore - import.meta is a Vite-specific global
2417
+ if (typeof import.meta !== 'undefined' && import.meta.env) {
2418
+ // @ts-ignore
2419
+ const key = import.meta.env.VITE_TURNSTILE_SITE_KEY;
2420
+ // Ensure we return a string or undefined, not an object
2421
+ return typeof key === 'string' ? key : undefined;
2422
+ }
2423
+ }
2424
+ catch (e) {
2425
+ // import.meta not available
2426
+ }
2427
+ return undefined;
2428
+ };
2429
+ const turnstilesiteKey = getTurnstilesiteKey();
2353
2430
  useEffect(() => {
2354
2431
  if (!form) {
2355
2432
  console.warn(`Form ${formId} not found`);
@@ -2408,6 +2485,11 @@ const MauticForm = ({ formId, title, description, className = '', form, onSubmit
2408
2485
  if (!validateForm()) {
2409
2486
  return;
2410
2487
  }
2488
+ // Check Turnstile token if enabled
2489
+ if (turnstilesiteKey && !turnstileToken) {
2490
+ setErrors(prev => ({ ...prev, _turnstile: 'Please complete the verification' }));
2491
+ return;
2492
+ }
2411
2493
  setIsSubmitting(true);
2412
2494
  setErrors({});
2413
2495
  try {
@@ -2423,7 +2505,12 @@ const MauticForm = ({ formId, title, description, className = '', form, onSubmit
2423
2505
  formId: parseInt(formId),
2424
2506
  fields: formData,
2425
2507
  returnUrl: window.location.href,
2426
- ...(derivedFormName ? { formName: derivedFormName } : {})
2508
+ ...(derivedFormName ? { formName: derivedFormName } : {}),
2509
+ ...(turnstileToken ? {
2510
+ headers: {
2511
+ 'cf-turnstile-response': turnstileToken
2512
+ }
2513
+ } : {})
2427
2514
  };
2428
2515
  // Call custom onSubmit if provided
2429
2516
  if (onSubmit) {
@@ -2512,7 +2599,23 @@ const MauticForm = ({ formId, title, description, className = '', form, onSubmit
2512
2599
  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
2513
2600
  // Filter out button/submit from field group; render them in actions
2514
2601
  .filter((field) => field.type !== 'button' && field.alias !== 'submit')
2515
- .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." }) }))] }));
2602
+ .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) => {
2603
+ setTurnstileToken(token);
2604
+ // Clear any turnstile error
2605
+ if (errors._turnstile) {
2606
+ setErrors(prev => {
2607
+ const next = { ...prev };
2608
+ delete next._turnstile;
2609
+ return next;
2610
+ });
2611
+ }
2612
+ }, onError: () => {
2613
+ setTurnstileToken(null);
2614
+ setErrors(prev => ({ ...prev, _turnstile: 'Verification failed. Please try again.' }));
2615
+ }, onExpire: () => {
2616
+ setTurnstileToken(null);
2617
+ setErrors(prev => ({ ...prev, _turnstile: 'Verification expired. Please verify again.' }));
2618
+ }, 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." }) }))] }));
2516
2619
  };
2517
2620
 
2518
2621
  const MauticTracking = ({ enabled, mauticUrl, proxyUrl, children }) => {
@@ -2655,65 +2758,6 @@ const useMauticEvent = () => {
2655
2758
  };
2656
2759
  };
2657
2760
 
2658
- const TurnstileWidget = ({ siteKey, onSuccess, onError, onExpire, theme = 'auto', size = 'normal', tabIndex, }) => {
2659
- const widgetRef = useRef(null);
2660
- const widgetId = useRef(null);
2661
- const scriptLoaded = useRef(false);
2662
- useEffect(() => {
2663
- if (!widgetRef.current || !siteKey)
2664
- return;
2665
- const loadTurnstile = () => {
2666
- if (window.turnstile && widgetRef.current && !widgetId.current) {
2667
- try {
2668
- widgetId.current = window.turnstile.render(widgetRef.current, {
2669
- sitekey: siteKey,
2670
- callback: onSuccess,
2671
- 'error-callback': onError,
2672
- 'expired-callback': onExpire,
2673
- theme,
2674
- size,
2675
- tabindex: tabIndex,
2676
- });
2677
- }
2678
- catch (error) {
2679
- console.error('Failed to render Turnstile widget:', error);
2680
- onError?.();
2681
- }
2682
- }
2683
- };
2684
- // Check if Turnstile is already loaded
2685
- if (window.turnstile) {
2686
- loadTurnstile();
2687
- }
2688
- else if (!scriptLoaded.current) {
2689
- // Load Turnstile script
2690
- scriptLoaded.current = true;
2691
- const script = document.createElement('script');
2692
- script.src = 'https://challenges.cloudflare.com/turnstile/v0/api.js';
2693
- script.async = true;
2694
- script.defer = true;
2695
- script.onload = loadTurnstile;
2696
- script.onerror = () => {
2697
- console.error('Failed to load Turnstile script');
2698
- onError?.();
2699
- };
2700
- document.head.appendChild(script);
2701
- }
2702
- return () => {
2703
- if (widgetId.current && window.turnstile) {
2704
- try {
2705
- window.turnstile.remove(widgetId.current);
2706
- }
2707
- catch (error) {
2708
- console.error('Failed to remove Turnstile widget:', error);
2709
- }
2710
- widgetId.current = null;
2711
- }
2712
- };
2713
- }, [siteKey, onSuccess, onError, onExpire, theme, size, tabIndex]);
2714
- return jsxRuntimeExports.jsx("div", { ref: widgetRef, className: "cf-turnstile" });
2715
- };
2716
-
2717
2761
  const MauticContext = createContext(null);
2718
2762
  const MauticProvider = ({ config, children }) => {
2719
2763
  const client = useMemo(() => {