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:
@@ -1,16 +1,46 @@
|
||||
import React from 'react';
|
||||
import { useLocation } from 'react-router-dom';
|
||||
import { BENEFITS } from '../constants';
|
||||
|
||||
const Benefits: React.FC = () => {
|
||||
const location = useLocation();
|
||||
const isEnglish = location.pathname.startsWith('/en');
|
||||
|
||||
const descriptions = BENEFITS.map((item) => {
|
||||
if (!isEnglish) return item.description;
|
||||
switch (item.title) {
|
||||
case 'Надежность':
|
||||
return 'A reliable company ranked among the top 10 in Russia.';
|
||||
case 'Опыт':
|
||||
return 'Experienced engineers with 10+ years of hands-on practice.';
|
||||
case 'Поддержка':
|
||||
return 'Direct communication and support from our specialists 24/7.';
|
||||
case 'Условия':
|
||||
return 'Tailored proposals and flexible terms of cooperation.';
|
||||
default:
|
||||
return item.description;
|
||||
}
|
||||
});
|
||||
|
||||
return (
|
||||
<div className="py-24 bg-white">
|
||||
<div className="container mx-auto px-6">
|
||||
<div className="grid grid-cols-1 lg:grid-cols-12 gap-12">
|
||||
|
||||
<div className="lg:col-span-4">
|
||||
<span className="text-sm text-gray-500 uppercase tracking-widest mb-2 block">Выбирая нас</span>
|
||||
<h2 className="text-4xl font-bold text-gray-900 mb-6">Вы получаете</h2>
|
||||
<p className="text-gray-500 text-sm">Нас выбирают люди</p>
|
||||
<span className="text-sm text-gray-500 uppercase tracking-widest mb-2 block">
|
||||
{isEnglish ? 'WHO WE WORK WITH' : 'Для кого мы работаем'}
|
||||
</span>
|
||||
<h2 className="text-4xl font-bold text-gray-900 mb-6">
|
||||
{isEnglish
|
||||
? 'For business and public sector clients'
|
||||
: 'Для бизнеса и государственных заказчиков'}
|
||||
</h2>
|
||||
<p className="text-gray-500 text-sm">
|
||||
{isEnglish
|
||||
? 'We help developers, industrial companies and public authorities solve complex engineering challenges and take responsibility for the final result.'
|
||||
: 'Мы работаем с девелоперами, промышленными компаниями и государственными организациями, беря на себя сложные инженерные задачи и ответственность за результат.'}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="lg:col-span-8 grid grid-cols-1 md:grid-cols-2 gap-x-12 gap-y-16">
|
||||
@@ -20,7 +50,7 @@ const Benefits: React.FC = () => {
|
||||
<item.icon size={24} />
|
||||
</div>
|
||||
<p className="text-gray-700 leading-relaxed font-medium">
|
||||
{item.description}
|
||||
{descriptions[index]}
|
||||
</p>
|
||||
</div>
|
||||
))}
|
||||
|
||||
59
components/FleetTeaser.tsx
Normal file
59
components/FleetTeaser.tsx
Normal file
@@ -0,0 +1,59 @@
|
||||
import React from 'react';
|
||||
import { Link, useLocation } from 'react-router-dom';
|
||||
|
||||
const FleetTeaser: React.FC = () => {
|
||||
const location = useLocation();
|
||||
const isEnglish = location.pathname.startsWith('/en');
|
||||
const prefix = isEnglish ? '/en' : '';
|
||||
|
||||
return (
|
||||
<section className="py-20 bg-white">
|
||||
<div className="container mx-auto px-6">
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-10 items-center">
|
||||
<div>
|
||||
<h2 className="text-3xl md:text-4xl font-bold text-gray-900 mb-4">
|
||||
{isEnglish ? 'Own vehicle fleet and equipment' : 'Собственный автопарк и техника'}
|
||||
</h2>
|
||||
<p className="text-gray-600 mb-4">
|
||||
{isEnglish
|
||||
? 'We operate drilling rigs, off-road vehicles, special-purpose trucks and auxiliary equipment, allowing us to mobilise quickly and work in challenging conditions.'
|
||||
: 'В нашем распоряжении буровые установки, вездеходы, спецтранспорт и вспомогательная техника, которые позволяют быстро выходить на объект и работать в сложных условиях.'}
|
||||
</p>
|
||||
<p className="text-gray-600 mb-6">
|
||||
{isEnglish
|
||||
? 'This shortens mobilisation time, reduces downtime risks and gives you confidence that the work will be completed on schedule.'
|
||||
: 'Это сокращает сроки мобилизации, снижает риски простоев и даёт вам уверенность в том, что работы будут выполнены в оговоренные сроки.'}
|
||||
</p>
|
||||
<Link
|
||||
to={`${prefix}/fleet`}
|
||||
className="inline-flex items-center px-6 py-3 bg-brand-orange text-white font-bold rounded-lg hover:bg-orange-600 transition-colors"
|
||||
>
|
||||
{isEnglish ? 'View our fleet' : 'Посмотреть автопарк'}
|
||||
</Link>
|
||||
</div>
|
||||
<div className="grid grid-cols-2 gap-4">
|
||||
<div className="rounded-2xl overflow-hidden shadow-lg">
|
||||
<img
|
||||
src="/media/cars/33725959_1920_q70.webp"
|
||||
alt="Техника ГеоВектор"
|
||||
className="w-full h-full object-cover"
|
||||
loading="lazy"
|
||||
/>
|
||||
</div>
|
||||
<div className="rounded-2xl overflow-hidden shadow-lg translate-y-6">
|
||||
<img
|
||||
src="/media/cars/33725970_1920_q70.webp"
|
||||
alt="Спецтранспорт ГеоВектор"
|
||||
className="w-full h-full object-cover"
|
||||
loading="lazy"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
export default FleetTeaser;
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
import React from 'react';
|
||||
import { Send, MapPin, Mail, Phone } from 'lucide-react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { Link, useLocation } from 'react-router-dom';
|
||||
|
||||
const Footer: React.FC = () => {
|
||||
const currentYear = new Date().getFullYear();
|
||||
const location = useLocation();
|
||||
const isEnglish = location.pathname.startsWith('/en');
|
||||
const prefix = isEnglish ? '/en' : '';
|
||||
|
||||
return (
|
||||
<footer className="bg-[#1a0f0f] text-white py-20 rounded-t-[3rem] mt-auto" id="contacts">
|
||||
<div className="container mx-auto px-6">
|
||||
@@ -10,9 +15,13 @@ const Footer: React.FC = () => {
|
||||
|
||||
{/* Contacts Section with Accent */}
|
||||
<div className="lg:w-1/2">
|
||||
<h2 className="text-4xl font-bold mb-8 text-brand-orange">Свяжитесь с нами</h2>
|
||||
<h2 className="text-4xl font-bold mb-8 text-brand-orange">
|
||||
{isEnglish ? 'Get in touch with us' : 'Свяжитесь с нами'}
|
||||
</h2>
|
||||
<p className="text-gray-300 text-lg mb-10 max-w-md">
|
||||
Готовы ответить на ваши вопросы и предложить лучшие решения для вашего проекта
|
||||
{isEnglish
|
||||
? 'We are ready to answer your questions and offer the best solutions for your project.'
|
||||
: 'Готовы ответить на ваши вопросы и предложить лучшие решения для вашего проекта'}
|
||||
</p>
|
||||
|
||||
<div className="space-y-6 max-w-md">
|
||||
@@ -22,9 +31,13 @@ const Footer: React.FC = () => {
|
||||
>
|
||||
<Phone size={28} className="text-brand-orange group-hover:text-white flex-shrink-0" />
|
||||
<div>
|
||||
<p className="text-xs text-gray-400 mb-1 group-hover:text-white/80">Телефон</p>
|
||||
<p className="text-xs text-gray-400 mb-1 group-hover:text-white/80">
|
||||
{isEnglish ? 'Phone' : 'Телефон'}
|
||||
</p>
|
||||
<p className="text-xl font-bold text-white">8 (347) 292 73 70</p>
|
||||
<p className="text-sm text-gray-400 mt-1 group-hover:text-white/70">Звоните с 9:00 до 18:00</p>
|
||||
<p className="text-sm text-gray-400 mt-1 group-hover:text-white/70">
|
||||
{isEnglish ? 'Call us from 9:00 to 18:00' : 'Звоните с 9:00 до 18:00'}
|
||||
</p>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
@@ -36,59 +49,135 @@ const Footer: React.FC = () => {
|
||||
<div>
|
||||
<p className="text-xs text-gray-400 mb-1 group-hover:text-white/80">Email</p>
|
||||
<p className="text-xl font-bold text-white">gw@geowektor.ru</p>
|
||||
<p className="text-sm text-gray-400 mt-1 group-hover:text-white/70">Ответим в течение часа</p>
|
||||
<p className="text-sm text-gray-400 mt-1 group-hover:text-white/70">
|
||||
{isEnglish ? 'We typically respond within one hour' : 'Ответим в течение часа'}
|
||||
</p>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
<div className="flex items-start gap-4 p-6 bg-brand-orange/10 border border-brand-orange/30 rounded-2xl">
|
||||
<MapPin size={28} className="text-brand-orange flex-shrink-0" />
|
||||
<div>
|
||||
<p className="text-xs text-gray-400 mb-1">Адрес</p>
|
||||
<p className="text-lg font-bold text-white">450001, РБ, г. Уфа</p>
|
||||
<p className="text-white/90">ул. Комсомольская 19/1</p>
|
||||
<p className="text-xs text-gray-400 mb-1">
|
||||
{isEnglish ? 'Address' : 'Адрес'}
|
||||
</p>
|
||||
<p className="text-lg font-bold text-white">
|
||||
{isEnglish ? '450001, RB, Ufa' : '450001, РБ, г. Уфа'}
|
||||
</p>
|
||||
<p className="text-white/90">
|
||||
{isEnglish ? '19/1 Komsomolskaya St.' : 'ул. Комсомольская 19/1'}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Links & Social Section */}
|
||||
<div className="lg:w-1/2 grid grid-cols-1 md:grid-cols-3 gap-8">
|
||||
<div className="lg:w-1/2 grid grid-cols-1 md:grid-cols-3 gap-8">
|
||||
{/* Основная навигация */}
|
||||
<div>
|
||||
<h4 className="font-bold mb-6 text-lg">Компания</h4>
|
||||
<h4 className="font-bold mb-6 text-lg">
|
||||
{isEnglish ? 'Company' : 'Компания'}
|
||||
</h4>
|
||||
<ul className="space-y-3 text-sm text-gray-400">
|
||||
<li><Link to="/" className="hover:text-brand-orange transition-colors">Главная</Link></li>
|
||||
<li><Link to="/about" className="hover:text-brand-orange transition-colors">О компании</Link></li>
|
||||
<li><Link to="/projects" className="hover:text-brand-orange transition-colors">Проекты</Link></li>
|
||||
<li><Link to="/fleet" className="hover:text-brand-orange transition-colors">Автопарк</Link></li>
|
||||
<li><Link to="/certificates" className="hover:text-brand-orange transition-colors">Сертификаты</Link></li>
|
||||
<li><Link to="/contacts" className="hover:text-brand-orange transition-colors">Контакты</Link></li>
|
||||
<li>
|
||||
<Link to={isEnglish ? '/en' : '/'} className="hover:text-brand-orange transition-colors">
|
||||
{isEnglish ? 'Home' : 'Главная'}
|
||||
</Link>
|
||||
</li>
|
||||
<li>
|
||||
<Link to={`${prefix}/about`} className="hover:text-brand-orange transition-colors">
|
||||
{isEnglish ? 'About' : 'О компании'}
|
||||
</Link>
|
||||
</li>
|
||||
<li>
|
||||
<Link to={`${prefix}/projects`} className="hover:text-brand-orange transition-colors">
|
||||
{isEnglish ? 'Projects' : 'Проекты'}
|
||||
</Link>
|
||||
</li>
|
||||
<li>
|
||||
<Link to={`${prefix}/fleet`} className="hover:text-brand-orange transition-colors">
|
||||
{isEnglish ? 'Fleet' : 'Автопарк'}
|
||||
</Link>
|
||||
</li>
|
||||
<li>
|
||||
<Link to={`${prefix}/certificates`} className="hover:text-brand-orange transition-colors">
|
||||
{isEnglish ? 'Certificates' : 'Сертификаты'}
|
||||
</Link>
|
||||
</li>
|
||||
<li>
|
||||
<Link to={`${prefix}/contacts`} className="hover:text-brand-orange transition-colors">
|
||||
{isEnglish ? 'Contacts' : 'Контакты'}
|
||||
</Link>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
{/* Услуги */}
|
||||
<div>
|
||||
<h4 className="font-bold mb-6 text-lg">Услуги</h4>
|
||||
<h4 className="font-bold mb-6 text-lg">
|
||||
{isEnglish ? 'Services' : 'Услуги'}
|
||||
</h4>
|
||||
<ul className="space-y-3 text-sm text-gray-400">
|
||||
<li><Link to="/services" className="hover:text-brand-orange transition-colors">Все услуги</Link></li>
|
||||
<li><Link to="/services/surveying" className="hover:text-brand-orange transition-colors">Инженерные изыскания</Link></li>
|
||||
<li><Link to="/services/design" className="hover:text-brand-orange transition-colors">Проектирование</Link></li>
|
||||
<li><Link to="/services/construction" className="hover:text-brand-orange transition-colors">Строительство</Link></li>
|
||||
<li><Link to="/services/soil-survey" className="hover:text-brand-orange transition-colors">Обследование грунтов</Link></li>
|
||||
<li><Link to="/services/building-survey" className="hover:text-brand-orange transition-colors">Обследование зданий</Link></li>
|
||||
<li><Link to="/services/land-survey" className="hover:text-brand-orange transition-colors">Кадастровые работы</Link></li>
|
||||
<li>
|
||||
<Link to={`${prefix}/services`} className="hover:text-brand-orange transition-colors">
|
||||
{isEnglish ? 'All services' : 'Все услуги'}
|
||||
</Link>
|
||||
</li>
|
||||
<li>
|
||||
<Link to={`${prefix}/services/surveying`} className="hover:text-brand-orange transition-colors">
|
||||
{isEnglish ? 'Engineering surveys' : 'Инженерные изыскания'}
|
||||
</Link>
|
||||
</li>
|
||||
<li>
|
||||
<Link to={`${prefix}/services/design`} className="hover:text-brand-orange transition-colors">
|
||||
{isEnglish ? 'Design' : 'Проектирование'}
|
||||
</Link>
|
||||
</li>
|
||||
<li>
|
||||
<Link to={`${prefix}/services/construction`} className="hover:text-brand-orange transition-colors">
|
||||
{isEnglish ? 'Construction' : 'Строительство'}
|
||||
</Link>
|
||||
</li>
|
||||
<li>
|
||||
<Link to={`${prefix}/services/soil-survey`} className="hover:text-brand-orange transition-colors">
|
||||
{isEnglish ? 'Soil investigation' : 'Обследование грунтов'}
|
||||
</Link>
|
||||
</li>
|
||||
<li>
|
||||
<Link to={`${prefix}/services/building-survey`} className="hover:text-brand-orange transition-colors">
|
||||
{isEnglish ? 'Building survey' : 'Обследование зданий'}
|
||||
</Link>
|
||||
</li>
|
||||
<li>
|
||||
<Link to={`${prefix}/services/land-survey`} className="hover:text-brand-orange transition-colors">
|
||||
{isEnglish ? 'Cadastral works' : 'Кадастровые работы'}
|
||||
</Link>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
{/* Лаборатории и соцсети */}
|
||||
<div>
|
||||
<h4 className="font-bold mb-6 text-lg">Лаборатории</h4>
|
||||
<h4 className="font-bold mb-6 text-lg">
|
||||
{isEnglish ? 'Laboratories' : 'Лаборатории'}
|
||||
</h4>
|
||||
<ul className="space-y-3 text-sm text-gray-400 mb-8">
|
||||
<li><Link to="/laboratories/soil" className="hover:text-brand-orange transition-colors">Грунтовая лаборатория</Link></li>
|
||||
<li><Link to="/laboratories/radiation" className="hover:text-brand-orange transition-colors">Радиационная лаборатория</Link></li>
|
||||
<li>
|
||||
<Link to={`${prefix}/laboratories/soil`} className="hover:text-brand-orange transition-colors">
|
||||
{isEnglish ? 'Soil testing laboratory' : 'Грунтовая лаборатория'}
|
||||
</Link>
|
||||
</li>
|
||||
<li>
|
||||
<Link to={`${prefix}/laboratories/radiation`} className="hover:text-brand-orange transition-colors">
|
||||
{isEnglish ? 'Radiation laboratory' : 'Радиационная лаборатория'}
|
||||
</Link>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h4 className="font-bold mb-4 text-lg">Мы в интернете</h4>
|
||||
<h4 className="font-bold mb-4 text-lg">
|
||||
{isEnglish ? 'Find us online' : 'Мы в интернете'}
|
||||
</h4>
|
||||
<div className="flex gap-4 mb-8">
|
||||
<a
|
||||
href="https://t.me/ooo_geo_wektor"
|
||||
@@ -112,16 +201,16 @@ const Footer: React.FC = () => {
|
||||
|
||||
<div className="space-y-3 text-sm">
|
||||
<Link
|
||||
to="/privacy-policy"
|
||||
to={`${prefix}/privacy-policy`}
|
||||
className="text-gray-400 hover:text-brand-orange transition-colors block"
|
||||
>
|
||||
Политика конфиденциальности
|
||||
{isEnglish ? 'Privacy policy' : 'Политика конфиденциальности'}
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
<div className="mt-8 text-xs text-gray-600">
|
||||
©2025 ООО «ГеоВектор».<br />
|
||||
Все права защищены.
|
||||
©{currentYear} ООО «ГеоВектор».<br />
|
||||
{isEnglish ? 'All rights reserved.' : 'Все права защищены.'}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,8 +1,17 @@
|
||||
import React from 'react';
|
||||
import { STATS } from '../constants';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { Link, useLocation } from 'react-router-dom';
|
||||
|
||||
interface HeroProps {
|
||||
title?: string;
|
||||
subtitle?: string;
|
||||
}
|
||||
|
||||
const Hero: React.FC<HeroProps> = ({ title, subtitle }) => {
|
||||
const location = useLocation();
|
||||
const isEnglish = location.pathname.startsWith('/en');
|
||||
const prefix = isEnglish ? '/en' : '';
|
||||
|
||||
const Hero: React.FC = () => {
|
||||
return (
|
||||
<div className="relative w-full min-h-screen bg-brand-dark text-white flex flex-col">
|
||||
{/* Background Image Overlay */}
|
||||
@@ -20,40 +29,62 @@ const Hero: React.FC = () => {
|
||||
<div className="relative z-10 container mx-auto px-6 flex-grow flex flex-col justify-center py-32 md:py-20">
|
||||
<div className="max-w-5xl mx-auto text-center mt-10 md:mt-0">
|
||||
<h1 className="text-4xl md:text-5xl lg:text-7xl font-bold leading-tight mb-8">
|
||||
Инженерные изыскания,
|
||||
<br />
|
||||
<span className="text-brand-orange">проектирование</span> и
|
||||
<br />
|
||||
<span className="text-brand-orange">строительство</span>
|
||||
{title || (
|
||||
<>
|
||||
Инженерные изыскания и проектирование
|
||||
<br />
|
||||
для сложных и ответственных объектов
|
||||
</>
|
||||
)}
|
||||
</h1>
|
||||
<p className="text-gray-300 text-lg md:text-xl mb-12 max-w-3xl mx-auto leading-relaxed">
|
||||
ООО «ГеоВектор» — профессиональные решения для вашего проекта от изысканий до сдачи объекта.
|
||||
Современное оборудование, опытные специалисты и соблюдение всех норм и стандартов.
|
||||
{subtitle || (
|
||||
<>
|
||||
ООО «ГеоВектор» — полный комплекс инженерных изысканий и проектных решений
|
||||
для девелоперов, промышленных предприятий и госзаказчиков в России и других странах.
|
||||
</>
|
||||
)}
|
||||
</p>
|
||||
<div className="flex flex-col sm:flex-row gap-4 justify-center items-center">
|
||||
<Link
|
||||
to="/contacts"
|
||||
to={`${prefix}/contacts`}
|
||||
className="inline-flex items-center justify-center bg-brand-orange text-white font-bold py-4 px-8 rounded-xl hover:bg-orange-600 transition-all duration-300 shadow-lg hover:shadow-xl hover:scale-105"
|
||||
>
|
||||
Рассчитать стоимость проекта
|
||||
{isEnglish ? 'Request a project quote' : 'Рассчитать стоимость проекта'}
|
||||
</Link>
|
||||
<Link
|
||||
to="/services"
|
||||
to={`${prefix}/services`}
|
||||
className="inline-flex items-center justify-center bg-white/10 backdrop-blur-sm text-white font-bold py-4 px-8 rounded-xl hover:bg-white/20 transition-all duration-300 border-2 border-white/30"
|
||||
>
|
||||
Наши услуги
|
||||
{isEnglish ? 'Our services' : 'Наши услуги'}
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Stats */}
|
||||
<div className="mt-24 grid grid-cols-1 md:grid-cols-3 gap-8 border-t border-white/10 pt-12 max-w-5xl mx-auto w-full">
|
||||
{STATS.map((stat, idx) => (
|
||||
<div key={idx} className="flex flex-col items-center text-center">
|
||||
<span className="text-4xl md:text-5xl font-bold text-brand-orange mb-2">{stat.value}</span>
|
||||
<p className="text-gray-400 text-sm md:text-base leading-relaxed">{stat.label}</p>
|
||||
</div>
|
||||
))}
|
||||
{STATS.map((stat, idx) => {
|
||||
const label = isEnglish
|
||||
? idx === 0
|
||||
? 'For over 10 years we have been helping organisations deliver projects of any complexity.'
|
||||
: idx === 1
|
||||
? 'More than 20 major companies trust us with their projects.'
|
||||
: idx === 2
|
||||
? 'Over 30 successfully completed projects in the last 3 years.'
|
||||
: stat.label
|
||||
: stat.label;
|
||||
|
||||
return (
|
||||
<div key={idx} className="flex flex-col items-center text-center">
|
||||
<span className="text-4xl md:text-5xl font-bold text-brand-orange mb-2">
|
||||
{stat.value}
|
||||
</span>
|
||||
<p className="text-gray-400 text-sm md:text-base leading-relaxed">
|
||||
{label}
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
import React from 'react';
|
||||
import { Microscope, Activity, ArrowRight, CheckCircle2, Shield } from 'lucide-react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { Link, useLocation } from 'react-router-dom';
|
||||
|
||||
const Laboratories: React.FC = () => {
|
||||
const location = useLocation();
|
||||
const isEnglish = location.pathname.startsWith('/en');
|
||||
const prefix = isEnglish ? '/en' : '';
|
||||
|
||||
return (
|
||||
<section className="py-20 bg-gradient-to-b from-white to-gray-50">
|
||||
<div className="container mx-auto px-6">
|
||||
@@ -11,11 +15,12 @@ const Laboratories: React.FC = () => {
|
||||
<Microscope className="text-brand-orange" size={32} />
|
||||
</div>
|
||||
<h2 className="text-4xl md:text-5xl font-bold text-gray-900 mb-4">
|
||||
Наши лаборатории
|
||||
{isEnglish ? 'Our laboratories' : 'Наши лаборатории'}
|
||||
</h2>
|
||||
<p className="text-gray-600 text-lg max-w-2xl mx-auto">
|
||||
Современное оборудование и квалифицированные специалисты для проведения
|
||||
комплексных исследований
|
||||
{isEnglish
|
||||
? 'State-of-the-art equipment and qualified specialists for comprehensive testing and research.'
|
||||
: 'Современное оборудование и квалифицированные специалисты для проведения комплексных исследований'}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -26,7 +31,7 @@ const Laboratories: React.FC = () => {
|
||||
<div className="relative h-64 overflow-hidden">
|
||||
<img
|
||||
src="/media/images/services/soil-survey.png"
|
||||
alt="Грунтовая лаборатория"
|
||||
alt={isEnglish ? 'Soil testing laboratory' : 'Грунтовая лаборатория'}
|
||||
className="w-full h-full object-cover group-hover:scale-110 transition-transform duration-500"
|
||||
loading="lazy"
|
||||
/>
|
||||
@@ -42,10 +47,12 @@ const Laboratories: React.FC = () => {
|
||||
{/* Заголовок на изображении */}
|
||||
<div className="absolute bottom-6 left-6 right-6">
|
||||
<h3 className="text-2xl font-bold text-white mb-2">
|
||||
Грунтовая лаборатория
|
||||
{isEnglish ? 'Soil testing laboratory' : 'Грунтовая лаборатория'}
|
||||
</h3>
|
||||
<p className="text-white/90 text-sm">
|
||||
Исследования физических, механических и химических свойств
|
||||
{isEnglish
|
||||
? 'Testing of physical, mechanical and chemical soil properties.'
|
||||
: 'Исследования физических, механических и химических свойств'}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -56,34 +63,46 @@ const Laboratories: React.FC = () => {
|
||||
<div className="flex items-start gap-3">
|
||||
<CheckCircle2 className="text-brand-orange flex-shrink-0 mt-1" size={20} />
|
||||
<div>
|
||||
<p className="text-gray-700 font-medium">Физические свойства грунтов</p>
|
||||
<p className="text-sm text-gray-500">Влажность, плотность, гранулометрический состав</p>
|
||||
<p className="text-gray-700 font-medium">
|
||||
{isEnglish ? 'Physical properties of soils' : 'Физические свойства грунтов'}
|
||||
</p>
|
||||
<p className="text-sm text-gray-500">
|
||||
{isEnglish ? 'Moisture content, density, grain-size distribution.' : 'Влажность, плотность, гранулометрический состав'}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-start gap-3">
|
||||
<CheckCircle2 className="text-brand-orange flex-shrink-0 mt-1" size={20} />
|
||||
<div>
|
||||
<p className="text-gray-700 font-medium">Механические характеристики</p>
|
||||
<p className="text-sm text-gray-500">Прочность, деформируемость, сжимаемость</p>
|
||||
<p className="text-gray-700 font-medium">
|
||||
{isEnglish ? 'Mechanical characteristics' : 'Механические характеристики'}
|
||||
</p>
|
||||
<p className="text-sm text-gray-500">
|
||||
{isEnglish ? 'Strength, deformability, compressibility.' : 'Прочность, деформируемость, сжимаемость'}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-start gap-3">
|
||||
<CheckCircle2 className="text-brand-orange flex-shrink-0 mt-1" size={20} />
|
||||
<div>
|
||||
<p className="text-gray-700 font-medium">Химический анализ</p>
|
||||
<p className="text-sm text-gray-500">Агрессивность грунтов, анализ воды</p>
|
||||
<p className="text-gray-700 font-medium">
|
||||
{isEnglish ? 'Chemical analysis' : 'Химический анализ'}
|
||||
</p>
|
||||
<p className="text-sm text-gray-500">
|
||||
{isEnglish ? 'Soil aggressiveness, water analysis.' : 'Агрессивность грунтов, анализ воды'}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Кнопка */}
|
||||
<Link
|
||||
to="/laboratories/soil"
|
||||
to={`${prefix}/laboratories/soil`}
|
||||
className="flex items-center justify-center gap-2 w-full py-4 bg-gradient-to-r from-brand-orange to-orange-600 text-white font-bold rounded-xl hover:from-orange-600 hover:to-brand-orange transition-all duration-300 group/btn"
|
||||
>
|
||||
Подробнее о лаборатории
|
||||
{isEnglish ? 'More about the laboratory' : 'Подробнее о лаборатории'}
|
||||
<ArrowRight className="group-hover/btn:translate-x-1 transition-transform" size={20} />
|
||||
</Link>
|
||||
</div>
|
||||
@@ -95,7 +114,7 @@ const Laboratories: React.FC = () => {
|
||||
<div className="relative h-64 overflow-hidden">
|
||||
<img
|
||||
src="/media/images/services/engineering-surveys.png"
|
||||
alt="Радиационная лаборатория"
|
||||
alt={isEnglish ? 'Radiation laboratory' : 'Радиационная лаборатория'}
|
||||
className="w-full h-full object-cover group-hover:scale-110 transition-transform duration-500"
|
||||
loading="lazy"
|
||||
/>
|
||||
@@ -111,10 +130,12 @@ const Laboratories: React.FC = () => {
|
||||
{/* Заголовок на изображении */}
|
||||
<div className="absolute bottom-6 left-6 right-6">
|
||||
<h3 className="text-2xl font-bold text-white mb-2">
|
||||
Радиационная лаборатория
|
||||
{isEnglish ? 'Radiation laboratory' : 'Радиационная лаборатория'}
|
||||
</h3>
|
||||
<p className="text-white/90 text-sm">
|
||||
Профессиональные исследования радиационной безопасности
|
||||
{isEnglish
|
||||
? 'Professional radiation safety and exposure assessments.'
|
||||
: 'Профессиональные исследования радиационной безопасности'}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -125,23 +146,33 @@ const Laboratories: React.FC = () => {
|
||||
<div className="flex items-start gap-3">
|
||||
<Shield className="text-brand-orange flex-shrink-0 mt-1" size={20} />
|
||||
<div>
|
||||
<p className="text-gray-700 font-medium">Радиационный контроль</p>
|
||||
<p className="text-sm text-gray-500">Измерение уровня радона и гамма-излучения</p>
|
||||
<p className="text-gray-700 font-medium">
|
||||
{isEnglish ? 'Radiation monitoring' : 'Радиационный контроль'}
|
||||
</p>
|
||||
<p className="text-sm text-gray-500">
|
||||
{isEnglish ? 'Measurement of radon and gamma radiation levels.' : 'Измерение уровня радона и гамма-излучения'}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-start gap-3">
|
||||
<Shield className="text-brand-orange flex-shrink-0 mt-1" size={20} />
|
||||
<div>
|
||||
<p className="text-gray-700 font-medium">Аккредитованная лаборатория</p>
|
||||
<p className="text-sm text-gray-500">Техническая компетентность и независимость</p>
|
||||
<p className="text-gray-700 font-medium">
|
||||
{isEnglish ? 'Accredited laboratory' : 'Аккредитованная лаборатория'}
|
||||
</p>
|
||||
<p className="text-sm text-gray-500">
|
||||
{isEnglish ? 'Technical competence and independence.' : 'Техническая компетентность и независимость'}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-start gap-3">
|
||||
<Shield className="text-brand-orange flex-shrink-0 mt-1" size={20} />
|
||||
<div>
|
||||
<p className="text-gray-700 font-medium">Современное оборудование</p>
|
||||
<p className="text-gray-700 font-medium">
|
||||
{isEnglish ? 'Modern equipment' : 'Современное оборудование'}
|
||||
</p>
|
||||
<p className="text-sm text-gray-500">КАМЕРА-01, ДКГ-02У, ДРБП-03</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -149,10 +180,10 @@ const Laboratories: React.FC = () => {
|
||||
|
||||
{/* Кнопка */}
|
||||
<Link
|
||||
to="/laboratories/radiation"
|
||||
to={`${prefix}/laboratories/radiation`}
|
||||
className="flex items-center justify-center gap-2 w-full py-4 bg-gradient-to-r from-brand-orange to-orange-600 text-white font-bold rounded-xl hover:from-orange-600 hover:to-brand-orange transition-all duration-300 group/btn"
|
||||
>
|
||||
Подробнее о лаборатории
|
||||
{isEnglish ? 'More about the laboratory' : 'Подробнее о лаборатории'}
|
||||
<ArrowRight className="group-hover/btn:translate-x-1 transition-transform" size={20} />
|
||||
</Link>
|
||||
</div>
|
||||
@@ -163,16 +194,20 @@ const Laboratories: React.FC = () => {
|
||||
<div className="mt-16 max-w-4xl mx-auto">
|
||||
<div className="bg-gradient-to-br from-gray-900 to-gray-800 text-white rounded-2xl p-8 md:p-12 text-center">
|
||||
<h3 className="text-2xl md:text-3xl font-bold mb-4">
|
||||
Нужна консультация по лабораторным исследованиям?
|
||||
{isEnglish
|
||||
? 'Need a consultation on laboratory testing?'
|
||||
: 'Нужна консультация по лабораторным исследованиям?'}
|
||||
</h3>
|
||||
<p className="text-gray-300 mb-6 max-w-2xl mx-auto">
|
||||
Наши специалисты помогут подобрать оптимальный комплекс исследований для вашего проекта
|
||||
{isEnglish
|
||||
? 'Our specialists will help you select the optimal set of tests for your project.'
|
||||
: 'Наши специалисты помогут подобрать оптимальный комплекс исследований для вашего проекта'}
|
||||
</p>
|
||||
<Link
|
||||
to="/contacts"
|
||||
to={`${prefix}/contacts`}
|
||||
className="inline-flex items-center gap-2 px-8 py-4 bg-brand-orange text-white font-bold rounded-xl hover:bg-orange-600 transition-colors"
|
||||
>
|
||||
Связаться с нами
|
||||
{isEnglish ? 'Contact us' : 'Связаться с нами'}
|
||||
<ArrowRight size={20} />
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
@@ -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>
|
||||
)}
|
||||
|
||||
@@ -4,12 +4,14 @@ interface PageHeaderProps {
|
||||
title: string;
|
||||
description?: string;
|
||||
image?: string;
|
||||
children?: React.ReactNode;
|
||||
}
|
||||
|
||||
const PageHeader: React.FC<PageHeaderProps> = ({
|
||||
title,
|
||||
description,
|
||||
image = "/media/images/headers/header-about.png"
|
||||
image = "/media/images/headers/header-about.png",
|
||||
children,
|
||||
}) => {
|
||||
return (
|
||||
<div className="relative w-full h-[400px] md:h-[500px] bg-brand-dark text-white flex flex-col justify-center items-center text-center overflow-hidden">
|
||||
@@ -22,13 +24,14 @@ const PageHeader: React.FC<PageHeaderProps> = ({
|
||||
<div className="absolute inset-0 bg-gradient-to-b from-brand-dark/80 to-brand-dark/40" />
|
||||
</div>
|
||||
|
||||
<div className="relative z-10 container mx-auto px-6 mt-16">
|
||||
<div className="relative z-10 container mx-auto px-6 mt-16 flex flex-col items-center">
|
||||
<h1 className="text-4xl md:text-5xl lg:text-6xl font-bold mb-6">{title}</h1>
|
||||
{description && (
|
||||
<p className="text-gray-300 text-lg max-w-2xl mx-auto leading-relaxed">
|
||||
<p className="text-gray-300 text-lg max-w-2xl mx-auto leading-relaxed mb-6">
|
||||
{description}
|
||||
</p>
|
||||
)}
|
||||
{children}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -1,18 +1,48 @@
|
||||
import React from 'react';
|
||||
import { STEPS } from '../constants';
|
||||
import { useLocation } from 'react-router-dom';
|
||||
|
||||
const Process: React.FC = () => {
|
||||
const location = useLocation();
|
||||
const isEnglish = location.pathname.startsWith('/en');
|
||||
|
||||
const steps = STEPS.map((step) => ({
|
||||
...step,
|
||||
description: isEnglish
|
||||
? (() => {
|
||||
switch (step.title) {
|
||||
case 'Звонок':
|
||||
return 'We get in touch with you, clarify all the details and agree on the price.';
|
||||
case 'ТЗ':
|
||||
return 'We prepare a technical assignment for our specialists.';
|
||||
case 'Договор':
|
||||
return 'We prepare all required documents and sign the contract.';
|
||||
case 'Работа':
|
||||
return 'We carry out on-site work and test collected samples.';
|
||||
case 'Отчет':
|
||||
return 'We prepare a technical report and hand over the full documentation package.';
|
||||
case 'Финал':
|
||||
return 'We present the report and provide recommendations.';
|
||||
default:
|
||||
return step.description;
|
||||
}
|
||||
})()
|
||||
: step.description,
|
||||
}));
|
||||
|
||||
return (
|
||||
<div className="py-20 bg-brand-light">
|
||||
<div className="container mx-auto px-6">
|
||||
<h2 className="text-4xl font-bold text-gray-900 mb-16 text-center">Как мы работаем</h2>
|
||||
<h2 className="text-4xl font-bold text-gray-900 mb-16 text-center">
|
||||
{isEnglish ? 'How we work' : 'Как мы работаем'}
|
||||
</h2>
|
||||
|
||||
<div className="relative max-w-6xl mx-auto">
|
||||
{/* Линия связи между шагами (только на больших экранах) */}
|
||||
<div className="hidden lg:block absolute top-9 left-0 right-0 h-1 bg-gradient-to-r from-brand-orange via-brand-orange/50 to-brand-orange" style={{ zIndex: 0 }} />
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8 relative" style={{ zIndex: 1 }}>
|
||||
{STEPS.map((step, idx) => (
|
||||
{steps.map((step, idx) => (
|
||||
<div key={idx} className="relative">
|
||||
{/* Номер шага */}
|
||||
<div className="absolute -top-4 -left-4 w-10 h-10 bg-brand-orange text-white rounded-full flex items-center justify-center font-bold text-lg shadow-lg z-10 border-4 border-brand-light">
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
import React, { useState } from 'react';
|
||||
import { groupProjectsByCategory } from '../constants';
|
||||
import { MapPin, ChevronDown } from 'lucide-react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { Link, useLocation } from 'react-router-dom';
|
||||
|
||||
const Projects: React.FC = () => {
|
||||
const location = useLocation();
|
||||
const isEnglish = location.pathname.startsWith('/en');
|
||||
const prefix = isEnglish ? '/en' : '';
|
||||
|
||||
const categories = groupProjectsByCategory().slice(0, 3); // Показываем только 3 категории
|
||||
const [openCategories, setOpenCategories] = useState<{ [key: string]: boolean }>({
|
||||
[categories[0]?.name]: true // Открываем первую категорию по умолчанию
|
||||
@@ -21,16 +25,33 @@ const Projects: React.FC = () => {
|
||||
<div className="container mx-auto px-6">
|
||||
<div className="flex flex-col md:flex-row justify-between items-start md:items-end mb-16 gap-8">
|
||||
<h2 className="text-4xl font-bold text-gray-900 max-w-xs leading-tight">
|
||||
Наши недавние проекты
|
||||
{isEnglish ? 'Our recent projects' : 'Наши недавние проекты'}
|
||||
</h2>
|
||||
<p className="text-gray-600 max-w-md text-sm leading-relaxed">
|
||||
Наша команда всегда ответственно относится к проектам, которые вы нам доверили.
|
||||
Спасибо, что вы рядом.
|
||||
{isEnglish
|
||||
? 'Our team treats every project with great responsibility. Thank you for your trust.'
|
||||
: 'Наша команда всегда ответственно относится к проектам, которые вы нам доверили. Спасибо, что вы рядом.'}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="space-y-4 mb-8">
|
||||
{categories.map((category) => (
|
||||
{categories.map((category) => {
|
||||
const categoryName = isEnglish
|
||||
? (() => {
|
||||
switch (category.name) {
|
||||
case 'Нефтегазовая промышленность':
|
||||
return 'Oil & gas industry';
|
||||
case 'Коммерческая недвижимость и туризм':
|
||||
return 'Commercial real estate and tourism';
|
||||
case 'Прочие объекты':
|
||||
return 'Other facilities';
|
||||
default:
|
||||
return category.name;
|
||||
}
|
||||
})()
|
||||
: category.name;
|
||||
|
||||
return (
|
||||
<div key={category.name} className="border border-gray-200 rounded-xl overflow-hidden">
|
||||
{/* Заголовок категории */}
|
||||
<button
|
||||
@@ -41,7 +62,7 @@ const Projects: React.FC = () => {
|
||||
<div className="flex-shrink-0 w-12 h-12 bg-brand-orange text-white rounded-lg flex items-center justify-center font-bold text-lg">
|
||||
{category.projects.length}
|
||||
</div>
|
||||
<h3 className="text-xl font-bold text-gray-900">{category.name}</h3>
|
||||
<h3 className="text-xl font-bold text-gray-900">{categoryName}</h3>
|
||||
</div>
|
||||
<ChevronDown
|
||||
size={24}
|
||||
@@ -60,7 +81,61 @@ const Projects: React.FC = () => {
|
||||
}`}
|
||||
>
|
||||
<div className="p-4 space-y-3 bg-white">
|
||||
{category.projects.slice(0, 3).map((project, index) => (
|
||||
{category.projects.slice(0, 3).map((project, index) => {
|
||||
const title = isEnglish
|
||||
? (() => {
|
||||
switch (project.title) {
|
||||
case 'ОАО «Газпромнефть-ОНПЗ»':
|
||||
return '“Gazpromneft‑ONPZ” OJSC';
|
||||
case 'ООО «Петон»':
|
||||
return '“Peton” LLC';
|
||||
case 'ОАО «Гипротрубопровод»':
|
||||
return '“Giprotuboprovod” OJSC';
|
||||
default:
|
||||
return project.title;
|
||||
}
|
||||
})()
|
||||
: project.title;
|
||||
|
||||
const description = isEnglish
|
||||
? (() => {
|
||||
switch (project.title) {
|
||||
case 'ОАО «Газпромнефть-ОНПЗ»':
|
||||
return 'Modernisation of unit 19/3 at Gazpromneft‑ONPZ in Omsk.';
|
||||
case 'ООО «Петон»':
|
||||
return 'L‑24/9. Technical upgrade. Heat recovery of diesel fuel hydrotreating unit (design and working documentation) at the Gazpromneft‑ONPZ site.';
|
||||
case 'ОАО «Гипротрубопровод»':
|
||||
return 'Reconstruction of the production base in Omsk.';
|
||||
|
||||
// Commercial real estate and tourism (examples)
|
||||
case 'ООО «СУ-1 ОАО «Госстрой»':
|
||||
return 'Fast‑food restaurant “KFC” at the intersection of Marshala Zhukova and Akademika Korolyova streets in the Oktyabrsky district of Ufa.';
|
||||
case 'ООО «Башкирский птицеводческий комплекс имени М. Гафури»':
|
||||
return 'Architectural civil facility “Administrative and utility building” for the Bashkir Poultry Complex named after M. Gafuri.';
|
||||
case 'ООО «Регион-Ресурс»':
|
||||
return 'Construction of an eco‑tourism centre in the Kirovsky district of Ufa, Republic of Bashkortostan, including development of design documentation, support through expert review and approvals.';
|
||||
case 'МБУ «Управление пожарной охраны ГО г. Уфа Республики Башкортостан':
|
||||
return 'Fire station building with four bays located in the Leninsky district, settlement 8 Marta, Republic of Bashkortostan.';
|
||||
case 'ООО «Управление капитального строительства «Монолитстрой»':
|
||||
return 'Administrative, retail and entertainment complex in the Dema‑9 neighbourhood, Demsky district of Ufa, Republic of Bashkortostan.';
|
||||
case 'ОАО «Уфимский хлопчатобумажный комбинат»':
|
||||
return '“Ferris wheel‑58” on the site of the Ufa Cotton Mill at 137 Mendeleeva Street, Ufa.';
|
||||
case 'ЗАО «Штрабаг»':
|
||||
return 'Technology park of energy‑efficient technologies on a land plot within the administrative boundaries of the Ufimsky municipal district, Republic of Bashkortostan.';
|
||||
case 'ООО «Уралстройсервис»':
|
||||
return 'Underground garage with public service premises on the roof, at Rossiyskaya Street and Davletkildeyev Boulevard intersection in the Oktyabrsky district of Ufa.';
|
||||
case 'ООО «РаушБиер»':
|
||||
return 'Two‑storey restaurant complex located at 8 Tukaeva Street, Tuymazy, Republic of Bashkortostan.';
|
||||
case 'ООО СОК «Трамплин»':
|
||||
return 'Ski tow lift in the Oktyabrsky district of Ufa, Republic of Bashkortostan.';
|
||||
|
||||
default:
|
||||
return project.description;
|
||||
}
|
||||
})()
|
||||
: project.description;
|
||||
|
||||
return (
|
||||
<div
|
||||
key={project.id}
|
||||
className="group cursor-pointer bg-gray-50 hover:bg-gray-100 rounded-lg p-5 transition-all duration-300 border border-gray-200 hover:border-brand-orange"
|
||||
@@ -71,28 +146,28 @@ const Projects: React.FC = () => {
|
||||
</div>
|
||||
<div className="flex-1">
|
||||
<h4 className="text-base font-bold text-gray-900 mb-2 group-hover:text-brand-orange transition-colors">
|
||||
{project.title}
|
||||
{title}
|
||||
</h4>
|
||||
<div className="flex items-start gap-2 text-gray-600 text-sm">
|
||||
<MapPin size={14} className="mt-1 flex-shrink-0 text-brand-orange" />
|
||||
<span className="leading-relaxed line-clamp-2">{project.description}</span>
|
||||
<span className="leading-relaxed line-clamp-2">{description}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
)})}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
)})}
|
||||
</div>
|
||||
|
||||
<div className="text-center">
|
||||
<Link
|
||||
to="/projects"
|
||||
to={`${prefix}/projects`}
|
||||
className="inline-block px-8 py-3 bg-brand-orange text-white font-bold rounded-lg hover:bg-orange-600 transition-colors"
|
||||
>
|
||||
Смотреть все проекты
|
||||
{isEnglish ? 'View all projects' : 'Смотреть все проекты'}
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
21
components/Seo.tsx
Normal file
21
components/Seo.tsx
Normal file
@@ -0,0 +1,21 @@
|
||||
import React from 'react';
|
||||
import { Helmet } from 'react-helmet';
|
||||
|
||||
interface SeoProps {
|
||||
title: string;
|
||||
description?: string;
|
||||
}
|
||||
|
||||
const Seo: React.FC<SeoProps> = ({ title, description }) => {
|
||||
const fullTitle = `${title} | ГеоВектор`;
|
||||
|
||||
return (
|
||||
<Helmet>
|
||||
<title>{fullTitle}</title>
|
||||
{description && <meta name="description" content={description} />}
|
||||
</Helmet>
|
||||
);
|
||||
};
|
||||
|
||||
export default Seo;
|
||||
|
||||
@@ -2,8 +2,13 @@ import React from 'react';
|
||||
import { ArrowRight } from 'lucide-react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { SERVICES } from '../constants';
|
||||
import { useLocation } from 'react-router-dom';
|
||||
|
||||
const Services: React.FC = () => {
|
||||
const location = useLocation();
|
||||
const isEnglish = location.pathname.startsWith('/en');
|
||||
const prefix = isEnglish ? '/en' : '';
|
||||
|
||||
// Exclude Technical Tasks and show first 3 actual services
|
||||
const actualServices = SERVICES.filter(service => service.title !== 'Технические задания');
|
||||
const displayedServices = actualServices.slice(0, 3);
|
||||
@@ -13,7 +18,6 @@ const Services: React.FC = () => {
|
||||
const urlMap: { [key: string]: string } = {
|
||||
'Инженерные изыскания': '/services/surveying',
|
||||
'Проектирование': '/services/design',
|
||||
'Строительство': '/services/construction',
|
||||
'Обследование грунтов': '/services/soil-survey',
|
||||
'Обследование здания': '/services/building-survey',
|
||||
'Землестроительный и Кадастровые работы': '/services/land-survey'
|
||||
@@ -25,16 +29,57 @@ const Services: React.FC = () => {
|
||||
<div className="py-20 bg-gray-50" id="services">
|
||||
<div className="container mx-auto px-6">
|
||||
<div className="flex justify-between items-end mb-12">
|
||||
<h2 className="text-4xl font-bold text-gray-900">Услуги</h2>
|
||||
<Link to="/services" className="flex items-center gap-2 text-sm font-medium hover:text-brand-orange transition-colors">
|
||||
Показать все <ArrowRight size={16} />
|
||||
<h2 className="text-4xl font-bold text-gray-900">
|
||||
{isEnglish ? 'Services' : 'Услуги'}
|
||||
</h2>
|
||||
<Link
|
||||
to={`${prefix}/services`}
|
||||
className="flex items-center gap-2 text-sm font-medium hover:text-brand-orange transition-colors"
|
||||
>
|
||||
{isEnglish ? 'Show all' : 'Показать все'} <ArrowRight size={16} />
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-6">
|
||||
{displayedServices.map((service, idx) => {
|
||||
const detailUrl = getServiceUrl(service.title);
|
||||
|
||||
|
||||
const title =
|
||||
isEnglish
|
||||
? (() => {
|
||||
switch (service.title) {
|
||||
case 'Инженерные изыскания':
|
||||
return 'Engineering surveys';
|
||||
case 'Проектирование':
|
||||
return 'Design';
|
||||
case 'Обследование грунтов':
|
||||
return 'Soil investigation';
|
||||
case 'Обследование здания':
|
||||
return 'Building survey';
|
||||
default:
|
||||
return service.title;
|
||||
}
|
||||
})()
|
||||
: service.title;
|
||||
|
||||
const description =
|
||||
isEnglish
|
||||
? (() => {
|
||||
switch (service.title) {
|
||||
case 'Инженерные изыскания':
|
||||
return 'Comprehensive investigation of construction site conditions: engineering-geodetic, geological, hydrometeorological and environmental surveys.';
|
||||
case 'Проектирование':
|
||||
return 'Development of design and working documentation for civil and industrial facilities with architectural and structural solutions.';
|
||||
case 'Обследование грунтов':
|
||||
return 'Laboratory and field testing of soils. Determination of physical and mechanical properties for designing foundations and subgrades.';
|
||||
case 'Обследование здания':
|
||||
return 'Technical inspection of buildings and structures, assessment of load-bearing elements and recommendations for strengthening.';
|
||||
default:
|
||||
return service.description;
|
||||
}
|
||||
})()
|
||||
: service.description;
|
||||
|
||||
return (
|
||||
<div
|
||||
key={idx}
|
||||
@@ -42,32 +87,32 @@ const Services: React.FC = () => {
|
||||
>
|
||||
<img
|
||||
src={service.image}
|
||||
alt={service.title}
|
||||
alt={title}
|
||||
className="absolute inset-0 w-full h-full object-cover transition-transform duration-700 group-hover:scale-110"
|
||||
loading="lazy"
|
||||
/>
|
||||
<div className="absolute inset-0 bg-gradient-to-t from-black/90 via-black/40 to-transparent" />
|
||||
|
||||
<div className="absolute bottom-0 left-0 p-8 w-full">
|
||||
<h3 className="text-2xl font-bold text-white mb-3">{service.title}</h3>
|
||||
<h3 className="text-2xl font-bold text-white mb-3">{title}</h3>
|
||||
<p className="text-gray-300 text-sm mb-6 line-clamp-3 opacity-90">
|
||||
{service.description}
|
||||
{description}
|
||||
</p>
|
||||
|
||||
<div className="flex flex-col gap-3">
|
||||
{detailUrl && (
|
||||
<Link
|
||||
to={detailUrl}
|
||||
to={`${prefix}${detailUrl}`}
|
||||
className="inline-flex items-center justify-center gap-2 bg-brand-orange text-white font-bold px-5 py-2.5 rounded-lg hover:bg-orange-600 transition-colors"
|
||||
>
|
||||
Подробнее <ArrowRight size={18} />
|
||||
{isEnglish ? 'Learn more' : 'Подробнее'} <ArrowRight size={18} />
|
||||
</Link>
|
||||
)}
|
||||
<Link
|
||||
to="/contacts"
|
||||
to={`${prefix}/contacts`}
|
||||
className="flex items-center gap-2 text-brand-orange text-sm font-medium group-hover:gap-4 transition-all"
|
||||
>
|
||||
Рассчитать стоимость <ArrowRight size={16} />
|
||||
{isEnglish ? 'Request a quote' : 'Рассчитать стоимость'} <ArrowRight size={16} />
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user