171 lines
6.1 KiB
TypeScript
171 lines
6.1 KiB
TypeScript
"use client";
|
|
|
|
import { useEffect, useState } from "react";
|
|
import Image from "next/image";
|
|
import { navigationData } from "@/data/navigation";
|
|
import { SearchIcon } from "@/components/shared/icons/SearchIcon";
|
|
|
|
export function Navbar() {
|
|
const [isSticky, setIsSticky] = useState(false);
|
|
const [openDropdown, setOpenDropdown] = useState<string | null>(null);
|
|
|
|
useEffect(() => {
|
|
const onScroll = () => setIsSticky(window.scrollY > 120);
|
|
|
|
onScroll();
|
|
window.addEventListener("scroll", onScroll, { passive: true });
|
|
return () => window.removeEventListener("scroll", onScroll);
|
|
}, []);
|
|
|
|
return (
|
|
<header
|
|
className={`tenext-navbar z-30 mx-auto grid h-[100px] max-w-[2520px] grid-cols-[280px_1fr_360px] items-center px-[34px] transition-[background-color,border-radius,box-shadow,transform] duration-500 ${
|
|
isSticky
|
|
? "fixed left-5 right-5 top-0 rounded-b-[25px] bg-[#111111] shadow-[0_12px_35px_rgba(0,0,0,0.18)]"
|
|
: "relative bg-transparent"
|
|
}`}
|
|
>
|
|
<div className="flex items-center gap-[64px]">
|
|
<button
|
|
className="navbar-reveal grid h-6 w-6 grid-cols-2 gap-[5px] text-white transition-colors hover:text-tenext-teal"
|
|
aria-label="Open menu"
|
|
>
|
|
<span className="h-[7px] w-[7px] rounded-[2px] border-2 border-current" />
|
|
<span className="h-[7px] w-[7px] rounded-[2px] border-2 border-current" />
|
|
<span className="h-[7px] w-[7px] rounded-[2px] border-2 border-current" />
|
|
<span className="h-[7px] w-[7px] rounded-[2px] border-2 border-current" />
|
|
</button>
|
|
|
|
{/* Logo */}
|
|
<a
|
|
href="#"
|
|
className="navbar-reveal flex items-center"
|
|
style={{ animationDelay: "120ms" }}
|
|
>
|
|
<Image
|
|
src="/images/tenext/logo-dark.png"
|
|
alt="tenext"
|
|
width={109.5}
|
|
height={19.5}
|
|
className="h-auto w-auto"
|
|
priority
|
|
/>
|
|
</a>
|
|
</div>
|
|
|
|
{/* Navigation */}
|
|
<nav
|
|
className="hidden items-center justify-center gap-[11px] lg:flex"
|
|
aria-label="Primary navigation"
|
|
>
|
|
{navigationData.map((item, index) => (
|
|
<div
|
|
key={item.label}
|
|
className="navbar-reveal relative"
|
|
style={{ animationDelay: `${140 + index * 70}ms` }}
|
|
onMouseEnter={() => setOpenDropdown(item.label)}
|
|
onMouseLeave={() => setOpenDropdown(null)}
|
|
>
|
|
<a
|
|
href={item.href}
|
|
className={`nav-link-swap flex h-10 items-center rounded-[10px] px-[21px] text-[13px] font-bold uppercase leading-none text-white transition-colors hover:bg-tenext-dark ${
|
|
item.label === "Home" ? "bg-tenext-dark" : ""
|
|
}`}
|
|
style={{ fontFamily: "var(--font-sora)" }}
|
|
>
|
|
<span className="text-active">{item.label}</span>
|
|
<span aria-hidden>{item.label}</span>
|
|
{item.children && (
|
|
<svg
|
|
className="ml-[12px] h-[5px] w-[5px] opacity-90"
|
|
viewBox="0 0 5 5"
|
|
fill="none"
|
|
>
|
|
<path
|
|
d="M4.35 0.9L3.75 4.05L0.65 3.45"
|
|
stroke="currentColor"
|
|
strokeWidth="1.1"
|
|
strokeLinecap="round"
|
|
strokeLinejoin="round"
|
|
/>
|
|
</svg>
|
|
)}
|
|
</a>
|
|
|
|
{/* Dropdown */}
|
|
{item.children && openDropdown === item.label && (
|
|
<div className="absolute left-0 top-full z-50 min-w-[286px] origin-top rounded-[20px] border border-tenext-card-border bg-[#111111] px-[45px] py-[30px] shadow-2xl">
|
|
{item.children.map((child, childIndex) => (
|
|
<a
|
|
key={child.label}
|
|
href={child.href}
|
|
className="dropdown-reveal block py-[10px] pr-5 text-[14px] font-medium text-white/80 transition-all hover:pl-5 hover:text-tenext-teal"
|
|
style={{
|
|
animationDelay: `${childIndex * 45}ms`,
|
|
fontFamily: "var(--font-sora)",
|
|
}}
|
|
>
|
|
{child.label}
|
|
</a>
|
|
))}
|
|
</div>
|
|
)}
|
|
</div>
|
|
))}
|
|
</nav>
|
|
|
|
{/* Right Icons */}
|
|
<div
|
|
className="navbar-reveal flex items-center justify-end gap-[10px]"
|
|
style={{ animationDelay: "620ms" }}
|
|
>
|
|
<button
|
|
className="hidden p-[8px] text-white transition-colors hover:text-tenext-teal md:block"
|
|
aria-label="Search"
|
|
>
|
|
<SearchIcon className="h-[18px] w-[18px]" />
|
|
</button>
|
|
|
|
<a
|
|
href="#"
|
|
className="hidden items-center gap-[8px] p-[8px] text-[13px] font-bold uppercase leading-none text-white transition-colors hover:text-tenext-teal md:flex"
|
|
style={{ fontFamily: "var(--font-sora)" }}
|
|
>
|
|
<svg className="h-4 w-4" viewBox="0 0 16 16" fill="none">
|
|
<circle
|
|
cx="8"
|
|
cy="5"
|
|
r="3.5"
|
|
stroke="currentColor"
|
|
strokeWidth="1.3"
|
|
/>
|
|
<path
|
|
d="M2 14.5C2 11.5 4.5 9.5 8 9.5C11.5 9.5 14 11.5 14 14.5"
|
|
stroke="currentColor"
|
|
strokeWidth="1.3"
|
|
strokeLinecap="round"
|
|
/>
|
|
</svg>
|
|
Log in
|
|
</a>
|
|
|
|
<a
|
|
href="#"
|
|
className="tenext-button tenext-button-gradient-border min-w-[188px] justify-center rounded-full px-[24px] py-[21px] text-[16px] font-semibold leading-none text-white"
|
|
style={{ fontFamily: "var(--font-sora)" }}
|
|
>
|
|
Get in Touch
|
|
<span className="button-inner" />
|
|
</a>
|
|
|
|
{/* Mobile menu button */}
|
|
<button className="flex flex-col gap-[5px] lg:hidden" aria-label="Menu">
|
|
<span className="h-[2px] w-[22px] bg-white" />
|
|
<span className="h-[2px] w-[22px] bg-white" />
|
|
<span className="h-[2px] w-[22px] bg-white" />
|
|
</button>
|
|
</div>
|
|
</header>
|
|
);
|
|
}
|