Files
geovektor/components/Navbar.tsx
Arsen Akhmetzyanov fde9609f9a feat: simplify navigation and add RU/EN home and contacts
- simplify main navigation and hide extra menu items
- make home page more sales-focused with updated hero, benefits and fleet teaser
- add RU/EN handling for home and contacts, including SEO defaults
- integrate basic Strapi homepage API client (no breaking changes)
- update contacts page with messenger buttons and dynamic footer year

Made-with: Cursor
2026-03-13 19:41:07 +05:00

263 lines
9.9 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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();
const isEnglish = location.pathname.startsWith('/en');
const prefix = isEnglish ? '/en' : '';
useEffect(() => {
const handleScroll = () => {
setIsScrolled(window.scrollY > 50);
};
window.addEventListener('scroll', handleScroll);
return () => window.removeEventListener('scroll', handleScroll);
}, []);
const isHome = location.pathname === '/' || location.pathname === '/en';
// 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 */}
<Link to={isEnglish ? '/en' : '/'} className="flex items-center gap-2 group">
{!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
to={isEnglish ? '/en' : '/'}
className={`transition-colors hover:text-brand-orange ${
(location.pathname === '/' || location.pathname === '/en')
? 'text-brand-orange'
: 'text-gray-300'
}`}
>
{isEnglish ? 'Home' : 'Главная'}
</Link>
</li>
{/* Услуги */}
<li>
<Link
to={`${prefix}/services`}
className={`transition-colors hover:text-brand-orange ${
location.pathname.replace('/en', '').startsWith('/services')
? 'text-brand-orange'
: 'text-gray-300'
}`}
>
{isEnglish ? 'Services' : 'Услуги'}
</Link>
</li>
{/* Проекты */}
<li>
<Link
to={`${prefix}/projects`}
className={`transition-colors hover:text-brand-orange ${
location.pathname.replace('/en', '') === '/projects'
? 'text-brand-orange'
: 'text-gray-300'
}`}
>
{isEnglish ? 'Projects' : 'Проекты'}
</Link>
</li>
{/* О компании */}
<li>
<Link
to={`${prefix}/about`}
className={`transition-colors hover:text-brand-orange ${
location.pathname.replace('/en', '') === '/about'
? 'text-brand-orange'
: 'text-gray-300'
}`}
>
{isEnglish ? 'About' : 'О компании'}
</Link>
</li>
{/* Контакты */}
<li>
<Link
to={`${prefix}/contacts`}
className={`transition-colors hover:text-brand-orange ${
location.pathname.replace('/en', '') === '/contacts'
? 'text-brand-orange'
: 'text-gray-300'
}`}
>
{isEnglish ? 'Contacts' : 'Контакты'}
</Link>
</li>
</ul>
{/* Language switcher, CTA & Mobile Toggle */}
<div className="flex items-center gap-4">
{/* Языковой переключатель */}
<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">
<Phone className="w-4 h-4 text-brand-orange" />
<span>{isEnglish ? 'Contact us' : 'Связаться'}</span>
</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
to={isEnglish ? '/en' : '/'}
className="text-lg font-medium text-gray-300 hover:text-brand-orange"
onClick={() => setIsMobileMenuOpen(false)}
>
{isEnglish ? 'Home' : 'Главная'}
</Link>
{/* О компании */}
<Link
to={`${prefix}/about`}
className="text-lg font-medium text-gray-300 hover:text-brand-orange"
onClick={() => setIsMobileMenuOpen(false)}
>
{isEnglish ? 'About' : 'О компании'}
</Link>
{/* Услуги в мобильном меню */}
<Link
to={`${prefix}/services`}
className="text-lg font-medium text-gray-300 hover:text-brand-orange"
onClick={() => setIsMobileMenuOpen(false)}
>
{isEnglish ? 'Services' : 'Услуги'}
</Link>
{/* Проекты */}
<Link
to={`${prefix}/projects`}
className="text-lg font-medium text-gray-300 hover:text-brand-orange"
onClick={() => setIsMobileMenuOpen(false)}
>
{isEnglish ? 'Projects' : 'Проекты'}
</Link>
{/* Автопарк, сертификаты и лаборатории убраны из основного мобильного меню */}
{/* Контакты */}
<Link
to={`${prefix}/contacts`}
className="text-lg font-medium text-gray-300 hover:text-brand-orange"
onClick={() => setIsMobileMenuOpen(false)}
>
{isEnglish ? 'Contacts' : 'Контакты'}
</Link>
{/* Языковой переключатель (мобильный) */}
<div className="flex items-center gap-2 text-sm font-medium text-gray-300 pt-4 border-t border-gray-800">
<button
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'}
>
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
</button>
</div>
<Link
to={`${prefix}/contacts`}
className="flex items-center gap-2 text-brand-orange font-bold mt-4"
onClick={() => setIsMobileMenuOpen(false)}
>
<Phone className="w-5 h-5" /> {isEnglish ? 'Contact us' : 'Связаться'}
</Link>
</div>
)}
</nav>
);
};
export default Navbar;