From 51599e8171a61ba0e615e826c7413eb58a956758 Mon Sep 17 00:00:00 2001 From: Jeet Vasoya Date: Mon, 25 May 2026 19:40:04 +0530 Subject: [PATCH 1/3] Email Validation Done --- src/pages/Contact/Contact.tsx | 140 ++++++++++++++++++++++++++++++++-- 1 file changed, 134 insertions(+), 6 deletions(-) diff --git a/src/pages/Contact/Contact.tsx b/src/pages/Contact/Contact.tsx index a0bfccbd..bf8eed6c 100644 --- a/src/pages/Contact/Contact.tsx +++ b/src/pages/Contact/Contact.tsx @@ -6,6 +6,7 @@ import { Send, X, CheckCircle, + AlertCircle, } from "lucide-react"; import { ThemeContext } from "../../context/ThemeContext"; import type { ThemeContextType } from "../../context/ThemeContext"; @@ -13,10 +14,78 @@ import type { ThemeContextType } from "../../context/ThemeContext"; function Contact() { const [showPopup, setShowPopup] = useState(false); const [isSubmitting, setIsSubmitting] = useState(false); + const [formData, setFormData] = useState({ + fullName: "", + email: "", + subject: "", + message: "", + }); + const [errors, setErrors] = useState<{ + fullName?: string; + email?: string; + subject?: string; + message?: string; + }>({}); + const themeContext = useContext(ThemeContext) as ThemeContextType; const { mode } = themeContext; - const handleSubmit = async () => { + // Email validation regex + const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; + + const validateForm = () => { + const newErrors: typeof errors = {}; + + if (!formData.fullName.trim()) { + newErrors.fullName = "Full name is required"; + } + + if (!formData.email.trim()) { + newErrors.email = "Email address is required"; + } else if (!emailRegex.test(formData.email)) { + newErrors.email = "Please enter a valid email address"; + } + + if (!formData.subject) { + newErrors.subject = "Subject is required"; + } + + if (!formData.message.trim()) { + newErrors.message = "Message is required"; + } else if (formData.message.trim().length < 10) { + newErrors.message = "Message must be at least 10 characters"; + } + + setErrors(newErrors); + return Object.keys(newErrors).length === 0; + }; + + const handleInputChange = ( + e: React.ChangeEvent< + HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement + > + ) => { + const { name, value } = e.target; + setFormData((prev) => ({ + ...prev, + [name]: value, + })); + // Clear error for this field when user starts typing + if (errors[name as keyof typeof errors]) { + setErrors((prev) => ({ + ...prev, + [name]: undefined, + })); + } + }; + + const handleSubmit = async (e: React.FormEvent) => { + e.preventDefault(); + + if (!validateForm()) { + return; + } + setIsSubmitting(true); // Simulate API call @@ -25,6 +94,14 @@ function Contact() { setIsSubmitting(false); setShowPopup(true); + // Reset form on successful submission + setFormData({ + fullName: "", + email: "", + subject: "", + message: "", + }); + // Auto-close popup after 5 seconds setTimeout(() => { setShowPopup(false); @@ -218,14 +295,27 @@ function Contact() { + {errors.fullName && ( +
+ + {errors.fullName} +
+ )} {/* Email */} @@ -241,14 +331,27 @@ function Contact() { + {errors.email && ( +
+ + {errors.email} +
+ )} {/* Subject */} @@ -263,13 +366,19 @@ function Contact() { Subject + {errors.subject && ( +
+ + {errors.subject} +
+ )} {/* Message */} @@ -293,15 +408,28 @@ function Contact() { Message + {errors.message && ( +
+ + {errors.message} +
+ )}