/** * ============================================================================= * 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 4–8s 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 (1–2 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);