Skip to content

Commit 2baeb04

Browse files
committed
feat: Implement advanced form validation on contact page
- Replaced default HTML5 validation with a custom validation solution using React state. - Added specific error messages for each field to improve user experience. - Removed 'required' attributes from form inputs. - Implemented 'useState' for form data and error handling.
1 parent 93ed237 commit 2baeb04

File tree

1 file changed

+102
-8
lines changed

1 file changed

+102
-8
lines changed

src/pages/contact-us/index.tsx

Lines changed: 102 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,92 @@
1-
import React from "react";
1+
import React, { useState } from "react";
22
import Layout from "@theme/Layout";
3-
import { Mail, MapPin, Phone, Clock } from "lucide-react";
3+
import { Mail, MapPin, Clock } from "lucide-react";
44

55
const ContactUs: React.FC = () => {
6+
const [formData, setFormData] = useState({
7+
firstName: "",
8+
lastName: "",
9+
email: "",
10+
subject: "",
11+
message: "",
12+
});
13+
14+
const [errors, setErrors] = useState({
15+
firstName: "",
16+
lastName: "",
17+
email: "",
18+
subject: "",
19+
message: "",
20+
});
21+
22+
const validate = () => {
23+
const newErrors = {
24+
firstName: "",
25+
lastName: "",
26+
email: "",
27+
subject: "",
28+
message: "",
29+
};
30+
31+
if (!formData.firstName) {
32+
newErrors.firstName = "First Name is required.";
33+
}
34+
35+
if (!formData.lastName) {
36+
newErrors.lastName = "Last Name is required.";
37+
}
38+
39+
if (!formData.email) {
40+
newErrors.email = "Email is required.";
41+
} else if (!/\S+@\S+\.\S+/.test(formData.email)) {
42+
newErrors.email = "Email is invalid.";
43+
}
44+
45+
if (!formData.subject) {
46+
newErrors.subject = "Subject is required.";
47+
}
48+
49+
if (!formData.message) {
50+
newErrors.message = "Message is required.";
51+
}
52+
53+
return newErrors;
54+
};
55+
56+
const handleChange = (e: React.ChangeEvent<HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement>) => {
57+
const { name, value } = e.target;
58+
setFormData({
59+
...formData,
60+
[name]: value,
61+
});
62+
};
63+
64+
const handleSubmit = (e: React.FormEvent) => {
65+
e.preventDefault();
66+
const newErrors = validate();
67+
if (Object.values(newErrors).some((error) => error)) {
68+
setErrors(newErrors);
69+
} else {
70+
// Form is valid, you can submit it here
71+
console.log("Form submitted successfully:", formData);
72+
setErrors({
73+
firstName: "",
74+
lastName: "",
75+
email: "",
76+
subject: "",
77+
message: "",
78+
});
79+
// You can reset the form here if needed
80+
// setFormData({
81+
// firstName: "",
82+
// lastName: "",
83+
// email: "",
84+
// subject: "",
85+
// message: "",
86+
// });
87+
}
88+
};
89+
690
return (
791
<Layout
892
title="Contact Us"
@@ -119,7 +203,7 @@ const ContactUs: React.FC = () => {
119203
Send us a message
120204
</h2>
121205

122-
<form className="space-y-6">
206+
<form onSubmit={handleSubmit} className="space-y-6">
123207
<div className="grid md:grid-cols-2 gap-4">
124208
<div>
125209
<label htmlFor="firstName" className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
@@ -129,10 +213,12 @@ const ContactUs: React.FC = () => {
129213
type="text"
130214
id="firstName"
131215
name="firstName"
216+
value={formData.firstName}
217+
onChange={handleChange}
132218
className="w-full px-4 py-3 border border-gray-300 dark:border-gray-600 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent dark:bg-gray-700 dark:text-white"
133219
placeholder="Your first name"
134-
required
135220
/>
221+
{errors.firstName && <p className="text-red-500 text-xs mt-1">{errors.firstName}</p>}
136222
</div>
137223
<div>
138224
<label htmlFor="lastName" className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
@@ -142,10 +228,12 @@ const ContactUs: React.FC = () => {
142228
type="text"
143229
id="lastName"
144230
name="lastName"
231+
value={formData.lastName}
232+
onChange={handleChange}
145233
className="w-full px-4 py-3 border border-gray-300 dark:border-gray-600 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent dark:bg-gray-700 dark:text-white"
146234
placeholder="Your last name"
147-
required
148235
/>
236+
{errors.lastName && <p className="text-red-500 text-xs mt-1">{errors.lastName}</p>}
149237
</div>
150238
</div>
151239

@@ -157,10 +245,12 @@ const ContactUs: React.FC = () => {
157245
type="email"
158246
id="email"
159247
name="email"
248+
value={formData.email}
249+
onChange={handleChange}
160250
className="w-full px-4 py-3 border border-gray-300 dark:border-gray-600 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent dark:bg-gray-700 dark:text-white"
161251
placeholder="[email protected]"
162-
required
163252
/>
253+
{errors.email && <p className="text-red-500 text-xs mt-1">{errors.email}</p>}
164254
</div>
165255

166256
<div>
@@ -170,8 +260,9 @@ const ContactUs: React.FC = () => {
170260
<select
171261
id="subject"
172262
name="subject"
263+
value={formData.subject}
264+
onChange={handleChange}
173265
className="w-full px-4 py-3 border border-gray-300 dark:border-gray-600 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent dark:bg-gray-700 dark:text-white"
174-
required
175266
>
176267
<option value="">Select a subject</option>
177268
<option value="general">General Inquiry</option>
@@ -181,6 +272,7 @@ const ContactUs: React.FC = () => {
181272
<option value="feedback">Feedback</option>
182273
<option value="other">Other</option>
183274
</select>
275+
{errors.subject && <p className="text-red-500 text-xs mt-1">{errors.subject}</p>}
184276
</div>
185277

186278
<div>
@@ -191,10 +283,12 @@ const ContactUs: React.FC = () => {
191283
id="message"
192284
name="message"
193285
rows={6}
286+
value={formData.message}
287+
onChange={handleChange}
194288
className="w-full px-4 py-3 border border-gray-300 dark:border-gray-600 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent dark:bg-gray-700 dark:text-white resize-none"
195289
placeholder="Tell us more about your inquiry..."
196-
required
197290
></textarea>
291+
{errors.message && <p className="text-red-500 text-xs mt-1">{errors.message}</p>}
198292
</div>
199293

200294
<button

0 commit comments

Comments
 (0)