Files
ayristech_new/components/templates/RestoranTemplate.tsx
T
2026-05-30 18:23:21 +03:00

509 lines
25 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";
import { motion, useScroll, useTransform, AnimatePresence } from "framer-motion";
import { useRef, useState } from "react";
import type { DemoData } from "@/data/demos";
import AnimatedCounter from "@/components/ui/AnimatedCounter";
const easeOutExpo = [0.16, 1, 0.3, 1] as [number, number, number, number];
const fadeUp = {
hidden: { opacity: 0, y: 40 },
show: { opacity: 1, y: 0, transition: { duration: 0.7, ease: easeOutExpo } },
};
const stagger = {
hidden: {},
show: { transition: { staggerChildren: 0.1 } },
};
export default function RestoranTemplate({ data }: { data: DemoData }) {
const { firma, istatistikler, hizmetler, menu = [], yorumlar = [] } = data;
const heroRef = useRef<HTMLDivElement>(null);
const { scrollYProgress } = useScroll({ target: heroRef, offset: ["start start", "end start"] });
const heroY = useTransform(scrollYProgress, [0, 1], ["0%", "20%"]);
const heroOpacity = useTransform(scrollYProgress, [0, 0.8], [1, 0]);
const [aktifKategori, setAktifKategori] = useState(0);
const [showBookingModal, setShowBookingModal] = useState(false);
// SVG Render Helper for clean iconography (Replaces all emojis)
const getIconSvg = (name: string) => {
switch (name) {
case "alacarte":
return (
<svg className="w-6 h-6 stroke-[#C5A880]" viewBox="0 0 24 24" fill="none" strokeWidth="1.5">
<path strokeLinecap="round" strokeLinejoin="round" d="M12 6.042A8.967 8.967 0 0 0 6 3.75c-1.052 0-2.062.18-3 .512v14.25A8.987 8.987 0 0 1 6 18c2.305 0 4.408.867 6 2.292m0-14.25a8.966 8.966 0 0 1 6-2.292c1.052 0 2.062.18 3 .512v14.25A8.987 8.987 0 0 0 18 18a8.967 8.967 0 0 0-6 2.292m0-14.25v14.25" />
</svg>
);
case "special":
return (
<svg className="w-6 h-6 stroke-[#C5A880]" viewBox="0 0 24 24" fill="none" strokeWidth="1.5">
<path strokeLinecap="round" strokeLinejoin="round" d="M21 8.25c0-2.485-2.099-4.5-4.688-4.5-1.935 0-3.597 1.126-4.312 2.733-.715-1.607-2.377-2.733-4.313-2.733C5.1 3.75 3 5.765 3 8.25c0 7.22 9 12 9 12s9-4.78 9-12Z" />
</svg>
);
case "catering":
return (
<svg className="w-6 h-6 stroke-[#C5A880]" viewBox="0 0 24 24" fill="none" strokeWidth="1.5">
<path strokeLinecap="round" strokeLinejoin="round" d="M15.75 10.5V6a3.75 3.75 0 1 0-7.5 0v4.5m11.356-1.993 1.263 12c.07.665-.45 1.243-1.119 1.243H4.25a1.125 1.125 0 0 1-1.12-1.243l1.264-12A1.125 1.125 0 0 1 5.513 7.5h12.974c.576 0 1.059.435 1.119 1.007ZM8.625 10.5a.375.375 0 1 1-.75 0 .375.375 0 0 1 .75 0Zm7.5 0a.375.375 0 1 1-.75 0 .375.375 0 0 1 .75 0Z" />
</svg>
);
case "delivery":
return (
<svg className="w-6 h-6 stroke-[#C5A880]" viewBox="0 0 24 24" fill="none" strokeWidth="1.5">
<path strokeLinecap="round" strokeLinejoin="round" d="M8.25 18.75a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0ZM19.5 18.75a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0Z" />
<path strokeLinecap="round" strokeLinejoin="round" d="M2.25 3h1.386c.51 0 .955.343 1.087.835l.383 1.437M7.5 14.25a3 3 0 0 0-3 3h15.75m-12.75-3h11.218c1.121-2.3 2.1-4.684 2.924-7.138a60.114 60.114 0 0 0-16.536-1.84" />
</svg>
);
default:
return (
<svg className="w-6 h-6 stroke-[#C5A880]" viewBox="0 0 24 24" fill="none" strokeWidth="1.5">
<path strokeLinecap="round" d="M12 21a9.004 9.004 0 0 0 8.716-6.747M12 21" />
</svg>
);
}
};
return (
<div className="bg-[#090A0C] text-white font-body">
{/* ── FLOATING NAVIGATION HEADER ── */}
<motion.header
className="fixed top-4 left-4 right-4 z-50 px-4"
initial={{ y: -80, opacity: 0 }}
animate={{ y: 0, opacity: 1 }}
transition={{ duration: 0.7, ease: easeOutExpo }}
>
<div className="mx-auto max-w-6xl h-20 flex items-center justify-between px-8 bg-[#090A0C]/80 backdrop-blur-xl border border-[#C5A880]/20 rounded-2xl shadow-2xl">
<a href="#" className="flex items-center gap-3 group">
<span className="font-display text-2xl font-bold tracking-widest text-white group-hover:text-[#C5A880] transition-colors uppercase">
{firma.adi}
</span>
</a>
<nav className="hidden lg:flex items-center gap-10">
{[
{ label: "Our Heritage", href: "#heritage" },
{ label: "Special Meal", href: "#special-meal" },
{ label: "Chalkboard Bakery", href: "#bakery" },
{ label: "Hizmetlerimiz", href: "#services" },
{ label: "Rezervasyon", href: "#randevu" }
].map(item => (
<a
key={item.label}
href={item.href}
className="text-[11px] font-sans-clean font-bold tracking-[2px] uppercase text-white/60 hover:text-white transition-colors cursor-pointer"
>
{item.label}
</a>
))}
</nav>
<div className="flex items-center gap-6">
<motion.button
onClick={() => setShowBookingModal(true)}
className="text-[11px] font-sans-clean font-black tracking-[2px] uppercase text-[#C5A880] border border-[#C5A880] hover:bg-[#C5A880] hover:text-[#090A0C] px-6 py-3 rounded-xl transition-all cursor-pointer"
whileHover={{ scale: 1.03 }}
whileTap={{ scale: 0.98 }}
>
Enquiry
</motion.button>
</div>
</div>
</motion.header>
{/* ── HERO SECTION ── */}
<section ref={heroRef} className="relative min-h-screen flex items-center justify-center overflow-hidden bg-[#090A0C]">
<motion.div
className="absolute inset-0 pointer-events-none"
style={{ y: heroY, opacity: heroOpacity }}
>
<div className="absolute inset-0 bg-gradient-to-b from-black/80 via-black/60 to-[#090A0C] z-10" />
</motion.div>
<div className="relative z-20 max-w-5xl mx-auto px-6 text-center pt-24">
<motion.div
variants={stagger}
initial="hidden"
animate="show"
className="flex flex-col items-center"
>
<motion.span
variants={fadeUp}
className="text-[#C5A880] italic text-lg lg:text-xl tracking-wider mb-6 block font-display"
>
welcome to our delicious corner
</motion.span>
<motion.h1
variants={fadeUp}
className="font-display text-5xl md:text-7xl lg:text-8xl font-black text-white leading-[1.05] tracking-widest uppercase mb-8"
>
Best Famous
<br />
Dishes
</motion.h1>
<motion.p
variants={fadeUp}
className="text-white/60 font-sans-clean font-medium text-sm lg:text-base leading-relaxed max-w-lg mb-12"
>
A journey of raw ingredients transformed by fire, smoke, and heritage. Exquisite tastes curated for refined palates.
</motion.p>
<motion.div variants={fadeUp}>
<motion.a
href="#special-meal"
className="inline-flex items-center gap-3 text-[11px] font-sans-clean font-bold tracking-[3px] uppercase border-b-2 border-[#C5A880] text-white hover:text-[#C5A880] pb-2 transition-colors cursor-pointer"
whileHover={{ y: -3 }}
>
Learn More
</motion.a>
</motion.div>
</motion.div>
</div>
</section>
{/* ── SECTION 2: HERITAGE ── */}
<section id="heritage" className="py-32 bg-[#090A0C] border-t border-[#C5A880]/15 relative z-10 px-6">
<div className="max-w-6xl mx-auto">
<div className="text-center mb-24">
<span className="text-[#C5A880] font-display italic text-base tracking-wider block mb-3">Special moments</span>
<h2 className="font-display text-4xl lg:text-5xl font-black tracking-widest text-white uppercase">
About Us
</h2>
</div>
<div className="grid lg:grid-cols-3 gap-8 items-stretch">
<div className="bg-[#13151A] rounded-2xl p-10 border border-[#C5A880]/10 flex flex-col items-center justify-center text-center shadow-2xl relative min-h-[300px]">
<span className="text-[#C5A880] text-xs tracking-wider mb-4 block">Taste perception</span>
<h3 className="font-display text-2xl lg:text-3xl font-black text-white tracking-widest uppercase mb-6 leading-tight">
Traditional
<br />
& Modern
</h3>
<p className="text-white/50 font-sans-clean text-xs leading-relaxed max-w-xs mb-8">
Palermonun en eski geleneksel tekniklerini modern gastronomi vizyonuyla harmanlıyoruz. Her ayrıntıda yüksek zanaatkarlık yatıyor.
</p>
<motion.button
onClick={() => setShowBookingModal(true)}
className="text-[10px] font-sans-clean font-bold tracking-[2px] uppercase text-[#C5A880] border border-[#C5A880]/40 hover:border-[#C5A880] px-5 py-3 rounded-lg transition-colors cursor-pointer"
whileHover={{ scale: 1.04 }}
>
Read More
</motion.button>
</div>
<div className="bg-[#13151A] rounded-2xl p-10 border border-[#C5A880]/10 flex flex-col items-center justify-center text-center shadow-2xl relative">
<span className="text-[#C5A880] text-xs tracking-wider mb-4 block">Crafted Flavours</span>
<h3 className="font-display text-2xl lg:text-3xl font-black text-white tracking-widest uppercase mb-6 leading-tight">
Wood &amp; Fire
</h3>
<p className="text-white/50 font-sans-clean text-xs leading-relaxed max-w-xs">
Ustalık gerektiren fırınlama ve pişirme aşamalarından geçerek servis edilen tabaklarımız, damak tadınızda unutulmaz izler bırakır.
</p>
</div>
<div className="bg-[#13151A] rounded-2xl p-10 border border-[#C5A880]/10 flex flex-col items-center justify-center text-center shadow-2xl relative">
<span className="text-[#C5A880] text-xs tracking-wider mb-4 block">Atmosphere</span>
<h3 className="font-display text-2xl lg:text-3xl font-black text-white tracking-widest uppercase mb-6 leading-tight">
Refined Space
</h3>
<p className="text-white/50 font-sans-clean text-xs leading-relaxed max-w-xs">
Özenle dekore edilmiş loş, taş döşemeli şık salonumuzda kendinizi İtalya sokaklarında hissedeceksiniz.
</p>
</div>
</div>
</div>
</section>
{/* ── SECTION 3: SPECIAL MEAL ── */}
<section id="special-meal" className="py-32 bg-[#0E0F12] border-t border-[#C5A880]/15 relative z-10 px-6">
<div className="max-w-6xl mx-auto">
<div className="text-center mb-16">
<span className="text-[#C5A880] font-display italic text-base tracking-wider block mb-4">our full menu</span>
<h2 className="font-display text-4xl lg:text-5xl font-black tracking-widest text-white uppercase mb-16">
Special Meal
</h2>
</div>
<div className="grid lg:grid-cols-12 gap-16 items-start">
<div className="lg:col-span-12 flex flex-col justify-center">
<div className="space-y-6 max-w-4xl mx-auto w-full">
{menu[aktifKategori]?.urunler.map((item) => (
<div key={item.ad} className="flex flex-col cursor-pointer group">
<div className="flex items-end justify-between gap-4">
<span className="font-display text-base lg:text-lg font-bold text-white group-hover:text-[#C5A880] transition-colors uppercase">
{item.ad}
</span>
<div className="grow border-b border-dashed border-[#C5A880]/20 mb-2 group-hover:border-[#C5A880]/40 transition-colors mx-2" />
<span className="font-display text-base font-black text-[#C5A880] shrink-0">
{item.fiyat}
</span>
</div>
<p className="text-white/50 font-sans-clean text-[11px] mt-1 leading-relaxed">
{item.aciklama}
</p>
</div>
))}
</div>
{/* Category Tab Buttons */}
<div className="flex items-center justify-center gap-4 mt-16 flex-wrap">
{menu.map((kat, idx) => (
<button
key={kat.kategori}
onClick={() => setAktifKategori(idx)}
className="text-[10px] font-sans-clean font-bold tracking-[2px] uppercase px-5 py-3 rounded-lg border transition-all cursor-pointer"
style={aktifKategori === idx
? { backgroundColor: "#C5A880", color: "#090A0C", borderColor: "#C5A880" }
: { backgroundColor: "transparent", color: "rgba(255,255,255,0.5)", borderColor: "rgba(197,168,128,0.2)" }
}
>
{kat.kategori}
</button>
))}
</div>
</div>
</div>
</div>
</section>
{/* ── SECTION 5: SERVICES ── */}
<section id="services" className="py-24 bg-[#090A0C] border-t border-[#C5A880]/15 relative z-10 px-6">
<div className="max-w-7xl mx-auto">
<div className="text-center mb-16">
<span className="text-[#C5A880] font-display italic text-base tracking-wider block mb-3">Our Offerings</span>
<h2 className="font-display text-3xl lg:text-4xl font-black tracking-widest text-white uppercase">
Hizmetlerimiz
</h2>
</div>
<div className="grid md:grid-cols-4 gap-6">
{hizmetler.map((h, i) => (
<motion.div
key={h.baslik}
className="bg-[#13151A] rounded-xl p-8 border border-white/5 hover:border-[#C5A880]/30 hover:bg-[#13151A]/80 transition-all duration-300 flex flex-col items-center text-center group cursor-default"
initial={{ opacity: 0, y: 20 }}
whileInView={{ opacity: 1, y: 0 }}
viewport={{ once: true }}
transition={{ duration: 0.5, delay: i * 0.1 }}
whileHover={{ y: -4 }}
>
<div className="w-14 h-14 rounded-xl bg-white/5 border border-white/10 flex items-center justify-center mb-5 transition-all group-hover:bg-[#C5A880]/10 group-hover:border-[#C5A880]/30">
{getIconSvg(h.ikon)}
</div>
<h3 className="font-display font-bold text-white text-sm mb-3 uppercase tracking-wider leading-snug">
{h.baslik}
</h3>
<p className="text-white/50 font-sans-clean text-[10px] leading-relaxed">
{h.aciklama}
</p>
</motion.div>
))}
</div>
</div>
</section>
{/* ── SECTION 6: TESTIMONIALS ── */}
<section id="yorumlar" className="py-28 bg-[#0E0F12] border-t border-[#C5A880]/15 px-6">
<div className="max-w-7xl mx-auto">
<div className="text-center mb-16">
<span className="text-[#C5A880] font-display italic text-base tracking-wider block mb-3">social proof</span>
<h2 className="font-display text-3xl lg:text-4xl font-black tracking-widest text-white uppercase">
Misafir Deneyimleri
</h2>
</div>
<div className="grid md:grid-cols-3 gap-6">
{yorumlar.map((y, i) => (
<motion.div
key={y.yazar}
className="bg-[#13151A] border border-[#C5A880]/10 rounded-xl p-8 flex flex-col justify-between"
initial={{ opacity: 0, y: 30 }}
whileInView={{ opacity: 1, y: 0 }}
viewport={{ once: true }}
transition={{ duration: 0.5, delay: i * 0.1 }}
whileHover={{ y: -4, borderColor: "rgba(197,168,128,0.3)" }}
>
<div className="flex gap-1 mb-6">
{[...Array(y.puan)].map((_, j) => (
<span key={j} className="text-[#C5A880]"></span>
))}
</div>
<p className="text-white/80 font-sans-clean text-xs leading-relaxed italic mb-8">
&ldquo;{y.yorum}&rdquo;
</p>
<div className="flex items-center gap-3">
<div className="w-10 h-10 rounded-full border border-[#C5A880]/30 flex items-center justify-center text-lg bg-[#090A0C] shrink-0">
{y.emoji}
</div>
<div>
<h4 className="font-display text-[#C5A880] text-xs font-bold uppercase tracking-wider">
{y.yazar}
</h4>
<span className="font-sans-clean text-[9px] text-white/40 uppercase tracking-widest">
{y.tarih}
</span>
</div>
</div>
</motion.div>
))}
</div>
</div>
</section>
{/* ── SECTION 7: RESERVATION ── */}
<section id="randevu" className="py-32 bg-[#090A0C] border-t border-[#C5A880]/15 relative z-10 px-6">
<div className="max-w-3xl mx-auto">
<div className="bg-[#13151A] rounded-2xl p-8 md:p-12 shadow-2xl border border-[#C5A880]/20">
<div className="text-center mb-10">
<span className="text-[#C5A880] font-display italic text-base tracking-wider block mb-3">booking reservation</span>
<h2 className="font-display text-3xl md:text-4xl font-black tracking-widest text-white uppercase">
Masa Rezervasyonu
</h2>
<p className="text-white/60 font-sans-clean text-xs mt-2 leading-relaxed">
Benzersiz bir fine dining deneyimi için masanızı önceden ayırtın.
</p>
</div>
<div className="grid grid-cols-2 gap-5">
{[
{ label: "Ad Soyad", placeholder: "Adınız Soyadınız", type: "text", full: false },
{ label: "Telefon", placeholder: "05xx xxx xx xx", type: "tel", full: false },
{ label: "Tarih", placeholder: "", type: "date", full: false },
{ label: "Saat", placeholder: "", type: "time", full: false },
{ label: "Kişi Sayısı", placeholder: "2", type: "number", full: false },
{ label: "Özel İstek / Not", placeholder: "Diyet hassasiyetleri, kutlamalar vb.", type: "text", full: true },
].map((field, i) => (
<div key={i} className={field.full ? "col-span-2" : "col-span-1"}>
<label className="block text-[9px] font-sans-clean font-bold text-[#C5A880] mb-1.5 uppercase tracking-widest">{field.label}</label>
<input
type={field.type}
placeholder={field.placeholder}
className="w-full px-4 py-3 rounded-xl border border-white/10 bg-[#090A0C] text-sm text-white focus:outline-none focus:ring-1 focus:ring-[#C5A880] placeholder-white/20 transition-all font-sans-clean"
/>
</div>
))}
</div>
<motion.button
className="mt-8 w-full py-4 rounded-xl text-[#090A0C] font-sans-clean font-black tracking-[2px] uppercase bg-[#C5A880] hover:bg-[#D5B990] transition-colors cursor-pointer text-xs"
whileHover={{ scale: 1.02, boxShadow: "0 10px 30px rgba(197, 168, 128, 0.25)" }}
whileTap={{ scale: 0.98 }}
>
Masa Ayırt
</motion.button>
</div>
</div>
</section>
{/* ── FOOTER ── */}
<footer className="bg-[#090A0C] border-t border-white/5 px-6 pt-20 pb-8 relative z-10">
<div className="max-w-7xl mx-auto">
<div className="grid md:grid-cols-4 gap-12 pb-16 border-b border-white/5">
<div className="md:col-span-2">
<span className="font-display text-2xl font-black text-[#C5A880] tracking-widest uppercase mb-4 block">
{firma.adi}
</span>
<p className="text-white/60 font-sans-clean text-xs leading-relaxed max-w-xs mb-8">
{firma.slogan} Geleneksel zanaat, modern vizyon.
</p>
<p className="text-white/60 font-sans-clean text-xs">📍 {firma.adres}</p>
<p className="text-white/60 font-sans-clean text-xs mt-1">📞 {firma.telefon}</p>
</div>
<div>
<h4 className="font-display text-white text-xs font-bold uppercase tracking-wider mb-5">
Şefin Menüsü
</h4>
{menu.map(kat => (
<a
key={kat.kategori}
href="#special-meal"
className="block text-white/50 hover:text-white text-xs mb-2.5 transition-colors font-sans-clean uppercase tracking-wider"
>
{kat.kategori}
</a>
))}
</div>
<div>
<h4 className="font-display text-white text-xs font-bold uppercase tracking-wider mb-5">
Karaköy Lezzet
</h4>
{["Heritage", "Special Meal", "Reservation"].map(item => (
<a
key={item}
href="#"
className="block text-white/50 hover:text-white text-xs mb-2.5 transition-colors font-sans-clean"
>
{item}
</a>
))}
</div>
</div>
<div className="flex flex-col md:flex-row justify-between items-center pt-8 gap-4 font-sans-clean text-white/40">
<p className="text-xs">© 2026 {firma.adi}. Tüm hakları saklıdır.</p>
<p className="text-[10px]">Gizlilik Politikası · Çerez Ayarları</p>
</div>
</div>
</footer>
{/* ── FAST BOOKING OVERLAY MODAL ── */}
<AnimatePresence>
{showBookingModal && (
<motion.div
className="fixed inset-0 z-50 flex items-center justify-center p-6 bg-black/80 backdrop-blur-sm"
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
>
<motion.div
className="bg-[#13151A] rounded-2xl p-8 max-w-md w-full relative shadow-2xl border border-[#C5A880]/30"
initial={{ scale: 0.95, y: 20 }}
animate={{ scale: 1, y: 0 }}
exit={{ scale: 0.95, y: 20 }}
>
<button
className="absolute top-6 right-6 w-8 h-8 rounded-full bg-white/5 flex items-center justify-center text-white/60 hover:text-white transition-colors"
onClick={() => setShowBookingModal(false)}
>
</button>
<h3 className="font-display font-black text-white text-xl mb-1 uppercase tracking-wider">
Hızlı Rezervasyon
</h3>
<p className="text-white/50 font-sans-clean text-[10px] mb-6 uppercase tracking-widest">
Karaköy Rezervasyon Hattı
</p>
<div className="space-y-4">
<div>
<label className="block text-[9px] font-sans-clean font-bold text-[#C5A880] mb-1 uppercase tracking-wider">Ad Soyad</label>
<input type="text" className="w-full px-4 py-3 rounded-xl border border-white/10 bg-[#090A0C] text-sm text-white focus:outline-none focus:ring-1 focus:ring-[#C5A880]" placeholder="Adınız Soyadınız" />
</div>
<div>
<label className="block text-[9px] font-sans-clean font-bold text-[#C5A880] mb-1 uppercase tracking-wider">Telefon Numarası</label>
<input type="tel" className="w-full px-4 py-3 rounded-xl border border-white/10 bg-[#090A0C] text-sm text-white focus:outline-none focus:ring-1 focus:ring-[#C5A880]" placeholder="05xx xxx xx xx" />
</div>
<motion.button
className="w-full py-4 rounded-xl bg-[#C5A880] text-[#090A0C] font-sans-clean font-black text-xs uppercase tracking-wider mt-4"
whileHover={{ scale: 1.02 }}
whileTap={{ scale: 0.98 }}
onClick={() => setShowBookingModal(false)}
>
Bilgileri Gönder
</motion.button>
</div>
</motion.div>
</motion.div>
)}
</AnimatePresence>
</div>
);
}