Files
geovektor/pages/CertificatesPage.tsx
2026-02-10 16:22:14 +05:00

285 lines
13 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 PageHeader from '../components/PageHeader';
import { FileText, X, ChevronLeft, ChevronRight } from 'lucide-react';
interface Certificate {
id: number;
image: string;
title: string;
}
interface CertificateSection {
title: string;
certificates: Certificate[];
}
const CertificatesPage: React.FC = () => {
const [selectedImageIndex, setSelectedImageIndex] = useState<number | null>(null);
const sections: CertificateSection[] = [
{
title: 'ПРОГРАММНЫЕ ПРОДУКТЫ КРЕДО',
certificates: [
{ id: 1, image: 'https://placehold.co/400x600/94a3b8/white', title: 'Сертификат' }
]
},
{
title: 'ВЫПИСКА ИЗ СРО ПО СТРОИТЕЛЬСТВУ',
certificates: [
{ id: 2, image: 'https://placehold.co/400x600/94a3b8/white', title: 'Документ 1' },
{ id: 3, image: 'https://placehold.co/400x600/94a3b8/white', title: 'Документ 2' },
{ id: 4, image: 'https://placehold.co/400x600/94a3b8/white', title: 'Документ 3' },
{ id: 5, image: 'https://placehold.co/400x600/94a3b8/white', title: 'Документ 4' }
]
},
{
title: 'ВЫПИСКА ИЗ СРО ПО ПРОЕКТИРОВАНИЮ',
certificates: [
{ id: 6, image: 'https://placehold.co/400x600/94a3b8/white', title: 'Документ 1' },
{ id: 7, image: 'https://placehold.co/400x600/94a3b8/white', title: 'Документ 2' }
]
},
{
title: 'ВЫПИСКА ИЗ СРО ПО ИЗЫСКАНИЯМ',
certificates: [
{ id: 8, image: 'https://placehold.co/400x600/94a3b8/white', title: 'Документ 1' },
{ id: 9, image: 'https://placehold.co/400x600/94a3b8/white', title: 'Документ 2' }
]
},
{
title: 'ВЫПИСКА ИЗ РЕЕСТРА ЧЛЕНОВ САМОРЕГУЛИРУЕМОЙ ОРГАНИЗАЦИИ, ОСНОВАННОЙ НА ЧЛЕНСТВЕ ЛИЦ, ОСУЩЕСТВЛЯЮЩИХ СТРОИТЕЛЬСТВО',
certificates: [
{ id: 10, image: 'https://placehold.co/400x600/94a3b8/white', title: 'Документ 1' },
{ id: 11, image: 'https://placehold.co/400x600/94a3b8/white', title: 'Документ 2' },
{ id: 12, image: 'https://placehold.co/400x600/94a3b8/white', title: 'Документ 3' }
]
},
{
title: 'ВЫПИСКА ИЗ РЕЕСТРА ЧЛЕНОВ САМОРЕГУЛИРУЕМОЙ ОРГАНИЗАЦИИ, ОСНОВАННОЙ НА ЧЛЕНСТВЕ ЛИЦ, ОСУЩЕСТВЛЯЮЩИХ ИНЖЕНЕРНЫЕ ИЗЫСКАНИЯ',
certificates: [
{ id: 13, image: 'https://placehold.co/400x600/94a3b8/white', title: 'Документ 1' },
{ id: 14, image: 'https://placehold.co/400x600/94a3b8/white', title: 'Документ 2' }
]
},
{
title: 'ВЫПИСКА ИЗ РЕЕСТРА ЧЛЕНОВ САМОРЕГУЛИРУЕМОЙ ОРГАНИЗАЦИИ, ОСНОВАННОЙ НА ЧЛЕНСТВЕ ЛИЦ, ОСУЩЕСТВЛЯЮЩИХ ПРОЕКТНЫЕ РАБОТЫ',
certificates: [
{ id: 15, image: 'https://placehold.co/400x600/94a3b8/white', title: 'Документ 1' },
{ id: 16, image: 'https://placehold.co/400x600/94a3b8/white', title: 'Документ 2' }
]
},
{
title: 'СВЕДЕНИЕ НА ОСУЩЕСТВЛЕНИЕ ГЕОДЕЗИЧЕСКОЙ И КАРТОГРАФИЧЕСКОЙ ДЕЯТЕЛЬНОСТИ ФЕДЕРАЛЬНАЯ СЛУЖБА ГОСУДАРСТВА',
certificates: [
{ id: 17, image: 'https://placehold.co/400x600/94a3b8/white', title: 'Документ 1' },
{ id: 18, image: 'https://placehold.co/400x600/94a3b8/white', title: 'Документ 2' }
]
},
{
title: 'СВИДЕТЕЛЬСТВО О ПРОХОЖДЕНИИ ИСПЫТАНИЙ И КОНТРОЛЯ ПО ISO 9001',
certificates: [
{ id: 19, image: 'https://placehold.co/400x600/94a3b8/white', title: 'Документ 1' },
{ id: 20, image: 'https://placehold.co/400x600/94a3b8/white', title: 'Документ 2' },
{ id: 21, image: 'https://placehold.co/400x600/94a3b8/white', title: 'Документ 3' },
{ id: 22, image: 'https://placehold.co/400x600/94a3b8/white', title: 'Документ 4' },
{ id: 23, image: 'https://placehold.co/400x600/94a3b8/white', title: 'Документ 5' },
{ id: 24, image: 'https://placehold.co/400x600/94a3b8/white', title: 'Документ 6' }
]
}
];
// Создаем плоский массив всех изображений для навигации
const allImages = sections.flatMap(section => section.certificates.map(cert => cert.image));
const openModal = (image: string) => {
const index = allImages.indexOf(image);
setSelectedImageIndex(index);
document.body.style.overflow = 'hidden';
};
const closeModal = () => {
setSelectedImageIndex(null);
document.body.style.overflow = 'auto';
};
const nextImage = () => {
if (selectedImageIndex !== null) {
setSelectedImageIndex((selectedImageIndex + 1) % allImages.length);
}
};
const prevImage = () => {
if (selectedImageIndex !== null) {
setSelectedImageIndex((selectedImageIndex - 1 + allImages.length) % allImages.length);
}
};
// Обработка клавиатуры
useEffect(() => {
const handleKeyDown = (e: KeyboardEvent) => {
if (selectedImageIndex === null) return;
if (e.key === 'Escape') {
closeModal();
} else if (e.key === 'ArrowRight') {
nextImage();
} else if (e.key === 'ArrowLeft') {
prevImage();
}
};
window.addEventListener('keydown', handleKeyDown);
return () => window.removeEventListener('keydown', handleKeyDown);
}, [selectedImageIndex]);
return (
<div className="bg-white pb-20">
<PageHeader
title="Сертификаты"
description="Документы, подтверждающие нашу квалификацию и соответствие стандартам качества"
image="/media/images/headers/header-certificates.png"
/>
<div className="container mx-auto px-6 py-20">
<div className="max-w-7xl mx-auto">
<h2 className="text-3xl font-bold text-gray-900 mb-12 text-center">
СВИДЕТЕЛЬСТВА
</h2>
{/* Секции с сертификатами */}
<div className="space-y-16">
{sections.map((section, sectionIndex) => (
<div key={sectionIndex} className="space-y-6">
{/* Заголовок секции */}
<div className="flex items-center gap-3 mb-8">
<FileText className="text-brand-orange" size={28} />
<h3 className="text-lg font-bold text-gray-900 uppercase leading-tight">
{section.title}
</h3>
</div>
{/* Сетка документов */}
<div className="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5 gap-6">
{section.certificates.map((cert) => (
<div
key={cert.id}
onClick={() => openModal(cert.image)}
className="group cursor-pointer"
>
<div className="relative aspect-[3/4] rounded-lg overflow-hidden shadow-md hover:shadow-xl transition-all duration-300 bg-gray-100">
<img
src={cert.image}
alt={cert.title}
className="w-full h-full object-cover group-hover:scale-105 transition-transform duration-500"
/>
<div className="absolute inset-0 bg-black/0 group-hover:bg-black/10 transition-colors" />
{/* Overlay при наведении */}
<div className="absolute inset-0 flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity">
<div className="bg-brand-orange text-white px-4 py-2 rounded-lg font-semibold text-sm">
Увеличить
</div>
</div>
</div>
</div>
))}
</div>
</div>
))}
</div>
{/* Информационный блок */}
<div className="mt-20 bg-gray-50 rounded-2xl p-8 md:p-12">
<div className="max-w-3xl mx-auto text-center">
<h3 className="text-2xl font-bold text-gray-900 mb-4">
Гарантия качества
</h3>
<p className="text-gray-600 leading-relaxed mb-6">
ООО «ГЕОВЕКТОР» имеет все необходимые лицензии и сертификаты для осуществления
деятельности в области проектирования, строительства и инженерных изысканий.
Наша компания является членом саморегулируемых организаций и соответствует
международным стандартам качества ISO 9001.
</p>
<div className="flex flex-wrap justify-center gap-4 mt-8">
<div className="bg-white px-6 py-3 rounded-lg shadow-sm">
<div className="text-2xl font-bold text-brand-orange mb-1">СРО</div>
<div className="text-sm text-gray-600">Член организации</div>
</div>
<div className="bg-white px-6 py-3 rounded-lg shadow-sm">
<div className="text-2xl font-bold text-brand-orange mb-1">ISO 9001</div>
<div className="text-sm text-gray-600">Сертифицирован</div>
</div>
<div className="bg-white px-6 py-3 rounded-lg shadow-sm">
<div className="text-2xl font-bold text-brand-orange mb-1">10+ лет</div>
<div className="text-sm text-gray-600">На рынке</div>
</div>
</div>
</div>
</div>
</div>
</div>
{/* Модальное окно для просмотра изображения */}
{selectedImageIndex !== null && (
<div
className="fixed inset-0 z-50 flex items-center justify-center bg-black/95 p-4"
onClick={closeModal}
>
{/* Кнопка закрытия */}
<button
onClick={closeModal}
className="absolute top-4 right-4 bg-white/10 hover:bg-white/20 text-white p-3 rounded-full transition-colors z-10"
aria-label="Закрыть"
>
<X size={28} />
</button>
{/* Кнопка "Назад" */}
<button
onClick={(e) => {
e.stopPropagation();
prevImage();
}}
className="absolute left-4 top-1/2 -translate-y-1/2 bg-white/10 hover:bg-white/20 text-white p-3 rounded-full transition-colors z-10"
aria-label="Предыдущее изображение"
>
<ChevronLeft size={32} />
</button>
{/* Кнопка "Вперед" */}
<button
onClick={(e) => {
e.stopPropagation();
nextImage();
}}
className="absolute right-4 top-1/2 -translate-y-1/2 bg-white/10 hover:bg-white/20 text-white p-3 rounded-full transition-colors z-10"
aria-label="Следующее изображение"
>
<ChevronRight size={32} />
</button>
{/* Индикатор */}
<div className="absolute bottom-4 left-1/2 -translate-x-1/2 bg-black/50 text-white px-4 py-2 rounded-full text-sm font-semibold z-10">
{selectedImageIndex + 1} / {allImages.length}
</div>
{/* Изображение */}
<div
className="relative w-full h-full flex items-center justify-center"
onClick={(e) => e.stopPropagation()}
>
<img
src={allImages[selectedImageIndex]}
alt={`Документ ${selectedImageIndex + 1}`}
className="max-w-full max-h-[90vh] object-contain rounded-lg shadow-2xl"
/>
</div>
</div>
)}
</div>
);
};
export default CertificatesPage;