implement catering inquiry system with nodemailer and add catering service pages
This commit is contained in:
parent
9efd6db977
commit
617034ff08
21
package-lock.json
generated
21
package-lock.json
generated
@ -11,6 +11,7 @@
|
||||
"axios": "^1.13.2",
|
||||
"framer-motion": "^12.23.24",
|
||||
"next": "16.0.3",
|
||||
"nodemailer": "^8.0.4",
|
||||
"react": "19.2.0",
|
||||
"react-dom": "19.2.0",
|
||||
"react-google-recaptcha": "^3.1.0",
|
||||
@ -21,6 +22,7 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^20",
|
||||
"@types/nodemailer": "^7.0.11",
|
||||
"@types/react": "^19",
|
||||
"@types/react-dom": "^19",
|
||||
"@types/react-google-recaptcha": "^2.1.9",
|
||||
@ -1340,6 +1342,16 @@
|
||||
"undici-types": "~6.21.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/nodemailer": {
|
||||
"version": "7.0.11",
|
||||
"resolved": "https://registry.npmjs.org/@types/nodemailer/-/nodemailer-7.0.11.tgz",
|
||||
"integrity": "sha512-E+U4RzR2dKrx+u3N4DlsmLaDC6mMZOM/TPROxA0UAPiTgI0y4CEFBmZE+coGWTjakDriRsXG368lNk1u9Q0a2g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/react": {
|
||||
"version": "19.2.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.7.tgz",
|
||||
@ -7575,6 +7587,15 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/nodemailer": {
|
||||
"version": "8.0.4",
|
||||
"resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-8.0.4.tgz",
|
||||
"integrity": "sha512-k+jf6N8PfQJ0Fe8ZhJlgqU5qJU44Lpvp2yvidH3vp1lPnVQMgi4yEEMPXg5eJS1gFIJTVq1NHBk7Ia9ARdSBdQ==",
|
||||
"license": "MIT-0",
|
||||
"engines": {
|
||||
"node": ">=6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/normalize-url": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-2.0.1.tgz",
|
||||
|
||||
@ -14,6 +14,7 @@
|
||||
"axios": "^1.13.2",
|
||||
"framer-motion": "^12.23.24",
|
||||
"next": "16.0.3",
|
||||
"nodemailer": "^8.0.4",
|
||||
"react": "19.2.0",
|
||||
"react-dom": "19.2.0",
|
||||
"react-google-recaptcha": "^3.1.0",
|
||||
@ -24,6 +25,7 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^20",
|
||||
"@types/nodemailer": "^7.0.11",
|
||||
"@types/react": "^19",
|
||||
"@types/react-dom": "^19",
|
||||
"@types/react-google-recaptcha": "^2.1.9",
|
||||
|
||||
@ -1,18 +1,78 @@
|
||||
'use server'
|
||||
|
||||
import nodemailer from 'nodemailer';
|
||||
|
||||
// Configure SMTP transport using environment variables
|
||||
const transporter = nodemailer.createTransport({
|
||||
host: process.env.EMAIL_HOST || 'smtp.gmail.com', // Replace with actual SMTP host if different
|
||||
port: Number(process.env.EMAIL_PORT) || 587,
|
||||
secure: (process.env.EMAIL_SECURE === 'true'),
|
||||
auth: {
|
||||
user: process.env.EMAIL_USER,
|
||||
pass: process.env.EMAIL_PASS,
|
||||
},
|
||||
});
|
||||
|
||||
export async function submitReservation(formData: FormData) {
|
||||
const name = formData.get('name');
|
||||
const phone = formData.get('phone');
|
||||
const date = formData.get('date');
|
||||
const message = formData.get('message');
|
||||
|
||||
// For reservations, we'll log it for now as per current logic
|
||||
console.log('Reservation received:', { name, phone, date, message });
|
||||
|
||||
// Simulate delay
|
||||
await new Promise(resolve => setTimeout(resolve, 1000));
|
||||
return { success: true, message: 'Reservation submitted successfully!' };
|
||||
}
|
||||
|
||||
export async function submitCateringInquiry(formData: FormData) {
|
||||
const rawFormData = {
|
||||
name: formData.get('name'),
|
||||
namhello@antalyarestaurant.ca),
|
||||
email: formData.get('email'),
|
||||
phone: formData.get('phone'),
|
||||
eventType: formData.get('eventType'),
|
||||
date: formData.get('date'),
|
||||
guests: formData.get('guests'),
|
||||
message: formData.get('message'),
|
||||
};
|
||||
|
||||
try {
|
||||
// Send email to hello@antalyarestaurant.ca
|
||||
await transporter.sendMail({
|
||||
from: process.env.EMAIL_USER || '"Antalya Website" <noreply@antalyarestaurant.ca>',
|
||||
to: 'hello@antalyarestaurant.ca',
|
||||
subject: `Catering Inquiry: ${rawFormData.eventType} - ${rawFormData.name}`,
|
||||
text: `
|
||||
Name: ${rawFormData.name}
|
||||
Email: ${rawFormData.email}
|
||||
Phone: ${rawFormData.phone}
|
||||
Event Type: ${rawFormData.eventType}
|
||||
Event Date: ${rawFormData.date}
|
||||
Number of Guests: ${rawFormData.guests}
|
||||
Message: ${rawFormData.message}
|
||||
`,
|
||||
html: `
|
||||
<div style="font-family: Arial, sans-serif; line-height: 1.6; color: #441109;">
|
||||
<h2 style="color: #c49c5c; border-bottom: 2px solid #c49c5c; padding-bottom: 10px;">New Catering Inquiry</h2>
|
||||
<p><strong>Name:</strong> ${rawFormData.name}</p>
|
||||
<p><strong>Email:</strong> ${rawFormData.email}</p>
|
||||
<p><strong>Phone:</strong> ${rawFormData.phone}</p>
|
||||
<p><strong>Event Type:</strong> ${rawFormData.eventType}</p>
|
||||
<p><strong>Event Date:</strong> ${rawFormData.date}</p>
|
||||
<p><strong>Number of Guests:</strong> ${rawFormData.guests}</p>
|
||||
<div style="margin-top: 20px; padding: 15px; background: #fdfaf5; border-radius: 8px;">
|
||||
<p><strong>Message:</strong></p>
|
||||
<p>${rawFormData.message || 'No special requests provided.'}</p>
|
||||
</div>
|
||||
</div>
|
||||
`,
|
||||
});
|
||||
|
||||
return { success: true, message: 'Your catering inquiry has been submitted successfully to hello@antalyarestaurant.ca!' };
|
||||
} catch (error) {
|
||||
console.error('Failed to send catering inquiry email:', error);
|
||||
return { success: false, message: 'There was an error sending your inquiry. Please try again or email us directly.' };
|
||||
}
|
||||
|
||||
// Simulate server-side processing
|
||||
console.log('Reservation received:', rawFormData)
|
||||
|
||||
// In a real app, you would save to DB or send email here
|
||||
await new Promise(resolve => setTimeout(resolve, 1000))
|
||||
|
||||
return { success: true, message: 'Reservation submitted successfully!' }
|
||||
}
|
||||
|
||||
@ -9,11 +9,19 @@ import Image from 'next/image'
|
||||
import styles from './catering.module.css'
|
||||
|
||||
import CateringPackages from './CateringPackages';
|
||||
import CateringPopup from './CateringPopup';
|
||||
|
||||
export default function CateringContent() {
|
||||
// Slider state for Visual Journey section
|
||||
const [currentSlide, setCurrentSlide] = useState(0);
|
||||
const [mounted, setMounted] = useState(false);
|
||||
const [isPopupOpen, setIsPopupOpen] = useState(false);
|
||||
const [selectedEventType, setSelectedEventType] = useState('');
|
||||
|
||||
const openPopup = (type: string) => {
|
||||
setSelectedEventType(type);
|
||||
setIsPopupOpen(true);
|
||||
};
|
||||
|
||||
const sliderImages = [
|
||||
'/images/catering/visual-slider/visual-journey-1.webp',
|
||||
@ -114,7 +122,12 @@ export default function CateringContent() {
|
||||
|
||||
return (
|
||||
<main className={styles.main}>
|
||||
|
||||
{/* Catering Popup Modal */}
|
||||
<CateringPopup
|
||||
isOpen={isPopupOpen}
|
||||
onClose={() => setIsPopupOpen(false)}
|
||||
initialEventType={selectedEventType}
|
||||
/>
|
||||
|
||||
{/* Page Hero */}
|
||||
<section className={styles.hero}>
|
||||
@ -149,7 +162,11 @@ export default function CateringContent() {
|
||||
|
||||
<div className={styles.topCardsGrid}>
|
||||
{/* Card 1: Events */}
|
||||
<motion.div className={styles.topCard} variants={scaleIn}>
|
||||
<motion.div
|
||||
className={`${styles.topCard} ${styles.clickableCard}`}
|
||||
variants={scaleIn}
|
||||
onClick={() => openPopup('Corporate & Social Events')}
|
||||
>
|
||||
<div className={styles.topCardImage}>
|
||||
<Image
|
||||
src="/images/catering/card/card-1.webp"
|
||||
@ -161,14 +178,15 @@ export default function CateringContent() {
|
||||
</div>
|
||||
<div className={styles.topCardContent}>
|
||||
<h3 className={styles.topCardTitle}>Corporate & Social Events</h3>
|
||||
{/* <button className={styles.topCardButton}>
|
||||
<span>→</span>
|
||||
</button> */}
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
{/* Card 2: Food & Drinks */}
|
||||
<motion.div className={styles.topCard} variants={scaleIn}>
|
||||
<motion.div
|
||||
className={`${styles.topCard} ${styles.clickableCard}`}
|
||||
variants={scaleIn}
|
||||
onClick={() => openPopup('Family Gatherings & Weddings')}
|
||||
>
|
||||
<div className={styles.topCardImage}>
|
||||
<Image
|
||||
src="/images/catering/card/card-2.webp"
|
||||
@ -180,14 +198,15 @@ export default function CateringContent() {
|
||||
</div>
|
||||
<div className={styles.topCardContent}>
|
||||
<h3 className={styles.topCardTitle}>Family Gatherings & Weddings</h3>
|
||||
{/* <button className={styles.topCardButton}>
|
||||
<span>→</span>
|
||||
</button> */}
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
{/* Card 3: Venues */}
|
||||
<motion.div className={styles.topCard} variants={scaleIn}>
|
||||
<motion.div
|
||||
className={`${styles.topCard} ${styles.clickableCard}`}
|
||||
variants={scaleIn}
|
||||
onClick={() => openPopup('Birthday Party & Baby Shower')}
|
||||
>
|
||||
<div className={styles.topCardImage}>
|
||||
<Image
|
||||
src="/images/catering/card/card-3.webp"
|
||||
@ -199,9 +218,6 @@ export default function CateringContent() {
|
||||
</div>
|
||||
<div className={styles.topCardContent}>
|
||||
<h3 className={styles.topCardTitle}>Birthday Party & Baby Shower</h3>
|
||||
{/* <button className={styles.topCardButton}>
|
||||
<span>→</span>
|
||||
</button> */}
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
@ -274,13 +290,6 @@ export default function CateringContent() {
|
||||
<Image src="/images/eat.png" alt="Catering Visualization Decorative Cutlery Icon" width={24} height={24} />
|
||||
</div>
|
||||
<h2 className={styles.mainHeadingSection}>A Visual Journey Through Antalya Catering</h2>
|
||||
{/* <div className={styles.welcomeDivider}>
|
||||
<svg width="120" height="20" viewBox="0 0 120 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<line x1="0" y1="10" x2="45" y2="10" stroke="#d3cab3" strokeWidth="2" />
|
||||
<path d="M52 5 Q60 10 52 15 M55 5 Q63 10 55 15 M58 5 Q66 10 58 15" stroke="#d3cab3" strokeWidth="1.5" fill="none" />
|
||||
<line x1="75" y1="10" x2="120" y2="10" stroke="#d3cab3" strokeWidth="2" />
|
||||
</svg>
|
||||
</div> */}
|
||||
<p className={styles.welcomeDescription}>
|
||||
Experience the essence of Antalya brought to your event - from beautifully presented dishes to elegant setups that elevate every occasion. Our catering blends authentic Turkish flavours with refined presentation, creating a feast that delights both the eyes and the palate.
|
||||
</p>
|
||||
@ -372,11 +381,6 @@ export default function CateringContent() {
|
||||
>
|
||||
hello@antalyarestaurant.ca
|
||||
</motion.a>
|
||||
|
||||
{/* <motion.button className={styles.storyButton} variants={fadeInUp}>
|
||||
<span className={styles.storyButtonIcon}>↗</span>
|
||||
<span>Visit site</span>
|
||||
</motion.button> */}
|
||||
</motion.div>
|
||||
</section>
|
||||
|
||||
|
||||
238
src/app/catering-services-ontario/CateringPopup.module.css
Normal file
238
src/app/catering-services-ontario/CateringPopup.module.css
Normal file
@ -0,0 +1,238 @@
|
||||
.overlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: rgba(0, 0, 0, 0.85);
|
||||
backdrop-filter: blur(8px);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
z-index: 1000;
|
||||
padding: 20px;
|
||||
overflow-y: auto; /* Enable overlay-level scrolling */
|
||||
}
|
||||
|
||||
.popup {
|
||||
background-color: #f5e6d3;
|
||||
padding: 3rem;
|
||||
border-radius: 20px;
|
||||
width: 95%;
|
||||
max-width: 750px;
|
||||
position: relative;
|
||||
box-shadow: 0 25px 50px rgba(0, 0, 0, 0.3);
|
||||
border: 1px solid rgba(196, 156, 92, 0.4);
|
||||
margin: auto; /* Center when scrollable */
|
||||
max-height: calc(100vh - 40px);
|
||||
overflow-y: auto; /* Scrollable content inside the popup */
|
||||
}
|
||||
|
||||
/* Custom scrollbar for the popup */
|
||||
.popup::-webkit-scrollbar {
|
||||
width: 6px;
|
||||
}
|
||||
|
||||
.popup::-webkit-scrollbar-track {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.popup::-webkit-scrollbar-thumb {
|
||||
background: #c49c5c;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.closeButton {
|
||||
position: absolute;
|
||||
top: 1rem;
|
||||
right: 1rem;
|
||||
background: #fff;
|
||||
border: none;
|
||||
font-size: 1.5rem;
|
||||
cursor: pointer;
|
||||
color: #441109;
|
||||
transition: transform 0.3s ease;
|
||||
z-index: 10;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
box-shadow: 0 4px 10px rgba(0,0,0,0.1);
|
||||
}
|
||||
|
||||
.closeButton:hover {
|
||||
transform: rotate(90deg) scale(1.1);
|
||||
}
|
||||
|
||||
.title {
|
||||
font-family: var(--font-playfair);
|
||||
font-size: 2.2rem;
|
||||
color: #441109;
|
||||
margin-bottom: 0.5rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.subtitle {
|
||||
font-size: 0.95rem;
|
||||
color: #5d4037;
|
||||
margin-bottom: 2.5rem;
|
||||
text-align: center;
|
||||
max-width: 500px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
.form {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.formGrid {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 1.2rem;
|
||||
}
|
||||
|
||||
.inputGroup {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.4rem;
|
||||
}
|
||||
|
||||
.fullWidth {
|
||||
grid-column: span 2;
|
||||
}
|
||||
|
||||
.label {
|
||||
font-size: 0.8rem;
|
||||
font-weight: 700;
|
||||
color: #441109;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
|
||||
.input, .textarea {
|
||||
padding: 0.8rem 1rem;
|
||||
border-radius: 10px;
|
||||
border: 1px solid #d3cab3;
|
||||
background-color: #fff;
|
||||
color: #441109;
|
||||
font-family: inherit;
|
||||
font-size: 0.95rem;
|
||||
outline: none;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.input:focus, .textarea:focus {
|
||||
border-color: #c49c5c;
|
||||
box-shadow: 0 0 0 4px rgba(196, 156, 92, 0.15);
|
||||
}
|
||||
|
||||
.textarea {
|
||||
resize: none;
|
||||
height: 100px;
|
||||
grid-column: span 2;
|
||||
}
|
||||
|
||||
.submitButton {
|
||||
background-color: #441109;
|
||||
color: #f5e6d3;
|
||||
padding: 1.1rem;
|
||||
border-radius: 10px;
|
||||
border: 1px solid #441109;
|
||||
font-weight: 700;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 2.5px;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
margin-top: 0.5rem;
|
||||
font-size: 0.95rem;
|
||||
grid-column: span 2;
|
||||
}
|
||||
|
||||
.submitButton:hover {
|
||||
background-color: #c49c5c;
|
||||
border-color: #c49c5c;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.submitButton:disabled {
|
||||
opacity: 0.6;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.successMessage {
|
||||
background-color: rgba(76, 175, 80, 0.1);
|
||||
color: #2e7d32;
|
||||
padding: 1rem;
|
||||
border-radius: 8px;
|
||||
text-align: center;
|
||||
font-size: 0.9rem;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.formGrid {
|
||||
grid-template-columns: 1fr;
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.textarea, .submitButton, .fullWidth {
|
||||
grid-column: span 1;
|
||||
}
|
||||
|
||||
.popup {
|
||||
padding: 2.5rem 1.5rem 2rem;
|
||||
max-height: calc(100vh - 40px);
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 1.8rem;
|
||||
}
|
||||
|
||||
.subtitle {
|
||||
margin-bottom: 1.5rem;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.input, .textarea {
|
||||
padding: 0.7rem 0.9rem;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
.popup {
|
||||
padding: 2.5rem 1.2rem 1.5rem;
|
||||
width: 100%;
|
||||
border-radius: 15px;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
.subtitle {
|
||||
font-size: 0.85rem;
|
||||
}
|
||||
|
||||
.form {
|
||||
gap: 0.8rem;
|
||||
}
|
||||
|
||||
.inputGroup {
|
||||
gap: 0.3rem;
|
||||
}
|
||||
|
||||
.label {
|
||||
font-size: 0.75rem;
|
||||
}
|
||||
|
||||
.submitButton {
|
||||
padding: 0.9rem;
|
||||
font-size: 0.9rem;
|
||||
margin-top: 0.2rem;
|
||||
}
|
||||
}
|
||||
133
src/app/catering-services-ontario/CateringPopup.tsx
Normal file
133
src/app/catering-services-ontario/CateringPopup.tsx
Normal file
@ -0,0 +1,133 @@
|
||||
'use client'
|
||||
|
||||
import { useState, useTransition } from 'react'
|
||||
import { motion, AnimatePresence } from 'framer-motion'
|
||||
import { submitCateringInquiry } from '../actions'
|
||||
import styles from './CateringPopup.module.css'
|
||||
|
||||
interface CateringPopupProps {
|
||||
isOpen: boolean;
|
||||
onClose: () => void;
|
||||
initialEventType?: string;
|
||||
}
|
||||
|
||||
export default function CateringPopup({ isOpen, onClose, initialEventType = '' }: CateringPopupProps) {
|
||||
const [isPending, startTransition] = useTransition();
|
||||
const [isSuccess, setIsSuccess] = useState(false);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
|
||||
const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
|
||||
event.preventDefault();
|
||||
setError(null);
|
||||
|
||||
const formData = new FormData(event.currentTarget);
|
||||
|
||||
startTransition(async () => {
|
||||
try {
|
||||
const result = await submitCateringInquiry(formData);
|
||||
if (result.success) {
|
||||
setIsSuccess(true);
|
||||
setTimeout(() => {
|
||||
onClose();
|
||||
setIsSuccess(false);
|
||||
}, 3000);
|
||||
} else {
|
||||
setError('Failed to submit inquiry. Please try again.');
|
||||
}
|
||||
} catch (err) {
|
||||
setError('Something went wrong. Please try again later.');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return (
|
||||
<AnimatePresence>
|
||||
{isOpen && (
|
||||
<motion.div
|
||||
className={styles.overlay}
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 1 }}
|
||||
exit={{ opacity: 0 }}
|
||||
onClick={(e) => e.target === e.currentTarget && onClose()}
|
||||
>
|
||||
<motion.div
|
||||
className={styles.popup}
|
||||
initial={{ opacity: 0, scale: 0.9, y: 20 }}
|
||||
animate={{ opacity: 1, scale: 1, y: 0 }}
|
||||
exit={{ opacity: 0, scale: 0.9, y: 20 }}
|
||||
transition={{ type: 'spring', damping: 25, stiffness: 300 }}
|
||||
>
|
||||
<button className={styles.closeButton} onClick={onClose}>✕</button>
|
||||
|
||||
<h2 className={styles.title}>Catering Inquiry</h2>
|
||||
<p className={styles.subtitle}>Let us make your event unforgettable with authentic Turkish flavors.</p>
|
||||
|
||||
{isSuccess ? (
|
||||
<motion.div
|
||||
className={styles.successMessage}
|
||||
initial={{ opacity: 0, y: 10 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
>
|
||||
Thank you! Your inquiry has been sent to hello@antalyarestaurant.ca. We will get back to you shortly.
|
||||
</motion.div>
|
||||
) : (
|
||||
<form className={styles.form} onSubmit={handleSubmit}>
|
||||
<div className={styles.formGrid}>
|
||||
<div className={styles.inputGroup}>
|
||||
<label className={styles.label} htmlFor="name">Full Name</label>
|
||||
<input className={styles.input} type="text" id="name" name="name" required placeholder="Enter Name" />
|
||||
</div>
|
||||
|
||||
<div className={styles.inputGroup}>
|
||||
<label className={styles.label} htmlFor="email">Email Address</label>
|
||||
<input className={styles.input} type="email" id="email" name="email" required placeholder="Enter Email" />
|
||||
</div>
|
||||
|
||||
<div className={styles.inputGroup}>
|
||||
<label className={styles.label} htmlFor="phone">Phone Number</label>
|
||||
<input className={styles.input} type="tel" id="phone" name="phone" required placeholder="Enter Phone Number" />
|
||||
</div>
|
||||
|
||||
<div className={styles.inputGroup}>
|
||||
<label className={styles.label} htmlFor="eventType">Event Type</label>
|
||||
<select className={styles.input} id="eventType" name="eventType" defaultValue={initialEventType} required>
|
||||
<option value="" disabled>Select Event Type</option>
|
||||
<option value="Corporate & Social Events">Corporate & Social Events</option>
|
||||
<option value="Family Gatherings & Weddings">Family Gatherings & Weddings</option>
|
||||
<option value="Birthday Party & Baby Shower">Birthday Party & Baby Shower</option>
|
||||
<option value="Other">Other Event</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div className={styles.inputGroup}>
|
||||
<label className={styles.label} htmlFor="date">Date of Event</label>
|
||||
<input className={styles.input} type="date" id="date" name="date" required />
|
||||
</div>
|
||||
|
||||
<div className={styles.inputGroup}>
|
||||
<label className={styles.label} htmlFor="guests">Number of Guests</label>
|
||||
<input className={styles.input} type="number" id="guests" name="guests" required min="1" placeholder="Enter Number of Guests" />
|
||||
</div>
|
||||
|
||||
<div className={`${styles.inputGroup} ${styles.fullWidth}`}>
|
||||
<label className={styles.label} htmlFor="message">Any Special Requests?</label>
|
||||
<textarea className={styles.textarea} id="message" name="message" placeholder="Enter Your Message..."></textarea>
|
||||
</div>
|
||||
|
||||
<button
|
||||
className={styles.submitButton}
|
||||
type="submit"
|
||||
disabled={isPending}
|
||||
>
|
||||
{isPending ? 'Sending Inquiry...' : 'Submit Inquiry'}
|
||||
</button>
|
||||
</div>
|
||||
{error && <p style={{ color: 'red', fontSize: '0.85rem', textAlign: 'center' }}>{error}</p>}
|
||||
</form>
|
||||
)}
|
||||
</motion.div>
|
||||
</motion.div>
|
||||
)}
|
||||
</AnimatePresence>
|
||||
)
|
||||
}
|
||||
@ -169,10 +169,10 @@
|
||||
cursor: pointer;
|
||||
transition: transform 0.4s ease, box-shadow 0.4s ease;
|
||||
border-radius: 30 30 30 30px;
|
||||
/* Rounded only at Bottom-Left to emphasize L shape */
|
||||
border: none;
|
||||
border-right: 8px solid #b07c4b;
|
||||
border-top: 8px solid #b07c4b;
|
||||
}
|
||||
|
||||
.clickableCard {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.topCard:hover {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user