Merge version_3_1776416099535 into main #5
@@ -4,6 +4,7 @@ import MenuPage from './pages/MenuPage';
|
||||
import AboutPage from './pages/AboutPage';
|
||||
import ContactPage from './pages/ContactPage';
|
||||
import TestimonialsGrid from './components/sections/testimonials/TestimonialsGrid';
|
||||
import BookingForm from './components/sections/booking/BookingForm';
|
||||
|
||||
export default function App() {
|
||||
return (
|
||||
@@ -13,8 +14,9 @@ export default function App() {
|
||||
<Route path="/menu" element={<MenuPage />} />
|
||||
<Route path="/about" element={<AboutPage />} />
|
||||
<Route path="/contact" element={<ContactPage />} />
|
||||
</Routes>
|
||||
<TestimonialsGrid />
|
||||
</Routes>
|
||||
<TestimonialsGrid />
|
||||
<BookingForm />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
110
src/components/sections/booking/BookingForm.tsx
Normal file
110
src/components/sections/booking/BookingForm.tsx
Normal file
@@ -0,0 +1,110 @@
|
||||
import { useState, type ChangeEvent, type FormEvent } from 'react';
|
||||
|
||||
const BookingForm = () => {
|
||||
const [formData, setFormData] = useState({
|
||||
name: '',
|
||||
email: '',
|
||||
date: '',
|
||||
time: '',
|
||||
guests: 1,
|
||||
});
|
||||
|
||||
const handleChange = (e: ChangeEvent<HTMLInputElement>) => {
|
||||
const { name, value } = e.target;
|
||||
setFormData(prevState => ({
|
||||
...prevState,
|
||||
[name]: value,
|
||||
}));
|
||||
};
|
||||
|
||||
const handleSubmit = (e: FormEvent<HTMLFormElement>) => {
|
||||
e.preventDefault();
|
||||
// Handle form submission logic here
|
||||
console.log('Booking submitted:', formData);
|
||||
alert('Your booking has been submitted!');
|
||||
setFormData({
|
||||
name: '',
|
||||
email: '',
|
||||
date: '',
|
||||
time: '',
|
||||
guests: 1,
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<section className="booking-section" id="booking">
|
||||
<div className="booking-container">
|
||||
<h2 className="booking-title">Book a Table or Tasting</h2>
|
||||
<p className="booking-description">
|
||||
Reserve a table for your next coffee break or book a private coffee tasting session with our experts.
|
||||
</p>
|
||||
<form className="booking-form" onSubmit={handleSubmit}>
|
||||
<div className="form-group">
|
||||
<label htmlFor="name">Full Name</label>
|
||||
<input
|
||||
type="text"
|
||||
id="name"
|
||||
name="name"
|
||||
value={formData.name}
|
||||
onChange={handleChange}
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
<div className="form-group">
|
||||
<label htmlFor="email">Email Address</label>
|
||||
<input
|
||||
type="email"
|
||||
id="email"
|
||||
name="email"
|
||||
value={formData.email}
|
||||
onChange={handleChange}
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
<div className="form-row">
|
||||
<div className="form-group">
|
||||
<label htmlFor="date">Date</label>
|
||||
<input
|
||||
type="date"
|
||||
id="date"
|
||||
name="date"
|
||||
value={formData.date}
|
||||
onChange={handleChange}
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
<div className="form-group">
|
||||
<label htmlFor="time">Time</label>
|
||||
<input
|
||||
type="time"
|
||||
id="time"
|
||||
name="time"
|
||||
value={formData.time}
|
||||
onChange={handleChange}
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="form-group">
|
||||
<label htmlFor="guests">Number of Guests</label>
|
||||
<input
|
||||
type="number"
|
||||
id="guests"
|
||||
name="guests"
|
||||
value={formData.guests}
|
||||
onChange={handleChange}
|
||||
min="1"
|
||||
max="10"
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
<button type="submit" className="submit-btn primary-button">
|
||||
Book Now
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
export default BookingForm;
|
||||
@@ -151,6 +151,53 @@ h6 {
|
||||
font-family: "Inter", sans-serif;
|
||||
}
|
||||
|
||||
input,
|
||||
button,
|
||||
select,
|
||||
textarea {
|
||||
font-family: "Inter", sans-serif;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
input[type="text"],
|
||||
input[type="email"],
|
||||
input[type="date"],
|
||||
input[type="time"],
|
||||
input[type="number"] {
|
||||
width: 100%;
|
||||
padding: 0.75rem 1rem;
|
||||
border-radius: var(--radius);
|
||||
border: 1px solid color-mix(in srgb, var(--color-accent) 25%, transparent);
|
||||
background-color: var(--background);
|
||||
color: var(--foreground);
|
||||
font-size: var(--text-base);
|
||||
transition: border-color 0.2s, box-shadow 0.2s;
|
||||
}
|
||||
|
||||
input[type="text"]:focus,
|
||||
input[type="email"]:focus,
|
||||
input[type="date"]:focus,
|
||||
input[type="time"]:focus,
|
||||
input[type="number"]:focus {
|
||||
outline: none;
|
||||
border-color: var(--accent);
|
||||
box-shadow: 0 0 0 2px color-mix(in srgb, var(--color-accent) 20%, transparent);
|
||||
}
|
||||
|
||||
button {
|
||||
cursor: pointer;
|
||||
border-radius: var(--radius);
|
||||
padding: 0.75rem 1.5rem;
|
||||
font-size: var(--text-lg);
|
||||
font-weight: 600;
|
||||
border: none;
|
||||
transition: transform 0.2s, box-shadow 0.2s;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
/* WEBILD_CARD_STYLE */
|
||||
/* @cards/gradient-bordered */
|
||||
.card {
|
||||
@@ -164,6 +211,7 @@ h6 {
|
||||
.primary-button {
|
||||
background: linear-gradient(to bottom, color-mix(in srgb, var(--color-primary-cta) 75%, transparent), var(--color-primary-cta));
|
||||
box-shadow: color-mix(in srgb, var(--color-background) 25%, transparent) 0px 1px 1px 0px inset, color-mix(in srgb, var(--color-primary-cta) 15%, transparent) 3px 3px 3px 0px;
|
||||
color: var(--primary-cta-text);
|
||||
}
|
||||
|
||||
/* WEBILD_SECONDARY_BUTTON */
|
||||
@@ -173,4 +221,5 @@ h6 {
|
||||
background: linear-gradient(to bottom right, color-mix(in srgb, var(--color-secondary-cta) 80%, transparent), var(--color-secondary-cta));
|
||||
box-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05);
|
||||
border: 1px solid var(--color-secondary-cta);
|
||||
color: var(--secondary-cta-text);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user