252 lines
14 KiB
TypeScript
252 lines
14 KiB
TypeScript
"use client"
|
|
|
|
import * as React from "react"
|
|
import Link from "next/link"
|
|
import Image from "next/image"
|
|
import { Button } from "@/components/ui/button"
|
|
import { cn } from "@/lib/utils"
|
|
import { useLanguage } from "@/lib/language-context"
|
|
import { Globe, Menu, X, ChevronDown, Bus } from "lucide-react"
|
|
import { motion, AnimatePresence } from "framer-motion"
|
|
|
|
interface NavbarProps {
|
|
darkMode?: boolean
|
|
}
|
|
|
|
const Navbar = ({ darkMode = false }: NavbarProps) => {
|
|
const [isScrolled, setIsScrolled] = React.useState(false)
|
|
const [isMenuOpen, setIsMenuOpen] = React.useState(false)
|
|
const [isDropdownOpen, setIsDropdownOpen] = React.useState(false)
|
|
const { language, setLanguage, t } = useLanguage()
|
|
const useLightNav = isScrolled || !darkMode
|
|
|
|
React.useEffect(() => {
|
|
const handleScroll = () => {
|
|
setIsScrolled(window.scrollY > 20)
|
|
}
|
|
window.addEventListener("scroll", handleScroll)
|
|
return () => window.removeEventListener("scroll", handleScroll)
|
|
}, [])
|
|
|
|
React.useEffect(() => {
|
|
if (isMenuOpen) {
|
|
document.body.style.overflow = 'hidden'
|
|
} else {
|
|
document.body.style.overflow = 'unset'
|
|
}
|
|
return () => {
|
|
document.body.style.overflow = 'unset'
|
|
}
|
|
}, [isMenuOpen])
|
|
|
|
return (
|
|
<>
|
|
<nav
|
|
className={cn(
|
|
"fixed top-0 left-0 right-0 z-50 transition-all duration-300 px-6 py-4",
|
|
useLightNav
|
|
? "bg-white/80 backdrop-blur-md shadow-sm border-b border-slate-200/60"
|
|
: "bg-transparent"
|
|
)}
|
|
>
|
|
<div className="max-w-7xl mx-auto flex items-center justify-between">
|
|
<Link href="/" className="flex items-center space-x-3 group z-50">
|
|
<div className="relative w-40 h-10 md:w-48 md:h-12">
|
|
<Image
|
|
src={useLightNav ? "/images/logo-dark.svg" : "/images/logo-white.svg"}
|
|
alt="SkyFly Travel"
|
|
fill
|
|
sizes="(min-width: 768px) 192px, 160px"
|
|
className="object-contain"
|
|
priority
|
|
/>
|
|
</div>
|
|
</Link>
|
|
|
|
<div className="hidden md:flex items-center space-x-8">
|
|
<Link
|
|
href="/arak"
|
|
className={cn(
|
|
"text-base font-semibold tracking-wide transition-colors",
|
|
useLightNav ? "text-slate-700 hover:text-primary" : "text-white/90 hover:text-slate-900"
|
|
)}
|
|
>
|
|
{t.nav.prices}
|
|
</Link>
|
|
|
|
{/* Services Dropdown */}
|
|
<div
|
|
className="relative"
|
|
onMouseEnter={() => setIsDropdownOpen(true)}
|
|
onMouseLeave={() => setIsDropdownOpen(false)}
|
|
>
|
|
<button
|
|
className={cn(
|
|
"flex items-center gap-1 text-base font-semibold tracking-wide transition-colors cursor-pointer",
|
|
useLightNav ? "text-slate-700 hover:text-primary" : "text-white/90 hover:text-slate-900"
|
|
)}
|
|
>
|
|
{t.nav.services}
|
|
<ChevronDown className={cn("w-3.5 h-3.5 transition-transform duration-300", isDropdownOpen && "rotate-180")} />
|
|
</button>
|
|
|
|
<AnimatePresence>
|
|
{isDropdownOpen && (
|
|
<motion.div
|
|
initial={{ opacity: 0, y: 10, scale: 0.95 }}
|
|
animate={{ opacity: 1, y: 0, scale: 1 }}
|
|
exit={{ opacity: 0, y: 10, scale: 0.95 }}
|
|
transition={{ duration: 0.2, ease: "easeOut" }}
|
|
className="absolute top-full left-1/2 -translate-x-1/2 mt-3 w-64 bg-white rounded-2xl shadow-2xl border border-slate-100 overflow-hidden p-2"
|
|
>
|
|
<Link
|
|
href="/szolgaltatasok"
|
|
className="flex items-center gap-3 px-4 py-3 rounded-xl hover:bg-slate-50 text-slate-700 hover:text-primary transition-all group"
|
|
>
|
|
<div className="bg-primary/10 p-2 rounded-lg group-hover:bg-primary group-hover:text-white transition-colors">
|
|
<Globe className="w-4 h-4" />
|
|
</div>
|
|
<span className="text-sm font-bold">{t.nav.servicePackages}</span>
|
|
</Link>
|
|
<Link
|
|
href="/egyeb-szemelyszallitas"
|
|
className="flex items-center gap-3 px-4 py-3 rounded-xl hover:bg-slate-50 text-slate-700 hover:text-primary transition-all group"
|
|
>
|
|
<div className="bg-slate-100 p-2 rounded-lg group-hover:bg-primary group-hover:text-white transition-colors">
|
|
<Bus className="w-4 h-4" />
|
|
</div>
|
|
<span className="text-sm font-bold">{t.nav.otherTransport}</span>
|
|
</Link>
|
|
</motion.div>
|
|
)}
|
|
</AnimatePresence>
|
|
</div>
|
|
|
|
<Link
|
|
href="/feltetelek"
|
|
className={cn(
|
|
"text-base font-semibold tracking-wide transition-colors",
|
|
useLightNav ? "text-slate-700 hover:text-primary" : "text-white/90 hover:text-slate-900"
|
|
)}
|
|
>
|
|
{t.nav.conditions}
|
|
</Link>
|
|
<Link
|
|
href="/flotta"
|
|
className={cn(
|
|
"text-base font-semibold tracking-wide transition-colors",
|
|
useLightNav ? "text-slate-700 hover:text-primary" : "text-white/90 hover:text-slate-900"
|
|
)}
|
|
>
|
|
{t.nav.fleet}
|
|
</Link>
|
|
<Link
|
|
href="/kapcsolat"
|
|
className={cn(
|
|
"text-base font-semibold tracking-wide transition-colors",
|
|
useLightNav ? "text-slate-700 hover:text-primary" : "text-white/90 hover:text-slate-900"
|
|
)}
|
|
>
|
|
{t.nav.contact}
|
|
</Link>
|
|
</div>
|
|
|
|
<div className="hidden md:flex items-center space-x-4">
|
|
{/* Language Switcher */}
|
|
<div className={cn(
|
|
"flex items-center rounded-full p-1 mr-2 transition-colors",
|
|
useLightNav ? "bg-white border border-slate-200/70 shadow-sm" : "bg-white/10 border border-white/10 backdrop-blur-sm"
|
|
)}>
|
|
<button
|
|
onClick={() => setLanguage("hu")}
|
|
className={cn(
|
|
"text-[10px] font-bold px-3 py-1 rounded-full transition-all",
|
|
language === "hu"
|
|
? "bg-white text-slate-900 shadow-sm"
|
|
: (useLightNav ? "text-slate-600 hover:text-slate-900" : "text-white/60 hover:text-white")
|
|
)}
|
|
>
|
|
{t.nav.language.hu}
|
|
</button>
|
|
<button
|
|
onClick={() => setLanguage("en")}
|
|
className={cn(
|
|
"text-[10px] font-bold px-3 py-1 rounded-full transition-all",
|
|
language === "en"
|
|
? "bg-white text-slate-900 shadow-sm"
|
|
: (useLightNav ? "text-slate-600 hover:text-slate-900" : "text-white/60 hover:text-white")
|
|
)}
|
|
>
|
|
{t.nav.language.en}
|
|
</button>
|
|
</div>
|
|
|
|
<Button
|
|
asChild
|
|
variant={useLightNav ? "pill" : "outline"}
|
|
className={cn(
|
|
"rounded-full px-6",
|
|
(!useLightNav && darkMode) && "text-white border-white/20 hover:bg-white/10 bg-transparent",
|
|
useLightNav && "bg-primary text-white"
|
|
)}
|
|
>
|
|
<a href="https://app.skyflytravel.hu/public/offers/new" target="_blank" rel="noopener noreferrer" className="text-[10px] md:text-sm">
|
|
{t.nav.cta}
|
|
</a>
|
|
</Button>
|
|
</div>
|
|
|
|
{/* Mobile Menu Toggle */}
|
|
<button
|
|
className={cn(
|
|
"md:hidden p-2 z-50 rounded-lg backdrop-blur-sm transition-colors",
|
|
useLightNav ? "text-slate-900 bg-white/80 border border-slate-200/70 hover:bg-white" : "text-white bg-black/50 hover:bg-black/70"
|
|
)}
|
|
onClick={() => setIsMenuOpen(!isMenuOpen)}
|
|
aria-label={isMenuOpen ? (language === "hu" ? "Menü bezárása" : "Close menu") : (language === "hu" ? "Menü megnyitása" : "Open menu")}
|
|
aria-expanded={isMenuOpen}
|
|
>
|
|
{isMenuOpen ? <X className="w-6 h-6" /> : <Menu className="w-6 h-6" />}
|
|
</button>
|
|
</div>
|
|
|
|
</nav>
|
|
|
|
{/* Mobile Menu Overlay */}
|
|
{isMenuOpen && (
|
|
<div className="fixed inset-0 z-40 flex flex-col pt-32 px-8 animate-in slide-in-from-top duration-300">
|
|
<div className="absolute inset-0 bg-slate-950/95 backdrop-blur-md" />
|
|
<div className="relative flex flex-col space-y-5 text-center">
|
|
<Link onClick={() => setIsMenuOpen(false)} href="/arak" className="text-xl font-bold text-white hover:text-primary transition-colors">{t.nav.prices}</Link>
|
|
|
|
<div className="flex flex-col space-y-4 py-4 px-6 bg-white/5 rounded-[2rem] border border-white/5">
|
|
<span className="text-[10px] font-black uppercase tracking-[0.3em] text-white/40">{t.nav.services}</span>
|
|
<div className="flex flex-col space-y-4">
|
|
<Link onClick={() => setIsMenuOpen(false)} href="/szolgaltatasok" className="text-lg font-bold text-white hover:text-primary transition-colors">{t.nav.servicePackages}</Link>
|
|
<Link onClick={() => setIsMenuOpen(false)} href="/egyeb-szemelyszallitas" className="text-lg font-bold text-white hover:text-primary transition-colors">{t.nav.otherTransport}</Link>
|
|
</div>
|
|
</div>
|
|
|
|
<Link onClick={() => setIsMenuOpen(false)} href="/feltetelek" className="text-xl font-bold text-white hover:text-primary transition-colors">{t.nav.conditions}</Link>
|
|
<Link onClick={() => setIsMenuOpen(false)} href="/flotta" className="text-xl font-bold text-white hover:text-primary transition-colors">{t.nav.fleet}</Link>
|
|
<Link onClick={() => setIsMenuOpen(false)} href="/kapcsolat" className="text-xl font-bold text-white hover:text-primary transition-colors">{t.nav.contact}</Link>
|
|
|
|
<div className="flex justify-center gap-4 pt-6">
|
|
<button onClick={() => { setLanguage("hu"); setIsMenuOpen(false) }} className={cn("px-6 py-2 rounded-full font-bold", language === "hu" ? "bg-white text-slate-900" : "bg-white/10 text-white")}>{t.nav.language.hu}</button>
|
|
<button onClick={() => { setLanguage("en"); setIsMenuOpen(false) }} className={cn("px-6 py-2 rounded-full font-bold", language === "en" ? "bg-white text-slate-900" : "bg-white/10 text-white")}>{t.nav.language.en}</button>
|
|
</div>
|
|
|
|
<Button asChild size="lg" className="mt-8 bg-primary text-white rounded-full">
|
|
<a href="https://app.skyflytravel.hu/public/offers/new" target="_blank" rel="noopener noreferrer">
|
|
{t.nav.cta}
|
|
</a>
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
)}
|
|
</>
|
|
)
|
|
}
|
|
|
|
export default Navbar
|