Files
shahikitchen/components/CartDrawer.tsx
T
Zeeshan Khan 56fe68eb48 Initial commit: Shahi Kitchen premium website
- Royal cream + gold theme
- Playful animated hero with chef mascot
- Advanced menu with sidebar + video hover
- Multilingual support (EN, SV, HI, UR)
- Cart system with WhatsApp ordering
- Real restaurant photos integration
- Responsive design with proper navbar
2026-06-01 15:14:19 +02:00

226 lines
8.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
'use client';
/**
* =============================================================================
* CART DRAWER (SLIDE-IN BASKET PANEL)
* =============================================================================
*
* This is the visual "basket" that slides in from the right when the user
* clicks the cart icon in the navbar or the "View Cart" toast action.
*
* KEY DESIGN CHOICES:
* - Fixed position, full-height, max-w-md (beautiful on both mobile and desktop)
* - Backdrop click closes it (standard mobile pattern)
* - z-[70] sits above almost everything (including the sticky category nav)
* - All cart mutations go through the context — this component is "dumb" UI only
*
* THE ORDERING FLOW (very important for restaurant context):
* Instead of a traditional Stripe checkout, we generate a pre-filled WhatsApp
* message containing every line item + quantities + grand total.
* This matches the restaurant's current real-world ordering process.
* The number 46709864995 is the same one used in the homepage reservation form.
*
* FUTURE ENHANCEMENTS (documented here so nothing is forgotten):
* - Add "Special requests" textarea per order
* - Show estimated preparation time
* - Allow "Order for later" date/time picker
* - Split "Pickup" vs "Delivery" with different messaging
* - After WhatsApp opens, optionally clear the cart (or keep it — current choice)
*/
import { useCart } from './CartContext';
import Link from 'next/link';
export default function CartDrawer() {
const {
items,
isOpen,
closeCart,
totalPrice,
removeFromCart,
updateQuantity,
clearCart
} = useCart();
/**
* WHATSAPP DEEP LINK ORDERING
*
* Builds a human-readable, copy-paste friendly message that the restaurant staff
* can immediately understand and action.
*
* The format deliberately mirrors how the restaurant currently receives orders
* over the phone or via Instagram DMs.
*/
const orderViaWhatsApp = () => {
if (items.length === 0) return;
const lines = items
.map((item) => `${item.quantity} × ${item.name}${item.price * item.quantity} kr`)
.join('\n');
const message =
`Hello Shahi Kitchen 👋
I would like to place an order:
${lines}
Total: ${totalPrice} kr
Thank you!`;
const encoded = encodeURIComponent(message);
// This is the same WhatsApp business number used for table reservations on the homepage
window.open(`https://wa.me/46709864995?text=${encoded}`, '_blank');
};
// Guard clause — drawer only renders when explicitly opened via context
if (!isOpen) return null;
return (
<>
{/* SEMI-TRANSPARENT BACKDROP */}
{/* Clicking anywhere outside the drawer closes it (standard mobile pattern) */}
<div
className="fixed inset-0 bg-black/40 z-[60]"
onClick={closeCart}
/>
{/* THE ACTUAL DRAWER — slides in from right */}
{/* z-[70] ensures it sits above sticky nav, category pills, and most other UI */}
<div className="fixed top-0 right-0 h-full w-full max-w-md bg-[#F8F5F0] z-[70] shadow-2xl flex flex-col">
{/* HEADER — Title + item count + quick clear + close button */}
<div className="flex items-center justify-between p-6 border-b border-[#EDE6D9]">
<div className="flex items-center gap-3">
<h2 className="text-2xl tracking-[-0.5px]">Your Basket</h2>
{items.length > 0 && (
<span className="text-xs px-2.5 py-0.5 rounded-full bg-[#EDE6D9] text-[#6B665F]">
{items.length} {items.length === 1 ? 'item' : 'items'}
</span>
)}
</div>
<div className="flex items-center gap-3">
{items.length > 0 && (
<button
onClick={clearCart}
className="text-xs text-[#B38B4D] hover:underline"
>
Clear
</button>
)}
<button
onClick={closeCart}
className="text-[#6B665F] hover:text-[#2C2A26] text-2xl leading-none pl-1"
>
×
</button>
</div>
</div>
{/* SCROLLABLE CONTENT AREA */}
{/* Empty state is friendly and routes the user back to the menu */}
<div className="flex-1 overflow-y-auto p-6">
{items.length === 0 ? (
<div className="flex flex-col items-center justify-center h-full text-center">
<div className="text-6xl mb-4">🛒</div>
<p className="text-lg text-[#6B665F]">Your basket is empty</p>
<Link
href="/menu"
onClick={closeCart}
className="mt-6 text-[#B38B4D] hover:underline"
>
Browse the menu
</Link>
</div>
) : (
<div className="space-y-6">
{items.map((item) => (
<div key={item.id} className="flex gap-4 border-b border-[#EDE6D9] pb-6">
<div className="flex-1">
<div className="flex justify-between">
<div>
<h4 className="font-medium tracking-[-0.3px]">{item.name}</h4>
<p className="text-sm text-[#6B665F]">{item.price} kr × {item.quantity}</p>
</div>
<div className="text-right font-medium">
{(item.price * item.quantity).toFixed(0)} kr
</div>
</div>
{/* Quantity controls */}
<div className="flex items-center gap-3 mt-3">
<button
onClick={() => updateQuantity(item.id, item.quantity - 1)}
className="w-8 h-8 flex items-center justify-center border border-[#EDE6D9] rounded hover:bg-white transition"
>
</button>
<span className="w-6 text-center font-medium">{item.quantity}</span>
<button
onClick={() => updateQuantity(item.id, item.quantity + 1)}
className="w-8 h-8 flex items-center justify-center border border-[#EDE6D9] rounded hover:bg-white transition"
>
+
</button>
<button
onClick={() => removeFromCart(item.id)}
className="ml-auto text-xs text-[#B38B4D] hover:underline"
>
Remove
</button>
</div>
</div>
</div>
))}
</div>
)}
</div>
{/* STICKY FOOTER — always visible when cart has items */}
{/* Contains the two primary actions: WhatsApp (primary) + Phone (secondary) */}
{items.length > 0 && (
<div className="p-6 border-t border-[#EDE6D9] bg-white">
<button
onClick={clearCart}
className="text-xs text-[#8A8478] hover:text-[#B38B4D] mb-3 underline"
>
Clear basket
</button>
<div className="flex justify-between text-lg font-medium mb-4">
<span>Total</span>
<span>{totalPrice.toFixed(0)} kr</span>
</div>
<button
onClick={orderViaWhatsApp}
className="btn-primary w-full py-4 rounded-full text-base tracking-[0.5px] font-medium mb-2 flex items-center justify-center gap-2"
>
Send order via WhatsApp
</button>
<button
onClick={() => window.open('tel:031288910', '_self')}
className="btn-outline w-full py-3 rounded-full text-sm tracking-[0.5px] font-medium mb-3"
>
Call 031-28 89 10
</button>
<button
onClick={closeCart}
className="w-full text-sm text-[#6B665F] hover:text-[#2C2A26] pt-1"
>
Continue browsing
</button>
<p className="text-[10px] text-center text-[#8A8478] mt-4">
WhatsApp opens with your order pre-filled. We will confirm availability.
</p>
</div>
)}
</div>
</>
);
}