173 lines
7.0 KiB
TypeScript
173 lines
7.0 KiB
TypeScript
'use client'
|
|
|
|
import { motion } from 'framer-motion'
|
|
import { useState, useEffect } from 'react'
|
|
import { Link, usePathname } from '@/i18n/routing'
|
|
import { useTranslations } from 'next-intl'
|
|
import LocaleSwitcher from './LocaleSwitcher'
|
|
import { cn } from '@/lib/utils'
|
|
import { Menu, X } from 'lucide-react'
|
|
|
|
export default function Header() {
|
|
const [scrolled, setScrolled] = useState(false)
|
|
const [mobileMenuOpen, setMobileMenuOpen] = useState(false)
|
|
const t = useTranslations('nav')
|
|
const pathname = usePathname()
|
|
|
|
const isHome = pathname === '/'
|
|
// If we are not on the home page, the header should always look "scrolled"
|
|
// so the text is visible against the light background.
|
|
const isScrolledOrInner = scrolled || !isHome
|
|
|
|
useEffect(() => {
|
|
const handler = () => setScrolled(window.scrollY > 50)
|
|
window.addEventListener('scroll', handler, { passive: true })
|
|
// Initialize
|
|
handler()
|
|
return () => window.removeEventListener('scroll', handler)
|
|
}, [])
|
|
|
|
return (
|
|
<motion.header
|
|
initial={{ y: -20, opacity: 0 }}
|
|
animate={{ y: 0, opacity: 1 }}
|
|
transition={{ duration: 0.6, ease: [0.22, 1, 0.36, 1] }}
|
|
className={cn(
|
|
'fixed top-0 inset-x-0 z-50 transition-all duration-300',
|
|
isScrolledOrInner
|
|
? 'bg-surface/85 backdrop-blur-md border-b border-outline-variant/20 shadow-sm py-4'
|
|
: 'bg-transparent py-6'
|
|
)}
|
|
>
|
|
<div className="max-w-container-max mx-auto px-margin-mobile md:px-gutter">
|
|
<div className="flex items-center justify-between">
|
|
{/* Logo */}
|
|
<Link href="/" className="flex items-center z-50">
|
|
<span className={cn(
|
|
"font-serif text-2xl md:text-[32px] font-bold tracking-tight italic transition-colors duration-300",
|
|
isScrolledOrInner ? "text-secondary" : "text-white"
|
|
)}>
|
|
Sitar Apart
|
|
</span>
|
|
</Link>
|
|
|
|
{/* Desktop Navigation */}
|
|
<nav className="hidden md:flex items-center gap-8">
|
|
<Link
|
|
href="/"
|
|
className={cn(
|
|
"text-[14px] font-bold tracking-wider uppercase transition-colors duration-300 hover:text-tertiary cursor-pointer focus:outline-none focus-visible:ring-2 focus-visible:ring-primary rounded-sm px-1",
|
|
isScrolledOrInner ? "text-secondary" : "text-white/90"
|
|
)}
|
|
>
|
|
{t('home')}
|
|
</Link>
|
|
<Link
|
|
href="/dairelerimiz"
|
|
className={cn(
|
|
"text-[14px] font-bold tracking-wider uppercase transition-colors duration-300 hover:text-tertiary cursor-pointer focus:outline-none focus-visible:ring-2 focus-visible:ring-primary rounded-sm px-1",
|
|
isScrolledOrInner ? "text-secondary" : "text-white/90"
|
|
)}
|
|
>
|
|
{t('rooms')}
|
|
</Link>
|
|
<Link
|
|
href="/galeri"
|
|
className={cn(
|
|
"text-[14px] font-bold tracking-wider uppercase transition-colors duration-300 hover:text-tertiary cursor-pointer focus:outline-none focus-visible:ring-2 focus-visible:ring-primary rounded-sm px-1",
|
|
isScrolledOrInner ? "text-secondary" : "text-white/90"
|
|
)}
|
|
>
|
|
{t('gallery')}
|
|
</Link>
|
|
<Link
|
|
href="/iletisim"
|
|
className={cn(
|
|
"text-[14px] font-bold tracking-wider uppercase transition-colors duration-300 hover:text-tertiary cursor-pointer focus:outline-none focus-visible:ring-2 focus-visible:ring-primary rounded-sm px-1",
|
|
isScrolledOrInner ? "text-secondary" : "text-white/90"
|
|
)}
|
|
>
|
|
{t('contact')}
|
|
</Link>
|
|
</nav>
|
|
|
|
{/* Desktop Actions */}
|
|
<div className="hidden md:flex items-center gap-4">
|
|
<LocaleSwitcher scrolled={isScrolledOrInner} />
|
|
<Link
|
|
href="/iletisim"
|
|
className={cn(
|
|
"px-6 py-3 rounded-full text-[14px] font-bold tracking-wider uppercase transition-all duration-300 hover:opacity-80 cursor-pointer focus:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-2",
|
|
isScrolledOrInner
|
|
? "bg-accent-pink text-white shadow-md"
|
|
: "bg-accent-pink text-white backdrop-blur-md"
|
|
)}
|
|
>
|
|
{t('book_now')}
|
|
</Link>
|
|
</div>
|
|
|
|
{/* Mobile Menu Button */}
|
|
<button
|
|
aria-label="Toggle menu"
|
|
className="md:hidden z-50 p-2 cursor-pointer focus:outline-none focus-visible:ring-2 focus-visible:ring-primary rounded-md transition-all duration-300"
|
|
onClick={() => setMobileMenuOpen(!mobileMenuOpen)}
|
|
>
|
|
{mobileMenuOpen ? (
|
|
<X className={cn("w-6 h-6", isScrolledOrInner ? "text-secondary" : "text-white")} />
|
|
) : (
|
|
<Menu className={cn("w-6 h-6", isScrolledOrInner ? "text-secondary" : "text-white")} />
|
|
)}
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Mobile Menu */}
|
|
{mobileMenuOpen && (
|
|
<div className="md:hidden absolute top-full left-0 right-0 bg-surface border-b border-outline-variant/20 shadow-lg p-6">
|
|
<nav className="flex flex-col gap-6">
|
|
<Link
|
|
href="/"
|
|
onClick={() => setMobileMenuOpen(false)}
|
|
className="text-secondary hover:text-tertiary font-bold tracking-wider uppercase text-[14px]"
|
|
>
|
|
{t('home')}
|
|
</Link>
|
|
<Link
|
|
href="/dairelerimiz"
|
|
onClick={() => setMobileMenuOpen(false)}
|
|
className="text-secondary hover:text-tertiary font-bold tracking-wider uppercase text-[14px]"
|
|
>
|
|
{t('rooms')}
|
|
</Link>
|
|
<Link
|
|
href="/galeri"
|
|
onClick={() => setMobileMenuOpen(false)}
|
|
className="text-secondary hover:text-tertiary font-bold tracking-wider uppercase text-[14px]"
|
|
>
|
|
{t('gallery')}
|
|
</Link>
|
|
<Link
|
|
href="/iletisim"
|
|
onClick={() => setMobileMenuOpen(false)}
|
|
className="text-secondary hover:text-tertiary font-bold tracking-wider uppercase text-[14px]"
|
|
>
|
|
{t('contact')}
|
|
</Link>
|
|
<div className="pt-6 border-t border-outline-variant/20 flex flex-col gap-4">
|
|
<div className="self-end"><LocaleSwitcher scrolled={true} /></div>
|
|
<Link
|
|
href="/iletisim"
|
|
onClick={() => setMobileMenuOpen(false)}
|
|
className="bg-accent-pink text-white px-6 py-3 rounded-full text-[14px] font-bold tracking-wider uppercase text-center"
|
|
>
|
|
{t('book_now')}
|
|
</Link>
|
|
</div>
|
|
</nav>
|
|
</div>
|
|
)}
|
|
</motion.header>
|
|
)
|
|
}
|