Merge version_2 into main #2

Merged
bender merged 3 commits from version_2 into main 2026-06-11 19:15:11 +00:00
3 changed files with 360 additions and 1 deletions

201
src/app/book/page.tsx Normal file
View File

@@ -0,0 +1,201 @@
"use client";
import { useState } from 'react';
import { ThemeProvider } from "@/providers/themeProvider/ThemeProvider";
import NavbarStyleFullscreen from '@/components/navbar/NavbarStyleFullscreen/NavbarStyleFullscreen';
import FooterLogoEmphasis from '@/components/sections/footer/FooterLogoEmphasis';
const navItems = [
{ name: "Home", href: "/" },
{ name: "Menu", id: "#menu-preview" },
{ name: "Events", id: "#private-events" },
{ name: "Reserve", href: "/book" },
{ name: "Find Us", href: "/contact" }
];
const footerColumns = [
{
items: [
{ label: "Menu", href: "#menu-preview" },
{ label: "Events", href: "#private-events" },
{ label: "Reservations", href: "/book" },
{ label: "Contact", href: "/contact" }
]
},
{
items: [
{ label: "Privacy Policy", href: "#" },
{ label: "Terms of Service", href: "#" },
{ label: "Cookie Policy", href: "#" }
]
},
{
items: [
{ label: "Instagram", href: "https://www.instagram.com/nowhereabudhabi" },
{ label: "Facebook", href: "https://www.facebook.com/nowhereabudhabi" }
]
}
];
export default function BookingPage() {
const [step, setStep] = useState(1);
const [formData, setFormData] = useState({
name: '',
email: '',
phone: '',
date: '', time: '',
guests: 1,
notes: ''
});
const [errors, setErrors] = useState({});
const validateStep1 = () => {
let newErrors = {};
if (!formData.name) newErrors.name = 'Name is required';
if (!formData.email) newErrors.email = 'Email is required';
else if (!/\S+@\S+\.\S+/.test(formData.email)) newErrors.email = 'Email is invalid';
setErrors(newErrors);
return Object.keys(newErrors).length === 0;
};
const validateStep2 = () => {
let newErrors = {};
if (!formData.date) newErrors.date = 'Date is required';
if (!formData.time) newErrors.time = 'Time is required';
if (formData.guests < 1) newErrors.guests = 'At least 1 guest is required';
setErrors(newErrors);
return Object.keys(newErrors).length === 0;
};
const handleChange = (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
const { name, value } = e.target;
setFormData(prev => ({ ...prev, [name]: value }));
};
const nextStep = () => {
if (step === 1 && !validateStep1()) return;
if (step === 2 && !validateStep2()) return; // Validation for step 2 before confirmation
setStep(prev => prev + 1);
};
const prevStep = () => setStep(prev => prev - 1);
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
// Here you would typically send formData to a backend
alert('Booking submitted: ' + JSON.stringify(formData, null, 2));
setStep(1); // Reset form
setFormData({ name: '', email: '', phone: '', date: '', time: '', guests: 1, notes: '' });
};
const renderStep = () => {
switch (step) {
case 1:
return (
<div>
<h3 className="text-2xl font-bold mb-4">Your Details</h3>
<div className="mb-4">
<input type="text" name="name" placeholder="Name" value={formData.name} onChange={handleChange} className="w-full p-3 border rounded mb-2 bg-neutral-900 text-white border-neutral-700" />
{errors.name && <p className="text-red-500 text-sm">{errors.name as string}</p>}
</div>
<div className="mb-4">
<input type="email" name="email" placeholder="Email" value={formData.email} onChange={handleChange} className="w-full p-3 border rounded mb-2 bg-neutral-900 text-white border-neutral-700" />
{errors.email && <p className="text-red-500 text-sm">{errors.email as string}</p>}
</div>
<div className="mb-4">
<input type="tel" name="phone" placeholder="Phone (Optional)" value={formData.phone} onChange={handleChange} className="w-full p-3 border rounded mb-2 bg-neutral-900 text-white border-neutral-700" />
</div>
<button onClick={nextStep} className="bg-primary-cta text-white py-3 px-6 rounded hover:opacity-90">Next</button>
</div>
);
case 2:
return (
<div>
<h3 className="text-2xl font-bold mb-4">Booking Details</h3>
<div className="mb-4">
<input type="date" name="date" value={formData.date} onChange={handleChange} className="w-full p-3 border rounded mb-2 bg-neutral-900 text-white border-neutral-700" />
{errors.date && <p className="text-red-500 text-sm">{errors.date as string}</p>}
</div>
<div className="mb-4">
<input type="time" name="time" value={formData.time} onChange={handleChange} className="w-full p-3 border rounded mb-2 bg-neutral-900 text-white border-neutral-700" />
{errors.time && <p className="text-red-500 text-sm">{errors.time as string}</p>}
</div>
<div className="mb-4">
<label htmlFor="guests" className="block text-sm font-medium text-foreground mb-1">Number of Guests</label>
<input type="number" name="guests" id="guests" min="1" value={formData.guests} onChange={handleChange} className="w-full p-3 border rounded mb-2 bg-neutral-900 text-white border-neutral-700" />
{errors.guests && <p className="text-red-500 text-sm">{errors.guests as string}</p>}
</div>
<div className="flex justify-between">
<button onClick={prevStep} className="bg-secondary-cta text-white py-3 px-6 rounded hover:opacity-90">Previous</button>
<button onClick={nextStep} className="bg-primary-cta text-white py-3 px-6 rounded hover:opacity-90">Next</button>
</div>
</div>
);
case 3:
return (
<div>
<h3 className="text-2xl font-bold mb-4">Confirmation</h3>
<p className="mb-2"><strong>Name:</strong> {formData.name}</p>
<p className="mb-2"><strong>Email:</strong> {formData.email}</p>
<p className="mb-2"><strong>Phone:</strong> {formData.phone}</p>
<p className="mb-2"><strong>Date:</strong> {formData.date}</p>
<p className="mb-2"><strong>Time:</strong> {formData.time}</p>
<p className="mb-4"><strong>Guests:</strong> {formData.guests}</p>
<div className="mb-4">
<label htmlFor="notes" className="block text-sm font-medium text-foreground mb-1">Special Notes (Optional)</label>
<textarea name="notes" id="notes" rows={3} value={formData.notes} onChange={handleChange} className="w-full p-3 border rounded mb-2 bg-neutral-900 text-white border-neutral-700"></textarea>
</div>
<div className="flex justify-between">
<button onClick={prevStep} className="bg-secondary-cta text-white py-3 px-6 rounded hover:opacity-90">Previous</button>
<button onClick={handleSubmit} className="bg-primary-cta text-white py-3 px-6 rounded hover:opacity-90">Confirm Booking</button>
</div>
</div>
);
default:
return null;
}
};
return (
<ThemeProvider
defaultButtonVariant="expand-hover"
defaultTextAnimation="reveal-blur"
borderRadius="soft"
contentWidth="medium"
sizing="largeSmall"
background="noise"
cardStyle="solid"
primaryButtonStyle="radial-glow"
secondaryButtonStyle="solid"
headingFontWeight="semibold"
>
<NavbarStyleFullscreen
navItems={navItems}
logoSrc="https://webuild-dev.s3.eu-north-1.amazonaws.com/default/no-image.jpg?id=2ma3a8"
logoAlt="Nowhere Restaurant Logo"
brandName="Nowhere."
bottomLeftText="Abu Dhabi"
bottomRightText="Find yourself Nowhere."
/>
<main className="min-h-screen flex items-center justify-center py-16 bg-background">
<div className="bg-card p-8 rounded-lg shadow-lg max-w-lg w-full text-foreground">
<h2 className="text-3xl font-bold mb-6 text-center">Book Your Table</h2>
<div className="flex justify-center mb-6">
<div className={`w-8 h-8 rounded-full flex items-center justify-center ${step === 1 ? 'bg-primary-cta text-white' : 'bg-secondary-cta text-white'} text-sm font-bold`}>1</div>
<div className="h-0.5 w-12 bg-neutral-700 mx-2 self-center"></div>
<div className={`w-8 h-8 rounded-full flex items-center justify-center ${step === 2 ? 'bg-primary-cta text-white' : 'bg-secondary-cta text-white'} text-sm font-bold`}>2</div>
<div className="h-0.5 w-12 bg-neutral-700 mx-2 self-center"></div>
<div className={`w-8 h-8 rounded-full flex items-center justify-center ${step === 3 ? 'bg-primary-cta text-white' : 'bg-secondary-cta text-white'} text-sm font-bold`}>3</div>
</div>
{renderStep()}
</div>
</main>
<FooterLogoEmphasis
logoSrc="https://webuild-dev.s3.eu-north-1.amazonaws.com/default/no-image.jpg?id=2ma3a8"
logoAlt="Nowhere Restaurant Logo"
columns={footerColumns}
logoText="Subscribe. We'll tell you nothing, beautifully. © 2023 Nowhere. All Rights Reserved. Licensed in Abu Dhabi."
/>
</ThemeProvider>
);
}

