diff --git a/src/app/menu/page.tsx b/src/app/menu/page.tsx new file mode 100644 index 0000000..d93cd34 --- /dev/null +++ b/src/app/menu/page.tsx @@ -0,0 +1,122 @@ +'use client' +import { useState, useMemo } from 'react' +import { useProducts } from '@/hooks/useProducts' +import { useVulaCart } from '@/hooks/useVulaCart' +import Image from 'next/image' +import Link from 'next/link' +import { ShoppingCart, Utensils } from 'lucide-react' + +const CURRENCY_SYMBOLS: Record = { zar: 'R', usd: '$', eur: '€', gbp: '£', kes: 'KSh', ngn: '₦', ghs: '₵' } +const formatPrice = (amount: number, code?: string) => { + const sym = CURRENCY_SYMBOLS[(code ?? '').toLowerCase()] ?? (code?.toUpperCase() ?? '') + return `${sym}${(amount / 100).toFixed(2)}` +} + +const DEFAULT_CATEGORIES = ['Starters', 'Mains', 'Drinks', 'Desserts'] + +export default function MenuPage() { + const { products, loading, error } = useProducts(100) + const { addToCart } = useVulaCart() + const [activeCategory, setActiveCategory] = useState('All') + + const categories = useMemo(() => { + const seen = new Set() + products.forEach(p => { if ((p as any).collection?.title) seen.add((p as any).collection.title) }) + const fromData = Array.from(seen) + return ['All', ...(fromData.length > 0 ? fromData : DEFAULT_CATEGORIES)] + }, [products]) + + const displayed = useMemo(() => { + if (activeCategory === 'All') return products + return products.filter(p => (p as any).collection?.title === activeCategory) + }, [products, activeCategory]) + + if (loading) return ( +
+
+
+

Loading menu…

+
+
+ ) + + if (error) return ( +
+

Failed to load menu. Please try again.

+
+ ) + + return ( +
+
+
+

Our Menu

+
+ + {/* Category tabs */} +
+ {categories.map(cat => ( + + ))} +
+ + {displayed.length === 0 ? ( +
+ +

No dishes in this category yet.

+
+ ) : ( +
+ {displayed.map((dish) => { + const variant = dish.variants?.[0] + const price = variant?.prices?.[0] + const imageUrl = dish.thumbnail || dish.images?.[0]?.url + return ( +
+ + {imageUrl ? ( +
+ {dish.title +
+ ) : ( +
+ +
+ )} + +
+ {(dish as any).collection?.title && ( + {(dish as any).collection.title} + )} + +

{dish.title}

+ + {dish.description && ( +

{dish.description}

+ )} + {price && ( +

{formatPrice(price.amount, price.currency_code)}

+ )} + +
+
+ ) + })} +
+ )} +
+
+ ) +}