2026-02-10 16:22:14 +05:00
|
|
|
|
import React, { useState, useEffect } from 'react';
|
|
|
|
|
|
import { Phone, Menu, X, ChevronDown } from 'lucide-react';
|
|
|
|
|
|
import { Link, useLocation } from 'react-router-dom';
|
|
|
|
|
|
import { NAV_LINKS } from '../constants';
|
|
|
|
|
|
|
|
|
|
|
|
interface NavbarProps {
|
|
|
|
|
|
transparent?: boolean;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const Navbar: React.FC<NavbarProps> = ({ transparent = false }) => {
|
|
|
|
|
|
const [isScrolled, setIsScrolled] = useState(false);
|
|
|
|
|
|
const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false);
|
|
|
|
|
|
const [imgError, setImgError] = useState(false);
|
|
|
|
|
|
const location = useLocation();
|
|
|
|
|
|
|
2026-03-13 19:41:07 +05:00
|
|
|
|
const isEnglish = location.pathname.startsWith('/en');
|
|
|
|
|
|
const prefix = isEnglish ? '/en' : '';
|
|
|
|
|
|
|
2026-02-10 16:22:14 +05:00
|
|
|
|
useEffect(() => {
|
|
|
|
|
|
const handleScroll = () => {
|
|
|
|
|
|
setIsScrolled(window.scrollY > 50);
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
window.addEventListener('scroll', handleScroll);
|
|
|
|
|
|
return () => window.removeEventListener('scroll', handleScroll);
|
|
|
|
|
|
}, []);
|
|
|
|
|
|
|
2026-03-13 19:41:07 +05:00
|
|
|
|
const isHome = location.pathname === '/' || location.pathname === '/en';
|
2026-02-10 16:22:14 +05:00
|
|
|
|
// Use transparent background only on Home and when not scrolled, if requested
|
|
|
|
|
|
const isTransparent = transparent && isHome && !isScrolled;
|
|
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
|
<nav
|
|
|
|
|
|
className={`fixed top-0 left-0 right-0 z-50 transition-all duration-300 ${
|
|
|
|
|
|
isTransparent ? 'bg-transparent py-6' : 'bg-brand-dark/95 backdrop-blur-md py-4 shadow-lg'
|
|
|
|
|
|
}`}
|
|
|
|
|
|
>
|
|
|
|
|
|
<div className="container mx-auto px-6 flex items-center justify-between text-white">
|
|
|
|
|
|
|
|
|
|
|
|
{/* Logo */}
|
2026-03-13 19:41:07 +05:00
|
|
|
|
<Link to={isEnglish ? '/en' : '/'} className="flex items-center gap-2 group">
|
2026-02-10 16:22:14 +05:00
|
|
|
|
{!imgError ? (
|
|
|
|
|
|
<img
|
|
|
|
|
|
src="/media/geo-logo.webp"
|
|
|
|
|
|
alt="ГеоВектор"
|
|
|
|
|
|
className="h-[64px] w-auto object-contain"
|
|
|
|
|
|
onError={() => setImgError(true)}
|
|
|
|
|
|
/>
|
|
|
|
|
|
) : (
|
|
|
|
|
|
<span className="text-xl font-bold tracking-tighter">
|
|
|
|
|
|
ГЕО<span className="text-brand-orange">ВЕКТОР</span>
|
|
|
|
|
|
</span>
|
|
|
|
|
|
)}
|
|
|
|
|
|
</Link>
|
|
|
|
|
|
|
|
|
|
|
|
{/* Desktop Menu */}
|
|
|
|
|
|
<ul className="hidden md:flex gap-8 text-sm font-medium items-center">
|
|
|
|
|
|
{/* Главная */}
|
|
|
|
|
|
<li>
|
|
|
|
|
|
<Link
|
2026-03-13 19:41:07 +05:00
|
|
|
|
to={isEnglish ? '/en' : '/'}
|
2026-02-10 16:22:14 +05:00
|
|
|
|
className={`transition-colors hover:text-brand-orange ${
|
2026-03-13 19:41:07 +05:00
|
|
|
|
(location.pathname === '/' || location.pathname === '/en')
|
|
|
|
|
|
? 'text-brand-orange'
|
|
|
|
|
|
: 'text-gray-300'
|
2026-02-10 16:22:14 +05:00
|
|
|
|
}`}
|
|
|
|
|
|
>
|
2026-03-13 19:41:07 +05:00
|
|
|
|
{isEnglish ? 'Home' : 'Главная'}
|
2026-02-10 16:22:14 +05:00
|
|
|
|
</Link>
|
|
|
|
|
|
</li>
|
2026-03-13 19:41:07 +05:00
|
|
|
|
|
|
|
|
|
|
{/* Услуги */}
|
2026-02-10 16:22:14 +05:00
|
|
|
|
<li>
|
|
|
|
|
|
<Link
|
2026-03-13 19:41:07 +05:00
|
|
|
|
to={`${prefix}/services`}
|
2026-02-10 16:22:14 +05:00
|
|
|
|
className={`transition-colors hover:text-brand-orange ${
|
2026-03-13 19:41:07 +05:00
|
|
|
|
location.pathname.replace('/en', '').startsWith('/services')
|
|
|
|
|
|
? 'text-brand-orange'
|
|
|
|
|
|
: 'text-gray-300'
|
2026-02-10 16:22:14 +05:00
|
|
|
|
}`}
|
|
|
|
|
|
>
|
2026-03-13 19:41:07 +05:00
|
|
|
|
{isEnglish ? 'Services' : 'Услуги'}
|
2026-02-10 16:22:14 +05:00
|
|
|
|
</Link>
|
|
|
|
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
{/* Проекты */}
|
|
|
|
|
|
<li>
|
|
|
|
|
|
<Link
|
2026-03-13 19:41:07 +05:00
|
|
|
|
to={`${prefix}/projects`}
|
2026-02-10 16:22:14 +05:00
|
|
|
|
className={`transition-colors hover:text-brand-orange ${
|
2026-03-13 19:41:07 +05:00
|
|
|
|
location.pathname.replace('/en', '') === '/projects'
|
|
|
|
|
|
? 'text-brand-orange'
|
|
|
|
|
|
: 'text-gray-300'
|
2026-02-10 16:22:14 +05:00
|
|
|
|
}`}
|
|
|
|
|
|
>
|
2026-03-13 19:41:07 +05:00
|
|
|
|
{isEnglish ? 'Projects' : 'Проекты'}
|
2026-02-10 16:22:14 +05:00
|
|
|
|
</Link>
|
|
|
|
|
|
</li>
|
|
|
|
|
|
|
2026-03-13 19:41:07 +05:00
|
|
|
|
{/* О компании */}
|
2026-02-10 16:22:14 +05:00
|
|
|
|
<li>
|
|
|
|
|
|
<Link
|
2026-03-13 19:41:07 +05:00
|
|
|
|
to={`${prefix}/about`}
|
2026-02-10 16:22:14 +05:00
|
|
|
|
className={`transition-colors hover:text-brand-orange ${
|
2026-03-13 19:41:07 +05:00
|
|
|
|
location.pathname.replace('/en', '') === '/about'
|
|
|
|
|
|
? 'text-brand-orange'
|
|
|
|
|
|
: 'text-gray-300'
|
2026-02-10 16:22:14 +05:00
|
|
|
|
}`}
|
|
|
|
|
|
>
|
2026-03-13 19:41:07 +05:00
|
|
|
|
{isEnglish ? 'About' : 'О компании'}
|
2026-02-10 16:22:14 +05:00
|
|
|
|
</Link>
|
|
|
|
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
{/* Контакты */}
|
|
|
|
|
|
<li>
|
|
|
|
|
|
<Link
|
2026-03-13 19:41:07 +05:00
|
|
|
|
to={`${prefix}/contacts`}
|
2026-02-10 16:22:14 +05:00
|
|
|
|
className={`transition-colors hover:text-brand-orange ${
|
2026-03-13 19:41:07 +05:00
|
|
|
|
location.pathname.replace('/en', '') === '/contacts'
|
|
|
|
|
|
? 'text-brand-orange'
|
|
|
|
|
|
: 'text-gray-300'
|
2026-02-10 16:22:14 +05:00
|
|
|
|
}`}
|
|
|
|
|
|
>
|
2026-03-13 19:41:07 +05:00
|
|
|
|
{isEnglish ? 'Contacts' : 'Контакты'}
|
2026-02-10 16:22:14 +05:00
|
|
|
|
</Link>
|
|
|
|
|
|
</li>
|
|
|
|
|
|
</ul>
|
|
|
|
|
|
|
2026-03-13 19:41:07 +05:00
|
|
|
|
{/* Language switcher, CTA & Mobile Toggle */}
|
2026-02-10 16:22:14 +05:00
|
|
|
|
<div className="flex items-center gap-4">
|
2026-03-13 19:41:07 +05:00
|
|
|
|
{/* Языковой переключатель */}
|
|
|
|
|
|
<div className="hidden md:flex items-center gap-1 text-sm font-medium">
|
|
|
|
|
|
<button
|
|
|
|
|
|
onClick={() => {
|
|
|
|
|
|
if (location.pathname.startsWith('/en')) {
|
|
|
|
|
|
const ruPath = location.pathname.replace('/en', '') || '/';
|
|
|
|
|
|
window.location.hash = `#${ruPath}`;
|
|
|
|
|
|
}
|
|
|
|
|
|
}}
|
|
|
|
|
|
className={location.pathname.startsWith('/en') ? 'text-gray-400 hover:text-white transition-colors' : 'text-white font-semibold'}
|
|
|
|
|
|
>
|
|
|
|
|
|
RU
|
|
|
|
|
|
</button>
|
|
|
|
|
|
<span className="text-gray-500">/</span>
|
|
|
|
|
|
<button
|
|
|
|
|
|
onClick={() => {
|
|
|
|
|
|
if (!location.pathname.startsWith('/en')) {
|
|
|
|
|
|
const basePath = location.pathname === '/' ? '' : location.pathname;
|
|
|
|
|
|
window.location.hash = `#/en${basePath}`;
|
|
|
|
|
|
}
|
|
|
|
|
|
}}
|
|
|
|
|
|
className={location.pathname.startsWith('/en') ? 'text-white font-semibold' : 'text-gray-400 hover:text-white transition-colors'}
|
|
|
|
|
|
>
|
|
|
|
|
|
EN
|
|
|
|
|
|
</button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<Link to={`${prefix}/contacts`} className="hidden md:flex items-center gap-2 text-sm font-medium hover:text-brand-orange transition-colors">
|
2026-02-10 16:22:14 +05:00
|
|
|
|
<Phone className="w-4 h-4 text-brand-orange" />
|
2026-03-13 19:41:07 +05:00
|
|
|
|
<span>{isEnglish ? 'Contact us' : 'Связаться'}</span>
|
2026-02-10 16:22:14 +05:00
|
|
|
|
</Link>
|
|
|
|
|
|
|
|
|
|
|
|
<button
|
|
|
|
|
|
className="md:hidden text-white"
|
|
|
|
|
|
onClick={() => setIsMobileMenuOpen(!isMobileMenuOpen)}
|
|
|
|
|
|
>
|
|
|
|
|
|
{isMobileMenuOpen ? <X /> : <Menu />}
|
|
|
|
|
|
</button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
{/* Mobile Menu */}
|
|
|
|
|
|
{isMobileMenuOpen && (
|
|
|
|
|
|
<div className="absolute top-full left-0 w-full bg-brand-dark border-t border-gray-800 p-6 flex flex-col gap-6 md:hidden shadow-xl">
|
|
|
|
|
|
{/* Главная */}
|
|
|
|
|
|
<Link
|
2026-03-13 19:41:07 +05:00
|
|
|
|
to={isEnglish ? '/en' : '/'}
|
2026-02-10 16:22:14 +05:00
|
|
|
|
className="text-lg font-medium text-gray-300 hover:text-brand-orange"
|
|
|
|
|
|
onClick={() => setIsMobileMenuOpen(false)}
|
|
|
|
|
|
>
|
2026-03-13 19:41:07 +05:00
|
|
|
|
{isEnglish ? 'Home' : 'Главная'}
|
2026-02-10 16:22:14 +05:00
|
|
|
|
</Link>
|
|
|
|
|
|
|
|
|
|
|
|
{/* О компании */}
|
|
|
|
|
|
<Link
|
2026-03-13 19:41:07 +05:00
|
|
|
|
to={`${prefix}/about`}
|
2026-02-10 16:22:14 +05:00
|
|
|
|
className="text-lg font-medium text-gray-300 hover:text-brand-orange"
|
|
|
|
|
|
onClick={() => setIsMobileMenuOpen(false)}
|
|
|
|
|
|
>
|
2026-03-13 19:41:07 +05:00
|
|
|
|
{isEnglish ? 'About' : 'О компании'}
|
2026-02-10 16:22:14 +05:00
|
|
|
|
</Link>
|
|
|
|
|
|
|
|
|
|
|
|
{/* Услуги в мобильном меню */}
|
|
|
|
|
|
<Link
|
2026-03-13 19:41:07 +05:00
|
|
|
|
to={`${prefix}/services`}
|
2026-02-10 16:22:14 +05:00
|
|
|
|
className="text-lg font-medium text-gray-300 hover:text-brand-orange"
|
|
|
|
|
|
onClick={() => setIsMobileMenuOpen(false)}
|
|
|
|
|
|
>
|
2026-03-13 19:41:07 +05:00
|
|
|
|
{isEnglish ? 'Services' : 'Услуги'}
|
2026-02-10 16:22:14 +05:00
|
|
|
|
</Link>
|
|
|
|
|
|
|
2026-03-13 19:41:07 +05:00
|
|
|
|
{/* Проекты */}
|
2026-02-10 16:22:14 +05:00
|
|
|
|
<Link
|
2026-03-13 19:41:07 +05:00
|
|
|
|
to={`${prefix}/projects`}
|
2026-02-10 16:22:14 +05:00
|
|
|
|
className="text-lg font-medium text-gray-300 hover:text-brand-orange"
|
|
|
|
|
|
onClick={() => setIsMobileMenuOpen(false)}
|
|
|
|
|
|
>
|
2026-03-13 19:41:07 +05:00
|
|
|
|
{isEnglish ? 'Projects' : 'Проекты'}
|
2026-02-10 16:22:14 +05:00
|
|
|
|
</Link>
|
|
|
|
|
|
|
2026-03-13 19:41:07 +05:00
|
|
|
|
{/* Автопарк, сертификаты и лаборатории убраны из основного мобильного меню */}
|
|
|
|
|
|
|
|
|
|
|
|
{/* Контакты */}
|
2026-02-10 16:22:14 +05:00
|
|
|
|
<Link
|
2026-03-13 19:41:07 +05:00
|
|
|
|
to={`${prefix}/contacts`}
|
2026-02-10 16:22:14 +05:00
|
|
|
|
className="text-lg font-medium text-gray-300 hover:text-brand-orange"
|
|
|
|
|
|
onClick={() => setIsMobileMenuOpen(false)}
|
|
|
|
|
|
>
|
2026-03-13 19:41:07 +05:00
|
|
|
|
{isEnglish ? 'Contacts' : 'Контакты'}
|
2026-02-10 16:22:14 +05:00
|
|
|
|
</Link>
|
|
|
|
|
|
|
2026-03-13 19:41:07 +05:00
|
|
|
|
{/* Языковой переключатель (мобильный) */}
|
|
|
|
|
|
<div className="flex items-center gap-2 text-sm font-medium text-gray-300 pt-4 border-t border-gray-800">
|
2026-02-10 16:22:14 +05:00
|
|
|
|
<button
|
2026-03-13 19:41:07 +05:00
|
|
|
|
onClick={() => {
|
|
|
|
|
|
setIsMobileMenuOpen(false);
|
|
|
|
|
|
if (location.pathname.startsWith('/en')) {
|
|
|
|
|
|
const ruPath = location.pathname.replace('/en', '') || '/';
|
|
|
|
|
|
window.location.hash = `#${ruPath}`;
|
|
|
|
|
|
}
|
|
|
|
|
|
}}
|
|
|
|
|
|
className={location.pathname.startsWith('/en') ? 'text-gray-500' : 'text-white'}
|
2026-02-10 16:22:14 +05:00
|
|
|
|
>
|
2026-03-13 19:41:07 +05:00
|
|
|
|
RU
|
|
|
|
|
|
</button>
|
|
|
|
|
|
<span className="text-gray-500">/</span>
|
|
|
|
|
|
<button
|
|
|
|
|
|
onClick={() => {
|
|
|
|
|
|
setIsMobileMenuOpen(false);
|
|
|
|
|
|
if (!location.pathname.startsWith('/en')) {
|
|
|
|
|
|
const basePath = location.pathname === '/' ? '' : location.pathname;
|
|
|
|
|
|
window.location.hash = `#/en${basePath}`;
|
|
|
|
|
|
}
|
|
|
|
|
|
}}
|
|
|
|
|
|
className={location.pathname.startsWith('/en') ? 'text-white' : 'text-gray-500'}
|
|
|
|
|
|
>
|
|
|
|
|
|
EN
|
2026-02-10 16:22:14 +05:00
|
|
|
|
</button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<Link
|
2026-03-13 19:41:07 +05:00
|
|
|
|
to={`${prefix}/contacts`}
|
2026-02-10 16:22:14 +05:00
|
|
|
|
className="flex items-center gap-2 text-brand-orange font-bold mt-4"
|
|
|
|
|
|
onClick={() => setIsMobileMenuOpen(false)}
|
|
|
|
|
|
>
|
2026-03-13 19:41:07 +05:00
|
|
|
|
<Phone className="w-5 h-5" /> {isEnglish ? 'Contact us' : 'Связаться'}
|
2026-02-10 16:22:14 +05:00
|
|
|
|
</Link>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
)}
|
|
|
|
|
|
</nav>
|
|
|
|
|
|
);
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
export default Navbar;
|