109
src/app/contact/page.tsx Normal file
View File

@@ -0,0 +1,109 @@
"use client";
import { ThemeProvider } from "@/providers/themeProvider/ThemeProvider";
import NavbarStyleFullscreen from '@/components/navbar/NavbarStyleFullscreen/NavbarStyleFullscreen';
import FooterLogoEmphasis from '@/components/sections/footer/FooterLogoEmphasis';
const navItems = [
{ name: "Home", href: "/" },
{ name: "Menu", id: "#menu-preview" },
{ name: "Events", id: "#private-events" },
{ name: "Reserve", href: "/book" },
{ name: "Find Us", href: "/contact" }
];
const footerColumns = [
{
items: [
{ label: "Menu", href: "#menu-preview" },
{ label: "Events", href: "#private-events" }, { label: "Reservations", href: "/book" },
{ label: "Contact", href: "/contact" }
]
},
{
items: [
{ label: "Privacy Policy", href: "#" },
{ label: "Terms of Service", href: "#" },
{ label: "Cookie Policy", href: "#" }
]
},
{
items: [
{ label: "Instagram", href: "https://www.instagram.com/nowhereabudhabi" },
{ label: "Facebook", href: "https://www.facebook.com/nowhereabudhabi" }
]
}
];
export default function ContactPage() {
return (
<ThemeProvider
defaultButtonVariant="expand-hover"
defaultTextAnimation="reveal-blur"
borderRadius="soft"
contentWidth="medium"
sizing="largeSmall"
background="noise"
cardStyle="solid"
primaryButtonStyle="radial-glow"
secondaryButtonStyle="solid"
headingFontWeight="semibold"
>
<NavbarStyleFullscreen
navItems={navItems}
logoSrc="https://webuild-dev.s3.eu-north-1.amazonaws.com/default/no-image.jpg?id=2ma3a8"
logoAlt="Nowhere Restaurant Logo"
brandName="Nowhere."
bottomLeftText="Abu Dhabi"
bottomRightText="Find yourself Nowhere."
/>
<main className="min-h-screen py-16 bg-background text-foreground">
<div className="container mx-auto px-4 sm:px-6 lg:px-8">
<h1 className="text-5xl font-extrabold text-center mb-12">Visit Us</h1>
<div className="grid grid-cols-1 md:grid-cols-2 gap-12 mb-16">
<div className="bg-card p-8 rounded-lg shadow-lg flex flex-col justify-between">
<div>
<h2 className="text-3xl font-bold mb-4">Our Location</h2>
<p className="text-lg mb-2"><strong>Address:</strong> Downtown, Al Maryah Island, Abu Dhabi</p>
<p className="text-lg mb-2"><strong>Phone:</strong> +971 50 123 4567</p>
<p className="text-lg mb-4"><strong>Email:</strong> info@nowhereabudhabi.com</p>
<p className="text-md text-gray-400">Exact location details will be provided upon reservation confirmation.</p>
</div>
</div>
<div className="bg-card p-2 rounded-lg shadow-lg overflow-hidden">
<iframe
src="https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d3630.9575819771143!2d54.3725792149811!3d24.4981329842525!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x3e5e4492194a32a7%3A0xc4a1c5d98d5c4b8b!2sAbu%20Dhabi%20Mall!5e0!3m2!1sen!2sae!4v1678912345678!5m2!1sen!2sae"
width="100%"
height="450"
style={{ border: 0 }}
allowFullScreen=""
loading="lazy"
referrerPolicy="no-referrer-when-downgrade"
title="Google Map of Nowhere Restaurant"
className="rounded-md"
></iframe>
</div>
</div>
<div className="text-center mt-16">
<h2 className="text-3xl font-bold mb-4">Opening Hours</h2>
<ul className="text-lg list-none p-0 mb-8">
<li className="mb-2"><strong>Dinner:</strong> Monday - Saturday, 7:00 PM - 1:00 AM</li>
<li className="mb-2"><strong>Café:</strong> Daily, 10:00 AM - 5:00 PM</li>
<li className="mb-2"><strong>Bar:</strong> Daily, 5:00 PM - 2:00 AM</li>
</ul>
<p className="text-xl">We look forward to welcoming you to Nowhere.</p>
</div>
</div>
</main>
<FooterLogoEmphasis
logoSrc="https://webuild-dev.s3.eu-north-1.amazonaws.com/default/no-image.jpg?id=2ma3a8"
logoAlt="Nowhere Restaurant Logo"
columns={footerColumns}
logoText="Subscribe. We'll tell you nothing, beautifully. © 2023 Nowhere. All Rights Reserved. Licensed in Abu Dhabi."
/>
</ThemeProvider>
);
}

