231 lines
8.5 KiB
TypeScript

'use client'
import { useState, useEffect } from 'react'
import Image from 'next/image'
import ReCAPTCHA from "react-google-recaptcha"
import axios from "axios"
import styles from './BookTable.module.css'
interface FormErrors {
name?: string;
phone?: string;
date?: string;
captcha?: string;
}
export default function BookTable() {
const [email, setEmail] = useState("");
useEffect(() => {
const user = "info";
const domain = "antalya-restaurant.com";
setEmail(`${user}@${domain}`);
}, []);
const [formData, setFormData] = useState({
name: "",
phone: "",
date: "",
message: "",
});
const [formErrors, setFormErrors] = useState<FormErrors>({});
const [captchaToken, setCaptchaToken] = useState<string | null>(null);
const [alert, setAlert] = useState({ show: false, type: "", message: "" });
const [charCount, setCharCount] = useState(0);
const handleChange = (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
const { name, value } = e.target;
setFormData((prev) => ({ ...prev, [name]: value }));
if (name === "message") {
setCharCount(value.length);
}
};
const handleCaptchaChange = (token: string | null) => {
setCaptchaToken(token);
};
const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
const errors: FormErrors = {};
if (!formData.name.trim()) errors.name = "Name is required.";
if (!formData.phone.trim()) errors.phone = "Phone is required.";
if (!formData.date.trim()) errors.date = "Date is required.";
if (!captchaToken) errors.captcha = "Please verify the CAPTCHA.";
setFormErrors(errors);
if (Object.keys(errors).length > 0) return;
const emailData = {
name: formData.name,
phone: formData.phone,
email: email,
subject: `Table Reservation - ${formData.name} on ${formData.date}`,
message: `
<strong>Reservation Details:</strong><br/>
Name: ${formData.name}<br/>
Phone: ${formData.phone}<br/>
Date: ${formData.date}<br/><br/>
<strong>Message:</strong><br/>
${formData.message || "None"}
`,
to: email,
senderName: "Antalya Restaurant - Table Reservation",
recaptchaToken: captchaToken,
};
try {
const res = await axios.post(
"https://mailserver.metatronnest.com/send",
emailData,
{ headers: { "Content-Type": "application/json" } }
);
setAlert({
show: true,
type: "success",
message: res?.data?.message || "Reservation request sent successfully! We'll contact you soon.",
});
setFormData({
name: "",
phone: "",
date: "",
message: "",
});
setCaptchaToken(null);
setFormErrors({});
setCharCount(0);
} catch (error) {
setAlert({
show: true,
type: "danger",
message: "Failed to send reservation request. Please try again later.",
});
}
};
useEffect(() => {
if (alert.show) {
const timer = setTimeout(() => {
setAlert((prev) => ({ ...prev, show: false }));
}, 5000);
return () => clearTimeout(timer);
}
}, [alert.show]);
return (
<section className={styles.section} id="book">
<div className={styles.imageContainer}>
<Image
src="/images/restaurant-interior.png"
alt="Luxury Restaurant Interior"
fill
style={{ objectFit: 'cover' }}
priority
/>
</div>
<div className={styles.formContainer}>
<div className={styles.content}>
<h2 className={styles.title}>Book A Table</h2>
{alert.show && (
<div className={`${styles.alert} ${styles[`alert${alert.type.charAt(0).toUpperCase() + alert.type.slice(1)}`]}`}>
{alert.message}
</div>
)}
<form
id="reservation-form"
onSubmit={handleSubmit}
className={styles.form}
>
{/* Name Input with Placeholder */}
<div className={styles.inputGroup}>
<label htmlFor="name" className={styles.label}>Name *</label>
<input
type="text"
id="name"
name="name"
required
className={styles.input}
placeholder="Your Full Name"
value={formData.name}
onChange={handleChange}
/>
{formErrors.name && <small className={styles.errorText}>{formErrors.name}</small>}
</div>
{/* Phone Input with Placeholder */}
<div className={styles.inputGroup}>
<label htmlFor="phone" className={styles.label}>Phone *</label>
<input
type="tel"
id="phone"
name="phone"
required
className={styles.input}
placeholder="(519) 000-0000"
value={formData.phone}
onChange={handleChange}
/>
{formErrors.phone && <small className={styles.errorText}>{formErrors.phone}</small>}
</div>
<div className={styles.inputGroup}>
<label htmlFor="date" className={styles.label}>Date *</label>
<input
type="date"
id="date"
name="date"
required
className={styles.input}
value={formData.date}
onChange={handleChange}
/>
{formErrors.date && <small className={styles.errorText}>{formErrors.date}</small>}
</div>
{/* Message Textarea with Placeholder */}
<div className={styles.inputGroup}>
<label htmlFor="message" className={styles.label}>Message</label>
<textarea
id="message"
name="message"
className={styles.textarea}
placeholder="Any special requests..."
maxLength={500}
value={formData.message}
onChange={handleChange}
/>
<span className={styles.charCount}>{charCount}/500 characters</span>
</div>
<div className={styles.recaptchaWrapper}>
<ReCAPTCHA
sitekey="6Lckq9MrAAAAABjBD9rQYm19BMGFFWiwb9mPiw2K"
onChange={handleCaptchaChange}
/>
{formErrors.captcha && <small className={styles.errorText}>{formErrors.captcha}</small>}
</div>
<button
type="submit"
className={styles.submitButton}
>
Submit Reservation
</button>
</form>
</div>
</div>
</section>
)
}