This commit is contained in:
Iliyan Angelov
2025-11-24 16:47:37 +02:00
parent d7ff5c71e6
commit 0b1cabcfaf
45 changed files with 2021 additions and 28 deletions

View File

@@ -41,7 +41,7 @@ const BlogSingle = () => {
</div>
<h2 className="text-secondary mb-3">Insight Not Found</h2>
<p className="text-tertiary mb-4">
The insight you're looking for doesn't exist or has been removed.
The insight you&apos;re looking for doesn&apos;t exist or has been removed.
</p>
<Link href="/insights" className="btn btn-primary">
<i className="fa-solid fa-arrow-left me-2"></i>

View File

@@ -1,6 +1,7 @@
"use client";
import { useState, useEffect } from "react";
import Link from "next/link";
import { JobPosition } from "@/lib/api/careerService";
import JobApplicationForm from "./JobApplicationForm";
@@ -529,7 +530,7 @@ const JobSingle = ({ job }: JobSingleProps) => {
<span className="d-sm-none">~5 min</span>
</p>
<a
<Link
href="/career"
className="btn w-100 mt-12 mt-md-16"
style={{
@@ -560,7 +561,7 @@ const JobSingle = ({ job }: JobSingleProps) => {
<span className="material-symbols-outlined" style={{ fontSize: 'clamp(16px, 3vw, 18px)' }}>arrow_back</span>
<span className="d-none d-sm-inline">Back to Career Page</span>
<span className="d-sm-none">Back</span>
</a>
</Link>
</div>
</div>
</div>

View File

@@ -67,7 +67,7 @@ const CaseSingle = ({ slug }: CaseSingleProps) => {
<div className="col-12">
<div className="error-state">
<h2>Case Study Not Found</h2>
<p>The case study you're looking for doesn't exist or has been removed.</p>
<p>The case study you&apos;re looking for doesn&apos;t exist or has been removed.</p>
<Link href="/case-study" className="btn btn-primary">
View All Case Studies
</Link>

View File

@@ -203,7 +203,7 @@ const CreateTicketForm = ({ onOpenStatusCheck }: CreateTicketFormProps) => {
</button>
</div>
<p className="ticket-info">
We've received your support request and will respond as soon as possible.
We&apos;ve received your support request and will respond as soon as possible.
Please save your ticket number for future reference.
</p>
<div className="success-actions">

View File

@@ -236,7 +236,7 @@ const KnowledgeBase = () => {
</div>
{searchTerm && (
<p className="search-info">
Found {displayArticles.length} {displayArticles.length === 1 ? 'article' : 'articles'} for "{searchTerm}"
Found {displayArticles.length} {displayArticles.length === 1 ? 'article' : 'articles'} for &quot;{searchTerm}&quot;
</p>
)}
</div>

View File

@@ -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>

View File

@@ -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>