updates
This commit is contained in:
@@ -153,11 +153,56 @@ const Footer = () => {
|
||||
</div>
|
||||
<h6 className="cta-title">Ready to Transform Your Business?</h6>
|
||||
<p className="cta-description">Start your software journey with our enterprise solutions, incident management, and custom development services.</p>
|
||||
<div className="cta-button-wrapper">
|
||||
<Link href="/contact-us" className="btn-luxury-cta">
|
||||
<span>Start Your Journey</span>
|
||||
<i className="fa-solid fa-arrow-right"></i>
|
||||
<div className="btn-shine"></div>
|
||||
</Link>
|
||||
<div className="goodfirms-wrapper text-center mt-3" style={{ lineHeight: 0 }}>
|
||||
<Link
|
||||
href="https://www.goodfirms.co/company/gnx-soft-ltd"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="goodfirms-badge d-inline-block"
|
||||
title="View our company profile on GoodFirms"
|
||||
style={{
|
||||
border: 'none',
|
||||
outline: 'none',
|
||||
boxShadow: 'none',
|
||||
textDecoration: 'none',
|
||||
padding: 0,
|
||||
margin: 0,
|
||||
display: 'inline-block',
|
||||
lineHeight: 0,
|
||||
background: 'transparent'
|
||||
}}
|
||||
>
|
||||
<Image
|
||||
src="/images/gnx-goodfirms.webp"
|
||||
alt="GoodFirms Company Profile"
|
||||
width={150}
|
||||
height={80}
|
||||
className="goodfirms-image"
|
||||
style={{
|
||||
width: '20px',
|
||||
height: '20px',
|
||||
objectFit: 'contain',
|
||||
border: 'none',
|
||||
outline: 'none',
|
||||
boxShadow: 'none',
|
||||
padding: 0,
|
||||
margin: 0,
|
||||
display: 'block',
|
||||
verticalAlign: 'top',
|
||||
borderWidth: 0,
|
||||
borderStyle: 'none',
|
||||
borderColor: 'transparent'
|
||||
}}
|
||||
/>
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
"use client";
|
||||
import { useState, useEffect, useMemo } from "react";
|
||||
import { useState, useEffect, useMemo, useRef } from "react";
|
||||
import { usePathname } from "next/navigation";
|
||||
import Link from "next/link";
|
||||
import Image from "next/image";
|
||||
@@ -12,6 +12,7 @@ const Header = () => {
|
||||
const [isActive, setIsActive] = useState(true);
|
||||
const [openDropdown, setOpenDropdown] = useState<number | null>(null);
|
||||
const [isMobile, setIsMobile] = useState(false);
|
||||
const dropdownTimeoutRef = useRef<NodeJS.Timeout | null>(null);
|
||||
|
||||
// Fetch services from API
|
||||
const { services: apiServices, loading: servicesLoading, error: servicesError } = useNavigationServices();
|
||||
@@ -112,6 +113,36 @@ const Header = () => {
|
||||
setOpenDropdown(openDropdown === index ? null : index);
|
||||
};
|
||||
|
||||
const handleDropdownEnter = (index: number) => {
|
||||
if (dropdownTimeoutRef.current) {
|
||||
clearTimeout(dropdownTimeoutRef.current);
|
||||
dropdownTimeoutRef.current = null;
|
||||
}
|
||||
if (!isMobile) {
|
||||
setOpenDropdown(index);
|
||||
}
|
||||
};
|
||||
|
||||
const handleDropdownLeave = (e: React.MouseEvent) => {
|
||||
if (!isMobile) {
|
||||
// Check if we're moving to the dropdown menu itself
|
||||
const relatedTarget = e.relatedTarget as HTMLElement;
|
||||
const currentTarget = e.currentTarget as HTMLElement;
|
||||
|
||||
// If moving to a child element (dropdown menu), don't close
|
||||
if (relatedTarget && currentTarget.contains(relatedTarget)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (dropdownTimeoutRef.current) {
|
||||
clearTimeout(dropdownTimeoutRef.current);
|
||||
}
|
||||
dropdownTimeoutRef.current = setTimeout(() => {
|
||||
setOpenDropdown(null);
|
||||
}, 300); // Increased delay to allow for scrolling
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const handleScroll = () => {
|
||||
const scrollPosition = window.scrollY;
|
||||
@@ -145,6 +176,9 @@ const Header = () => {
|
||||
|
||||
return () => {
|
||||
window.removeEventListener("resize", handleResize);
|
||||
if (dropdownTimeoutRef.current) {
|
||||
clearTimeout(dropdownTimeoutRef.current);
|
||||
}
|
||||
};
|
||||
}, []);
|
||||
|
||||
@@ -200,12 +234,12 @@ const Header = () => {
|
||||
<div className="navbar__menu d-none d-lg-flex">
|
||||
<ul>
|
||||
{navigationData.map((item) =>
|
||||
item.title === "Support Center" ? null : item.submenu ? (
|
||||
item.title === "Support Center" ? null : item.submenu ? (
|
||||
<li
|
||||
className="navbar__item navbar__item--has-children"
|
||||
key={item.id}
|
||||
onMouseEnter={() => !isMobile && setOpenDropdown(item.id)}
|
||||
onMouseLeave={() => !isMobile && setOpenDropdown(null)}
|
||||
onMouseEnter={() => handleDropdownEnter(item.id)}
|
||||
onMouseLeave={(e) => handleDropdownLeave(e)}
|
||||
>
|
||||
<button
|
||||
aria-label="dropdown menu"
|
||||
@@ -222,7 +256,27 @@ const Header = () => {
|
||||
<span className="loading-indicator">⏳</span>
|
||||
)}
|
||||
</button>
|
||||
<ul className={`navbar__sub-menu ${openDropdown === item.id ? 'show' : ''}`}>
|
||||
<ul
|
||||
className={`navbar__sub-menu ${openDropdown === item.id ? 'show' : ''}`}
|
||||
onMouseEnter={() => {
|
||||
if (dropdownTimeoutRef.current) {
|
||||
clearTimeout(dropdownTimeoutRef.current);
|
||||
dropdownTimeoutRef.current = null;
|
||||
}
|
||||
if (!isMobile) {
|
||||
setOpenDropdown(item.id);
|
||||
}
|
||||
}}
|
||||
onMouseLeave={(e) => handleDropdownLeave(e)}
|
||||
onWheel={(e) => {
|
||||
// Prevent dropdown from closing when scrolling
|
||||
e.stopPropagation();
|
||||
if (dropdownTimeoutRef.current) {
|
||||
clearTimeout(dropdownTimeoutRef.current);
|
||||
dropdownTimeoutRef.current = null;
|
||||
}
|
||||
}}
|
||||
>
|
||||
{item.title === "Services" && servicesLoading ? (
|
||||
<li>
|
||||
<span className="text-muted">Loading services...</span>
|
||||
|
||||
Reference in New Issue
Block a user