11<script >
2+ import { onMount } from ' svelte' ;
3+
24 export let color;
35 export let text;
46 export let subscribeForm;
57
6- let breveo_url = " https://e84a0152.sibforms.com/serve/MUIFABjdnMHTbxQ2khl6ph4PImtHS0y057KeTtnZ8ST-53106GteNUOJUzjhpVFibL3A_kN8NSvM-dHnI4U0Eu2CLfsvr_sm9db1VdgsqQvtFJFiM9KySFp7o3hZxzON2vLkcj-ioBELpTPFkCBfA2M2lg0fRjsXNlo99Mynwc6T2rYL4mDx6KHLxCXgwauF_DuSGhxf_l71MVh9"
8+ let breveo_url =
9+ ' https://e84a0152.sibforms.com/serve/MUIFABjdnMHTbxQ2khl6ph4PImtHS0y057KeTtnZ8ST-53106GteNUOJUzjhpVFibL3A_kN8NSvM-dHnI4U0Eu2CLfsvr_sm9db1VdgsqQvtFJFiM9KySFp7o3hZxzON2vLkcj-ioBELpTPFkCBfA2M2lg0fRjsXNlo99Mynwc6T2rYL4mDx6KHLxCXgwauF_DuSGhxf_l71MVh9' ;
710 // todo: Este regex testeado no deja pasar un dominio sin TLD (ej. a@a) pero implementado aquí, sí lo permite. hay que modificarlo
8- let regex = " (?:[a-z0-9!#$%&*+/=?^_`{|}~-]+(?:\. [a-z0-9!#$%&*+/=?^_`{|}~-]+)*|(?:[\x01 -\x08\x0b\x0c\x0e -\x1f\x21\x23 -\x5b\x5d -\x7f ]|\\ [\x01 -\x09\x0b\x0c\x0e -\x7f ])*)@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\. )+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[ (?:(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\. ){3}(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9])|[a-z0-9-]*[a-z0-9]:(?:[\x01 -\x08\x0b\x0c\x0e -\x1f\x21 -\x5a\x53 -\x7f ]|\\ [\x01 -\x09\x0b\x0c\x0e -\x7f ])+)\] )"
11+ let regex =
12+ ' (?:[a-z0-9!#$%&*+/=?^_`{|}~-]+(?:.[a-z0-9!#$%&*+/=?^_`{|}~-]+)*|(?:[\x01 -\x08\x0b\x0c\x0e -\x1f\x21\x23 -\x5b\x5d -\x7f ]|\\ [\x01 -\x09\x0b\x0c\x0e -\x7f ])*)@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|[(?:(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9])).){3}(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9])|[a-z0-9-]*[a-z0-9]:(?:[\x01 -\x08\x0b\x0c\x0e -\x1f\x21 -\x5a\x53 -\x7f ]|\\ [\x01 -\x09\x0b\x0c\x0e -\x7f ])+)])' ;
13+
14+ // Spam prevention variables
15+ let formStartTime = Date .now ();
16+ let turnstileResponse = ' ' ;
17+ let turnstileWidgetId = null ;
18+ let isTurnstileLoaded = false ;
19+
20+ onMount (() => {
21+ if (! window .turnstile ) {
22+ console .log (' Cargando script de Turnstile...' );
23+ const script = document .createElement (' script' );
24+ script .src = ' https://challenges.cloudflare.com/turnstile/v0/api.js' ;
25+ script .async = true ;
26+ script .defer = true ;
27+ script .onload = () => {
28+ console .log (' Script de Turnstile cargado exitosamente' );
29+ isTurnstileLoaded = true ;
30+ setTimeout (() => {
31+ initTurnstile ();
32+ }, 500 );
33+ };
34+ script .onerror = () => {
35+ console .error (' Error al cargar el script de Turnstile' );
36+ };
37+ document .head .appendChild (script);
38+ } else {
39+ console .log (' Turnstile ya está cargado' );
40+ isTurnstileLoaded = true ;
41+ initTurnstile ();
42+ }
43+ });
44+
45+ // Widget para el Captcha de Cloudflare Turnstile
46+ function initTurnstile () {
47+ console .log (' Intentando inicializar Turnstile...' );
48+ console .log (' window.turnstile:' , window .turnstile );
49+ console .log (' isTurnstileLoaded:' , isTurnstileLoaded);
50+
51+ if (window .turnstile && isTurnstileLoaded) {
52+ try {
53+ console .log (' Renderizando widget de Turnstile...' );
54+ turnstileWidgetId = window .turnstile .render (' #turnstile-container' , {
55+ sitekey: ' 0x4AAAAAAB6c7nCtT4Pnd6ZP' ,
56+ callback : function (token ) {
57+ console .log (' Callback de Turnstile recibido:' , token);
58+ turnstileResponse = token;
59+ },
60+ ' expired-callback ' : function () {
61+ console .log (' Turnstile caducado' );
62+ turnstileResponse = ' ' ;
63+ },
64+ ' error-callback ' : function (error ) {
65+ console .error (' Error de Turnstile:' , error);
66+ turnstileResponse = ' ' ;
67+ }
68+ });
69+ console .log (' ID del widget de Turnstile:' , turnstileWidgetId);
70+ } catch (error) {
71+ console .error (' Error al inicializar Turnstile:' , error);
72+ }
73+ } else {
74+ console .log (' Turnstile aún no está listo' );
75+ }
76+ }
77+
78+ // Validate form submission
79+ function validateForm (event ) {
80+ const target = event .target ;
81+
82+ // Check honeypot field
83+ const honeypot = target .querySelector (' input[name="website"]' );
84+ if (honeypot && honeypot .value !== ' ' ) {
85+ event .preventDefault ();
86+ console .log (' Bot detectado: campo honeypot llenado' );
87+ alert (' Solicitud bloqueada por seguridad.' );
88+ return false ;
89+ }
90+
91+ if (isFormTooFast ()) {
92+ event .preventDefault ();
93+ console .log (' Bot detectado: formulario enviado muy rápido' );
94+ alert (' Por favor, espera unos segundos antes de enviar el formulario.' );
95+ return false ;
96+ }
97+
98+ console .log (' Verificando respuesta de Turnstile:' , turnstileResponse);
99+ console .log (' ID del widget de Turnstile:' , turnstileWidgetId);
100+ console .log (' isTurnstileLoaded:' , isTurnstileLoaded);
101+
102+ if (! turnstileResponse) {
103+ event .preventDefault ();
104+ alert (' Por favor, completa la verificación de seguridad.' );
105+ return false ;
106+ }
107+
108+ console .log (' Validación del formulario pasada, enviando a Brevo' );
109+ return true ;
110+ }
111+
112+ // Initialize Turnstile when component becomes visible
113+ function handleFormFocus () {
114+ if (isTurnstileLoaded && ! turnstileWidgetId) {
115+ setTimeout (initTurnstile, 100 );
116+ }
117+ }
118+
119+ // For localhost testing - bypass Turnstile
120+ function bypassTurnstileForTesting () {
121+ console .log (' Saltando Turnstile para pruebas en localhost' );
122+ turnstileResponse = ' test-token-for-localhost' ;
123+ }
9124 </script >
10125
11- <div class ="bg-[url('/grid-bg.png')] min-h-[350px] p-2 md:p-10 h-auto w-full container m-auto flex items-center drop-shadow-full" style ="background-color: {color };" >
126+ <div
127+ class =" bg-[url('/grid-bg.png')] min-h-[350px] p-2 md:p-10 h-auto w-full container m-auto flex items-center drop-shadow-full"
128+ style ="background-color: {color };"
129+ >
12130 <div class =" Frame52 w-full flex-col justify-center items-center md:p-5" >
13- <div class =" text-center text-black text-2xl md:text-5xl font-bold font-['Albert Sans'] md:leading-[63.44px] md:p-5 text-wrap" >
131+ <div
132+ class =" text-center text-black text-2xl md:text-5xl font-bold font-['Albert Sans'] md:leading-[63.44px] md:p-5 text-wrap"
133+ >
14134 <p >
15135 {@html text }
16136 </p >
17137 </div >
18- {#if subscribeForm }
138+ {#if subscribeForm }
19139 <div class =" flex justify-center mx-auto my-3" >
20- <form class ="w-full max-w-sm validate" action ={breveo_url } method =" post" id =" newsletter-form" target =" _blank" >
21- <div class =" flex items-center" >
22- <
input class =
"appearance-none border-none w-full text-gray-700 px-4 py-3 rounded-tl-3xl rounded-bl-3xl border-zinc-300 leading-tight focus:outline-none" placeholder =
"[email protected] " aria-label =
"Full name" type =
"email" name =
"EMAIL" required =
"true" value =
"" pattern ={
regex }>
140+ <form
141+ class =" w-full max-w-sm validate"
142+ action ={breveo_url }
143+ method =" post"
144+ id =" newsletter-form"
145+ target =" _blank"
146+ on:submit ={validateForm }
147+ on:focus ={handleFormFocus }
148+ >
149+ <div class =" flex flex-col items-center space-y-3" >
150+ <div class =" flex items-center w-full" >
151+ <input
152+ class =" appearance-none border-none w-full text-gray-700 px-4 py-3 rounded-tl-3xl rounded-bl-3xl border-zinc-300 leading-tight focus:outline-none"
153+ 154+ aria-label =" Email address"
155+ type =" email"
156+ name =" EMAIL"
157+ required ={true }
158+ value =" "
159+ pattern ={regex }
160+ />
161+ <button
162+ class =" flex-shrink-0 px-5 py-2 bg-black rounded-tr-3xl h-11 rounded-br-3xl text-sm border border-black text-white rounded text-base font-bold font-['Albert Sans'] uppercase leading-normal"
163+ type =" submit"
164+ >
165+ <input
166+ type =" submit"
167+ name =" subscribe"
168+ class =" button uppercase"
169+ value =" Suscribirme"
170+ />
171+ </button >
172+ </div >
173+
174+ <div id =" turnstile-container" class =" flex justify-center" ></div >
175+
23176 <div style =" position: absolute; left: -5000px;" aria-hidden =" true" >
24- /* real people should not fill this in and expect good things - do not remove this or risk form bot signups */
25- <input type =" text" name =" b_6a37b9b668c1da15bcc718fa4_203574be23" tabindex =" -1" value =" " >
177+ <input
178+ type =" text"
179+ name =" b_6a37b9b668c1da15bcc718fa4_203574be23"
180+ tabindex =" -1"
181+ value =" "
182+ />
183+ <input type =" text" name =" website" tabindex =" -1" value =" " autocomplete =" off" />
184+ <input type ="hidden" name ="form_time" value ={formStartTime } />
26185 </div >
27- <button class =" flex-shrink-0 px-5 py-2 bg-black rounded-tr-3xl h-11 rounded-br-3xl text-sm border border-black text-white rounded text-base font-bold font-['Albert Sans'] uppercase leading-normal" type =" button" >
28- <input type =" submit" name =" subscribe" class =" button uppercase" value =" Suscribirme" >
29- </button >
30186 </div >
31187 </form >
32188 </div >
33- {/if }
189+ {/if }
34190 </div >
35- </div >
191+ </div >
0 commit comments