"use client"; import { useEffect, useState, useRef, useCallback } from "react"; import Image from "next/image"; /* ────── Helpers ────── */ interface MenuItem { name: string; ingredients?: string | null; tasteProfile?: string | null; grapeVariety?: string | null; price: any; } interface Category { id: string; title: string; externalId?: string | null; items: MenuItem[]; } interface MenuData { restaurant_name: string; footer_note: string; categories: Category[]; } /* ────── Stars component ────── */ interface Star { id: number; left: string; top: string; duration: string; delay: string; maxOpacity: number; } function HeroStars() { const [stars, setStars] = useState([]); useEffect(() => { setStars( Array.from({ length: 40 }, (_, i) => ({ id: i, left: `${Math.random() * 100}%`, top: `${Math.random() * 100}%`, duration: `${3 + Math.random() * 4}s`, delay: `${Math.random() * 5}s`, maxOpacity: 0.3 + Math.random() * 0.5, })) ); }, []); return (
{stars.map((s) => ( ))}
); } /* ────── Price renderer ────── */ function PriceDisplay({ price }: { price: MenuItem["price"] }) { if (typeof price === "string") { return {price}; } const entries: [string, string][] = []; if (price.single) entries.push(["Tek", price.single]); if (price.double) entries.push(["Dbl", price.double]); if (price.glass) entries.push(["Kadeh", price.glass]); if (price.bottle) entries.push(["Şişe", price.bottle]); return (
{entries.map(([label, val]) => (
{label} {val}
))}
); } /* ────── Category Icon (decorative) ────── */ function getCategoryIcon(id: string): string { const icons: Record = { classic_cocktails: "🍸", lunas_cocktails: "🌙", shots: "🥃", gin: "🫒", whiskey: "🥂", rum: "🏴‍☠️", tequila: "🌵", vodka: "🧊", cognac: "🍷", red_wine: "🍷", white_wine: "🥂", roze_blush: "🌸", champagne_prosecco: "🍾", draft_beer: "🍺", bottle_beer: "🍻", coffee: "☕", soft_drinks: "🧃", snacks: "🥜", }; return icons[id] || "✦"; } export default function MenuView({ data }: { data: MenuData }) { const [activeCategory, setActiveCategory] = useState( data.categories[0]?.id || "" ); const [showBackToTop, setShowBackToTop] = useState(false); const navRef = useRef(null); const sectionRefs = useRef>(new Map()); useEffect(() => { const observer = new IntersectionObserver( (entries) => { const visible = entries .filter((e) => e.isIntersecting) .sort((a, b) => a.boundingClientRect.top - b.boundingClientRect.top); if (visible.length > 0) { const id = visible[0].target.getAttribute("data-category-id"); if (id) setActiveCategory(id); } }, { rootMargin: "-50% 0px -50% 0px", threshold: 0 } ); sectionRefs.current.forEach((el) => observer.observe(el)); return () => observer.disconnect(); }, []); useEffect(() => { const onScroll = () => setShowBackToTop(window.scrollY > 600); window.addEventListener("scroll", onScroll, { passive: true }); return () => window.removeEventListener("scroll", onScroll); }, []); useEffect(() => { if (!navRef.current) return; const btn = navRef.current.querySelector( `[data-nav-id="${activeCategory}"]` ); if (btn) { btn.scrollIntoView({ behavior: "smooth", block: "nearest", inline: "center" }); } }, [activeCategory]); const scrollToCategory = useCallback((id: string) => { const el = sectionRefs.current.get(id); if (el) { const offset = 56; const y = el.getBoundingClientRect().top + window.scrollY - offset; window.scrollTo({ top: y, behavior: "smooth" }); } }, []); const setSectionRef = useCallback( (id: string) => (el: HTMLElement | null) => { if (el) sectionRefs.current.set(id, el); }, [] ); return ( <>
{data.categories.map((cat) => (

{getCategoryIcon(cat.externalId || cat.id)} {cat.title}

{cat.items.length} ÜRÜN

{cat.items.map((item, idx) => (

{item.name}

{item.grapeVariety && ( {item.grapeVariety} )} {item.ingredients && ( {item.ingredients} )} {item.tasteProfile && (
{item.tasteProfile.split("-").map((t, i) => ( {t.trim()} ))}
)}
))}
))}

{data.footer_note}

LUNA ✦

); }