Files
Omoluabi/src/components/ContactForm.jsx

147 lines
6.0 KiB
JavaScript

import React, { useState } from 'react';
export default function ContactForm() {
const [formData, setFormData] = useState({
name: '',
email: '',
subject: '',
message: '',
});
const [errors, setErrors] = useState({});
const [isSubmitting, setIsSubmitting] = useState(false);
const [submitMessage, setSubmitMessage] = useState(null);
const [hp, setHp] = useState('');
const validate = () => {
let newErrors = {};
if (!formData.name) newErrors.name = 'Name is required';
if (!formData.email) {
newErrors.email = 'Email is required';
} else if (!/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i.test(formData.email)) {
newErrors.email = 'Invalid email address';
}
if (!formData.subject) newErrors.subject = 'Subject is required';
if (!formData.message) newErrors.message = 'Message is required';
return newErrors;
};
const handleChange = (e) => {
const { name, value } = e.target;
setFormData({ ...formData, [name]: value });
// Clear error for the field as user types
if (errors[name]) {
setErrors({ ...errors, [name]: null });
}
};
const handleSubmit = async (e) => {
e.preventDefault();
setIsSubmitting(true);
setSubmitMessage(null);
const validationErrors = validate();
setErrors(validationErrors);
if (Object.keys(validationErrors).length === 0) {
try {
// Simulate API call
await new Promise(resolve => setTimeout(resolve, 1000));
console.log('Form data submitted:', formData);
setSubmitMessage({ type: 'success', text: 'Your message has been sent successfully!' });
setFormData({ name: '', email: '', subject: '', message: '' }); // Clear form
} catch (error) {
setSubmitMessage({ type: 'error', text: 'There was an error sending your message. Please try again later.' });
} finally {
setIsSubmitting(false);
}
} else {
setIsSubmitting(false);
setSubmitMessage({ type: 'error', text: 'Please correct the errors in the form.' });
}
};
return (
<form onSubmit={handleSubmit} className="bg-white p-8 rounded-xl shadow-lg border border-gray-200 max-w-2xl mx-auto" noValidate>
<div className="hidden" aria-hidden="true">
<label htmlFor="website">Website</label>
<input id="website" name="website" value={hp} onChange={(e)=>setHp(e.target.value)} tabIndex={-1} autoComplete="off" />
</div>
<h2 className="text-3xl font-bold text-center text-nigerian-green-700 mb-8">Send Us a Message</h2>
{submitMessage && (
<div className={`p-4 mb-4 rounded-lg text-center ${submitMessage.type === 'success' ? 'bg-green-100 text-green-700' : 'bg-red-100 text-red-700'}`}>
{submitMessage.text}
</div>
)}
<div className="mb-5">
<label htmlFor="name" className="block text-gray-700 text-sm font-bold mb-2">Name</label>
<input
type="text"
id="name"
name="name"
value={formData.name}
onChange={handleChange}
aria-invalid={Boolean(errors.name)}
aria-describedby={errors.name ? 'name-error' : undefined}
className={`shadow appearance-none border rounded-lg w-full py-3 px-4 text-gray-700 leading-tight focus:outline-none focus:ring-2 focus:ring-nigerian-green-500 ${errors.name ? 'border-red-500' : 'border-gray-300'}`}
placeholder="Your Name"
/>
{errors.name && <p id="name-error" className="text-red-500 text-xs italic mt-2">{errors.name}</p>}
</div>
<div className="mb-5">
<label htmlFor="email" className="block text-gray-700 text-sm font-bold mb-2">Email</label>
<input
type="email"
id="email"
name="email"
value={formData.email}
onChange={handleChange}
className={`shadow appearance-none border rounded-lg w-full py-3 px-4 text-gray-700 leading-tight focus:outline-none focus:ring-2 focus:ring-nigerian-green-500 ${errors.email ? 'border-red-500' : 'border-gray-300'}`}
placeholder="your.email@example.com"
/>
{errors.email && <p className="text-red-500 text-xs italic mt-2">{errors.email}</p>}
</div>
<div className="mb-5">
<label htmlFor="subject" className="block text-gray-700 text-sm font-bold mb-2">Subject</label>
<input
type="text"
id="subject"
name="subject"
value={formData.subject}
onChange={handleChange}
className={`shadow appearance-none border rounded-lg w-full py-3 px-4 text-gray-700 leading-tight focus:outline-none focus:ring-2 focus:ring-nigerian-green-500 ${errors.subject ? 'border-red-500' : 'border-gray-300'}`}
placeholder="Subject of your message"
/>
{errors.subject && <p className="text-red-500 text-xs italic mt-2">{errors.subject}</p>}
</div>
<div className="mb-6">
<label htmlFor="message" className="block text-gray-700 text-sm font-bold mb-2">Message</label>
<textarea
id="message"
name="message"
rows="6"
value={formData.message}
onChange={handleChange}
className={`shadow appearance-none border rounded-lg w-full py-3 px-4 text-gray-700 leading-tight focus:outline-none focus:ring-2 focus:ring-nigerian-green-500 ${errors.message ? 'border-red-500' : 'border-gray-300'}`}
placeholder="Your message..."
></textarea>
{errors.message && <p className="text-red-500 text-xs italic mt-2">{errors.message}</p>}
</div>
<div className="flex items-center justify-center">
<button
type="submit"
className="bg-gradient-to-r from-nigerian-green-500 to-kente-gold-500 hover:from-nigerian-green-600 hover:to-kente-gold-600 text-white font-bold py-3 px-8 rounded-lg focus:outline-none focus:shadow-outline transition-all duration-300 transform hover:scale-105"
disabled={isSubmitting}
>
{isSubmitting ? 'Sending...' : 'Send Message'}
</button>
</div>
</form>
);
}