Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
211 changes: 135 additions & 76 deletions src/components/Contact/form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,65 @@

import React, { useState } from "react";

// Accept the API access key as a prop
interface ContactProps {
contactFormAccess: string;
}

const Contact: React.FC<ContactProps> = ({ contactFormAccess }) => {
const [result, setResult] = useState<string>("");
const [errors, setErrors] = useState<Record<string, string>>({});

const validateForm = (formData: FormData) => {
const errors: Record<string, string> = {};

const fullName = (formData.get("fullName") || "").toString().trim();
const email = (formData.get("email") || "").toString().trim();
const phone = (formData.get("phone") || "").toString().trim();
const message = (formData.get("message") || "").toString().trim();

if (!fullName) errors.fullName = "Full Name is required";
if (!email) errors.email = "Email is required";
else if (!/^\S+@\S+\.\S+$/.test(email)) errors.email = "Email is not valid";

if (!phone) errors.phone = "Phone number is required";
else if (!/^\+?\d{7,15}$/.test(phone))
errors.phone = "Phone number is invalid";

if (!message) errors.message = "Message is required";

return errors;
};

const handleFieldChange = (field: string, value: string) => {
setErrors((prevErrors) => {
const updatedErrors = { ...prevErrors };
if (field === "email") {
if (/^\S+@\S+\.\S+$/.test(value)) delete updatedErrors.email;
} else if (field === "phone") {
if (/^\+?\d{7,15}$/.test(value)) delete updatedErrors.phone;
} else {
if (value.trim()) delete updatedErrors[field];
}
return updatedErrors;
});
};

const onSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();

// Ensure the form element is valid
const form = event.currentTarget;
if (!form) return;
setErrors({});
setResult("");

setResult("Sending...");
const form = event.currentTarget;
const formData = new FormData(form);

// Append the API access key dynamically
const validationErrors = validateForm(formData);

if (Object.keys(validationErrors).length > 0) {
setErrors(validationErrors);
return;
}

formData.append("access_key", contactFormAccess);
setResult("Sending...");

try {
const response = await fetch("https://api.web3forms.com/submit", {
Expand All @@ -33,9 +72,8 @@ const Contact: React.FC<ContactProps> = ({ contactFormAccess }) => {

if (data.success) {
setResult("Form Submitted Successfully");
form.reset(); // Reset the form safely
form.reset();
} else {
console.error("Error", data);
setResult(data.message);
}
} catch (error) {
Expand All @@ -47,72 +85,93 @@ const Contact: React.FC<ContactProps> = ({ contactFormAccess }) => {
return (
<div>
<form onSubmit={onSubmit}>
<div className="mb-[22px]">
<label
htmlFor="fullName"
className="mb-4 block text-sm text-body-color dark:text-dark-6"
>
Full Name*
</label>
<input
type="text"
name="fullName"
placeholder="Adam Gelius"
className="w-full border-0 border-b border-[#f1f1f1] bg-transparent pb-3 text-dark placeholder:text-body-color/60 focus:border-primary focus:outline-none dark:border-dark-3 dark:text-white"
/>
</div>
<div className="mb-[22px]">
<label
htmlFor="email"
className="mb-4 block text-sm text-body-color dark:text-dark-6"
>
Email*
</label>
<input
type="email"
name="email"
placeholder="[email protected]"
className="w-full border-0 border-b border-[#f1f1f1] bg-transparent pb-3 text-dark placeholder:text-body-color/60 focus:border-primary focus:outline-none dark:border-dark-3 dark:text-white"
/>
</div>
<div className="mb-[22px]">
<label
htmlFor="phone"
className="mb-4 block text-sm text-body-color dark:text-dark-6"
>
Phone*
</label>
<input
type="text"
name="phone"
placeholder="+885 1254 5211 552"
className="w-full border-0 border-b border-[#f1f1f1] bg-transparent pb-3 text-dark placeholder:text-body-color/60 focus:border-primary focus:outline-none dark:border-dark-3 dark:text-white"
/>
</div>
<div className="mb-[30px]">
<label
htmlFor="message"
className="mb-4 block text-sm text-body-color dark:text-dark-6"
>
Message*
</label>
<textarea
name="message"
rows={1}
placeholder="type your message here"
className="w-full resize-none border-0 border-b border-[#f1f1f1] bg-transparent pb-3 text-dark placeholder:text-body-color/60 focus:border-primary focus:outline-none dark:border-dark-3 dark:text-white"
></textarea>
</div>
<div className="mb-0">
<button
type="submit"
className="inline-flex items-center justify-center rounded-md bg-primary px-10 py-3 text-base font-medium text-white transition duration-300 ease-in-out hover:bg-primary/90"
>
Send
</button>
</div>
</form>
<span>{result}</span>
<div className="mb-[22px]">
<label
htmlFor="fullName"
className="mb-4 block text-sm text-body-color dark:text-dark-6"
>
Full Name*
</label>
<input
type="text"
name="fullName"
placeholder="Adam Gelius"
className="w-full border-0 border-b border-[#f1f1f1] bg-transparent pb-3 text-dark placeholder:text-body-color/60 focus:border-primary focus:outline-none dark:border-dark-3 dark:text-white"
onChange={(e) => handleFieldChange("fullName", e.target.value)}
/>
{errors.fullName && (
<p className="mt-1 text-sm text-red-500">{errors.fullName}</p>
)}
</div>

<div className="mb-[22px]">
<label
htmlFor="email"
className="mb-4 block text-sm text-body-color dark:text-dark-6"
>
Email*
</label>
<input
type="email"
name="email"
placeholder="[email protected]"
className="w-full border-0 border-b border-[#f1f1f1] bg-transparent pb-3 text-dark placeholder:text-body-color/60 focus:border-primary focus:outline-none dark:border-dark-3 dark:text-white"
onChange={(e) => handleFieldChange("email", e.target.value)}
/>
{errors.email && (
<p className="mt-1 text-sm text-red-500">{errors.email}</p>
)}
</div>

<div className="mb-[22px]">
<label
htmlFor="phone"
className="mb-4 block text-sm text-body-color dark:text-dark-6"
>
Phone*
</label>
<input
type="text"
name="phone"
placeholder="+885 1254 5211 552"
className="w-full border-0 border-b border-[#f1f1f1] bg-transparent pb-3 text-dark placeholder:text-body-color/60 focus:border-primary focus:outline-none dark:border-dark-3 dark:text-white"
onChange={(e) => handleFieldChange("phone", e.target.value)}
/>
{errors.phone && (
<p className="mt-1 text-sm text-red-500">{errors.phone}</p>
)}
</div>

<div className="mb-[30px]">
<label
htmlFor="message"
className="mb-4 block text-sm text-body-color dark:text-dark-6"
>
Message*
</label>
<textarea
name="message"
rows={1}
placeholder="type your message here"
className="w-full resize-none border-0 border-b border-[#f1f1f1] bg-transparent pb-3 text-dark placeholder:text-body-color/60 focus:border-primary focus:outline-none dark:border-dark-3 dark:text-white"
onChange={(e) => handleFieldChange("message", e.target.value)}
></textarea>
{errors.message && (
<p className="mt-1 text-sm text-red-500">{errors.message}</p>
)}
</div>

<div className="mb-0">
<button
type="submit"
className="inline-flex items-center justify-center rounded-md bg-primary px-10 py-3 text-base font-medium text-white transition duration-300 ease-in-out hover:bg-primary/90"
>
Send
</button>
</div>
</form>

<span className="mt-4 block text-sm">{result}</span>
</div>
);
};
Expand Down