Files
tm-landing/app/_inquires/form.tsx
T
AmirReza Jamali cfe943d269 feat(inquires): Make contact form configurable via CMS data
- Add CmsContact type support to FooterForm, Inquires, and InquiresForm components
- Make form fields dynamic by accepting contactData prop with configurable Fields array
- Add placeholder prop to InputGroup component for enhanced field customization
- Replace hardcoded form fields with dynamic field mapping from CMS data
- Support dynamic form title and description from contactData
- Use CMS-provided submit button text with fallback to default "Submit"
- Implement field-level validation configuration including required field handling
- Auto-detect input type based on field name (email, phone, text)
- Pass contact data from marketing page to FooterForm component
- Maintain backward compatibility with default fields when contactData is not provided
2025-11-23 11:31:52 +03:30

136 lines
3.4 KiB
TypeScript

"use client";
import api from "@/service/api";
import { CmsContact } from "@/types/TCms";
import { useState } from "react";
import { useForm } from "react-hook-form";
import { toast } from "react-toastify";
import InputGroup from "../_components/InputGroup";
import Loading from "../_components/Loading";
type TInquiresForm = {
[key: string]: string;
};
type InquiresFormProps = {
columnsPerRow?: 1 | 2 | 3 | 4;
buttonText?: string;
contactData?: CmsContact;
};
const InquiresForm = ({
columnsPerRow = 2,
buttonText,
contactData,
}: InquiresFormProps) => {
const [isLoading, setIsLoading] = useState(false);
const {
register,
handleSubmit,
formState: { errors },
reset,
} = useForm<TInquiresForm>();
const onSubmit = async (data: TInquiresForm) => {
setIsLoading(true);
try {
const response = (await api.post("inquiries", { ...data })).data;
toast.success(response.message);
reset();
} catch (error) {
console.log(error);
toast.error("Something went wrong");
throw error;
} finally {
setIsLoading(false);
}
};
const gridColsClass = {
1: "lg:grid-cols-1",
2: "lg:grid-cols-2",
3: "lg:grid-cols-3",
4: "lg:grid-cols-4",
}[columnsPerRow];
const colSpanClass = {
1: "lg:col-span-1",
2: "lg:col-span-2",
3: "lg:col-span-3",
4: "lg:col-span-4",
}[columnsPerRow];
const defaultFields = [
{ Name: "full_name", Label: "Full Name", Placeholder: "", Required: false },
{
Name: "company_name",
Label: "Company Name",
Placeholder: "",
Required: false,
},
{
Name: "work_email",
Label: "Work Email",
Placeholder: "",
Required: false,
},
{
Name: "phone_number",
Label: "Phone Number",
Placeholder: "",
Required: false,
},
];
const fields = contactData?.Fields || defaultFields;
const submitText = contactData?.SubmitButtonText || buttonText || "Submit";
return (
<form
className={`w-full px-4 lg:px-16 py-10 grid ${gridColsClass} gap-4`}
onSubmit={handleSubmit(onSubmit)}>
{fields.map((field) => {
const inputType =
field.Name.includes("email") || field.Name === "work_email"
? "email"
: "text";
const isPhoneField =
field.Name.includes("phone") || field.Name === "phone_number";
return (
<InputGroup
key={field.Name}
id={field.Name}
label={field.Label}
placeholder={field.Placeholder}
register={register}
type={inputType}
error={errors[field.Name]?.message}
validation={
isPhoneField
? {
pattern: {
value: /^[+\d]+$/,
message: "Please enter a valid phone number",
},
required: field.Required
? "This field is required"
: undefined,
}
: field.Required
? { required: "This field is required" }
: undefined
}
/>
);
})}
<div className={`${colSpanClass} flex justify-end`}>
<button className="bg-(--primary) cursor-pointer w-fit text-white rounded-full py-4 px-6">
{isLoading ? <Loading /> : submitText}
</button>
</div>
</form>
);
};
export default InquiresForm;