Files
shahikitchen/components/Navbar.tsx
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

236 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.
"use client";
import { useState, useEffect } from "react";
import Link from "next/link";
import { useCart } from "./CartContext";
import { ShoppingBag, ArrowRight } from "lucide-react";
import LanguageSwitcher from "./LanguageSwitcher";
import { useLanguage } from "@/lib/language-context";
import { getTranslation } from "@/lib/translations";
import { motion } from "framer-motion";
import { usePathname } from "next/navigation";
/**
* =============================================================================
* GLOBAL NAVIGATION BAR — Shahi Kitchen (Luxury Edition)
* =============================================================================
*/
interface NavbarProps {
variant?: "default" | "menu";
}
export default function Navbar({ variant = "default" }: NavbarProps) {
const [isOpen, setIsOpen] = useState(false);
const [scrolled, setScrolled] = useState(false);
const { totalItems, openCart } = useCart();
const { language } = useLanguage();
const t = getTranslation(language);
const pathname = usePathname();
// Scroll effect - only for subtle visual polish, NOT height (height must stay consistent)
useEffect(() => {
const handleScroll = () => setScrolled(window.scrollY > 20);
window.addEventListener("scroll", handleScroll);
return () => window.removeEventListener("scroll", handleScroll);
}, []);
const navLinks = [
{ href: "/", label: t.nav.home },
{ href: "/menu", label: t.nav.menu },
{ href: "/locations", label: t.nav.locations },
{ href: "/#experience", label: t.nav.experience },
{ href: "/#contact", label: t.nav.contact },
];
// Determine active link (supports hash links)
const isActive = (href: string) => {
if (href === "/") return pathname === "/";
if (href.includes("#")) return false; // hash links handled separately
return pathname === href;
};
const closeMenu = () => setIsOpen(false);
return (
<nav
className="fixed top-0 left-0 right-0 z-50 h-16 border-b border-[#c99a2e]/10 bg-[#fbf7ef]/80 backdrop-blur-3xl"
>
<div className="max-w-7xl mx-auto px-6 flex items-center justify-between h-full">
{/* Subtle gold accent line at the very bottom */}
<div className="absolute bottom-0 left-0 right-0 h-px bg-gradient-to-r from-transparent via-[#c99a2e]/30 to-transparent" />
{/* Premium Animated Logo */}
<Link href="/" className="group flex items-center gap-3">
<div className="relative">
<motion.span
whileHover={{ scale: 1.08, rotate: 2 }}
transition={{ type: "spring", stiffness: 300, damping: 15 }}
className="grid h-12 w-12 place-items-center overflow-hidden rounded-2xl border border-[#c99a2e]/30 bg-white shadow-xl shadow-[#0f5a4a]/10 p-1 transition-all duration-300 group-hover:border-[#c99a2e]/70 group-hover:shadow-[#c99a2e]/25"
>
<img
src="/images/logo-shahi-chef-icon.jpg"
alt="Shahi Kitchen - Cute Chef with Large Mustaches"
className="h-10 w-10 object-contain transition-all duration-500"
/>
</motion.span>
<div className="absolute inset-0 rounded-2xl bg-[#c99a2e]/0 group-hover:bg-[#c99a2e]/15 blur-2xl transition-all duration-500 pointer-events-none" />
</div>
<span className="hidden leading-none sm:block">
<span className="block font-serif text-[21px] tracking-[-0.5px] text-[#101724] transition-colors group-hover:text-[#0f5a4a]">Shahi Kitchen</span>
<span className="text-[10px] font-semibold uppercase tracking-[0.32em] text-[#8a6a25]">Royal Taste Gothenburg</span>
</span>
</Link>
{/* Desktop Navigation - Premium Mesmerizing Design */}
<div className="hidden md:block">
<div className="flex items-center rounded-full border border-[#c99a2e]/20 bg-white/60 px-2 py-1.5 backdrop-blur-3xl shadow-sm">
<div className="relative flex items-center gap-1 text-sm font-medium text-[#101724]">
{navLinks.map((link, index) => {
const active = isActive(link.href);
return (
<Link
key={index}
href={link.href}
className="relative px-5 py-2 rounded-full transition-colors hover:text-[#0f5a4a] z-10"
>
<span className="relative z-10">{link.label}</span>
{/* Sliding Active Indicator - Very Premium */}
{active && (
<motion.div
layoutId="activeNavPill"
className="absolute inset-0 rounded-full bg-gradient-to-r from-[#c99a2e] to-[#d4a73d] shadow-md"
transition={{ type: "spring", stiffness: 380, damping: 30 }}
/>
)}
{/* Mesmerizing Gold Underline on Hover */}
<motion.span
className="absolute bottom-1 left-1/2 h-[1.5px] w-0 bg-gradient-to-r from-[#c99a2e] to-[#f4d47f] rounded-full"
whileHover={{ width: "60%", x: "-30%" }}
transition={{ type: "spring", stiffness: 300, damping: 20 }}
/>
</Link>
);
})}
</div>
</div>
</div>
{/* Desktop Actions — Stunning Mesmerizing Buttons */}
<div className="hidden md:flex items-center gap-3">
<LanguageSwitcher />
{/* Cart Button - Elegant dark with gold accent */}
<button
onClick={openCart}
className="group flex items-center gap-2.5 rounded-full border border-[#c99a2e]/30 bg-white/70 px-5 py-2.5 text-sm font-semibold text-[#101724] backdrop-blur-xl transition-all hover:border-[#c99a2e] hover:bg-white hover:shadow-lg active:scale-[0.985]"
>
<ShoppingBag className="h-4 w-4 transition-transform group-hover:scale-110" />
{t.cart}
{totalItems > 0 && (
<span className="ml-0.5 rounded-full bg-[#c99a2e] px-2 py-px text-[10px] font-black text-white">{totalItems}</span>
)}
</button>
{/* Reserve Table - The star of the nav, with mesmerizing gold gradient + shine */}
<Link
href="/#contact"
className="relative overflow-hidden rounded-full bg-gradient-to-r from-[#c99a2e] via-[#d4a73d] to-[#c99a2e] px-7 py-2.5 text-sm font-bold text-[#241806] shadow-lg shadow-[#c99a2e]/25 transition-all hover:scale-[1.02] active:scale-[0.985] bg-[length:200%_100%] hover:bg-right"
>
<span className="relative z-10 flex items-center gap-2 tracking-[0.3px]">
{t.reserve}
<ArrowRight className="h-4 w-4" />
</span>
{/* Subtle shine sweep on hover */}
<span className="absolute inset-0 bg-gradient-to-r from-transparent via-white/40 to-transparent opacity-0 group-hover:animate-[shimmer_1.2s_ease] group-hover:opacity-100" />
</Link>
</div>
{/* Mobile Hamburger */}
<div className="md:hidden flex items-center gap-3">
{/* MOBILE CART ICON (always visible even when hamburger is closed) */}
<button
onClick={openCart}
className="relative flex items-center justify-center w-9 h-9 rounded-full hover:bg-[#F5F1E9] transition-colors"
aria-label="Open cart"
>
<svg xmlns="http://www.w3.org/2000/svg" className="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M3 3h2l.4 2M7 13h10l4-8H5.4M7 13L5.4 5M7 13l-2.293 2.293c-.63.63-.184 1.707.707 1.707H17m0 0a2 2 0 100 4 2 2 0 000-4zm-8 2a2 2 0 11-4 0 2 2 0 014 0z" />
</svg>
{totalItems > 0 && (
<span className="absolute -top-1 -right-1 bg-[#B38B4D] text-white text-[10px] font-medium min-w-[16px] h-[16px] rounded-full flex items-center justify-center px-1">
{totalItems}
</span>
)}
</button>
<button
onClick={() => setIsOpen(!isOpen)}
className="text-[#B38B4D] p-2 -mr-2"
aria-label="Toggle menu"
>
<div className="space-y-1.5">
<span className={`block h-px w-6 bg-current transition-all ${isOpen ? "rotate-45 translate-y-1.5" : ""}`} />
<span className={`block h-px w-6 bg-current transition-all ${isOpen ? "opacity-0" : ""}`} />
<span className={`block h-px w-6 bg-current transition-all ${isOpen ? "-rotate-45 -translate-y-1.5" : ""}`} />
</div>
</button>
</div>
</div>
{/* Mobile Menu - Stunning Elegant Drawer */}
{isOpen && (
<div className="md:hidden fixed inset-0 z-[60] bg-[#101724]/60 backdrop-blur-md">
<div className="ml-auto h-full w-[82%] max-w-[320px] bg-[#fbf7ef] p-8 shadow-2xl border-l border-[#c99a2e]/10">
<div className="flex items-center justify-between mb-10">
<div className="flex items-center gap-3">
<img
src="/images/logo-shahi-chef-icon.jpg"
alt="Shahi Kitchen"
className="h-12 w-12 rounded-xl object-contain"
/>
<span className="font-serif text-xl text-[#101724]">Shahi Kitchen</span>
</div>
<button onClick={closeMenu} className="grid h-10 w-10 place-items-center rounded-full bg-[#f3f5f7] text-[#101724]">
<span className="text-2xl leading-none">×</span>
</button>
</div>
<div className="flex flex-col gap-5 text-xl font-medium text-[#101724]">
{navLinks.map((link) => (
<Link
key={link.href}
href={link.href}
onClick={closeMenu}
className="py-1 border-b border-[#e5e1d7] pb-4 hover:text-[#0f5a4a] transition-colors"
>
{link.label}
</Link>
))}
</div>
<div className="mt-10 space-y-3">
<LanguageSwitcher />
<Link
href="/#contact"
onClick={closeMenu}
className="block w-full rounded-full bg-gradient-to-r from-[#c99a2e] to-[#d4a73d] py-4 text-center text-base font-bold text-[#241806] shadow-lg"
>
{t.reserve}
</Link>
<button
onClick={() => { openCart(); closeMenu(); }}
className="block w-full rounded-full border border-[#c99a2e]/40 bg-white py-4 text-base font-semibold text-[#101724]"
>
{t.cart} {totalItems > 0 && `(${totalItems})`}
</button>
</div>
</div>
</div>
)}
</nav>
);
}