Spaces:
Sleeping
Sleeping
File size: 5,441 Bytes
691cdd0 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 | import React, { useState } from 'react';
import axios from 'axios';
const DEFAULT_ENDPOINT = 'https://formsubmit.co/ajax/jadeinfrapune@gmail.com';
export default function ContactForm() {
const [status, setStatus] = useState({ state: 'idle', message: '' });
async function onSubmit(e) {
e.preventDefault();
const form = new FormData(e.currentTarget);
const payload = {
name: String(form.get('name') || '').trim(),
email: String(form.get('email') || '').trim(),
phone: String(form.get('phone') || '').trim(),
message: String(form.get('message') || '').trim()
};
if (!payload.name || !payload.email || !payload.phone || !payload.message) {
setStatus({
state: 'error',
message: 'All fields are required. Please complete the form.'
});
return;
}
const namePattern = /^[A-Za-z\s]{2,60}$/;
if (!namePattern.test(payload.name)) {
setStatus({
state: 'error',
message: 'Please enter a valid name using alphabets only.'
});
return;
}
const emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
if (!emailPattern.test(payload.email)) {
setStatus({
state: 'error',
message: 'Please enter a valid email address.'
});
return;
}
const phonePattern = /^[0-9]{10}$/;
if (!phonePattern.test(payload.phone)) {
setStatus({
state: 'error',
message: 'Please enter a valid 10-digit phone number.'
});
return;
}
setStatus({ state: 'loading', message: '' });
try {
const endpoint = import.meta.env.VITE_CONTACT_ENDPOINT || DEFAULT_ENDPOINT;
const structuredMessage = [
'New enquiry received via jadeinfra.in contact form:',
'',
`Name : ${payload.name}`,
`Email : ${payload.email}`,
`Phone : ${payload.phone}`,
'',
'Message:',
payload.message
].join('\n');
await axios.post(
endpoint,
{
name: payload.name,
email: payload.email,
phone: payload.phone,
message: payload.message,
_subject: 'New enquiry via jadeinfra.in contact form',
_template: 'box',
_replyto: payload.email,
_captcha: 'false',
content: structuredMessage
},
{
headers: { 'Content-Type': 'application/json' }
}
);
setStatus({ state: 'success', message: 'Thanks! We will get back to you shortly.' });
e.currentTarget.reset();
} catch (err) {
setStatus({
state: 'error',
message:
'Sorry, there was an issue sending your message. Please try again or email us directly.'
});
}
}
return (
<form className="space-y-4" onSubmit={onSubmit} noValidate aria-labelledby="contact-heading">
<div className="grid grid-cols-1 gap-4 md:grid-cols-2">
<div>
<label htmlFor="name" className="block text-sm font-medium text-slate-700">Name</label>
<input
id="name"
name="name"
required
pattern="[A-Za-z\s]{2,60}"
autoComplete="name"
className="mt-1 w-full rounded-md border border-slate-300 px-3 py-2
focus:outline-none focus:ring-2 focus:ring-brand-600"
/>
</div>
<div>
<label htmlFor="email" className="block text-sm font-medium text-slate-700">Email</label>
<input
id="email"
name="email"
type="email"
required
pattern="^[^\s@]+@[^\s@]+\.[^\s@]+$"
autoComplete="email"
className="mt-1 w-full rounded-md border border-slate-300 px-3 py-2
focus:outline-none focus:ring-2 focus:ring-brand-600"
/>
</div>
<div className="md:col-span-2">
<label htmlFor="phone" className="block text-sm font-medium text-slate-700">Phone</label>
<input
id="phone"
name="phone"
type="tel"
required
pattern="[0-9]{10}"
inputMode="numeric"
autoComplete="tel"
className="mt-1 w-full rounded-md border border-slate-300 px-3 py-2
focus:outline-none focus:ring-2 focus:ring-brand-600"
/>
</div>
<div className="md:col-span-2">
<label htmlFor="message" className="block text-sm font-medium text-slate-700">Message</label>
<textarea
id="message"
name="message"
required
rows="5"
className="mt-1 w-full rounded-md border border-slate-300 px-3 py-2
focus:outline-none focus:ring-2 focus:ring-brand-600"
></textarea>
</div>
</div>
<div className="flex items-center gap-3">
<button type="submit" className="btn btn-primary" aria-live="polite">
Send Message
</button>
{status.state === 'loading' && (
<span role="status" className="text-sm text-slate-600">Sending…</span>
)}
{status.state === 'success' && (
<span className="text-sm text-green-700">{status.message}</span>
)}
{status.state === 'error' && (
<span className="text-sm text-red-700">{status.message}</span>
)}
</div>
</form>
);
}
|