166 lines
5.9 KiB
TypeScript
166 lines
5.9 KiB
TypeScript
"use client";
|
|
|
|
import { useTranslations } from 'next-intl';
|
|
import { Link, usePathname, useRouter } from '@/i18n/routing';
|
|
import Image from 'next/image';
|
|
import { useState, useEffect } from 'react';
|
|
import { Menu, X } from 'lucide-react';
|
|
import { motion, AnimatePresence } from 'framer-motion';
|
|
|
|
export default function Navbar({ locale }: { locale: string }) {
|
|
const t = useTranslations('Navbar');
|
|
const pathname = usePathname();
|
|
const router = useRouter();
|
|
|
|
const [isScrolled, setIsScrolled] = useState(false);
|
|
const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false);
|
|
|
|
useEffect(() => {
|
|
const handleScroll = () => setIsScrolled(window.scrollY > 50);
|
|
window.addEventListener('scroll', handleScroll);
|
|
return () => window.removeEventListener('scroll', handleScroll);
|
|
}, []);
|
|
|
|
const switchLocale = (newLocale: string) => {
|
|
router.replace(pathname, { locale: newLocale });
|
|
};
|
|
|
|
const navLinks = [
|
|
{ href: pathname === '/' ? '#about' : '/#about', label: t('about') },
|
|
{ href: pathname === '/' ? '#beach' : '/#beach', label: t('beach') },
|
|
{ href: pathname === '/' ? '#dining' : '/#dining', label: t('dining') },
|
|
{ href: pathname === '/' ? '#events' : '/#events', label: t('events') },
|
|
{ href: pathname === '/' ? '#gallery' : '/#gallery', label: t('gallery') },
|
|
{ href: pathname === '/' ? '#contact' : '/#contact', label: t('contact') },
|
|
];
|
|
|
|
return (
|
|
<nav
|
|
className={`fixed top-0 left-0 w-full z-50 transition-all duration-300 ${isScrolled
|
|
? 'bg-white/90 backdrop-blur-lg shadow-sm py-4 border-b border-sandy/40'
|
|
: 'bg-transparent py-6'
|
|
}`}
|
|
>
|
|
<div className="container mx-auto px-6 lg:px-12 flex justify-between items-center">
|
|
|
|
{/* Logo */}
|
|
<Link href="/" className="relative w-40 h-16 flex items-center transform transition-transform hover:scale-105">
|
|
<Image
|
|
src="/logo.png"
|
|
alt="Kozmos Logo"
|
|
fill
|
|
priority
|
|
sizes="(max-width: 768px) 160px, 160px"
|
|
className={`object-contain transition-all duration-300 ${
|
|
isScrolled ? 'filter-none' : 'brightness-0 invert drop-shadow-[0_2px_4px_rgba(0,0,0,0.5)]'
|
|
}`}
|
|
/>
|
|
</Link>
|
|
|
|
{/* Desktop Nav */}
|
|
<div className="hidden lg:flex items-center gap-8">
|
|
<div className="flex gap-6">
|
|
{navLinks.map((link) => (
|
|
<Link
|
|
key={link.href}
|
|
href={link.href}
|
|
className={`text-sm font-medium tracking-wide transition-colors hover:text-coral ${isScrolled ? 'text-midnight/70' : 'text-white/80'
|
|
}`}
|
|
>
|
|
{link.label}
|
|
</Link>
|
|
))}
|
|
</div>
|
|
|
|
<div
|
|
className={`flex items-center gap-3 border-l pl-5 ${isScrolled ? 'border-sandy' : 'border-white/20'
|
|
}`}
|
|
>
|
|
{(['tr', 'en'] as const).map((l) => (
|
|
<button
|
|
key={l}
|
|
onClick={() => switchLocale(l)}
|
|
className={`text-[11px] font-black uppercase tracking-wider transition-colors ${locale === l
|
|
? 'text-coral'
|
|
: isScrolled
|
|
? 'text-midnight/40'
|
|
: 'text-white/40'
|
|
}`}
|
|
>
|
|
{l}
|
|
</button>
|
|
))}
|
|
</div>
|
|
|
|
<a
|
|
href="#contact"
|
|
className="px-5 py-2.5 rounded-full text-xs font-black text-white tracking-wider transition-all hover:scale-105 hover:shadow-[0_0_24px_rgba(255,90,54,0.45)]"
|
|
style={{ background: 'linear-gradient(135deg, #FF5A36, #FFA827)' }}
|
|
>
|
|
{t('reservation')}
|
|
</a>
|
|
</div>
|
|
|
|
{/* Mobile toggle */}
|
|
<button
|
|
className="lg:hidden"
|
|
onClick={() => setIsMobileMenuOpen(!isMobileMenuOpen)}
|
|
aria-label="Toggle menu"
|
|
>
|
|
{isMobileMenuOpen ? (
|
|
<X className={isScrolled ? 'text-midnight' : 'text-white'} size={26} />
|
|
) : (
|
|
<Menu className={isScrolled ? 'text-midnight' : 'text-white'} size={26} />
|
|
)}
|
|
</button>
|
|
</div>
|
|
|
|
{/* Mobile menu */}
|
|
<AnimatePresence>
|
|
{isMobileMenuOpen && (
|
|
<motion.div
|
|
initial={{ opacity: 0, y: -10 }}
|
|
animate={{ opacity: 1, y: 0 }}
|
|
exit={{ opacity: 0, y: -10 }}
|
|
className="lg:hidden absolute top-full left-0 w-full bg-white/96 backdrop-blur-lg shadow-xl border-t border-sandy/30"
|
|
>
|
|
<div className="flex flex-col py-6 px-8 gap-3">
|
|
{navLinks.map((link) => (
|
|
<Link
|
|
key={link.href}
|
|
href={link.href}
|
|
className="text-midnight text-base font-heading font-semibold py-2 border-b border-sandy/20 hover:text-coral transition-colors"
|
|
onClick={() => setIsMobileMenuOpen(false)}
|
|
>
|
|
{link.label}
|
|
</Link>
|
|
))}
|
|
|
|
<div className="flex gap-4 pt-3">
|
|
{(['tr', 'en'] as const).map((l) => (
|
|
<button
|
|
key={l}
|
|
onClick={() => switchLocale(l)}
|
|
className={`text-sm font-black uppercase ${locale === l ? 'text-coral' : 'text-midnight/40'}`}
|
|
>
|
|
{l}
|
|
</button>
|
|
))}
|
|
</div>
|
|
|
|
<a
|
|
href="#contact"
|
|
className="mt-2 text-center py-3.5 rounded-full text-sm font-black text-white"
|
|
style={{ background: 'linear-gradient(135deg, #FF5A36, #FFA827)' }}
|
|
onClick={() => setIsMobileMenuOpen(false)}
|
|
>
|
|
{t('reservation')}
|
|
</a>
|
|
</div>
|
|
</motion.div>
|
|
)}
|
|
</AnimatePresence>
|
|
</nav>
|
|
);
|
|
}
|