feat: complete UI/UX improvements and localization
This commit is contained in:
@@ -0,0 +1,172 @@
|
||||
'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>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user