244 lines
9.2 KiB
TypeScript
244 lines
9.2 KiB
TypeScript
"use client";
|
|
import { useEffect, useState } from "react";
|
|
import Link from "next/link";
|
|
import { ChevronDown, Phone, Menu, X } from "lucide-react";
|
|
import Image from "next/image";
|
|
import LanguageSelectRadix from "../languageSwitcher";
|
|
import { useLocale, useTranslations } from "next-intl";
|
|
import UpHeader from "./upHeader";
|
|
import {
|
|
DropdownMenu,
|
|
DropdownMenuContent,
|
|
DropdownMenuItem,
|
|
DropdownMenuTrigger,
|
|
} from "../ui/dropdown-menu";
|
|
import { useQuery } from "@tanstack/react-query";
|
|
import httpClient from "@/request/api";
|
|
import { endPoints } from "@/request/links";
|
|
import { NavbarItem } from "@/lib/types";
|
|
|
|
export function Navbar() {
|
|
const locale = useLocale();
|
|
const t = useTranslations();
|
|
const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false);
|
|
const [scrolled, setScrolled] = useState(false);
|
|
|
|
const { data: navbarItems } = useQuery({
|
|
queryKey: ["navbaritem",locale],
|
|
queryFn: () => httpClient(endPoints.navbar),
|
|
select: (data: any) => ({
|
|
results: data?.data?.data?.results,
|
|
total_items: data?.data?.data?.total_items,
|
|
total_pages: data?.data?.data?.total_pages,
|
|
}),
|
|
});
|
|
|
|
useEffect(() => {
|
|
const handleScroll = () => {
|
|
setScrolled(window.scrollY > 50);
|
|
};
|
|
window.addEventListener("scroll", handleScroll);
|
|
return () => window.removeEventListener("scroll", handleScroll);
|
|
}, []);
|
|
|
|
// Prevent body scroll when mobile menu is open
|
|
useEffect(() => {
|
|
if (isMobileMenuOpen) {
|
|
document.body.style.overflow = "hidden";
|
|
} else {
|
|
document.body.style.overflow = "unset";
|
|
}
|
|
}, [isMobileMenuOpen]);
|
|
|
|
return (
|
|
<>
|
|
<nav
|
|
className={`fixed top-0 left-0 right-0 z-50 border-b border-gray-400/50 ${scrolled && "bg-black"} transition`}
|
|
>
|
|
<div
|
|
className={`overflow-hidden transition-all duration-500 ease-in-out ${
|
|
scrolled
|
|
? "max-h-0 opacity-0 -translate-y-2"
|
|
: "max-h-20 opacity-100 translate-y-0"
|
|
}`}
|
|
style={{ transform: scrolled ? "translateY(-8px)" : "translateY(0)" }}
|
|
>
|
|
<UpHeader />
|
|
</div>
|
|
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
|
<div className="flex justify-between items-center h-20">
|
|
{/* Logo */}
|
|
<Link href={`/${locale}/home`} className="hover:cursor-pointer">
|
|
<div className="flex items-center gap-2">
|
|
<div className=" flex items-center justify-center">
|
|
<Image
|
|
src={"/images/IGNUM/PNG/1.@6x.png"}
|
|
alt="logo image"
|
|
width={80}
|
|
height={80}
|
|
/>
|
|
</div>
|
|
</div>
|
|
</Link>
|
|
|
|
{/* Desktop Navigation Menu */}
|
|
<div className="hidden h-full lg:flex items-center gap-8">
|
|
{navbarItems?.results ? (
|
|
navbarItems.results.map((item: NavbarItem) => (
|
|
<DropdownMenu key={item.id}>
|
|
<DropdownMenuTrigger asChild>
|
|
<Link
|
|
key={item.id}
|
|
href={`/${locale}/${item.url}`}
|
|
className="font-unbounded uppercase text-white text-sm h-full flex items-center font-semibold hover:cursor-pointer hover:text-red-500 transition"
|
|
>
|
|
{item.name}
|
|
{item.children.length > 0 && (
|
|
<ChevronDown size={12} className="ml-1" />
|
|
)}
|
|
</Link>
|
|
</DropdownMenuTrigger>
|
|
{item.children.length > 0 && (
|
|
<DropdownMenuContent className="space-y-2">
|
|
{item.children.map((child: NavbarItem) => (
|
|
<DropdownMenuItem asChild key={child.id}>
|
|
<Link
|
|
href={`/${locale}/${child.url}`}
|
|
className="font-unbounded uppercase text-white text-sm h-full flex items-center font-semibold hover:cursor-pointer hover:text-red-500 transition"
|
|
>
|
|
{child.name}
|
|
</Link>
|
|
</DropdownMenuItem>
|
|
))}
|
|
</DropdownMenuContent>
|
|
)}
|
|
</DropdownMenu>
|
|
))
|
|
) : (
|
|
<Link
|
|
href={`/${locale}/home`}
|
|
className="font-unbounded uppercase text-white text-sm h-full flex items-center font-semibold hover:cursor-pointer hover:text-red-500 transition"
|
|
>
|
|
{t("navbar.home")}
|
|
</Link>
|
|
)}
|
|
</div>
|
|
|
|
<div className="flex items-center gap-5">
|
|
{/* Language Switcher */}
|
|
<LanguageSelectRadix />
|
|
|
|
{/* Emergency Call Button - Hidden on mobile */}
|
|
<div className="hidden lg:flex items-center hover:cursor-pointer gap-3 px-4 py-2 rounded-full">
|
|
<span
|
|
className="shrink-0 w-10 h-10 bg-red-600 rounded-full flex items-center justify-center
|
|
shadow-[0_0_0px_4px_rgba(239,68,68,0.1)]"
|
|
>
|
|
<Phone size={20} className="text-white" />
|
|
</span>
|
|
<div>
|
|
<div className="text-white text-sm font-bold">
|
|
<div>+998-55-055-21-21</div>
|
|
<div>+998-77-372-21-21</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Mobile Menu Button */}
|
|
<button
|
|
onClick={() => setIsMobileMenuOpen(true)}
|
|
className="lg:hidden text-white p-2 hover:bg-red-600 rounded-md transition"
|
|
>
|
|
<Menu size={24} />
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</nav>
|
|
|
|
{/* Mobile Menu Overlay */}
|
|
<div
|
|
className={`fixed inset-0 bg-black/50 z-50 transition-opacity duration-300 lg:hidden ${
|
|
isMobileMenuOpen
|
|
? "opacity-100 pointer-events-auto"
|
|
: "opacity-0 pointer-events-none"
|
|
}`}
|
|
onClick={() => setIsMobileMenuOpen(false)}
|
|
/>
|
|
|
|
{/* Mobile Menu Sidebar */}
|
|
<div
|
|
className={`fixed top-0 left-0 bottom-0 w-80 bg-black z-50 transform transition-transform duration-300 ease-in-out lg:hidden ${
|
|
isMobileMenuOpen ? "translate-x-0" : "-translate-x-full"
|
|
}`}
|
|
>
|
|
{/* Mobile Menu Header */}
|
|
<div className="flex justify-between items-center p-6 border-b border-gray-700">
|
|
{/* Logo */}
|
|
<Link href={`/${locale}/home`} className="hover:cursor-pointer">
|
|
<div className="font-unbounded uppercase flex flex-col items-center text-2xl gap-2 text-white font-bold">
|
|
<div className=" flex items-center justify-center">
|
|
<Image
|
|
src="/images/IGNUM/PNG/1.@6x.png"
|
|
alt="logo image"
|
|
width={50}
|
|
height={50}
|
|
className=""
|
|
/>
|
|
</div>
|
|
</div>
|
|
</Link>
|
|
<button
|
|
onClick={() => setIsMobileMenuOpen(false)}
|
|
className="text-white p-2 hover:bg-red-600 rounded-md transition"
|
|
>
|
|
<X size={24} />
|
|
</button>
|
|
</div>
|
|
|
|
{/* Mobile Menu Links */}
|
|
<div className="flex flex-col p-6 gap-4">
|
|
{navbarItems?.results ? (
|
|
navbarItems.results.map((item: NavbarItem) => (
|
|
<DropdownMenu key={item.id}>
|
|
<DropdownMenuTrigger asChild>
|
|
<Link
|
|
key={item.id}
|
|
href={`/${locale}/${item.url}`}
|
|
className="font-unbounded uppercase text-white text-sm h-full flex items-center font-semibold hover:cursor-pointer hover:text-red-500 transition"
|
|
>
|
|
{item.name}
|
|
{item.children.length > 0 && (
|
|
<ChevronDown size={12} className="ml-1" />
|
|
)}
|
|
</Link>
|
|
</DropdownMenuTrigger>
|
|
{item.children.length > 0 && (
|
|
<DropdownMenuContent className="space-y-2">
|
|
{item.children.map((child: NavbarItem) => (
|
|
<Link
|
|
key={child.id}
|
|
href={`/${locale}/${child.url}`}
|
|
className="font-unbounded uppercase text-white text-sm h-full flex items-center font-semibold hover:cursor-pointer hover:text-red-500 transition"
|
|
>
|
|
{child.name}
|
|
</Link>
|
|
))}
|
|
</DropdownMenuContent>
|
|
)}
|
|
</DropdownMenu>
|
|
))
|
|
) : (
|
|
<Link
|
|
href={`/${locale}/home`}
|
|
className="font-unbounded uppercase text-white text-sm h-full flex items-center font-semibold hover:cursor-pointer hover:text-red-500 transition"
|
|
>
|
|
{t("navbar.home")}
|
|
</Link>
|
|
)}
|
|
</div>
|
|
</div>
|
|
</>
|
|
);
|
|
}
|