Files
shahikitchen/lib/menu-data.ts
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

206 lines
11 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.
/**
* =============================================================================
* CENTRAL MENU DATA — Shahi Kitchen
* =============================================================================
*
* This is the SINGLE SOURCE OF TRUTH for every dish shown on the website.
*
* WHY THIS FILE EXISTS:
* - Keeps menu content decoupled from UI components (easy for restaurant staff
* or future devs to update prices/descriptions without touching React code)
* - Powers BOTH the public menu page AND the cart system
* - Enables future features: search, filters, online ordering, admin CMS, etc.
*
* DATA MODEL:
* - MenuCategory: A logical section (Street Food, Vegetarian, Chicken, Sweets...)
* - MenuItem: One dish
* id → stable unique key (used in cart, URLs, analytics). NEVER change.
* name → displayed title
* price → integer in Swedish Krona (kr). No decimals in current design.
* description → optional rich text shown under the name
* image → filename inside /public/images/dishes/ (fallback when no video)
* video → filename inside /public/videos/ (MP4 or WebM)
* The menu page automatically looks for a matching
* `-poster.jpg` first frame in /public/images/dishes/
* isVegetarian → boolean flag. Powers the green "VEGETARIAN" pill + filter toggle
*
* VIDEO + POSTER CONTRACT (critical):
* When `video: "butter-chicken-steam.mp4"` exists:
* 1. The card shows the static poster image first (performance + first-frame accuracy)
* 2. On hover the actual video plays (only while hovering)
* 3. On mouse leave → video pauses + resets to time 0
* Poster lookup order (see menu/page.tsx for the exact fallback logic):
* butter-chicken-steam-poster.jpg
* butter-chicken-steam-optimized-poster.jpg
* (and a few legacy variants for safety)
*
* HOW TO ADD A NEW DISH (future-proof instructions):
* 1. Add a high-quality image to /public/images/dishes/your-dish.jpg
* 2. (Optional but recommended) Generate a short 48s video → optimize with ffmpeg
* and place in /public/videos/your-dish.webm + .mp4
* 3. Extract first frame as your-dish-poster.jpg (see extract-video-posters.sh)
* 4. Add the item object below in the correct category
* 5. If vegetarian → set isVegetarian: true
* 6. Update price in both places if the restaurant changes pricing
*
* IMPORTANT GOTCHAS:
* - The `id` must be kebab-case and globally unique across all categories.
* - Price is stored as number (not string) so cart math works.
* - Do NOT delete items that have already been ordered by real customers
* (the cart uses the id as primary key).
*
* RELATED FILES:
* - app/menu/page.tsx → consumes this data + adds cart buttons + video hover
* - components/CartContext.tsx → stores references by id + name + price
*/
export type MenuItem = {
id: string;
name: string;
description?: string;
price: number;
image?: string; // filename from /public/images/dishes/
video?: string; // filename from /public/videos/ (for animated dishes)
isVegetarian?: boolean;
};
export type MenuCategory = {
id: string;
name: string;
items: MenuItem[];
};
/**
* THE ACTUAL MENU DATA
*
* Categories are rendered in the exact order they appear here on /menu.
* Each category has a stable `id` used for:
* - URL hash navigation (#street-food)
* - IntersectionObserver active state
* - Category filter pills (the beautiful sliding gold indicator)
*
* Keep descriptions concise (12 lines max) — the design is generous but not verbose.
*/
export const menuCategories: MenuCategory[] = [
{
id: "street-food",
name: "Street Food & Starters",
items: [
{ id: "samosa-aloo", name: "Samosa Aloo Veg", price: 34, image: "aloo-samosa.jpg", video: "samosa-aloo.mp4" },
{ id: "samosa-keema", name: "Samosa Keema", price: 39, image: "keema-samosa.jpg", video: "samosa-keema.mp4" },
{ id: "samosa-chat", name: "Samosa Chat", price: 89, image: "samosa-chaat.jpg", video: "samosa-chaat.mp4" },
{ id: "chana-chat", name: "Chana Chat", price: 69, image: "chana-chaat.jpg", video: "chana-chaat.mp4" },
{ id: "panipuri", name: "Panipuri / Golgappe", price: 69, image: "panipuri.jpg", video: "panipuri.mp4" },
{ id: "keema-naan-starter", name: "Keema Naan", price: 75, image: "keema-naan.jpg", video: "keema-naan.mp4" },
],
},
{
id: "vegetarian",
name: "Vegetarian",
items: [
{ id: "palak-paneer", name: "Palak Paneer", description: "Cottage cheese cooked in a creamy spinach gravy with mild spices and aromatic herbs.", price: 139, image: "palak-paneer.jpg", video: "palak-paneer.mp4", isVegetarian: true },
{ id: "shahi-paneer", name: "Shahi Paneer", description: "Soft cottage cheese in a rich, creamy cashew and tomato gravy with Indian spices.", price: 139, image: "shahi-paneer.jpg", video: "shahi-paneer.mp4", isVegetarian: true },
{ id: "malai-kofta", name: "Malai Kofta", description: "Soft vegetable koftas simmered in a rich and creamy onion-tomato gravy with mild spices.", price: 139, image: "malai-kofta.jpg", video: "malai-kofta.mp4", isVegetarian: true },
{ id: "daal-makhani", name: "Daal Makhani", description: "Slow-cooked black lentils in a buttery, creamy tomato gravy with aromatic spices.", price: 139, image: "daal-makhani.jpg", video: "daal-makhani.mp4", isVegetarian: true },
{ id: "lahore-chana", name: "Lahore Chana", description: "Spiced chickpeas cooked in a tangy onion-tomato gravy with traditional Punjabi spices.", price: 139, image: "lahore-chana.jpg", isVegetarian: true },
],
},
{
id: "meat",
name: "Meat",
items: [
{ id: "lamm-palak", name: "Lamm Palak", price: 179, image: "lamm-palak.jpg", video: "lamm-palak.mp4" },
{ id: "lamm-vindaloo", name: "Lamm Vindaloo", price: 179, image: "lamm-vindaloo.jpg", video: "lamm-vindaloo.mp4" },
{ id: "lamm-rogan-josh", name: "Lamm Rogan Josh", price: 199, image: "lamm-rogan-josh.jpg", video: "lamm-rogan-josh.mp4" },
{ id: "lamm-karahi", name: "Lamm Karahi", price: 179, image: "lamm-karahi.jpg", video: "lamm-karahi.mp4" },
{ id: "bong-nihari", name: "Bong Nihari", price: 199, image: "bong-nihari.jpg", video: "bong-nihari.mp4" },
{ id: "paye", name: "Paye", price: 149, image: "paye.jpg", video: "paye.mp4" },
],
},
{
id: "burger-sandwich",
name: "Burger & Sandwich",
items: [
{ id: "shahi-burger", name: "Shahi Burger", price: 119, image: "shahi-burger.jpg", video: "shahi-burger.mp4" },
{ id: "shami-sandwich", name: "Shami Sandwich Menu", price: 99, image: "shami-sandwich.jpg", video: "shami-sandwich.mp4" },
],
},
{
id: "chicken",
name: "Chicken",
items: [
{ id: "chicken-biryani", name: "Chicken Biryani", price: 149, image: "chicken-biryani.jpg", video: "chicken-biryani.mp4" },
{ id: "chicken-tikka", name: "Chicken Tikka", price: 149, image: "chicken-tikka.jpg", video: "chicken-tikka.mp4" },
{ id: "tikka-boti", name: "Tikka Boti", price: 149, image: "chicken-tikka.jpg", video: "tikka-boti.mp4" },
{ id: "chicken-karahi", name: "Chicken Karahi", price: 149, image: "chicken-karahi.jpg", video: "chicken-karahi.mp4" },
{ id: "lahore-sizzler", name: "Lahore Sizzler", price: 169, image: "lahore-sizzler.jpg", video: "lahore-sizzler.mp4" },
{ id: "butter-chicken", name: "Butter Chicken", price: 149, image: "butter-chicken.jpg" },
{ id: "chicken-haleem", name: "Chicken Haleem", price: 149, image: "chicken-haleem.jpg", video: "chicken-haleem.mp4" },
],
},
{
id: "pizza",
name: "Pizza",
items: [
{ id: "lahore-pizza", name: "Lahore Pizza", price: 119, image: "lahore-pizza.jpg", video: "lahore-pizza.mp4" },
{ id: "kebab-pizza", name: "Kebab Pizza", price: 119, image: "kebab-pizza.jpg", video: "kebab-pizza.mp4" },
{ id: "tikka-boti-pizza", name: "Tikka Boti Pizza", price: 119, image: "tikka-boti-pizza.jpg", video: "tikka-boti-pizza.mp4" },
{ id: "peshawari-pizza", name: "Peshawari Pizza", price: 119, image: "peshawari-pizza.jpg", video: "peshawari-pizza.mp4" },
{ id: "veg-pizza", name: "Veg Pizza", price: 109, image: "veg-pizza.jpg", isVegetarian: true },
],
},
{
id: "naan-roll",
name: "Naan Roll",
items: [
{ id: "tikka-boti-roll", name: "Tikka Boti Roll", price: 99, image: "tikka-boti-roll.jpg", video: "tikka-boti-roll.mp4" },
{ id: "kebab-roll", name: "Kebab Roll", price: 99, image: "kebab-roll.jpg", video: "kebab-roll.mp4" },
{ id: "falafel-roll", name: "Falafel Roll", price: 99, image: "falafel-roll.jpg", video: "falafel-roll.mp4", isVegetarian: true },
{ id: "paneer-roll", name: "Paneer Roll", price: 99, image: "paneer-roll.jpg", video: "paneer-roll.mp4", isVegetarian: true },
],
},
{
id: "sweets",
name: "Sweets / Mithai",
items: [
{ id: "namakpare", name: "Namakpare", price: 135, image: "namakpare.jpg", video: "namakpare.mp4" },
{ id: "jalebi", name: "Jalebi", price: 119, image: "jalebi.jpg", video: "jalebi.mp4" },
{ id: "gajar-halwa", name: "Gajar Halwa", price: 149, image: "gajar-halwa.jpg", video: "gajar-halwa.mp4" },
{ id: "rasmalai", name: "Rasmalai", price: 45, image: "rasmalai.jpg", video: "rasmalai.mp4" },
{ id: "kulfi", name: "Kulfi", price: 39, image: "kulfi.jpg", video: "kulfi.mp4" },
],
},
{
id: "drinks",
name: "Drinks",
items: [
{ id: "masala-chai", name: "Masala Chai", price: 39, image: "masala-chai.jpg" },
{ id: "mango-lassi", name: "Mango Lassi", price: 45, image: "mango-lassi.jpg", video: "mango-lassi.mp4" },
{ id: "coca-cola", name: "Coca-Cola", price: 29 },
{ id: "pepsi-fanta", name: "Pepsi / Fanta", price: 29 },
{ id: "sprite-ramlosa", name: "Sprite / Ramlösa", price: 29 },
{ id: "energy-drink", name: "Energy Drink", price: 39 },
{ id: "juice", name: "Juice", price: 20, image: "mango-juice.jpg" },
{ id: "coffee", name: "Coffee", price: 39, image: "black-coffee.jpg" },
{ id: "latte", name: "Latte", price: 49, image: "latte.jpg", video: "latte.mp4" },
{ id: "cappuccino", name: "Cappuccino", price: 49, image: "cappuccino.jpg" },
{ id: "tea", name: "Tea", price: 30 },
],
},
];
/**
* UTILITY EXPORT
*
* Flattened list of every single menu item across all categories.
*
* Current use cases:
* - Future global search / command palette
* - Admin tools that need to iterate over everything
* - Analytics or sitemap generation
*
* Example:
* const butterChicken = allMenuItems.find(i => i.id === "butter-chicken");
*/
export const allMenuItems = menuCategories.flatMap((category) => category.items);