Files
GNX-WEB/gnx-react/components/shared/layout/header/OffcanvasMenu.tsx
Iliyan Angelov 76c857b4f5 update
2025-10-10 21:54:39 +03:00

205 lines
7.0 KiB
TypeScript

"use client";
import { useState, useEffect } from "react";
import { usePathname } from "next/navigation";
import AnimateHeight from "react-animate-height";
import Image from "next/legacy/image";
import Link from "next/link";
import { OffcanvasData } from "@/public/data/offcanvas-data";
import logoLight from "@/public/images/logo-light.png";
interface OffcanvasMenuProps {
isOffcanvasOpen: boolean;
isActive: boolean;
handleClick: () => void;
navigationData?: any[];
servicesLoading?: boolean;
servicesError?: string | null;
}
const OffcanvasMenu = ({
isOffcanvasOpen,
isActive,
handleClick,
navigationData = OffcanvasData,
servicesLoading = false,
servicesError = null
}: OffcanvasMenuProps) => {
const [openDropdown, setOpenDropdown] = useState(null);
const [mounted, setMounted] = useState(false);
const handleDropdownToggle = (index: any) => {
setOpenDropdown((prev) => (prev === index ? null : index));
};
const pathname = usePathname();
useEffect(() => {
setMounted(true);
}, []);
useEffect(() => {
const parentItems = document.querySelectorAll(
".navbar__item--has-children"
);
parentItems.forEach((parentItem) => {
const childItems = parentItem.querySelectorAll(".active-current-sub");
if (childItems.length > 0) {
parentItem.classList.add("active-current-parent");
}
});
}, []);
return (
<div className="offcanvas-nav">
<div
className={
"offcanvas-menu" + (isOffcanvasOpen ? " show-offcanvas-menu" : " ")
}
suppressHydrationWarning
>
<nav
className={
"offcanvas-menu__wrapper" + (isActive ? " " : " nav-fade-active")
}
data-lenis-prevent
>
<div className="offcanvas-menu__header nav-fade">
<div className="logo">
<Link href="/" className="logo-img">
<Image src={logoLight} priority alt="Image" title="Logo" width={160} height={60} />
</Link>
</div>
<button
aria-label="close offcanvas menu"
className="close-offcanvas-menu"
onClick={handleClick}
>
<i className="fa-solid fa-xmark"></i>
</button>
</div>
<div className="offcanvas-menu__list">
<div className="navbar__menu">
<ul>
{navigationData.map((item, index) =>
item.submenu ? (
<li
className="navbar__item navbar__item--has-children nav-fade"
key={index}
>
<button
aria-label="dropdown menu"
className={
"navbar__dropdown-label" +
(openDropdown === index
? " navbar__item-active"
: " ")
}
onClick={() => handleDropdownToggle(index)}
>
{item.title}
{item.title === "Services" && servicesLoading && (
<span className="loading-indicator"></span>
)}
</button>
<AnimateHeight
duration={400}
height={openDropdown === index ? "auto" : 0}
>
<ul className="navbar__sub-menu">
{item.title === "Services" && servicesLoading ? (
<li>
<span className="text-muted">Loading services...</span>
</li>
) : item.title === "Services" && servicesError ? (
<li>
<span className="text-danger">Failed to load services</span>
</li>
) : (
item.submenu.map((subItem: any, subIndex: number) => (
<li key={subIndex}>
<Link
href={subItem.path || "#"}
className={
mounted && pathname === subItem.path
? " active-current-sub"
: " "
}
>
{subItem.title}
</Link>
</li>
))
)}
</ul>
</AnimateHeight>
</li>
) : (
<li className="navbar__item nav-fade" key={index}>
<Link
href={item.path || "#"}
className={
mounted && pathname === item.path ? " active-current-link" : " "
}
>
{item.title}
</Link>
</li>
)
)}
</ul>
</div>
</div>
</nav>
<div className="offcanvas-menu__enterprise-info nav-fade">
<div className="enterprise-contact">
<h4>Get in Touch</h4>
<p>Ready to transform your business?</p>
<div className="contact-methods">
<a href="tel:+359896138030" className="contact-item">
<i className="fa-solid fa-phone"></i>
<span>+359896138030</span>
</a>
<a href="mailto:info@gnxsoft.com" className="contact-item">
<i className="fa-solid fa-envelope"></i>
<span>info@gnxsoft.com</span>
</a>
</div>
</div>
</div>
<ul className="enterprise-social nav-fade">
<li>
<Link
href="https://www.linkedin.com/company/gnxtech"
target="_blank"
aria-label="Connect with us on LinkedIn"
>
<i className="fa-brands fa-linkedin-in"></i>
</Link>
</li>
<li>
<Link
href="https://github.com/gnxtech"
target="_blank"
aria-label="View our code on GitHub"
>
<i className="fa-brands fa-github"></i>
</Link>
</li>
</ul>
<div className="anime">
<span className="nav-fade"></span>
<span className="nav-fade"></span>
<span className="nav-fade"></span>
<span className="nav-fade"></span>
<span className="nav-fade"></span>
<span className="nav-fade"></span>
</div>
</div>
</div>
);
};
export default OffcanvasMenu;