/** * FLOWDESK - FORM HANDLER * Manejo del formulario de contacto con validación, estados visuales * y sección preparada para integración SMTP / EmailJS / fetch POST. */ (function () { 'use strict'; // ============================================================ // ELEMENTOS DEL DOM // ============================================================ const form = document.getElementById('contactForm'); const submitBtn = document.getElementById('submitBtn'); const alertSuccess = document.getElementById('alertSuccess'); const alertError = document.getElementById('alertError'); const backToTop = document.getElementById('backToTop'); // ============================================================ // BOTÓN VOLVER ARRIBA // ============================================================ function initBackToTop() { if (!backToTop) return; function toggleVisibility() { if (window.scrollY > 400) { backToTop.classList.add('back-to-top--visible'); } else { backToTop.classList.remove('back-to-top--visible'); } } window.addEventListener('scroll', toggleVisibility, { passive: true }); toggleVisibility(); backToTop.addEventListener('click', function (e) { e.preventDefault(); window.scrollTo({ top: 0, behavior: 'smooth' }); }); } // ============================================================ // ANIMACIONES POR SCROLL (Intersección) // ============================================================ function initScrollAnimations() { const animatedSelectors = [ '.feature-card', '.info-card', '.sector-card', '.stat-item', '.plan-item' ]; const observer = new IntersectionObserver( (entries) => { entries.forEach((entry) => { if (entry.isIntersecting) { entry.target.classList.add(entry.target.classList[0] + '--visible'); observer.unobserve(entry.target); } }); }, { threshold: 0.1, rootMargin: '0px 0px -40px 0px' } ); animatedSelectors.forEach((selector) => { document.querySelectorAll(selector).forEach((el) => { observer.observe(el); }); }); } // ============================================================ // VALIDACIÓN DE FORMULARIO // ============================================================ function validateField(field) { const isValid = field.checkValidity(); if (isValid) { field.classList.remove('is-invalid'); } else { field.classList.add('is-invalid'); } return isValid; } function validateForm() { let isFormValid = true; const fields = form.querySelectorAll('input, textarea'); fields.forEach((field) => { if (!validateField(field)) { isFormValid = false; } }); return isFormValid; } function clearValidation() { const fields = form.querySelectorAll('input, textarea'); fields.forEach((field) => { field.classList.remove('is-invalid'); }); } // ============================================================ // ESTADOS DEL BOTÓN // ============================================================ function setLoadingState(loading) { if (loading) { submitBtn.disabled = true; submitBtn.classList.add('contacto__submit--loading'); } else { submitBtn.disabled = false; submitBtn.classList.remove('contacto__submit--loading'); } } // ============================================================ // ALERTAS // ============================================================ function showAlert(type) { alertSuccess.classList.remove('contacto__alert--visible'); alertError.classList.remove('contacto__alert--visible'); if (type === 'success') { alertSuccess.classList.add('contacto__alert--visible'); } else if (type === 'error') { alertError.classList.add('contacto__alert--visible'); } } function hideAlerts() { alertSuccess.classList.remove('contacto__alert--visible'); alertError.classList.remove('contacto__alert--visible'); } // ============================================================ // ENVÍO DEL FORMULARIO // ============================================================ async function handleSubmit(event) { event.preventDefault(); event.stopPropagation(); hideAlerts(); // Validación nativa HTML5 if (!validateForm()) { // Scroll al primer campo inválido const firstInvalid = form.querySelector('.is-invalid'); if (firstInvalid) { firstInvalid.scrollIntoView({ behavior: 'smooth', block: 'center' }); firstInvalid.focus(); } return; } setLoadingState(true); // Recolectar datos del formulario const formData = new FormData(form); const data = Object.fromEntries(formData.entries()); // ============================================================ // CONFIGURACIÓN SMTP / SERVICIO DE EMAIL // ============================================================ // Descomentá y configurá una de las siguientes opciones según // el servicio que vayas a utilizar. // ============================================================ /* // -------------------------------------------------------- // OPCIÓN 1: EmailJS // -------------------------------------------------------- // 1. Crear cuenta en https://www.emailjs.com/ // 2. Configurar un servicio de email (Gmail, Outlook, etc.) // 3. Crear una plantilla de email // 4. Reemplazar los valores de serviceID, templateID y publicKey try { await emailjs.send( 'TU_SERVICE_ID', // <-- Reemplazar 'TU_TEMPLATE_ID', // <-- Reemplazar { from_name: data.nombre, from_email: data.email, empresa: data.empresa, whatsapp: data.whatsapp, mensaje: data.mensaje, }, 'TU_PUBLIC_KEY' // <-- Reemplazar ); showAlert('success'); form.reset(); clearValidation(); } catch (error) { console.error('Error al enviar con EmailJS:', error); showAlert('error'); } */ /* // -------------------------------------------------------- // OPCIÓN 2: Fetch POST a tu propio backend / API // -------------------------------------------------------- // Reemplazar la URL con tu endpoint real. try { const response = await fetch('https://tu-api.com/enviar-formulario', { method: 'POST', headers: { 'Content-Type': 'application/json', // 'Authorization': 'Bearer TU_TOKEN_AQUI' // Si es necesario }, body: JSON.stringify(data) }); if (response.ok) { showAlert('success'); form.reset(); clearValidation(); } else { throw new Error('Respuesta no OK del servidor'); } } catch (error) { console.error('Error al enviar formulario:', error); showAlert('error'); } */ /* // -------------------------------------------------------- // OPCIÓN 3: SMTP.js (vía CDN en el HTML) // -------------------------------------------------------- // Incluir en el
de index.html: // try { await Email.send({ Host: 'smtp.tudominio.com', Username: 'tu-usuario', Password: 'tu-contraseña', To: 'destino@tudominio.com', From: data.email, Subject: `Nueva consulta de ${data.nombre} - ${data.empresa}`, Body: ` Nombre: ${data.nombre}