Files
valeainversionesca/apps/web/src/components/ContactForm.jsx
T

105 lines
5.7 KiB
React

import React, { useState, useRef } from 'react';
import { motion } from 'framer-motion';
import { Send, Loader2 } from 'lucide-react';
import { Button } from '@/components/ui/button';
import { useToast } from '@/components/ui/use-toast';
const ContactForm = () => {
const { toast } = useToast();
const form = useRef();
const [loading, setLoading] = useState(false);
const [formData, setFormData] = useState({
nombre: '', email: '', telefono: '', empresa: '', asunto: '', mensaje: ''
});
const [errors, setErrors] = useState({});
const validateForm = () => {
const newErrors = {};
if (!formData.nombre.trim()) newErrors.nombre = 'El nombre es requerido';
if (!formData.email.trim()) newErrors.email = 'El email es requerido';
else if (!/\S+@\S+\.\S+/.test(formData.email)) newErrors.email = 'Email inválido';
if (!formData.telefono.trim()) newErrors.telefono = 'El teléfono es requerido';
if (!formData.asunto.trim()) newErrors.asunto = 'El asunto es requerido';
if (!formData.mensaje.trim()) newErrors.mensaje = 'El mensaje es requerido';
setErrors(newErrors);
return Object.keys(newErrors).length === 0;
};
const handleChange = (e) => {
const { name, value } = e.target;
setFormData(prev => ({ ...prev, [name]: value }));
if (errors[name]) setErrors(prev => ({ ...prev, [name]: '' }));
};
const handleSubmit = async (e) => {
e.preventDefault();
if (!validateForm()) {
toast({ title: "Error de validación", description: "Por favor complete todos los campos requeridos.", variant: "destructive" });
return;
}
setLoading(true);
try {
await new Promise(resolve => setTimeout(resolve, 1500));
toast({ title: "¡Mensaje enviado!", description: "Gracias por contactarnos. Le responderemos pronto." });
setFormData({ nombre: '', email: '', telefono: '', empresa: '', asunto: '', mensaje: '' });
} catch (error) {
toast({ title: "Error", description: "Hubo un problema. Intente de nuevo.", variant: "destructive" });
} finally {
setLoading(false);
}
};
const inputClasses = (error) => `w-full px-4 py-3 bg-blanco border ${error ? 'border-red-500' : 'border-azulClaro'} rounded-lg text-azulOscuro placeholder-grisMedio focus:outline-none focus:ring-2 focus:ring-azulClaro focus:border-azulPrincipal transition-colors`;
return (
<motion.form
ref={form}
initial={{ opacity: 0, y: 30 }}
whileInView={{ opacity: 1, y: 0 }}
viewport={{ once: true }}
transition={{ duration: 0.6 }}
onSubmit={handleSubmit}
className="bg-grisClaro backdrop-blur-sm border border-azulMedio/30 rounded-xl p-8 shadow-xl"
>
<div className="grid grid-cols-1 md:grid-cols-2 gap-6 mb-6">
<div>
<label htmlFor="nombre" className="block text-sm font-medium text-azulPrincipal mb-2">Nombre <span className="text-naranjaAccento">*</span></label>
<input type="text" id="nombre" name="nombre" value={formData.nombre} onChange={handleChange} className={inputClasses(errors.nombre)} placeholder="Su nombre completo" />
{errors.nombre && <p className="mt-1 text-sm text-red-500">{errors.nombre}</p>}
</div>
<div>
<label htmlFor="email" className="block text-sm font-medium text-azulPrincipal mb-2">Email <span className="text-naranjaAccento">*</span></label>
<input type="email" id="email" name="email" value={formData.email} onChange={handleChange} className={inputClasses(errors.email)} placeholder="correo@ejemplo.com" />
{errors.email && <p className="mt-1 text-sm text-red-500">{errors.email}</p>}
</div>
<div>
<label htmlFor="telefono" className="block text-sm font-medium text-azulPrincipal mb-2">Teléfono <span className="text-naranjaAccento">*</span></label>
<input type="tel" id="telefono" name="telefono" value={formData.telefono} onChange={handleChange} className={inputClasses(errors.telefono)} placeholder="0414-1234567" />
{errors.telefono && <p className="mt-1 text-sm text-red-500">{errors.telefono}</p>}
</div>
<div>
<label htmlFor="empresa" className="block text-sm font-medium text-azulPrincipal mb-2">Empresa <span className="text-grisMedio text-xs font-normal">(Opcional)</span></label>
<input type="text" id="empresa" name="empresa" value={formData.empresa} onChange={handleChange} className={inputClasses(false)} placeholder="Nombre de su empresa" />
</div>
</div>
<div className="mb-6">
<label htmlFor="asunto" className="block text-sm font-medium text-azulPrincipal mb-2">Asunto <span className="text-naranjaAccento">*</span></label>
<input type="text" id="asunto" name="asunto" value={formData.asunto} onChange={handleChange} className={inputClasses(errors.asunto)} placeholder="Asunto de su consulta" />
{errors.asunto && <p className="mt-1 text-sm text-red-500">{errors.asunto}</p>}
</div>
<div className="mb-6">
<label htmlFor="mensaje" className="block text-sm font-medium text-azulPrincipal mb-2">Mensaje <span className="text-naranjaAccento">*</span></label>
<textarea id="mensaje" name="mensaje" value={formData.mensaje} onChange={handleChange} rows={6} className={`${inputClasses(errors.mensaje)} resize-none`} placeholder="Escriba su mensaje aquí..." />
{errors.mensaje && <p className="mt-1 text-sm text-red-500">{errors.mensaje}</p>}
</div>
<Button type="submit" variant="cta" disabled={loading} className="w-full py-6 text-lg rounded-lg shadow-lg">
{loading ? <><Loader2 className="w-5 h-5 mr-2 animate-spin" /> Enviando...</> : <><Send className="w-5 h-5 mr-2" /> Enviar Mensaje</>}
</Button>
</motion.form>
);
};
export default ContactForm;