first commit
This commit is contained in:
@@ -0,0 +1,173 @@
|
||||
"use client";
|
||||
|
||||
import { useTranslations } from 'next-intl';
|
||||
import { Link, usePathname, useRouter } from '@/i18n/routing';
|
||||
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: '/accommodation', label: t('accommodation') },
|
||||
{ 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="flex flex-col items-start">
|
||||
<span
|
||||
className={`font-heading text-2xl font-black uppercase tracking-tighter ${
|
||||
isScrolled ? 'text-midnight' : 'gradient-text-warm'
|
||||
}`}
|
||||
>
|
||||
Kozmos
|
||||
</span>
|
||||
<span
|
||||
className={`text-[10px] tracking-[0.4em] font-body uppercase ${
|
||||
isScrolled ? 'text-coral' : 'text-white/40'
|
||||
}`}
|
||||
>
|
||||
Beach & More
|
||||
</span>
|
||||
</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>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user