'use client'; import Navbar from "@/components/Navbar"; import Footer from "@/components/Footer"; import { buildBookingWhatsAppMessage } from '@/application/messaging/whatsapp-message-builder'; import { isBookingComplete } from '@/domain/booking/validation'; import type { BookingDetails, PreOrderLine } from '@/domain/booking/entities'; import { addOrderLine, calculateLineTotal, calculateOrderTotal, formatLineQuantityLabel, removeOrderLine, updateOrderLineQuantity, } from '@/domain/shared/order-line'; import { buildCartLineFromMenuItem } from '@/application/cart/cart-line-builder'; import type { MenuItem } from '@/domain/menu/entities'; import { getMenuPosterSrc, getMenuPosterCandidates, logoUrl, applyNextImageFallback, SITE_ASSETS, } from '@/lib/assets'; import { container } from '@/infrastructure/di/container'; import { useLanguage } from '@/presentation/providers/language-provider'; import { getTranslation } from '@/presentation/i18n/translations'; import { getMenuItemDescription, getMenuItemName, localizeOrderLineName, } from '@/application/i18n/menu-localization'; import { useState } from 'react'; import { motion, AnimatePresence } from "framer-motion"; import { MapPin, Calendar, Clock, Users, User, Phone, Mail, MessageCircle, Plus, Minus, X, ArrowRight, Search, CheckCircle } from "lucide-react"; import { menuCategories } from "@/lib/menu-data"; import { playAddSound, playHoverSound, playSuccessSound } from "@/lib/sounds"; /** * ============================================================================= * TABLE RESERVATION / BOOKING PAGE * ============================================================================= * * Beautiful, theme-matched table booking experience with optional pre-order. * - Swap implemented: Reserve Table now in central nav pills, Login is the gold CTA. * - Form first (location, date, time, guests, name, phone, email, notes). * - After form: full menu selector for pre-ordering (reuse menu-data). * - End: builds rich WhatsApp inquiry (booking + pre-order items) using same number as cart. * - Fully translated (sv default + en/hi/ur). * - Mobile-first, large targets, elegant cards matching /login and site theme. * - Uses framer-motion for reveals, lucide icons. * - No backend: client-side only, like staff login and cart WhatsApp. * * Linked from navbar (after swap) and locations. */ export default function ReservePage() { const { language } = useLanguage(); const t = getTranslation(language); const [booking, setBooking] = useState({ location: '', date: '', time: '', guests: '', name: '', phone: '', email: '', notes: '', }); const [preOrder, setPreOrder] = useState([]); const [showMenu, setShowMenu] = useState(false); const [search, setSearch] = useState(''); const [sent, setSent] = useState(false); const handleBookingChange = (e: React.ChangeEvent) => { const { name, value } = e.target; setBooking((prev) => ({ ...prev, [name]: value })); }; const validateForm = (): boolean => isBookingComplete(booking); const handleContinue = (e: React.FormEvent) => { e.preventDefault(); if (validateForm()) { setShowMenu(true); // Smooth scroll to menu on mobile setTimeout(() => { const menuEl = document.getElementById('preorder-menu'); if (menuEl) menuEl.scrollIntoView({ behavior: 'smooth', block: 'start' }); }, 100); } else { alert('Please fill in all required fields (location, date, time, guests, name, phone).'); } }; // Flatten menu for selector (with search) const allDishes = menuCategories.flatMap((cat) => cat.items); const filteredDishes = allDishes.filter((dish) => { const q = search.toLowerCase(); const localizedName = getMenuItemName(language, dish).toLowerCase(); const localizedDescription = getMenuItemDescription(language, t, dish).toLowerCase(); return ( localizedName.includes(q) || localizedDescription.includes(q) || dish.name.toLowerCase().includes(q) ); }); const addToPreOrder = (dish: MenuItem) => { setPreOrder((prev) => addOrderLine(prev, buildCartLineFromMenuItem(dish))); }; const updatePreOrderQty = (id: string, newQty: number) => { setPreOrder((prev) => updateOrderLineQuantity(prev, id, newQty)); }; const removeFromPreOrder = (id: string) => { setPreOrder((prev) => removeOrderLine(prev, id)); }; const getPreOrderTotal = () => calculateOrderTotal(preOrder); const handleSendInquiry = () => { if (!validateForm()) { alert('Please complete the booking form first.'); return; } playSuccessSound(); const message = buildBookingWhatsAppMessage(booking, preOrder, { askim: t.booking.askim, backaplan: t.booking.backaplan, }); if (!message) return; container.messagingGateway.openWhatsApp(message); setSent(true); }; const resetAll = () => { setBooking({ location: '', date: '', time: '', guests: '', name: '', phone: '', email: '', notes: '' }); setPreOrder([]); setShowMenu(false); setSearch(''); setSent(false); }; const editBooking = () => { setShowMenu(false); setSent(false); }; // Location options from translations const locationOptions = [ { value: 'askim', label: t.booking.askim }, { value: 'backaplan', label: t.booking.backaplan }, ]; return (
{/* Elegant Header */}
EXCLUSIVE EXPERIENCE

{t.booking.title}

{t.booking.subtitle}

{/* Decorative header info - now ABOVE the form (not on side) so form can be wider */}
Shahi Kitchen
Shahi Kitchen
TABLE RESERVATIONS

Two locations. Unforgettable evenings. Pre-order your favorites for a perfect arrival.

ASKIM • BACKAPLAN
{!sent ? (
{/* Booking Form Card - now wider (full in max-w-4xl) */}

{t.booking.formTitle}

Fill in your details to secure your table.

{/* Location */}
{/* Date */}
{/* Time */}
{/* Guests */}
{/* Name */}
{/* Phone */}
{/* Email */}
{/* Notes */}