fb
This commit is contained in:
167
components/Navbar.tsx
Normal file
167
components/Navbar.tsx
Normal file
@@ -0,0 +1,167 @@
|
||||
'use client'
|
||||
|
||||
import { useState, useEffect } from 'react'
|
||||
import Link from 'next/link'
|
||||
import { motion, AnimatePresence } from 'framer-motion'
|
||||
import { usePathname, useRouter } from 'next/navigation'
|
||||
import Image from 'next/image'
|
||||
import { ArrowRight, ChevronDown, Menu, X, Plus } from 'lucide-react'
|
||||
|
||||
export default function Navbar({ lang, dict }: { lang: string, dict: any }) {
|
||||
const router = useRouter()
|
||||
const pathname = usePathname()
|
||||
|
||||
const [isVisible, setIsVisible] = useState(true)
|
||||
const [lastScrollY, setLastScrollY] = useState(0)
|
||||
const [isScrolled, setIsScrolled] = useState(false)
|
||||
const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false)
|
||||
|
||||
const handleLangChange = (newLang: string) => {
|
||||
const segments = pathname.split('/')
|
||||
if (segments[1] === 'en' || segments[1] === 'tr') {
|
||||
segments[1] = newLang
|
||||
} else {
|
||||
segments.splice(1, 0, newLang)
|
||||
}
|
||||
router.push(segments.join('/'))
|
||||
}
|
||||
|
||||
const navLinks = [
|
||||
{ name: dict.nav.about, href: `/${lang}/about` },
|
||||
{ name: dict.nav.suites, href: `/${lang}/suites`, hasDropdown: true },
|
||||
{ name: dict.nav.news, href: `/${lang}/news` },
|
||||
]
|
||||
|
||||
useEffect(() => {
|
||||
const controlNavbar = () => {
|
||||
if (typeof window !== 'undefined') {
|
||||
const currentScrollY = window.scrollY
|
||||
if (currentScrollY > lastScrollY && currentScrollY > 100) {
|
||||
setIsVisible(false)
|
||||
} else {
|
||||
setIsVisible(true)
|
||||
}
|
||||
setLastScrollY(currentScrollY)
|
||||
setIsScrolled(currentScrollY > 50)
|
||||
}
|
||||
}
|
||||
window.addEventListener('scroll', controlNavbar)
|
||||
return () => window.removeEventListener('scroll', controlNavbar)
|
||||
}, [lastScrollY])
|
||||
|
||||
return (
|
||||
<>
|
||||
<motion.nav
|
||||
initial={{ y: -100 }}
|
||||
animate={{ y: isVisible ? 0 : -100 }}
|
||||
transition={{ duration: 0.6, ease: [0.33, 1, 0.68, 1] }}
|
||||
className={`fixed top-0 left-0 right-0 z-[100] transition-all duration-500 flex justify-center py-4 px-6 md:px-12`}
|
||||
>
|
||||
<div className={`w-full flex items-center justify-between bg-white rounded-[2px] transition-all duration-500 border border-[#1A1A1A]/5 ${isScrolled ? 'py-3 px-10' : 'py-5 px-12'}`}>
|
||||
{/* LOGO */}
|
||||
<Link href={`/${lang}`} className="flex items-center group">
|
||||
<span className="text-[24px] font-serif tracking-[0.25em] text-[#1A1A1A] uppercase">
|
||||
AYRIS APART
|
||||
</span>
|
||||
</Link>
|
||||
|
||||
{/* DESKTOP NAV */}
|
||||
<div className="hidden md:flex items-center space-x-12">
|
||||
{navLinks.map((link) => (
|
||||
<Link
|
||||
key={link.name}
|
||||
href={link.href}
|
||||
className="group relative text-[11px] font-bold tracking-[0.35em] uppercase text-[#1A1A1A]/70 hover:text-[#1A1A1A] transition-colors overflow-hidden"
|
||||
>
|
||||
<span className="block">{link.name}</span>
|
||||
<span className="absolute bottom-0 left-0 w-full h-[1.5px] bg-[#C88C4B] transform scale-x-0 group-hover:scale-x-100 transition-transform duration-500 origin-left" />
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className="flex items-center space-x-8">
|
||||
{/* LANGUAGE SWITCHER */}
|
||||
<div className="hidden md:flex items-center space-x-3 text-[11px] font-bold tracking-widest mr-4">
|
||||
<button
|
||||
onClick={() => handleLangChange('tr')}
|
||||
className={`transition-colors ${lang === 'tr' ? 'text-[#C88C4B]' : 'text-[#1A1A1A]/30 hover:text-[#1A1A1A]'}`}
|
||||
>
|
||||
TR
|
||||
</button>
|
||||
<span className="w-[1px] h-3 bg-[#1A1A1A]/10" />
|
||||
<button
|
||||
onClick={() => handleLangChange('en')}
|
||||
className={`transition-colors ${lang === 'en' ? 'text-[#C88C4B]' : 'text-[#1A1A1A]/30 hover:text-[#1A1A1A]'}`}
|
||||
>
|
||||
EN
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<Link
|
||||
href={`/${lang}/contact`}
|
||||
className="hidden lg:flex items-center space-x-3 group"
|
||||
>
|
||||
<span className="text-[11px] font-bold tracking-[0.35em] uppercase text-[#1A1A1A]">{dict.nav.contact}</span>
|
||||
<div className="w-10 h-10 rounded-full border border-[#1A1A1A]/10 flex items-center justify-center group-hover:bg-[#1A1A1A] group-hover:border-[#1A1A1A] transition-all duration-500">
|
||||
<ArrowRight size={16} className="text-[#1A1A1A] group-hover:text-white transition-colors" />
|
||||
</div>
|
||||
</Link>
|
||||
|
||||
{/* MOBILE MENU TOGGLE */}
|
||||
<button
|
||||
onClick={() => setIsMobileMenuOpen(!isMobileMenuOpen)}
|
||||
className="md:hidden w-10 h-10 flex flex-col items-center justify-center space-y-1.5"
|
||||
>
|
||||
<div className={`w-6 h-[1.5px] bg-[#1A1A1A] transition-all duration-300 ${isMobileMenuOpen ? 'rotate-45 translate-y-2' : ''}`} />
|
||||
<div className={`w-6 h-[1.5px] bg-[#1A1A1A] transition-all duration-300 ${isMobileMenuOpen ? 'opacity-0' : ''}`} />
|
||||
<div className={`w-6 h-[1.5px] bg-[#1A1A1A] transition-all duration-300 ${isMobileMenuOpen ? '-rotate-45 -translate-y-2' : ''}`} />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</motion.nav>
|
||||
|
||||
{/* MOBILE MENU */}
|
||||
<AnimatePresence>
|
||||
{isMobileMenuOpen && (
|
||||
<motion.div
|
||||
initial={{ opacity: 0, x: '100%' }}
|
||||
animate={{ opacity: 1, x: 0 }}
|
||||
exit={{ opacity: 0, x: '100%' }}
|
||||
transition={{ type: 'spring', damping: 25, stiffness: 200 }}
|
||||
className="fixed inset-0 z-[150] bg-[#FAF7F0] flex flex-col md:hidden"
|
||||
>
|
||||
<div className="flex items-center justify-between p-8 border-b border-[#1A1A1A]/5">
|
||||
<span className="text-[20px] font-serif tracking-[0.25em] text-[#1A1A1A] uppercase">AYRIS</span>
|
||||
<button onClick={() => setIsMobileMenuOpen(false)} className="p-2"><X size={32} /></button>
|
||||
</div>
|
||||
<div className="flex flex-col flex-1 p-8 space-y-10">
|
||||
{navLinks.map((link, idx) => (
|
||||
<motion.div
|
||||
key={link.name}
|
||||
initial={{ opacity: 0, x: 20 }}
|
||||
animate={{ opacity: 1, x: 0 }}
|
||||
transition={{ delay: 0.1 * idx }}
|
||||
>
|
||||
<Link href={link.href} onClick={() => setIsMobileMenuOpen(false)} className="text-5xl font-serif text-[#1A1A1A] tracking-tighter">
|
||||
{link.name}
|
||||
</Link>
|
||||
</motion.div>
|
||||
))}
|
||||
<motion.div initial={{ opacity: 0, x: 20 }} animate={{ opacity: 1, x: 0 }} transition={{ delay: 0.4 }}>
|
||||
<Link href={`/${lang}/contact`} onClick={() => setIsMobileMenuOpen(false)} className="text-5xl font-serif text-[#1A1A1A] tracking-tighter">
|
||||
{dict.nav.contact}
|
||||
</Link>
|
||||
</motion.div>
|
||||
|
||||
{/* Lang Toggle Mobile */}
|
||||
<div className="flex items-center space-x-6 pt-12">
|
||||
<button onClick={() => { handleLangChange('tr'); setIsMobileMenuOpen(false); }} className={`text-xl font-bold tracking-widest ${lang === 'tr' ? 'text-[#C88C4B]' : 'text-[#1A1A1A]/30'}`}>TR</button>
|
||||
<button onClick={() => { handleLangChange('en'); setIsMobileMenuOpen(false); }} className={`text-xl font-bold tracking-widest ${lang === 'en' ? 'text-[#C88C4B]' : 'text-[#1A1A1A]/30'}`}>EN</button>
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
)}
|
||||
</AnimatePresence>
|
||||
</>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user