View File

@@ -12,6 +12,8 @@ import MetricSplitMediaAbout from '@/components/sections/about/MetricSplitMediaA
import NavbarStyleFullscreen from '@/components/navbar/NavbarStyleFullscreen/NavbarStyleFullscreen';
import ProductCardTwo from '@/components/sections/product/ProductCardTwo';
import TestimonialCardSix from '@/components/sections/testimonial/TestimonialCardSix';
import ProductCardThree from '@/components/sections/product/ProductCardThree';
import TestimonialCardFive from '@/components/sections/testimonial/TestimonialCardFive';
export default function LandingPage() {
return (
@@ -35,6 +37,10 @@ export default function LandingPage() {
name: "Home", id: "#hero"},
{
name: "Menu", id: "#menu-preview"},
{
name: "Before & After", id: "#before-after-gallery"},
{
name: "Reviews", id: "#reviews"},
{
name: "Events", id: "#private-events"},
{
@@ -175,6 +181,49 @@ export default function LandingPage() {
/>
</div>
<div id="before-after-gallery" data-section="before-after-gallery">
<ProductCardThree
animationType="slide-up"
textboxLayout="default"
gridVariant="two-columns-alternating-heights"
useInvertedBackground={false}
title="OUR EVOLUTION. CAPTURED."
description="Witness the transformation and meticulous craftsmanship behind Nowhere's unique ambiance and culinary spaces. A journey from concept to captivating reality."
products={[
{
id: "before-after-1", name: "Dining Area Transformation", price: "Before: Rustic Charm", imageSrc: "http://img.b2bpic.net/free-photo/empty-restaurant_23-2147811210.jpg", imageAlt: "Dining area before transformation"},
{
id: "before-after-2", name: "Dining Area Transformation", price: "After: Cinematic Elegance", imageSrc: "http://img.b2bpic.net/free-photo/restaurant-private-room-with-table-14-persons-wooden-ceiling-brick-walls-fireplace_140725-8452.jpg", imageAlt: "Dining area after transformation"},
{
id: "before-after-3", name: "Bar Area Enhancement", price: "Before: Simple Setup", imageSrc: "http://img.b2bpic.net/free-photo/empty-bar-counter_23-2147811211.jpg", imageAlt: "Bar area before styling"},
{
id: "before-after-4", name: "Bar Area Enhancement", price: "After: Curated Bar", imageSrc: "http://img.b2bpic.net/free-photo/front-view-bartender-preparing-drink_23-2150494242.jpg", imageAlt: "Bar area after styling"},
{
id: "before-after-5", name: "Lounge Design Evolution", price: "Before: Raw Space", imageSrc: "http://img.b2bpic.net/free-photo/modern-empty-kitchen_23-2147779730.jpg", imageAlt: "Lounge area initial setup"},
{
id: "before-after-6", name: "Lounge Design Evolution", price: "After: Intimate Seating", imageSrc: "http://img.b2bpic.net/free-photo/chandelier-luxury-restaurant_23-2147981232.jpg", imageAlt: "Lounge area after redesign"},
]}
/>
</div>
<div id="reviews" data-section="reviews">
<TestimonialCardFive
animationType="slide-up"
textboxLayout="default"
useInvertedBackground={false}
title="WHAT OUR GUESTS SAY"
description="Hear directly from those who have discovered the magic of Nowhere. Their experiences paint a vivid picture of our unique world."
testimonials={[
{
id: "review-1", name: "Anya Sharma", date: "14th May 2024", title: "An Unforgettable Evening", quote: "Nowhere truly lives up to its name it transported us to another world. The ambiance was mesmerizing, and every dish was a masterpiece. Highly recommend!", tag: "Fine Dining", avatarSrc: "http://img.b2bpic.net/free-photo/young-pretty-woman_23-2147811216.jpg", avatarAlt: "Anya Sharma", imageSrc: "http://img.b2bpic.net/free-photo/friends-enjoying-dinner_23-2148293979.jpg", imageAlt: "Happy diners at Nowhere"},
{
id: "review-2", name: "Omar Al-Farsi", date: "10th May 2024", title: "Culinary Perfection", quote: "The Desert Bloom Lamb was simply divine, and the Oasis Old Fashioned was the best cocktail I've had in years. Nowhere is a gem in Abu Dhabi's culinary scene.", tag: "Food & Drink", avatarSrc: "http://img.b2bpic.net/free-photo/attractive-man-wearing-glasses_23-2148281086.jpg", avatarAlt: "Omar Al-Farsi", imageSrc: "http://img.b2bpic.net/free-photo/gourmet-plate-food_23-2148152179.jpg", imageAlt: "Close-up of a gourmet dish"},
{
id: "review-3", name: "Sarah Chen", date: "08th May 2024", title: "Hidden Gem for Events", quote: "We hosted our anniversary party at Nowhere, and the team exceeded all expectations. The private event space is stunning, and the service was impeccable. Thank you for a magical night!", tag: "Private Events", avatarSrc: "http://img.b2bpic.net/free-photo/front-view-young-woman-with-curly-hair_23-2148202518.jpg", avatarAlt: "Sarah Chen", imageSrc: "http://img.b2bpic.net/free-photo/chandelier-luxury-restaurant_23-2147981232.jpg", imageAlt: "Elegant event setup"},
]}
/>
</div>
<div id="reservations" data-section="reservations">
<FaqSplitMedia
textboxLayout="default"
@@ -293,4 +342,4 @@ export default function LandingPage() {
</ReactLenis>
</ThemeProvider>
);
}
}