feat: implement public contact and reservation forms connected to DB

This commit is contained in:
mstfyldz
2026-06-05 17:45:15 +03:00
parent a9a2c08e5f
commit 744283f167
3 changed files with 183 additions and 32 deletions
+80 -18
View File
@@ -1,9 +1,53 @@
"use client";
import { motion } from "framer-motion";
import { Calendar, Users, Coffee } from "lucide-react";
import { Calendar, Users, Coffee, Mail } from "lucide-react";
import { useState } from "react";
import { submitContactMessage } from "@/app/actions";
export default function Reservation() {
const [isSubmitting, setIsSubmitting] = useState(false);
const [status, setStatus] = useState<{ type: 'success' | 'error', message: string } | null>(null);
const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
setIsSubmitting(true);
setStatus(null);
const form = e.currentTarget;
const formData = new FormData(form);
// Construct message from reservation fields
const date = formData.get('date') as string;
const guests = formData.get('guests') as string;
const serviceType = formData.get('serviceType') as string;
const name = formData.get('name') as string;
const phone = formData.get('phone') as string;
const email = formData.get('email') as string;
const messageBody = `REZERVASYON TALEBİ
Tarih: ${date}
Kişi Sayısı: ${guests}
Hizmet Tipi: ${serviceType}
Telefon: ${phone}`;
const contactFormData = new FormData();
contactFormData.append('name', name);
contactFormData.append('email', email);
contactFormData.append('subject', 'Yeni Rezervasyon Talebi');
contactFormData.append('message', messageBody);
const result = await submitContactMessage(contactFormData);
if (result.error) {
setStatus({ type: 'error', message: result.error });
} else {
setStatus({ type: 'success', message: 'Rezervasyon talebiniz alınmıştır. Ekibimiz en kısa sürede sizinle iletişime geçecektir.' });
form.reset();
}
setIsSubmitting(false);
};
return (
<section id="reservation" className="py-24 bg-white relative overflow-hidden">
{/* Decorative background blobs */}
@@ -33,10 +77,9 @@ export default function Reservation() {
viewport={{ once: true }}
transition={{ duration: 0.6 }}
className="relative z-10 bg-white p-7 md:p-10 rounded-2xl shadow-xl max-w-4xl mx-auto"
onSubmit={(e) => e.preventDefault()}
onSubmit={handleSubmit}
>
<div className="grid md:grid-cols-3 gap-5 mb-6">
{/* Date */}
<div className="space-y-1.5">
<label className="text-xs font-semibold text-gray-600 uppercase tracking-wide flex items-center gap-1.5">
@@ -44,6 +87,8 @@ export default function Reservation() {
</label>
<input
type="date"
name="date"
required
className="w-full px-4 py-3 rounded-xl border border-gray-200 focus:outline-none focus:ring-2 focus:ring-coral/40 focus:border-coral transition-colors text-sm"
/>
</div>
@@ -53,12 +98,12 @@ export default function Reservation() {
<label className="text-xs font-semibold text-gray-600 uppercase tracking-wide flex items-center gap-1.5">
<Users size={13} className="text-coral" /> Kişi Sayısı
</label>
<select className="w-full px-4 py-3 rounded-xl border border-gray-200 focus:outline-none focus:ring-2 focus:ring-coral/40 focus:border-coral transition-colors bg-white text-sm">
<option>1 Kişi</option>
<option>2 Kişi</option>
<option>3 Kişi</option>
<option>4 Kişi</option>
<option>5+ Kişi</option>
<select name="guests" className="w-full px-4 py-3 rounded-xl border border-gray-200 focus:outline-none focus:ring-2 focus:ring-coral/40 focus:border-coral transition-colors bg-white text-sm">
<option value="1 Kişi">1 Kişi</option>
<option value="2 Kişi">2 Kişi</option>
<option value="3 Kişi">3 Kişi</option>
<option value="4 Kişi">4 Kişi</option>
<option value="5+ Kişi">5+ Kişi</option>
</select>
</div>
@@ -67,34 +112,51 @@ export default function Reservation() {
<label className="text-xs font-semibold text-gray-600 uppercase tracking-wide flex items-center gap-1.5">
<Coffee size={13} className="text-coral" /> Hizmet Tipi
</label>
<select className="w-full px-4 py-3 rounded-xl border border-gray-200 focus:outline-none focus:ring-2 focus:ring-coral/40 focus:border-coral transition-colors bg-white text-sm">
<option>Beach Club (Şezlong/Loca)</option>
<option>Restoran Akşam Yemeği</option>
<option>Konaklama</option>
<option>Özel Etkinlik / Organizasyon</option>
<select name="serviceType" className="w-full px-4 py-3 rounded-xl border border-gray-200 focus:outline-none focus:ring-2 focus:ring-coral/40 focus:border-coral transition-colors bg-white text-sm">
<option value="Beach Club (Şezlong/Loca)">Beach Club (Şezlong/Loca)</option>
<option value="Restoran Akşam Yemeği">Restoran Akşam Yemeği</option>
<option value="Konaklama">Konaklama</option>
<option value="Özel Etkinlik / Organizasyon">Özel Etkinlik / Organizasyon</option>
</select>
</div>
</div>
<div className="grid md:grid-cols-2 gap-5 mb-7">
<div className="grid md:grid-cols-3 gap-5 mb-7">
<input
type="text"
name="name"
required
placeholder="Adınız Soyadınız"
className="w-full px-4 py-3 rounded-xl border border-gray-200 focus:outline-none focus:ring-2 focus:ring-coral/40 focus:border-coral transition-colors text-sm"
/>
<input
type="tel"
name="phone"
required
placeholder="Telefon Numaranız"
className="w-full px-4 py-3 rounded-xl border border-gray-200 focus:outline-none focus:ring-2 focus:ring-coral/40 focus:border-coral transition-colors text-sm"
/>
<input
type="email"
name="email"
required
placeholder="E-Posta Adresiniz"
className="w-full px-4 py-3 rounded-xl border border-gray-200 focus:outline-none focus:ring-2 focus:ring-coral/40 focus:border-coral transition-colors text-sm"
/>
</div>
{/* Shimmer submit button */}
{status && (
<div className={`p-4 mb-6 rounded-xl text-sm ${status.type === 'success' ? 'bg-green-50 text-green-700 border border-green-200' : 'bg-red-50 text-red-700 border border-red-200'}`}>
{status.message}
</div>
)}
<button
type="submit"
className="btn-shimmer w-full bg-coral hover:bg-coral-dark text-white font-medium py-4 rounded-xl transition-colors shadow-lg hover:shadow-xl text-sm tracking-wide uppercase"
disabled={isSubmitting}
className="btn-shimmer w-full bg-coral hover:bg-coral-dark text-white font-medium py-4 rounded-xl transition-colors shadow-lg hover:shadow-xl text-sm tracking-wide uppercase disabled:opacity-70 flex justify-center items-center"
>
Rezervasyon Talebi Gönder
{isSubmitting ? 'Talebiniz Gönderiliyor...' : 'Rezervasyon Talebi Gönder'}
</button>
<p className="text-[11px] text-center text-gray-400 mt-4">