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
This commit is contained in:
@@ -10,11 +10,12 @@ interface NavbarProps {
|
||||
const Navbar: React.FC<NavbarProps> = ({ transparent = false }) => {
|
||||
const [isScrolled, setIsScrolled] = useState(false);
|
||||
const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false);
|
||||
const [isMobileServicesMenuOpen, setIsMobileServicesMenuOpen] = useState(false);
|
||||
const [isMobileLabMenuOpen, setIsMobileLabMenuOpen] = 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);
|
||||
@@ -24,7 +25,7 @@ const Navbar: React.FC<NavbarProps> = ({ transparent = false }) => {
|
||||
return () => window.removeEventListener('scroll', handleScroll);
|
||||
}, []);
|
||||
|
||||
const isHome = location.pathname === '/';
|
||||
const isHome = location.pathname === '/' || location.pathname === '/en';
|
||||
// Use transparent background only on Home and when not scrolled, if requested
|
||||
const isTransparent = transparent && isHome && !isScrolled;
|
||||
|
||||
@@ -37,7 +38,7 @@ const Navbar: React.FC<NavbarProps> = ({ transparent = false }) => {
|
||||
<div className="container mx-auto px-6 flex items-center justify-between text-white">
|
||||
|
||||
{/* Logo */}
|
||||
<Link to="/" className="flex items-center gap-2 group">
|
||||
<Link to={isEnglish ? '/en' : '/'} className="flex items-center gap-2 group">
|
||||
{!imgError ? (
|
||||
<img
|
||||
src="/media/geo-logo.webp"
|
||||
@@ -57,177 +58,105 @@ const Navbar: React.FC<NavbarProps> = ({ transparent = false }) => {
|
||||
{/* Главная */}
|
||||
<li>
|
||||
<Link
|
||||
to="/"
|
||||
to={isEnglish ? '/en' : '/'}
|
||||
className={`transition-colors hover:text-brand-orange ${
|
||||
location.pathname === '/' ? 'text-brand-orange' : 'text-gray-300'
|
||||
(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="/about"
|
||||
to={`${prefix}/about`}
|
||||
className={`transition-colors hover:text-brand-orange ${
|
||||
location.pathname === '/about' ? 'text-brand-orange' : 'text-gray-300'
|
||||
location.pathname.replace('/en', '') === '/about'
|
||||
? 'text-brand-orange'
|
||||
: 'text-gray-300'
|
||||
}`}
|
||||
>
|
||||
О компании
|
||||
{isEnglish ? 'About' : 'О компании'}
|
||||
</Link>
|
||||
</li>
|
||||
|
||||
{/* Услуги с выпадающим меню */}
|
||||
<li className="relative group">
|
||||
<button
|
||||
className={`flex items-center gap-1 transition-colors hover:text-brand-orange ${
|
||||
location.pathname.startsWith('/services') ? 'text-brand-orange' : 'text-gray-300'
|
||||
}`}
|
||||
>
|
||||
Услуги
|
||||
<ChevronDown size={16} className={`transition-transform group-hover:rotate-180`} />
|
||||
</button>
|
||||
|
||||
{/* Выпадающее меню */}
|
||||
<div className="absolute top-full left-0 pt-2 opacity-0 invisible group-hover:opacity-100 group-hover:visible transition-all duration-200">
|
||||
<div className="w-72 bg-brand-dark border border-gray-700 rounded-lg shadow-xl overflow-hidden">
|
||||
<Link
|
||||
to="/services"
|
||||
className="block px-6 py-3 text-gray-300 hover:bg-brand-orange hover:text-white transition-colors font-semibold border-b border-gray-700"
|
||||
>
|
||||
Все услуги
|
||||
</Link>
|
||||
<Link
|
||||
to="/services/surveying"
|
||||
className="block px-6 py-3 text-gray-300 hover:bg-brand-orange hover:text-white transition-colors"
|
||||
>
|
||||
Инженерные изыскания
|
||||
</Link>
|
||||
<Link
|
||||
to="/services/design"
|
||||
className="block px-6 py-3 text-gray-300 hover:bg-brand-orange hover:text-white transition-colors"
|
||||
>
|
||||
Проектирование
|
||||
</Link>
|
||||
<Link
|
||||
to="/services/construction"
|
||||
className="block px-6 py-3 text-gray-300 hover:bg-brand-orange hover:text-white transition-colors"
|
||||
>
|
||||
Строительство
|
||||
</Link>
|
||||
<Link
|
||||
to="/services/soil-survey"
|
||||
className="block px-6 py-3 text-gray-300 hover:bg-brand-orange hover:text-white transition-colors"
|
||||
>
|
||||
Обследование грунтов
|
||||
</Link>
|
||||
<Link
|
||||
to="/services/building-survey"
|
||||
className="block px-6 py-3 text-gray-300 hover:bg-brand-orange hover:text-white transition-colors"
|
||||
>
|
||||
Обследование здания
|
||||
</Link>
|
||||
<Link
|
||||
to="/services/land-survey"
|
||||
className="block px-6 py-3 text-gray-300 hover:bg-brand-orange hover:text-white transition-colors"
|
||||
>
|
||||
Кадастровые работы
|
||||
</Link>
|
||||
<Link
|
||||
to="/services/technical-tasks"
|
||||
className="block px-6 py-3 text-gray-300 hover:bg-brand-orange hover:text-white transition-colors border-t border-gray-700"
|
||||
>
|
||||
Образцы технических заданий
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
{/* Проекты */}
|
||||
<li>
|
||||
<Link
|
||||
to="/projects"
|
||||
className={`transition-colors hover:text-brand-orange ${
|
||||
location.pathname === '/projects' ? 'text-brand-orange' : 'text-gray-300'
|
||||
}`}
|
||||
>
|
||||
Проекты
|
||||
</Link>
|
||||
</li>
|
||||
|
||||
{/* Автопарк */}
|
||||
<li>
|
||||
<Link
|
||||
to="/fleet"
|
||||
className={`transition-colors hover:text-brand-orange ${
|
||||
location.pathname === '/fleet' ? 'text-brand-orange' : 'text-gray-300'
|
||||
}`}
|
||||
>
|
||||
Автопарк
|
||||
</Link>
|
||||
</li>
|
||||
|
||||
{/* Сертификаты */}
|
||||
<li>
|
||||
<Link
|
||||
to="/certificates"
|
||||
className={`transition-colors hover:text-brand-orange ${
|
||||
location.pathname === '/certificates' ? 'text-brand-orange' : 'text-gray-300'
|
||||
}`}
|
||||
>
|
||||
Сертификаты
|
||||
</Link>
|
||||
</li>
|
||||
|
||||
{/* Лаборатории с выпадающим меню */}
|
||||
<li className="relative group">
|
||||
<button
|
||||
className={`flex items-center gap-1 transition-colors hover:text-brand-orange ${
|
||||
location.pathname.startsWith('/laboratories') ? 'text-brand-orange' : 'text-gray-300'
|
||||
}`}
|
||||
>
|
||||
Лаборатории
|
||||
<ChevronDown size={16} className={`transition-transform group-hover:rotate-180`} />
|
||||
</button>
|
||||
|
||||
{/* Выпадающее меню */}
|
||||
<div className="absolute top-full left-0 pt-2 opacity-0 invisible group-hover:opacity-100 group-hover:visible transition-all duration-200">
|
||||
<div className="w-64 bg-brand-dark border border-gray-700 rounded-lg shadow-xl overflow-hidden">
|
||||
<Link
|
||||
to="/laboratories/soil"
|
||||
className="block px-6 py-3 text-gray-300 hover:bg-brand-orange hover:text-white transition-colors"
|
||||
>
|
||||
Грунтовая лаборатория
|
||||
</Link>
|
||||
<Link
|
||||
to="/laboratories/radiation"
|
||||
className="block px-6 py-3 text-gray-300 hover:bg-brand-orange hover:text-white transition-colors"
|
||||
>
|
||||
Радиационная лаборатория
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
{/* Контакты */}
|
||||
<li>
|
||||
<Link
|
||||
to="/contacts"
|
||||
to={`${prefix}/contacts`}
|
||||
className={`transition-colors hover:text-brand-orange ${
|
||||
location.pathname === '/contacts' ? 'text-brand-orange' : 'text-gray-300'
|
||||
location.pathname.replace('/en', '') === '/contacts'
|
||||
? 'text-brand-orange'
|
||||
: 'text-gray-300'
|
||||
}`}
|
||||
>
|
||||
Контакты
|
||||
{isEnglish ? 'Contacts' : 'Контакты'}
|
||||
</Link>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
{/* CTA & Mobile Toggle */}
|
||||
{/* Language switcher, CTA & Mobile Toggle */}
|
||||
<div className="flex items-center gap-4">
|
||||
<Link to="/contacts" className="hidden md:flex items-center gap-2 text-sm font-medium hover:text-brand-orange transition-colors">
|
||||
{/* Языковой переключатель */}
|
||||
<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>Связаться</span>
|
||||
<span>{isEnglish ? 'Contact us' : 'Связаться'}</span>
|
||||
</Link>
|
||||
|
||||
<button
|
||||
@@ -244,166 +173,86 @@ const Navbar: React.FC<NavbarProps> = ({ transparent = false }) => {
|
||||
<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="/"
|
||||
to={isEnglish ? '/en' : '/'}
|
||||
className="text-lg font-medium text-gray-300 hover:text-brand-orange"
|
||||
onClick={() => setIsMobileMenuOpen(false)}
|
||||
>
|
||||
Главная
|
||||
{isEnglish ? 'Home' : 'Главная'}
|
||||
</Link>
|
||||
|
||||
{/* О компании */}
|
||||
<Link
|
||||
to="/about"
|
||||
to={`${prefix}/about`}
|
||||
className="text-lg font-medium text-gray-300 hover:text-brand-orange"
|
||||
onClick={() => setIsMobileMenuOpen(false)}
|
||||
>
|
||||
О компании
|
||||
{isEnglish ? 'About' : 'О компании'}
|
||||
</Link>
|
||||
|
||||
{/* Услуги в мобильном меню */}
|
||||
<div>
|
||||
<button
|
||||
className="flex items-center justify-between w-full text-lg font-medium text-gray-300 hover:text-brand-orange"
|
||||
onClick={() => setIsMobileServicesMenuOpen(!isMobileServicesMenuOpen)}
|
||||
>
|
||||
Услуги
|
||||
<ChevronDown size={20} className={`transition-transform ${isMobileServicesMenuOpen ? 'rotate-180' : ''}`} />
|
||||
</button>
|
||||
|
||||
{isMobileServicesMenuOpen && (
|
||||
<div className="ml-4 mt-3 flex flex-col gap-3">
|
||||
<Link
|
||||
to="/services"
|
||||
className="text-gray-400 hover:text-brand-orange font-semibold"
|
||||
onClick={() => setIsMobileMenuOpen(false)}
|
||||
>
|
||||
Все услуги
|
||||
</Link>
|
||||
<Link
|
||||
to="/services/surveying"
|
||||
className="text-gray-400 hover:text-brand-orange"
|
||||
onClick={() => setIsMobileMenuOpen(false)}
|
||||
>
|
||||
Инженерные изыскания
|
||||
</Link>
|
||||
<Link
|
||||
to="/services/design"
|
||||
className="text-gray-400 hover:text-brand-orange"
|
||||
onClick={() => setIsMobileMenuOpen(false)}
|
||||
>
|
||||
Проектирование
|
||||
</Link>
|
||||
<Link
|
||||
to="/services/construction"
|
||||
className="text-gray-400 hover:text-brand-orange"
|
||||
onClick={() => setIsMobileMenuOpen(false)}
|
||||
>
|
||||
Строительство
|
||||
</Link>
|
||||
<Link
|
||||
to="/services/soil-survey"
|
||||
className="text-gray-400 hover:text-brand-orange"
|
||||
onClick={() => setIsMobileMenuOpen(false)}
|
||||
>
|
||||
Обследование грунтов
|
||||
</Link>
|
||||
<Link
|
||||
to="/services/building-survey"
|
||||
className="text-gray-400 hover:text-brand-orange"
|
||||
onClick={() => setIsMobileMenuOpen(false)}
|
||||
>
|
||||
Обследование здания
|
||||
</Link>
|
||||
<Link
|
||||
to="/services/land-survey"
|
||||
className="text-gray-400 hover:text-brand-orange"
|
||||
onClick={() => setIsMobileMenuOpen(false)}
|
||||
>
|
||||
Кадастровые работы
|
||||
</Link>
|
||||
<Link
|
||||
to="/services/technical-tasks"
|
||||
className="text-gray-400 hover:text-brand-orange"
|
||||
onClick={() => setIsMobileMenuOpen(false)}
|
||||
>
|
||||
Образцы ТЗ
|
||||
</Link>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<Link
|
||||
to={`${prefix}/services`}
|
||||
className="text-lg font-medium text-gray-300 hover:text-brand-orange"
|
||||
onClick={() => setIsMobileMenuOpen(false)}
|
||||
>
|
||||
{isEnglish ? 'Services' : 'Услуги'}
|
||||
</Link>
|
||||
|
||||
{/* Проекты */}
|
||||
<Link
|
||||
to="/projects"
|
||||
to={`${prefix}/projects`}
|
||||
className="text-lg font-medium text-gray-300 hover:text-brand-orange"
|
||||
onClick={() => setIsMobileMenuOpen(false)}
|
||||
>
|
||||
Проекты
|
||||
{isEnglish ? 'Projects' : 'Проекты'}
|
||||
</Link>
|
||||
|
||||
{/* Автопарк */}
|
||||
<Link
|
||||
to="/fleet"
|
||||
className="text-lg font-medium text-gray-300 hover:text-brand-orange"
|
||||
onClick={() => setIsMobileMenuOpen(false)}
|
||||
>
|
||||
Автопарк
|
||||
</Link>
|
||||
|
||||
{/* Сертификаты */}
|
||||
<Link
|
||||
to="/certificates"
|
||||
className="text-lg font-medium text-gray-300 hover:text-brand-orange"
|
||||
onClick={() => setIsMobileMenuOpen(false)}
|
||||
>
|
||||
Сертификаты
|
||||
</Link>
|
||||
|
||||
{/* Лаборатории в мобильном меню */}
|
||||
<div>
|
||||
<button
|
||||
className="flex items-center justify-between w-full text-lg font-medium text-gray-300 hover:text-brand-orange"
|
||||
onClick={() => setIsMobileLabMenuOpen(!isMobileLabMenuOpen)}
|
||||
>
|
||||
Лаборатории
|
||||
<ChevronDown size={20} className={`transition-transform ${isMobileLabMenuOpen ? 'rotate-180' : ''}`} />
|
||||
</button>
|
||||
|
||||
{isMobileLabMenuOpen && (
|
||||
<div className="ml-4 mt-3 flex flex-col gap-3">
|
||||
<Link
|
||||
to="/laboratories/soil"
|
||||
className="text-gray-400 hover:text-brand-orange"
|
||||
onClick={() => setIsMobileMenuOpen(false)}
|
||||
>
|
||||
Грунтовая лаборатория
|
||||
</Link>
|
||||
<Link
|
||||
to="/laboratories/radiation"
|
||||
className="text-gray-400 hover:text-brand-orange"
|
||||
onClick={() => setIsMobileMenuOpen(false)}
|
||||
>
|
||||
Радиационная лаборатория
|
||||
</Link>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
{/* Автопарк, сертификаты и лаборатории убраны из основного мобильного меню */}
|
||||
|
||||
{/* Контакты */}
|
||||
<Link
|
||||
to="/contacts"
|
||||
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="/contacts"
|
||||
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" /> Связаться
|
||||
<Phone className="w-5 h-5" /> {isEnglish ? 'Contact us' : 'Связаться'}
|
||||
</Link>
|
||||
</div>
|
||||
)}
|
||||
|
||||
Reference in New Issue
Block a user