feat(validation): Implement form validation and error handling utilities

- Add validation rules for form fields with XSS protection
- Create API error handler to parse and manage server validation errors
- Integrate validation rules into contact and inquiries forms
- Enhance error handling with user feedback for form submissions
- Introduce unit tests for validation and error handling functionalities
This commit is contained in:
AmirReza Jamali
2026-02-08 13:35:07 +03:30
parent 5fc6469752
commit 7b6cd4d965
9 changed files with 4834 additions and 108 deletions
+11 -59
View File
@@ -1,4 +1,6 @@
"use client";
import { handleApiError } from "@/lib/apiErrorHandler";
import { validationRules } from "@/lib/validation";
import api from "@/service/api";
import HCaptcha from "@hcaptcha/react-hcaptcha";
import { useRef, useState } from "react";
@@ -14,6 +16,9 @@ type TContactUsForm = {
phone: string;
message: string;
};
const FORM_FIELDS = ["full_name", "email", "phone", "message"];
interface IProps {
columnsPerRow?: 1 | 2 | 3 | 4;
buttonText?: string;
@@ -30,6 +35,7 @@ const ContactUsForm = ({
handleSubmit,
formState: { errors },
reset,
setError,
} = useForm<TContactUsForm>();
const onCaptchaVerify = (token: string) => {
@@ -55,9 +61,7 @@ const ContactUsForm = ({
setHcaptchaToken(null);
captchaRef.current?.resetCaptcha();
} catch (error) {
console.log(error);
toast.error("Something went wrong");
throw error;
handleApiError(error, setError, toast.error, FORM_FIELDS);
} finally {
setIsLoading(() => false);
}
@@ -84,20 +88,7 @@ const ContactUsForm = ({
id="full_name"
label="Full Name"
register={register}
validation={{
required: {
message: "This field is required",
value: true,
},
minLength: {
value: 2,
message: "Please enter at least 2 characters",
},
maxLength: {
value: 100,
message: "Please enter at most 100 characters",
},
}}
validation={validationRules.fullName}
type="text"
error={errors.full_name?.message}
/>
@@ -105,16 +96,7 @@ const ContactUsForm = ({
id="email"
label="Email"
register={register}
validation={{
required: {
message: "This field is required",
value: true,
},
pattern: {
value: /^[^\s@]+@[^\s@]+\.[^\s@]+$/,
message: "Please enter a valid email address",
},
}}
validation={validationRules.email}
type="email"
error={errors.email?.message}
/>
@@ -122,24 +104,7 @@ const ContactUsForm = ({
id="phone"
label="Phone"
register={register}
validation={{
required: {
message: "This field is required",
value: true,
},
minLength: {
value: 10,
message: "Please enter at least 10 characters",
},
maxLength: {
value: 20,
message: "Please enter at most 20 characters",
},
pattern: {
value: /^[+\d]+$/,
message: "Please enter a valid phone number",
},
}}
validation={validationRules.phone}
type="text"
error={errors.phone?.message}
/>
@@ -148,20 +113,7 @@ const ContactUsForm = ({
label="Message"
register={register}
error={errors.message?.message}
validation={{
required: {
value: true,
message: "This field is required",
},
maxLength: {
value: 1000,
message: "Please enter at most 1000 characters",
},
minLength: {
value: 10,
message: "Please enter at least 10 characters",
},
}}
validation={validationRules.message}
/>
<div className={`${colSpanClass}`}>
<HCaptcha