Enhance UXSoftware page with live metrics, interactive server map, and consultation modal. Implemented animations for UX improvements and added functionality for user input forms. Updated styles for better user experience.

This commit is contained in:
albivkt
2025-07-06 00:11:58 +03:00
parent ba84ccdbda
commit afcb9ba27b
10 changed files with 5085 additions and 400 deletions

View File

@ -1,6 +1,297 @@
'use client';
import { useState, useEffect } from 'react';
import Navigation from '../components/Navigation';
export default function About() {
const [mounted, setMounted] = useState(false);
const [activeTimelineStep, setActiveTimelineStep] = useState(0);
const [teamMemberFlipped, setTeamMemberFlipped] = useState<number | null>(null);
const [liveCounters, setLiveCounters] = useState({
projects: 0,
clients: 0,
years: 0,
support: 0
});
const [workDaySimulation, setWorkDaySimulation] = useState({
currentTime: '09:00',
currentActivity: 'Планирование задач',
teamStatus: 'active'
});
const [floatingTechs, setFloatingTechs] = useState<Array<{
id: number;
tech: string;
x: string;
y: string;
delay: number;
duration: number;
}>>([]);
const [competencyGraph, setCompetencyGraph] = useState({
activeNode: null as string | null,
connections: [] as Array<{from: string, to: string}>
});
const [backgroundParticles, setBackgroundParticles] = useState<Array<{
id: number;
x: number;
y: number;
vx: number;
vy: number;
size: number;
color: string;
opacity: number;
}>>([]);
const [mousePosition, setMousePosition] = useState({ x: 0, y: 0 });
const timelineSteps = [
{ year: '2019', title: 'Основание компании', description: 'Начало деятельности в сфере разработки ПО', color: 'bg-green-500' },
{ year: '2020', title: 'Расширение услуг', description: 'Добавление поставки электроники и системной интеграции', color: 'bg-blue-500' },
{ year: '2021', title: 'Первые крупные проекты', description: 'Реализация комплексных IT-решений для бизнеса', color: 'bg-purple-500' },
{ year: '2022', title: 'Государственные контракты', description: 'Начало работы с госсектором по 44-ФЗ и 223-ФЗ', color: 'bg-amber-500' },
{ year: '2023', title: 'Собственные продукты', description: 'Запуск Соловей и других авторских решений', color: 'bg-cyan-500' },
{ year: '2024', title: 'Полный спектр услуг', description: 'Комплексный поставщик IT-решений и оборудования', color: 'bg-pink-500' }
];
const teamMembers = [
{
name: 'Александр Гундырев',
role: 'Основатель и CEO',
avatar: '👨‍💼',
skills: ['Стратегия', 'Управление', 'Бизнес-процессы'],
experience: '10+ лет',
projects: '200+',
description: 'Визионер компании, определяет стратегическое направление развития'
},
{
name: 'Мария Петрова',
role: 'CTO',
avatar: '👩‍💻',
skills: ['Архитектура', 'DevOps', 'Команда'],
experience: '8+ лет',
projects: '150+',
description: 'Руководит техническим направлением и командой разработки'
},
{
name: 'Дмитрий Козлов',
role: 'Lead Developer',
avatar: '👨‍💻',
skills: ['React', 'Node.js', 'Python'],
experience: '6+ лет',
projects: '100+',
description: 'Ведущий разработчик, эксперт по современным технологиям'
},
{
name: 'Елена Смирнова',
role: 'Project Manager',
avatar: '👩‍💼',
skills: ['Agile', 'Scrum', 'Планирование'],
experience: '7+ лет',
projects: '80+',
description: 'Координирует проекты и обеспечивает качественную реализацию'
},
{
name: 'Антон Васильев',
role: 'DevOps Engineer',
avatar: '👨‍🔧',
skills: ['Docker', 'Kubernetes', 'AWS'],
experience: '5+ лет',
projects: '60+',
description: 'Отвечает за инфраструктуру и автоматизацию процессов'
},
{
name: 'Ольга Новикова',
role: 'UX/UI Designer',
avatar: '👩‍🎨',
skills: ['Figma', 'Prototyping', 'Research'],
experience: '4+ лет',
projects: '90+',
description: 'Создает интуитивные и красивые пользовательские интерфейсы'
}
];
const technologies = [
'React', 'Node.js', 'Python', 'Docker', 'AWS', 'PostgreSQL',
'TypeScript', 'Next.js', 'Kubernetes', 'Redis', 'GraphQL', 'MongoDB',
'Vue.js', 'Express', 'Nginx', 'Linux', 'Git', 'Jenkins'
];
const competencies = {
'Frontend': ['React', 'Vue.js', 'TypeScript', 'Next.js'],
'Backend': ['Node.js', 'Python', 'Express', 'GraphQL'],
'Database': ['PostgreSQL', 'MongoDB', 'Redis'],
'DevOps': ['Docker', 'Kubernetes', 'AWS', 'Jenkins'],
'Infrastructure': ['Linux', 'Nginx', 'Git']
};
const workDayActivities = [
{ time: '09:00', activity: 'Планирование задач', icon: '📋' },
{ time: '10:00', activity: 'Разработка', icon: '💻' },
{ time: '11:30', activity: 'Code Review', icon: '🔍' },
{ time: '13:00', activity: 'Обед', icon: '🍽️' },
{ time: '14:00', activity: 'Встреча с клиентом', icon: '🤝' },
{ time: '15:30', activity: 'Тестирование', icon: '🧪' },
{ time: '17:00', activity: 'Деплой', icon: '🚀' },
{ time: '18:00', activity: 'Планирование на завтра', icon: '📅' }
];
// Автоматическое переключение временной шкалы
useEffect(() => {
const interval = setInterval(() => {
setActiveTimelineStep(prev => (prev + 1) % timelineSteps.length);
}, 3000);
return () => clearInterval(interval);
}, []);
// Анимация счетчиков
useEffect(() => {
const targets = { projects: 500, clients: 150, years: 5, support: 24 };
const duration = 2000;
const steps = 50;
const stepDuration = duration / steps;
let currentStep = 0;
const interval = setInterval(() => {
currentStep++;
const progress = currentStep / steps;
setLiveCounters({
projects: Math.floor(targets.projects * progress),
clients: Math.floor(targets.clients * progress),
years: Math.floor(targets.years * progress),
support: Math.floor(targets.support * progress)
});
if (currentStep >= steps) {
clearInterval(interval);
}
}, stepDuration);
return () => clearInterval(interval);
}, []);
// Генерация плавающих технологий
useEffect(() => {
const techs = technologies.map((tech, i) => ({
id: i,
tech,
x: `${10 + (i * 80) % 80}%`,
y: `${20 + (i * 60) % 60}%`,
delay: i * 0.5,
duration: 8 + (i % 4)
}));
setFloatingTechs(techs);
}, []);
// Симуляция рабочего дня
useEffect(() => {
let activityIndex = 0;
const interval = setInterval(() => {
const activity = workDayActivities[activityIndex];
setWorkDaySimulation({
currentTime: activity.time,
currentActivity: activity.activity,
teamStatus: activity.time === '13:00' ? 'break' : 'active'
});
activityIndex = (activityIndex + 1) % workDayActivities.length;
}, 4000);
return () => clearInterval(interval);
}, []);
// Инициализация монтирования
useEffect(() => {
setMounted(true);
}, []);
const handleTeamMemberClick = (index: number) => {
setTeamMemberFlipped(teamMemberFlipped === index ? null : index);
};
const handleCompetencyClick = (competency: string) => {
setCompetencyGraph(prev => ({
...prev,
activeNode: prev.activeNode === competency ? null : competency
}));
};
// Генерация фоновых частиц (детерминированно)
useEffect(() => {
if (!mounted) return;
const colors = ['#10b981', '#3b82f6', '#8b5cf6', '#f59e0b', '#ef4444', '#06b6d4'];
const particles = Array.from({ length: 50 }, (_, i) => ({
id: i,
x: (i * 17 + 23) % 100,
y: (i * 31 + 47) % 100,
vx: ((i % 7) - 3) * 0.1,
vy: ((i % 5) - 2) * 0.1,
size: (i % 3) + 1,
color: colors[i % colors.length],
opacity: 0.3 + (i % 7) * 0.1
}));
setBackgroundParticles(particles);
}, [mounted]);
// Анимация частиц
useEffect(() => {
if (!mounted) return;
const interval = setInterval(() => {
setBackgroundParticles(prev => prev.map(particle => {
let newX = particle.x + particle.vx;
let newY = particle.y + particle.vy;
let newVx = particle.vx;
let newVy = particle.vy;
// Отскок от границ
if (newX <= 0 || newX >= 100) {
newVx = -newVx;
newX = newX <= 0 ? 0 : 100;
}
if (newY <= 0 || newY >= 100) {
newVy = -newVy;
newY = newY <= 0 ? 0 : 100;
}
// Притяжение к курсору
const mouseInfluence = 0.02;
const screenWidth = typeof window !== 'undefined' ? window.innerWidth : 1920;
const screenHeight = typeof window !== 'undefined' ? window.innerHeight : 1080;
const dx = (mousePosition.x / screenWidth * 100) - newX;
const dy = (mousePosition.y / screenHeight * 100) - newY;
const distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 20) {
newVx += dx * mouseInfluence / distance;
newVy += dy * mouseInfluence / distance;
}
return {
...particle,
x: newX,
y: newY,
vx: newVx * 0.99, // Затухание
vy: newVy * 0.99
};
}));
}, 50);
return () => clearInterval(interval);
}, [mounted, mousePosition]);
// Отслеживание позиции мыши
useEffect(() => {
if (!mounted) return;
const handleMouseMove = (e: MouseEvent) => {
setMousePosition({ x: e.clientX, y: e.clientY });
};
if (typeof window !== 'undefined') {
window.addEventListener('mousemove', handleMouseMove);
return () => window.removeEventListener('mousemove', handleMouseMove);
}
}, [mounted]);
return (
<>
<Navigation />
@ -8,6 +299,121 @@ export default function About() {
{/* Hero Section */}
<section className="min-h-screen flex items-center justify-center relative overflow-hidden pt-16">
<div className="absolute inset-0 bg-gradient-to-br from-slate-900 via-black to-gray-900"></div>
{/* Интерактивный фон с частицами */}
<div className="absolute inset-0 overflow-hidden">
{/* Анимированная сетка */}
<div className="absolute inset-0 opacity-10">
<svg className="w-full h-full">
<defs>
<pattern id="grid" width="50" height="50" patternUnits="userSpaceOnUse">
<path d="M 50 0 L 0 0 0 50" fill="none" stroke="rgba(16, 185, 129, 0.3)" strokeWidth="1">
<animate attributeName="stroke-opacity" values="0.1;0.5;0.1" dur="4s" repeatCount="indefinite"/>
</path>
</pattern>
</defs>
<rect width="100%" height="100%" fill="url(#grid)" />
</svg>
</div>
{/* Волновые эффекты */}
<div className="absolute inset-0">
{[...Array(3)].map((_, i) => (
<div
key={i}
className="absolute inset-0 opacity-20"
style={{
background: `radial-gradient(circle at ${30 + i * 20}% ${40 + i * 15}%, rgba(16, 185, 129, 0.1) 0%, transparent 50%)`,
animation: `wave ${8 + i * 2}s ease-in-out infinite`,
animationDelay: `${i * 2}s`
}}
/>
))}
</div>
{/* Анимированные частицы */}
{mounted && backgroundParticles.map((particle) => (
<div
key={particle.id}
className="absolute rounded-full pointer-events-none transition-all duration-100"
style={{
left: `${particle.x}%`,
top: `${particle.y}%`,
width: `${particle.size}px`,
height: `${particle.size}px`,
backgroundColor: particle.color,
opacity: particle.opacity,
boxShadow: `0 0 ${particle.size * 2}px ${particle.color}`,
transform: 'translate(-50%, -50%)'
}}
/>
))}
{/* Соединительные линии между близкими частицами */}
{mounted && (
<svg className="absolute inset-0 w-full h-full pointer-events-none">
{backgroundParticles.map((particle1, i) =>
backgroundParticles.slice(i + 1).map((particle2, j) => {
const dx = particle1.x - particle2.x;
const dy = particle1.y - particle2.y;
const distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 15) {
return (
<line
key={`${i}-${j}`}
x1={`${particle1.x}%`}
y1={`${particle1.y}%`}
x2={`${particle2.x}%`}
y2={`${particle2.y}%`}
stroke={particle1.color}
strokeWidth="1"
opacity={0.1 + (0.8 - distance / 15) * 0.7}
/>
);
}
return null;
})
)}
</svg>
)}
{/* Дополнительные световые эффекты */}
<div className="absolute top-0 left-0 w-full h-full">
{[...Array(5)].map((_, i) => (
<div
key={i}
className="absolute w-2 h-2 bg-green-400 rounded-full opacity-30"
style={{
left: `${20 + i * 15}%`,
top: `${30 + i * 10}%`,
animation: `twinkle ${3 + i}s ease-in-out infinite`,
animationDelay: `${i * 0.5}s`,
boxShadow: '0 0 10px rgba(16, 185, 129, 0.8)'
}}
/>
))}
</div>
</div>
{/* Плавающие технологии */}
<div className="absolute inset-0 overflow-hidden">
{floatingTechs.map((tech) => (
<div
key={tech.id}
className="absolute text-sm font-mono text-gray-500 opacity-30 pointer-events-none"
style={{
left: tech.x,
top: tech.y,
animation: `float ${tech.duration}s ease-in-out infinite`,
animationDelay: `${tech.delay}s`
}}
>
{tech.tech}
</div>
))}
</div>
<div className="absolute inset-0 opacity-20">
<div className="absolute top-1/4 left-1/4 w-96 h-96 bg-slate-500 rounded-full blur-3xl opacity-30"></div>
<div className="absolute bottom-1/4 right-1/4 w-96 h-96 bg-gray-500 rounded-full blur-3xl opacity-30"></div>
@ -23,74 +429,411 @@ export default function About() {
</div>
</section>
{/* Company Story */}
{/* Интерактивное представление компании */}
<section className="section-padding">
<div className="max-w-7xl mx-auto px-4">
<div className="text-center mb-16">
<h2 className="text-4xl font-bold mb-6">
Кто мы <span className="gradient-text">такие</span>
</h2>
<p className="text-xl text-gray-300">Познакомьтесь с GUNDYREV через интерактивную презентацию</p>
</div>
<div className="grid md:grid-cols-2 gap-12 items-center mb-16">
{/* Анимированная схема компании */}
<div className="relative h-96 glass-effect rounded-lg overflow-hidden">
<div className="absolute inset-0 bg-gradient-to-br from-green-900/20 to-blue-900/20">
{/* Центральный логотип */}
<div className="absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2">
<div className="w-16 h-16 bg-gradient-to-br from-green-500 to-blue-500 rounded-full flex items-center justify-center animate-pulse">
<span className="text-white font-bold text-xl">G</span>
</div>
<div className="text-center mt-2 text-sm font-bold text-green-400">GUNDYREV</div>
</div>
{/* Орбитальные элементы услуг */}
<div className="absolute inset-0">
{[
{ name: 'Разработка ПО', icon: '💻', angle: 0, color: 'text-purple-400' },
{ name: 'Электроника', icon: '⚡', angle: 60, color: 'text-cyan-400' },
{ name: 'Соловей', icon: '🐦', angle: 120, color: 'text-amber-400' },
{ name: 'Secure-T', icon: '🛡️', angle: 180, color: 'text-red-400' },
{ name: 'Dr.Web', icon: '🔧', angle: 240, color: 'text-green-400' },
{ name: 'UX Софт', icon: '🎨', angle: 300, color: 'text-blue-400' }
].map((service, index) => (
<div
key={index}
className="absolute w-12 h-12 rounded-full glass-effect flex items-center justify-center hover-glow transition-all duration-300 cursor-pointer"
style={{
left: `${50 + 35 * Math.cos((service.angle * Math.PI) / 180)}%`,
top: `${50 + 35 * Math.sin((service.angle * Math.PI) / 180)}%`,
transform: 'translate(-50%, -50%)'
}}
title={service.name}
>
<span className={`text-xl ${service.color}`}>{service.icon}</span>
</div>
))}
</div>
{/* Соединительные линии */}
<svg className="absolute inset-0 w-full h-full pointer-events-none">
<defs>
<circle id="orbit" cx="50%" cy="50%" r="35%" fill="none" stroke="rgba(34, 197, 94, 0.2)" strokeWidth="1" strokeDasharray="5,5">
</circle>
</defs>
<use href="#orbit"/>
</svg>
</div>
</div>
{/* Интерактивная информация */}
<div className="space-y-6">
<div className="glass-effect p-6 rounded-lg hover-glow transition-all duration-300">
<div className="flex items-center gap-4 mb-4">
<div className="w-12 h-12 bg-green-500 rounded-full flex items-center justify-center">
<span className="text-white font-bold">🎯</span>
</div>
<h3 className="text-xl font-bold">Наша миссия</h3>
</div>
<p className="text-gray-300">
Создавать технологические решения, которые действительно работают и приносят пользу нашим клиентам
</p>
</div>
<div className="glass-effect p-6 rounded-lg hover-glow transition-all duration-300">
<div className="flex items-center gap-4 mb-4">
<div className="w-12 h-12 bg-blue-500 rounded-full flex items-center justify-center">
<span className="text-white font-bold">🚀</span>
</div>
<h3 className="text-xl font-bold">Наше видение</h3>
</div>
<p className="text-gray-300">
Стать ведущей IT-компанией, которая помогает бизнесу развиваться с помощью современных технологий
</p>
</div>
<div className="glass-effect p-6 rounded-lg hover-glow transition-all duration-300">
<div className="flex items-center gap-4 mb-4">
<div className="w-12 h-12 bg-purple-500 rounded-full flex items-center justify-center">
<span className="text-white font-bold">💡</span>
</div>
<h3 className="text-xl font-bold">Наш подход</h3>
</div>
<p className="text-gray-300">
Комплексный подход к решению задач от анализа потребностей до постпроектной поддержки
</p>
</div>
</div>
</div>
{/* Живая карта экспертизы */}
<div className="glass-effect p-8 rounded-lg">
<h3 className="text-2xl font-bold mb-6 text-center">
Области нашей <span className="gradient-text">экспертизы</span>
</h3>
<div className="grid md:grid-cols-3 gap-6">
{[
{
category: 'Разработка',
skills: ['React', 'Node.js', 'Python', 'Mobile Apps'],
level: 95,
color: 'bg-purple-500',
icon: '🔧'
},
{
category: 'Инфраструктура',
skills: ['AWS', 'Docker', 'Kubernetes', 'DevOps'],
level: 88,
color: 'bg-blue-500',
icon: '🏗️'
},
{
category: 'Безопасность',
skills: ['Secure-T', 'Dr.Web', 'Защита данных'],
level: 92,
color: 'bg-red-500',
icon: '🛡️'
},
{
category: 'Поставки',
skills: ['Электроника', 'Серверы', 'Госзакупки'],
level: 90,
color: 'bg-cyan-500',
icon: '📦'
},
{
category: 'Консалтинг',
skills: ['Архитектура', 'Планирование', 'Оптимизация'],
level: 85,
color: 'bg-green-500',
icon: '💼'
},
{
category: 'Поддержка',
skills: ['24/7', 'Мониторинг', 'Обслуживание'],
level: 97,
color: 'bg-amber-500',
icon: '🔧'
}
].map((area, index) => (
<div key={index} className="glass-effect p-6 rounded-lg hover-glow transition-all duration-300 transform hover:scale-105">
<div className="flex items-center gap-3 mb-4">
<div className={`w-10 h-10 ${area.color} rounded-full flex items-center justify-center`}>
<span className="text-white">{area.icon}</span>
</div>
<h4 className="text-lg font-bold">{area.category}</h4>
</div>
<div className="space-y-2 mb-4">
{area.skills.map((skill, skillIndex) => (
<div key={skillIndex} className="text-sm text-gray-400"> {skill}</div>
))}
</div>
<div className="mb-2">
<div className="flex justify-between text-sm">
<span>Экспертиза</span>
<span className="text-green-400">{area.level}%</span>
</div>
<div className="w-full bg-gray-700 rounded-full h-2">
<div
className={`h-2 rounded-full ${area.color} transition-all duration-1000`}
style={{ width: `${area.level}%` }}
></div>
</div>
</div>
</div>
))}
</div>
</div>
</div>
</section>
{/* Интерактивная временная шкала */}
<section className="section-padding bg-gray-900/50">
<div className="max-w-7xl mx-auto px-4">
<div className="grid md:grid-cols-2 gap-12 items-center">
<div>
<div className="text-center mb-16">
<h2 className="text-4xl font-bold mb-6">
Наша <span className="gradient-text">история</span>
</h2>
<p className="text-gray-300 mb-6 leading-relaxed">
Компания GUNDYREV была основана с целью предоставления комплексных IT-решений,
которые действительно работают и приносят результат. Мы начинали как небольшая
команда разработчиков, а сегодня представляем собой многопрофильную IT-компанию
с широким спектром услуг.
</p>
<p className="text-gray-300 mb-6 leading-relaxed">
За годы работы мы накопили огромный опыт в различных областях информационных
технологий от разработки программного обеспечения до поставки сложного
электронного оборудования. Наш подход основан на глубоком понимании потребностей
клиентов и применении самых современных технологий.
</p>
<p className="text-gray-300 leading-relaxed">
Сегодня мы гордимся тем, что являемся надежным партнером как для частных
компаний, так и для государственных организаций, предоставляя им качественные
решения, которые помогают развивать их бизнес и повышать эффективность работы.
</p>
<p className="text-xl text-gray-300">Путь от стартапа до ведущей IT-компании</p>
</div>
<div className="space-y-6">
<div className="glass-effect p-6 rounded-lg">
<div className="flex items-center space-x-4 mb-4">
<div className="w-12 h-12 bg-green-500 rounded-full flex items-center justify-center">
<span className="text-black font-bold">2019</span>
<div className="relative">
{/* Временная линия */}
<div className="absolute left-1/2 transform -translate-x-1/2 w-1 h-full bg-gray-700"></div>
<div className="space-y-12">
{timelineSteps.map((step, index) => (
<div
key={index}
className={`relative flex items-center ${
index % 2 === 0 ? 'justify-start' : 'justify-end'
}`}
>
{/* Точка на временной линии */}
<div className={`absolute left-1/2 transform -translate-x-1/2 w-6 h-6 rounded-full border-4 border-gray-900 transition-all duration-500 ${
activeTimelineStep === index ? `${step.color} scale-125 animate-pulse` : 'bg-gray-600'
}`}></div>
{/* Карточка события */}
<div className={`w-5/12 ${
activeTimelineStep === index ? 'scale-105' : 'scale-100'
} transition-all duration-500`}>
<div className={`glass-effect p-6 rounded-lg ${
activeTimelineStep === index ? 'ring-2 ring-green-400' : ''
}`}>
<div className="flex items-center gap-3 mb-3">
<div className={`w-12 h-12 rounded-full flex items-center justify-center text-white font-bold ${step.color}`}>
{step.year}
</div>
<h3 className="text-xl font-bold">Основание компании</h3>
<h3 className="text-xl font-bold">{step.title}</h3>
</div>
<p className="text-gray-300">Начало деятельности в сфере разработки ПО</p>
<p className="text-gray-300">{step.description}</p>
</div>
</div>
</div>
))}
</div>
</div>
</div>
</section>
{/* 3D Команда */}
<section className="section-padding">
<div className="max-w-7xl mx-auto px-4">
<div className="text-center mb-16">
<h2 className="text-4xl font-bold mb-6">
Наша <span className="gradient-text">команда</span>
</h2>
<p className="text-xl text-gray-300">Профессионалы, которые создают будущее</p>
</div>
<div className="glass-effect p-6 rounded-lg">
<div className="flex items-center space-x-4 mb-4">
<div className="w-12 h-12 bg-blue-500 rounded-full flex items-center justify-center">
<span className="text-white font-bold">2020</span>
</div>
<h3 className="text-xl font-bold">Расширение услуг</h3>
</div>
<p className="text-gray-300">Добавление поставки электроники и системной интеграции</p>
<div className="grid md:grid-cols-2 lg:grid-cols-3 gap-8">
{teamMembers.map((member, index) => (
<div
key={index}
className="relative h-80 cursor-pointer"
onClick={() => handleTeamMemberClick(index)}
>
<div className={`absolute inset-0 w-full h-full transition-all duration-700 transform-gpu ${
teamMemberFlipped === index ? 'rotateY-180' : ''
}`} style={{ transformStyle: 'preserve-3d' }}>
{/* Лицевая сторона */}
<div className="absolute inset-0 w-full h-full glass-effect rounded-lg p-6 flex flex-col items-center justify-center text-center hover-glow transition-all duration-300"
style={{ backfaceVisibility: 'hidden' }}>
<div className="text-6xl mb-4">{member.avatar}</div>
<h3 className="text-xl font-bold mb-2">{member.name}</h3>
<p className="text-gray-400 mb-4">{member.role}</p>
<div className="text-sm text-gray-500">Нажмите для подробностей</div>
</div>
<div className="glass-effect p-6 rounded-lg">
<div className="flex items-center space-x-4 mb-4">
<div className="w-12 h-12 bg-purple-500 rounded-full flex items-center justify-center">
<span className="text-white font-bold">2022</span>
{/* Обратная сторона */}
<div className="absolute inset-0 w-full h-full glass-effect rounded-lg p-6 flex flex-col justify-center"
style={{ backfaceVisibility: 'hidden', transform: 'rotateY(180deg)' }}>
<h3 className="text-lg font-bold mb-3 text-green-400">{member.name}</h3>
<p className="text-sm text-gray-300 mb-4">{member.description}</p>
<div className="space-y-2 mb-4">
<div className="flex justify-between">
<span className="text-xs text-gray-400">Опыт:</span>
<span className="text-xs text-white">{member.experience}</span>
</div>
<h3 className="text-xl font-bold">Государственные контракты</h3>
<div className="flex justify-between">
<span className="text-xs text-gray-400">Проекты:</span>
<span className="text-xs text-white">{member.projects}</span>
</div>
<p className="text-gray-300">Начало работы с госсектором по 44-ФЗ и 223-ФЗ</p>
</div>
<div className="glass-effect p-6 rounded-lg">
<div className="flex items-center space-x-4 mb-4">
<div className="w-12 h-12 bg-amber-500 rounded-full flex items-center justify-center">
<span className="text-black font-bold">2024</span>
<div className="flex flex-wrap gap-1">
{member.skills.map((skill, skillIndex) => (
<span key={skillIndex} className="px-2 py-1 bg-green-500/20 text-green-400 rounded text-xs">
{skill}
</span>
))}
</div>
<h3 className="text-xl font-bold">Полный спектр услуг</h3>
</div>
<p className="text-gray-300">Комплексный поставщик IT-решений и оборудования</p>
</div>
</div>
))}
</div>
</div>
</section>
{/* Живые счетчики достижений */}
<section className="section-padding bg-gray-900/50">
<div className="max-w-7xl mx-auto px-4">
<div className="text-center mb-16">
<h2 className="text-4xl font-bold mb-6">
Наши <span className="gradient-text">достижения</span>
</h2>
</div>
<div className="grid md:grid-cols-4 gap-8">
<div className="glass-effect p-8 rounded-lg text-center hover-glow transition-all duration-300 transform hover:scale-105">
<div className="text-5xl font-bold text-green-400 mb-4 count-up">
{liveCounters.projects}+
</div>
<p className="text-gray-300">Выполненных проектов</p>
<div className="mt-2 h-2 bg-gray-700 rounded-full overflow-hidden">
<div
className="h-full bg-green-400 transition-all duration-2000"
style={{ width: `${(liveCounters.projects / 500) * 100}%` }}
></div>
</div>
</div>
<div className="glass-effect p-8 rounded-lg text-center hover-glow transition-all duration-300 transform hover:scale-105">
<div className="text-5xl font-bold text-blue-400 mb-4 count-up">
{liveCounters.clients}+
</div>
<p className="text-gray-300">Довольных клиентов</p>
<div className="mt-2 h-2 bg-gray-700 rounded-full overflow-hidden">
<div
className="h-full bg-blue-400 transition-all duration-2000"
style={{ width: `${(liveCounters.clients / 150) * 100}%` }}
></div>
</div>
</div>
<div className="glass-effect p-8 rounded-lg text-center hover-glow transition-all duration-300 transform hover:scale-105">
<div className="text-5xl font-bold text-purple-400 mb-4 count-up">
{liveCounters.years}+
</div>
<p className="text-gray-300">Лет на рынке</p>
<div className="mt-2 h-2 bg-gray-700 rounded-full overflow-hidden">
<div
className="h-full bg-purple-400 transition-all duration-2000"
style={{ width: `${(liveCounters.years / 5) * 100}%` }}
></div>
</div>
</div>
<div className="glass-effect p-8 rounded-lg text-center hover-glow transition-all duration-300 transform hover:scale-105">
<div className="text-5xl font-bold text-amber-400 mb-4 count-up">
{liveCounters.support}/7
</div>
<p className="text-gray-300">Техническая поддержка</p>
<div className="mt-2 h-2 bg-gray-700 rounded-full overflow-hidden">
<div
className="h-full bg-amber-400 transition-all duration-2000"
style={{ width: `${(liveCounters.support / 24) * 100}%` }}
></div>
</div>
</div>
</div>
</div>
</section>
{/* Интерактивный граф компетенций */}
<section className="section-padding">
<div className="max-w-7xl mx-auto px-4">
<div className="text-center mb-16">
<h2 className="text-4xl font-bold mb-6">
Наши <span className="gradient-text">компетенции</span>
</h2>
<p className="text-xl text-gray-300">Технологии, которыми мы владеем</p>
</div>
<div className="relative h-96 glass-effect rounded-lg p-8 overflow-hidden">
<div className="absolute inset-0 bg-gradient-to-br from-purple-900/20 to-blue-900/20"></div>
<div className="relative z-10 flex flex-wrap justify-center items-center gap-8 h-full">
{Object.entries(competencies).map(([category, techs]) => (
<div key={category} className="relative">
<button
onClick={() => handleCompetencyClick(category)}
className={`px-6 py-3 rounded-lg font-semibold transition-all duration-300 transform hover:scale-110 ${
competencyGraph.activeNode === category
? 'bg-purple-500 text-white scale-125'
: 'glass-effect text-gray-300 hover:text-white'
}`}
>
{category}
</button>
{/* Связанные технологии */}
{competencyGraph.activeNode === category && (
<div className="absolute top-full mt-4 left-1/2 transform -translate-x-1/2 z-20">
<div className="flex flex-wrap gap-2 justify-center max-w-xs">
{techs.map((tech, index) => (
<span
key={index}
className="px-3 py-1 bg-purple-500/20 text-purple-300 rounded-full text-sm animate-fadeIn"
style={{ animationDelay: `${index * 0.1}s` }}
>
{tech}
</span>
))}
</div>
</div>
)}
</div>
))}
</div>
</div>
</div>
</section>

View File

@ -108,16 +108,34 @@ export default function InteractiveBlocks() {
},
];
// Генерируем случайные начальные позиции для каждого блока
const getRandomInitialPosition = (index: number) => {
// Используем простую логику без зависимости от containerBounds
// Генерируем детерминированные начальные позиции для каждого блока
const getInitialPosition = (index: number) => {
const screenWidth = typeof window !== 'undefined' ? window.innerWidth : 1200;
const cardWidth = 288; // w-72 = 18rem = 288px
const safeZoneWidth = Math.max(400, screenWidth - cardWidth - 40);
const safeZoneWidth = Math.max(600, screenWidth - cardWidth - 80);
// Детерминированные позиции на основе индекса - более разбросанные
const positions = [
{ x: 50, y: -300 },
{ x: 350, y: -650 },
{ x: 650, y: -450 },
{ x: 150, y: -800 },
{ x: 450, y: -350 },
{ x: 250, y: -550 }
];
const basePos = positions[index % positions.length];
// Адаптируем позицию под ширину экрана
const adaptedX = Math.min(basePos.x, safeZoneWidth - 50);
const finalX = adaptedX + (index * 123) % (safeZoneWidth - adaptedX - 50);
// Добавляем дополнительную высоту для каждого блока
const extraHeight = (index * 200) + ((index * 17) % 300);
return {
x: 20 + Math.random() * (safeZoneWidth - 40),
y: -300 - (index * 150) - Math.random() * 200
x: Math.max(20, Math.min(finalX, safeZoneWidth - 20)),
y: basePos.y - extraHeight
};
};
@ -133,7 +151,7 @@ export default function InteractiveBlocks() {
{/* Падающие блоки */}
{blocks.map((block, index) => {
const initialPos = getRandomInitialPosition(index);
const initialPos = getInitialPosition(index);
return (
<DraggableCard
key={block.id}
@ -209,19 +227,15 @@ export default function InteractiveBlocks() {
key={i}
className="absolute w-1 h-1 bg-green-400 rounded-full floating-particle"
style={{
left: `${Math.random() * 100}%`,
top: `${Math.random() * 100}%`,
animationDelay: `${Math.random() * 5}s`,
animationDuration: `${3 + Math.random() * 4}s`,
left: `${(i * 7 + 13) % 100}%`,
top: `${(i * 11 + 23) % 100}%`,
animationDelay: `${i * 0.5}s`,
animationDuration: `${3 + (i % 4)}s`,
}}
/>
))}
</div>
{/* Индикатор "земли" */}
<div className="absolute bottom-0 left-0 right-0 h-1 bg-gradient-to-r from-green-400/20 via-cyan-400/20 to-purple-400/20 pointer-events-none" />
</div>
);
}

View File

@ -1,6 +1,281 @@
'use client';
import Navigation from '../components/Navigation';
import { useState, useEffect } from 'react';
export default function DrWeb() {
// Добавляем стили для анимации
useEffect(() => {
const style = document.createElement('style');
style.textContent = `
@keyframes slide-in-right {
from {
transform: translateX(100%);
opacity: 0;
}
to {
transform: translateX(0);
opacity: 1;
}
}
.animate-slide-in-right {
animation: slide-in-right 0.5s ease-out;
}
@keyframes float-in {
from {
transform: scale(0) rotate(180deg);
opacity: 0;
}
to {
transform: scale(1) rotate(0deg);
opacity: 1;
}
}
.animate-float-in {
animation: float-in 0.6s ease-out;
}
@keyframes pulse-glow {
0%, 100% {
box-shadow: 0 0 5px rgba(34, 197, 94, 0.5);
}
50% {
box-shadow: 0 0 20px rgba(34, 197, 94, 0.8);
}
}
.animate-pulse-glow {
animation: pulse-glow 2s infinite;
}
@keyframes bounce-in {
0% {
transform: translateY(100vh) scale(0.3);
opacity: 0;
}
50% {
transform: translateY(-30px) scale(1.05);
}
70% {
transform: translateY(10px) scale(0.95);
}
100% {
transform: translateY(0) scale(1);
opacity: 1;
}
}
.animate-bounce-in {
animation: bounce-in 0.8s ease-out;
}
`;
document.head.appendChild(style);
return () => {
document.head.removeChild(style);
};
}, []);
const [isProductsModalOpen, setIsProductsModalOpen] = useState(false);
const [isLicenseModalOpen, setIsLicenseModalOpen] = useState(false);
const [isConsultationModalOpen, setIsConsultationModalOpen] = useState(false);
const [licenseForm, setLicenseForm] = useState({
name: '',
email: '',
company: '',
product: '',
licenses: '',
message: ''
});
const [consultationForm, setConsultationForm] = useState({
name: '',
email: '',
company: '',
message: ''
});
// Анимированная статистика
const [stats, setStats] = useState({
threatsBlocked: 0,
devicesProtected: 0,
updatesDaily: 0,
yearsExperience: 0
});
// Живые уведомления
const [notifications, setNotifications] = useState<Array<{id: number, message: string, type: 'threat' | 'update' | 'scan'}>>([]);
const [notificationId, setNotificationId] = useState(0);
// Дополнительные уведомления для разных частей экрана
const [floatingAlerts, setFloatingAlerts] = useState<Array<{
id: number,
message: string,
type: 'success' | 'warning' | 'info' | 'danger',
position: 'top-left' | 'bottom-left' | 'bottom-right' | 'center',
x: number,
y: number
}>>([]);
const [alertId, setAlertId] = useState(0);
// Анимация статистики
useEffect(() => {
const targets = {
threatsBlocked: 15420000,
devicesProtected: 2800000,
updatesDaily: 150000,
yearsExperience: 30
};
const duration = 2000; // 2 секунды
const steps = 60;
const stepDuration = duration / steps;
const intervals = Object.keys(targets).map(key => {
const targetValue = targets[key as keyof typeof targets];
const increment = targetValue / steps;
let currentValue = 0;
let step = 0;
return setInterval(() => {
if (step < steps) {
currentValue += increment;
setStats(prev => ({
...prev,
[key]: Math.floor(currentValue)
}));
step++;
}
}, stepDuration);
});
return () => intervals.forEach(interval => clearInterval(interval));
}, []);
// Живые уведомления
useEffect(() => {
const threatMessages = [
'Заблокирована попытка фишинга на drweb-user-2847',
'Обнаружен троян на устройстве corp-laptop-156',
'Предотвращена атака на почтовый сервер',
'Заблокирован подозрительный URL-адрес',
'Обновлены вирусные базы для 1,247 устройств',
'Завершено сканирование сети компании',
'Обнаружено и удалено вредоносное ПО'
];
const addNotification = () => {
const message = threatMessages[Math.floor(Math.random() * threatMessages.length)];
const types: Array<'threat' | 'update' | 'scan'> = ['threat', 'update', 'scan'];
const type = types[Math.floor(Math.random() * types.length)];
const newNotification = {
id: notificationId,
message,
type
};
setNotifications(prev => [newNotification, ...prev.slice(0, 4)]);
setNotificationId(prev => prev + 1);
// Удаляем уведомление через 5 секунд
setTimeout(() => {
setNotifications(prev => prev.filter(n => n.id !== newNotification.id));
}, 5000);
};
const interval = setInterval(addNotification, 3000);
return () => clearInterval(interval);
}, [notificationId]);
// Плавающие алерты по всему экрану
useEffect(() => {
const floatingMessages = [
{ message: 'Система защищена', type: 'success' as const },
{ message: 'Подозрительная активность', type: 'warning' as const },
{ message: 'Обновление завершено', type: 'info' as const },
{ message: 'Угроза заблокирована', type: 'danger' as const },
{ message: 'Сканирование активно', type: 'info' as const },
{ message: 'Файрвол активен', type: 'success' as const },
{ message: 'Вирусные базы обновлены', type: 'info' as const }
];
const positions: Array<'top-left' | 'bottom-left' | 'bottom-right' | 'center'> =
['top-left', 'bottom-left', 'bottom-right', 'center'];
const addFloatingAlert = () => {
const messageData = floatingMessages[Math.floor(Math.random() * floatingMessages.length)];
const position = positions[Math.floor(Math.random() * positions.length)];
const newAlert = {
id: alertId,
...messageData,
position,
x: Math.random() * 200 - 100, // Случайное смещение
y: Math.random() * 100 - 50
};
setFloatingAlerts(prev => [newAlert, ...prev.slice(0, 6)]);
setAlertId(prev => prev + 1);
// Удаляем через 4 секунды
setTimeout(() => {
setFloatingAlerts(prev => prev.filter(a => a.id !== newAlert.id));
}, 4000);
};
const interval = setInterval(addFloatingAlert, 2000);
return () => clearInterval(interval);
}, [alertId]);
const handleProductsClick = () => {
setIsProductsModalOpen(true);
document.body.style.overflow = 'hidden';
};
const handleLicenseClick = () => {
setIsLicenseModalOpen(true);
document.body.style.overflow = 'hidden';
};
const handleConsultationClick = () => {
setIsConsultationModalOpen(true);
document.body.style.overflow = 'hidden';
};
const handleCloseModal = () => {
setIsProductsModalOpen(false);
setIsLicenseModalOpen(false);
setIsConsultationModalOpen(false);
document.body.style.overflow = 'unset';
};
const handleLicenseInputChange = (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement>) => {
const { name, value } = e.target;
setLicenseForm(prev => ({
...prev,
[name]: value
}));
};
const handleConsultationInputChange = (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
const { name, value } = e.target;
setConsultationForm(prev => ({
...prev,
[name]: value
}));
};
const handleLicenseSubmit = (e: React.FormEvent) => {
e.preventDefault();
alert(`Спасибо за заявку, ${licenseForm.name}! Мы свяжемся с вами для оформления лицензии.`);
setLicenseForm({ name: '', email: '', company: '', product: '', licenses: '', message: '' });
handleCloseModal();
};
const handleConsultationSubmit = (e: React.FormEvent) => {
e.preventDefault();
alert(`Спасибо за заявку, ${consultationForm.name}! Наш специалист свяжется с вами.`);
setConsultationForm({ name: '', email: '', company: '', message: '' });
handleCloseModal();
};
return (
<>
<Navigation />
@ -26,16 +301,235 @@ export default function DrWeb() {
Официальный партнер Dr.Web надежная антивирусная защита для бизнеса и дома
</p>
<div className="flex flex-col sm:flex-row gap-4 justify-center">
<button className="px-8 py-3 bg-green-500 text-black font-semibold rounded-lg hover-glow transition-all duration-300">
<button
onClick={handleProductsClick}
className="px-8 py-3 bg-green-500 text-black font-semibold rounded-lg hover-glow transition-all duration-300 hover:bg-green-600 active:scale-95 cursor-pointer"
>
Продукты Dr.Web
</button>
<button className="px-8 py-3 glass-effect text-white font-semibold rounded-lg hover:bg-white/10 transition-all duration-300">
<button
onClick={handleLicenseClick}
className="px-8 py-3 glass-effect text-white font-semibold rounded-lg hover:bg-white/10 transition-all duration-300 active:scale-95 cursor-pointer"
>
Получить лицензию
</button>
</div>
</div>
</section>
{/* Live Security Dashboard */}
<section className="section-padding bg-black/50 relative overflow-hidden">
{/* Живые уведомления */}
<div className="fixed top-20 right-4 z-40 space-y-2 max-w-sm">
{notifications.map((notification) => (
<div
key={notification.id}
className={`p-3 rounded-lg border-l-4 glass-effect animate-slide-in-right animate-pulse-glow ${
notification.type === 'threat' ? 'border-red-500 bg-red-900/20' :
notification.type === 'update' ? 'border-blue-500 bg-blue-900/20' :
'border-green-500 bg-green-900/20'
}`}
>
<div className="flex items-start space-x-2">
<div className={`text-lg animate-bounce ${
notification.type === 'threat' ? 'text-red-400' :
notification.type === 'update' ? 'text-blue-400' :
'text-green-400'
}`}>
{notification.type === 'threat' ? '🛡️' :
notification.type === 'update' ? '🔄' : '🔍'}
</div>
<div>
<p className="text-sm text-gray-300">{notification.message}</p>
<p className="text-xs text-gray-500 mt-1">Только что</p>
</div>
</div>
</div>
))}
</div>
{/* Плавающие алерты в левом верхнем углу */}
<div className="fixed top-20 left-4 z-40 space-y-2 max-w-sm">
{floatingAlerts.filter(alert => alert.position === 'top-left').map((alert) => (
<div
key={alert.id}
className={`p-3 rounded-lg border glass-effect animate-float-in ${
alert.type === 'success' ? 'border-green-500 bg-green-900/20' :
alert.type === 'warning' ? 'border-yellow-500 bg-yellow-900/20' :
alert.type === 'info' ? 'border-blue-500 bg-blue-900/20' :
'border-red-500 bg-red-900/20'
}`}
>
<div className="flex items-center space-x-2">
<div className={`text-lg ${
alert.type === 'success' ? 'text-green-400' :
alert.type === 'warning' ? 'text-yellow-400' :
alert.type === 'info' ? 'text-blue-400' : 'text-red-400'
}`}>
{alert.type === 'success' ? '✅' :
alert.type === 'warning' ? '⚠️' :
alert.type === 'info' ? '' : '❌'}
</div>
<p className="text-sm text-gray-300">{alert.message}</p>
</div>
</div>
))}
</div>
{/* Плавающие алерты в нижнем левом углу */}
<div className="fixed bottom-20 left-4 z-40 space-y-2 max-w-sm">
{floatingAlerts.filter(alert => alert.position === 'bottom-left').map((alert) => (
<div
key={alert.id}
className={`p-3 rounded-lg border glass-effect animate-bounce-in ${
alert.type === 'success' ? 'border-green-500 bg-green-900/20' :
alert.type === 'warning' ? 'border-yellow-500 bg-yellow-900/20' :
alert.type === 'info' ? 'border-blue-500 bg-blue-900/20' :
'border-red-500 bg-red-900/20'
}`}
>
<div className="flex items-center space-x-2">
<div className={`text-lg animate-pulse ${
alert.type === 'success' ? 'text-green-400' :
alert.type === 'warning' ? 'text-yellow-400' :
alert.type === 'info' ? 'text-blue-400' : 'text-red-400'
}`}>
{alert.type === 'success' ? '✅' :
alert.type === 'warning' ? '⚠️' :
alert.type === 'info' ? '' : '❌'}
</div>
<p className="text-sm text-gray-300">{alert.message}</p>
</div>
</div>
))}
</div>
{/* Плавающие алерты в нижнем правом углу */}
<div className="fixed bottom-20 right-4 z-40 space-y-2 max-w-sm">
{floatingAlerts.filter(alert => alert.position === 'bottom-right').map((alert) => (
<div
key={alert.id}
className={`p-3 rounded-lg border glass-effect animate-slide-in-right ${
alert.type === 'success' ? 'border-green-500 bg-green-900/20' :
alert.type === 'warning' ? 'border-yellow-500 bg-yellow-900/20' :
alert.type === 'info' ? 'border-blue-500 bg-blue-900/20' :
'border-red-500 bg-red-900/20'
}`}
>
<div className="flex items-center space-x-2">
<div className={`text-lg animate-spin ${
alert.type === 'success' ? 'text-green-400' :
alert.type === 'warning' ? 'text-yellow-400' :
alert.type === 'info' ? 'text-blue-400' : 'text-red-400'
}`}>
{alert.type === 'success' ? '✅' :
alert.type === 'warning' ? '⚠️' :
alert.type === 'info' ? '' : '❌'}
</div>
<p className="text-sm text-gray-300">{alert.message}</p>
</div>
</div>
))}
</div>
<div className="max-w-7xl mx-auto px-4">
<div className="text-center mb-16">
<h2 className="text-4xl md:text-5xl font-bold mb-6">
Защита в <span className="text-green-400">реальном времени</span>
</h2>
<p className="text-xl text-gray-300 max-w-3xl mx-auto">
Dr.Web защищает миллионы устройств по всему миру каждую секунду
</p>
</div>
{/* Анимированная статистика */}
<div className="grid md:grid-cols-4 gap-8 mb-16">
<div className="glass-effect p-8 rounded-lg text-center hover-glow transition-all duration-300 border border-green-500/30">
<div className="text-green-400 text-4xl mb-4">🛡</div>
<div className="text-3xl font-bold text-green-400 mb-2">
{stats.threatsBlocked.toLocaleString()}+
</div>
<p className="text-gray-300">Угроз заблокировано</p>
<div className="mt-2 h-1 bg-gray-700 rounded-full overflow-hidden">
<div className="h-full bg-green-500 rounded-full animate-pulse" style={{width: '85%'}}></div>
</div>
</div>
<div className="glass-effect p-8 rounded-lg text-center hover-glow transition-all duration-300 border border-green-500/30">
<div className="text-green-400 text-4xl mb-4">📱</div>
<div className="text-3xl font-bold text-green-400 mb-2">
{stats.devicesProtected.toLocaleString()}+
</div>
<p className="text-gray-300">Устройств защищено</p>
<div className="mt-2 h-1 bg-gray-700 rounded-full overflow-hidden">
<div className="h-full bg-green-500 rounded-full animate-pulse" style={{width: '92%'}}></div>
</div>
</div>
<div className="glass-effect p-8 rounded-lg text-center hover-glow transition-all duration-300 border border-green-500/30">
<div className="text-green-400 text-4xl mb-4">🔄</div>
<div className="text-3xl font-bold text-green-400 mb-2">
{stats.updatesDaily.toLocaleString()}+
</div>
<p className="text-gray-300">Обновлений в день</p>
<div className="mt-2 h-1 bg-gray-700 rounded-full overflow-hidden">
<div className="h-full bg-green-500 rounded-full animate-pulse" style={{width: '78%'}}></div>
</div>
</div>
<div className="glass-effect p-8 rounded-lg text-center hover-glow transition-all duration-300 border border-green-500/30">
<div className="text-green-400 text-4xl mb-4">🏆</div>
<div className="text-3xl font-bold text-green-400 mb-2">
{stats.yearsExperience}+
</div>
<p className="text-gray-300">Лет опыта</p>
<div className="mt-2 h-1 bg-gray-700 rounded-full overflow-hidden">
<div className="h-full bg-green-500 rounded-full animate-pulse" style={{width: '100%'}}></div>
</div>
</div>
</div>
{/* Интерактивная карта угроз */}
<div className="glass-effect p-8 rounded-lg border border-green-500/30">
<h3 className="text-2xl font-bold mb-6 text-center text-green-400">
Глобальная карта угроз
</h3>
<div className="relative h-64 bg-gray-900/50 rounded-lg overflow-hidden">
{/* Имитация карты мира */}
<div className="absolute inset-0 flex items-center justify-center">
<div className="text-6xl text-gray-600">🌍</div>
</div>
{/* Анимированные точки угроз */}
<div className="absolute top-1/4 left-1/4 w-3 h-3 bg-red-500 rounded-full animate-ping"></div>
<div className="absolute top-1/3 right-1/3 w-2 h-2 bg-yellow-500 rounded-full animate-ping" style={{animationDelay: '0.5s'}}></div>
<div className="absolute bottom-1/3 left-1/2 w-4 h-4 bg-red-600 rounded-full animate-ping" style={{animationDelay: '1s'}}></div>
<div className="absolute top-1/2 right-1/4 w-2 h-2 bg-orange-500 rounded-full animate-ping" style={{animationDelay: '1.5s'}}></div>
<div className="absolute bottom-1/4 right-1/2 w-3 h-3 bg-red-400 rounded-full animate-ping" style={{animationDelay: '2s'}}></div>
{/* Защищенные зоны */}
<div className="absolute top-1/2 left-1/3 w-6 h-6 bg-green-500 rounded-full animate-pulse opacity-70"></div>
<div className="absolute bottom-1/2 right-1/3 w-5 h-5 bg-green-400 rounded-full animate-pulse opacity-70" style={{animationDelay: '0.7s'}}></div>
</div>
<div className="mt-6 grid md:grid-cols-3 gap-4 text-center">
<div className="flex items-center justify-center space-x-2">
<div className="w-3 h-3 bg-red-500 rounded-full animate-ping"></div>
<span className="text-sm text-gray-300">Активные угрозы</span>
</div>
<div className="flex items-center justify-center space-x-2">
<div className="w-3 h-3 bg-green-500 rounded-full animate-pulse"></div>
<span className="text-sm text-gray-300">Защищенные зоны</span>
</div>
<div className="flex items-center justify-center space-x-2">
<div className="w-3 h-3 bg-blue-500 rounded-full"></div>
<span className="text-sm text-gray-300">Мониторинг</span>
</div>
</div>
</div>
</div>
</section>
{/* Products Section */}
<section className="section-padding bg-gray-900/50">
<div className="max-w-7xl mx-auto px-4">
@ -49,88 +543,151 @@ export default function DrWeb() {
</div>
<div className="grid md:grid-cols-2 lg:grid-cols-3 gap-8">
<div className="glass-effect p-8 rounded-lg hover-glow transition-all duration-300 border-l-4 border-green-500">
<div className="text-green-400 text-4xl mb-4">🖥</div>
<h3 className="text-xl font-bold mb-4">Dr.Web Security Space</h3>
<div className="glass-effect p-8 rounded-lg hover-glow transition-all duration-300 border-l-4 border-green-500 group hover:scale-105 hover:border-green-400">
<div className="text-green-400 text-4xl mb-4 group-hover:animate-bounce">🖥</div>
<h3 className="text-xl font-bold mb-4 group-hover:text-green-300 transition-colors">Dr.Web Security Space</h3>
<p className="text-gray-300 mb-4">
Комплексная защита для домашних компьютеров и ноутбуков
</p>
<ul className="text-sm text-gray-400 space-y-1">
<li> Антивирус и антишпион</li>
<li> Файрвол</li>
<li> Антиспам</li>
<li> Родительский контроль</li>
<ul className="text-sm text-gray-400 space-y-1 mb-4">
<li className="group-hover:text-gray-300 transition-colors"> Антивирус и антишпион</li>
<li className="group-hover:text-gray-300 transition-colors"> Файрвол</li>
<li className="group-hover:text-gray-300 transition-colors"> Антиспам</li>
<li className="group-hover:text-gray-300 transition-colors"> Родительский контроль</li>
</ul>
<div className="opacity-0 group-hover:opacity-100 transition-opacity duration-300">
<button
onClick={() => {
setLicenseForm(prev => ({ ...prev, product: 'Dr.Web Security Space' }));
handleLicenseClick();
}}
className="w-full px-4 py-2 bg-green-500 text-black rounded-lg hover:bg-green-600 transition-colors font-semibold"
>
Получить лицензию
</button>
</div>
</div>
<div className="glass-effect p-8 rounded-lg hover-glow transition-all duration-300 border-l-4 border-green-500">
<div className="text-green-400 text-4xl mb-4">🏢</div>
<h3 className="text-xl font-bold mb-4">Dr.Web Enterprise Suite</h3>
<div className="glass-effect p-8 rounded-lg hover-glow transition-all duration-300 border-l-4 border-green-500 group hover:scale-105 hover:border-green-400">
<div className="text-green-400 text-4xl mb-4 group-hover:animate-bounce">🏢</div>
<h3 className="text-xl font-bold mb-4 group-hover:text-green-300 transition-colors">Dr.Web Enterprise Suite</h3>
<p className="text-gray-300 mb-4">
Корпоративное решение для защиты бизнеса
</p>
<ul className="text-sm text-gray-400 space-y-1">
<li> Централизованное управление</li>
<li> Защита серверов</li>
<li> Почтовая безопасность</li>
<li> Мобильная защита</li>
<ul className="text-sm text-gray-400 space-y-1 mb-4">
<li className="group-hover:text-gray-300 transition-colors"> Централизованное управление</li>
<li className="group-hover:text-gray-300 transition-colors"> Защита серверов</li>
<li className="group-hover:text-gray-300 transition-colors"> Почтовая безопасность</li>
<li className="group-hover:text-gray-300 transition-colors"> Мобильная защита</li>
</ul>
<div className="opacity-0 group-hover:opacity-100 transition-opacity duration-300">
<button
onClick={() => {
setLicenseForm(prev => ({ ...prev, product: 'Dr.Web Enterprise Suite' }));
handleLicenseClick();
}}
className="w-full px-4 py-2 bg-green-500 text-black rounded-lg hover:bg-green-600 transition-colors font-semibold"
>
Получить лицензию
</button>
</div>
</div>
<div className="glass-effect p-8 rounded-lg hover-glow transition-all duration-300 border-l-4 border-green-500">
<div className="text-green-400 text-4xl mb-4">📱</div>
<h3 className="text-xl font-bold mb-4">Dr.Web Mobile Security</h3>
<div className="glass-effect p-8 rounded-lg hover-glow transition-all duration-300 border-l-4 border-green-500 group hover:scale-105 hover:border-green-400">
<div className="text-green-400 text-4xl mb-4 group-hover:animate-bounce">📱</div>
<h3 className="text-xl font-bold mb-4 group-hover:text-green-300 transition-colors">Dr.Web Mobile Security</h3>
<p className="text-gray-300 mb-4">
Защита мобильных устройств Android и iOS
</p>
<ul className="text-sm text-gray-400 space-y-1">
<li> Антивирус для мобильных</li>
<li> Антивор</li>
<li> URL-фильтр</li>
<li> Родительский контроль</li>
<ul className="text-sm text-gray-400 space-y-1 mb-4">
<li className="group-hover:text-gray-300 transition-colors"> Антивирус для мобильных</li>
<li className="group-hover:text-gray-300 transition-colors"> Антивор</li>
<li className="group-hover:text-gray-300 transition-colors"> URL-фильтр</li>
<li className="group-hover:text-gray-300 transition-colors"> Родительский контроль</li>
</ul>
<div className="opacity-0 group-hover:opacity-100 transition-opacity duration-300">
<button
onClick={() => {
setLicenseForm(prev => ({ ...prev, product: 'Dr.Web Mobile Security' }));
handleLicenseClick();
}}
className="w-full px-4 py-2 bg-green-500 text-black rounded-lg hover:bg-green-600 transition-colors font-semibold"
>
Получить лицензию
</button>
</div>
</div>
<div className="glass-effect p-8 rounded-lg hover-glow transition-all duration-300 border-l-4 border-green-500">
<div className="text-green-400 text-4xl mb-4">🌐</div>
<h3 className="text-xl font-bold mb-4">Dr.Web Gateway Security</h3>
<div className="glass-effect p-8 rounded-lg hover-glow transition-all duration-300 border-l-4 border-green-500 group hover:scale-105 hover:border-green-400">
<div className="text-green-400 text-4xl mb-4 group-hover:animate-bounce">🌐</div>
<h3 className="text-xl font-bold mb-4 group-hover:text-green-300 transition-colors">Dr.Web Gateway Security</h3>
<p className="text-gray-300 mb-4">
Защита интернет-шлюзов и почтовых серверов
</p>
<ul className="text-sm text-gray-400 space-y-1">
<li> Фильтрация трафика</li>
<li> Антиспам</li>
<li> Контент-фильтр</li>
<li> Защита от фишинга</li>
<ul className="text-sm text-gray-400 space-y-1 mb-4">
<li className="group-hover:text-gray-300 transition-colors"> Фильтрация трафика</li>
<li className="group-hover:text-gray-300 transition-colors"> Антиспам</li>
<li className="group-hover:text-gray-300 transition-colors"> Контент-фильтр</li>
<li className="group-hover:text-gray-300 transition-colors"> Защита от фишинга</li>
</ul>
<div className="opacity-0 group-hover:opacity-100 transition-opacity duration-300">
<button
onClick={() => {
setLicenseForm(prev => ({ ...prev, product: 'Dr.Web Gateway Security' }));
handleLicenseClick();
}}
className="w-full px-4 py-2 bg-green-500 text-black rounded-lg hover:bg-green-600 transition-colors font-semibold"
>
Получить лицензию
</button>
</div>
</div>
<div className="glass-effect p-8 rounded-lg hover-glow transition-all duration-300 border-l-4 border-green-500">
<div className="text-green-400 text-4xl mb-4"></div>
<h3 className="text-xl font-bold mb-4">Dr.Web Cloud</h3>
<div className="glass-effect p-8 rounded-lg hover-glow transition-all duration-300 border-l-4 border-green-500 group hover:scale-105 hover:border-green-400">
<div className="text-green-400 text-4xl mb-4 group-hover:animate-bounce"></div>
<h3 className="text-xl font-bold mb-4 group-hover:text-green-300 transition-colors">Dr.Web Cloud</h3>
<p className="text-gray-300 mb-4">
Облачные решения безопасности
</p>
<ul className="text-sm text-gray-400 space-y-1">
<li> Облачная консоль</li>
<li> Удаленное управление</li>
<li> Автоматические обновления</li>
<li> Масштабируемость</li>
<ul className="text-sm text-gray-400 space-y-1 mb-4">
<li className="group-hover:text-gray-300 transition-colors"> Облачная консоль</li>
<li className="group-hover:text-gray-300 transition-colors"> Удаленное управление</li>
<li className="group-hover:text-gray-300 transition-colors"> Автоматические обновления</li>
<li className="group-hover:text-gray-300 transition-colors"> Масштабируемость</li>
</ul>
<div className="opacity-0 group-hover:opacity-100 transition-opacity duration-300">
<button
onClick={() => {
setLicenseForm(prev => ({ ...prev, product: 'Dr.Web Cloud' }));
handleLicenseClick();
}}
className="w-full px-4 py-2 bg-green-500 text-black rounded-lg hover:bg-green-600 transition-colors font-semibold"
>
Получить лицензию
</button>
</div>
</div>
<div className="glass-effect p-8 rounded-lg hover-glow transition-all duration-300 border-l-4 border-green-500">
<div className="text-green-400 text-4xl mb-4">🔧</div>
<h3 className="text-xl font-bold mb-4">Dr.Web CureIt!</h3>
<div className="glass-effect p-8 rounded-lg hover-glow transition-all duration-300 border-l-4 border-green-500 group hover:scale-105 hover:border-green-400">
<div className="text-green-400 text-4xl mb-4 group-hover:animate-bounce">🔧</div>
<h3 className="text-xl font-bold mb-4 group-hover:text-green-300 transition-colors">Dr.Web CureIt!</h3>
<p className="text-gray-300 mb-4">
Бесплатная утилита для лечения зараженных компьютеров
</p>
<ul className="text-sm text-gray-400 space-y-1">
<li> Не требует установки</li>
<li> Быстрое сканирование</li>
<li> Лечение вирусов</li>
<li> Регулярные обновления</li>
<ul className="text-sm text-gray-400 space-y-1 mb-4">
<li className="group-hover:text-gray-300 transition-colors"> Не требует установки</li>
<li className="group-hover:text-gray-300 transition-colors"> Быстрое сканирование</li>
<li className="group-hover:text-gray-300 transition-colors"> Лечение вирусов</li>
<li className="group-hover:text-gray-300 transition-colors"> Регулярные обновления</li>
</ul>
<div className="opacity-0 group-hover:opacity-100 transition-opacity duration-300">
<button
onClick={() => window.open('https://free.drweb.ru/cureit/', '_blank')}
className="w-full px-4 py-2 bg-green-500 text-black rounded-lg hover:bg-green-600 transition-colors font-semibold"
>
Скачать бесплатно
</button>
</div>
</div>
</div>
</div>
@ -266,10 +823,16 @@ export default function DrWeb() {
Поможем выбрать и внедрить оптимальное решение Dr.Web для вашего бизнеса
</p>
<div className="flex flex-col sm:flex-row gap-4 justify-center">
<button className="px-8 py-3 bg-green-500 text-black font-semibold rounded-lg hover-glow transition-all duration-300">
<button
onClick={handleConsultationClick}
className="px-8 py-3 bg-green-500 text-black font-semibold rounded-lg hover-glow transition-all duration-300 hover:bg-green-600 active:scale-95 cursor-pointer"
>
Получить консультацию
</button>
<button className="px-8 py-3 glass-effect text-white font-semibold rounded-lg hover:bg-white/10 transition-all duration-300">
<button
onClick={handleLicenseClick}
className="px-8 py-3 glass-effect text-white font-semibold rounded-lg hover:bg-white/10 transition-all duration-300 active:scale-95 cursor-pointer"
>
Заказать лицензию
</button>
</div>
@ -291,6 +854,337 @@ export default function DrWeb() {
</p>
</div>
</footer>
{/* Products Modal */}
{isProductsModalOpen && (
<div className="fixed inset-0 bg-black bg-opacity-30 flex items-center justify-center z-50 p-4">
<div className="bg-gray-900 rounded-lg p-8 max-w-4xl w-full relative border border-green-500/30 max-h-[90vh] overflow-y-auto">
<button
onClick={handleCloseModal}
className="absolute top-4 right-4 text-gray-400 hover:text-white text-2xl"
>
×
</button>
<h3 className="text-3xl font-bold mb-6 text-green-400">Продукты Dr.Web</h3>
<div className="grid md:grid-cols-2 gap-6">
<div className="glass-effect p-6 rounded-lg border border-green-500/20">
<h4 className="text-xl font-bold mb-3 text-green-400">Dr.Web Security Space</h4>
<p className="text-gray-300 mb-4">Комплексная защита для дома</p>
<ul className="text-sm text-gray-400 space-y-1 mb-4">
<li> Антивирус и антишпион</li>
<li> Файрвол и антиспам</li>
<li> Родительский контроль</li>
</ul>
<button
onClick={() => {
setLicenseForm(prev => ({ ...prev, product: 'Dr.Web Security Space' }));
setIsProductsModalOpen(false);
setIsLicenseModalOpen(true);
}}
className="w-full px-4 py-2 bg-green-500 text-black rounded-lg hover:bg-green-600 transition-colors"
>
Заказать лицензию
</button>
</div>
<div className="glass-effect p-6 rounded-lg border border-green-500/20">
<h4 className="text-xl font-bold mb-3 text-green-400">Dr.Web Enterprise Suite</h4>
<p className="text-gray-300 mb-4">Корпоративное решение</p>
<ul className="text-sm text-gray-400 space-y-1 mb-4">
<li> Централизованное управление</li>
<li> Защита серверов</li>
<li> Почтовая безопасность</li>
</ul>
<button
onClick={() => {
setLicenseForm(prev => ({ ...prev, product: 'Dr.Web Enterprise Suite' }));
setIsProductsModalOpen(false);
setIsLicenseModalOpen(true);
}}
className="w-full px-4 py-2 bg-green-500 text-black rounded-lg hover:bg-green-600 transition-colors"
>
Заказать лицензию
</button>
</div>
<div className="glass-effect p-6 rounded-lg border border-green-500/20">
<h4 className="text-xl font-bold mb-3 text-green-400">Dr.Web Mobile Security</h4>
<p className="text-gray-300 mb-4">Защита мобильных устройств</p>
<ul className="text-sm text-gray-400 space-y-1 mb-4">
<li> Антивирус для мобильных</li>
<li> Антивор и URL-фильтр</li>
<li> Родительский контроль</li>
</ul>
<button
onClick={() => {
setLicenseForm(prev => ({ ...prev, product: 'Dr.Web Mobile Security' }));
setIsProductsModalOpen(false);
setIsLicenseModalOpen(true);
}}
className="w-full px-4 py-2 bg-green-500 text-black rounded-lg hover:bg-green-600 transition-colors"
>
Заказать лицензию
</button>
</div>
<div className="glass-effect p-6 rounded-lg border border-green-500/20">
<h4 className="text-xl font-bold mb-3 text-green-400">Dr.Web Gateway Security</h4>
<p className="text-gray-300 mb-4">Защита интернет-шлюзов</p>
<ul className="text-sm text-gray-400 space-y-1 mb-4">
<li> Фильтрация трафика</li>
<li> Антиспам и контент-фильтр</li>
<li> Защита от фишинга</li>
</ul>
<button
onClick={() => {
setLicenseForm(prev => ({ ...prev, product: 'Dr.Web Gateway Security' }));
setIsProductsModalOpen(false);
setIsLicenseModalOpen(true);
}}
className="w-full px-4 py-2 bg-green-500 text-black rounded-lg hover:bg-green-600 transition-colors"
>
Заказать лицензию
</button>
</div>
</div>
<div className="mt-6 text-center">
<button
onClick={handleCloseModal}
className="px-6 py-2 bg-gray-600 text-white rounded-lg hover:bg-gray-700 transition-colors"
>
Закрыть
</button>
</div>
</div>
</div>
)}
{/* License Modal */}
{isLicenseModalOpen && (
<div className="fixed inset-0 bg-black bg-opacity-30 flex items-center justify-center z-50 p-4">
<div className="bg-gray-900 rounded-lg p-8 max-w-md w-full relative border border-green-500/30">
<button
onClick={handleCloseModal}
className="absolute top-4 right-4 text-gray-400 hover:text-white text-2xl"
>
×
</button>
<h3 className="text-2xl font-bold mb-6 text-green-400">Получить лицензию Dr.Web</h3>
<form onSubmit={handleLicenseSubmit} className="space-y-4">
<div>
<label htmlFor="name" className="block text-sm font-medium text-gray-300 mb-1">
Имя *
</label>
<input
type="text"
id="name"
name="name"
value={licenseForm.name}
onChange={handleLicenseInputChange}
required
className="w-full px-3 py-2 bg-gray-800 border border-gray-600 rounded-lg text-white focus:outline-none focus:border-green-500"
/>
</div>
<div>
<label htmlFor="email" className="block text-sm font-medium text-gray-300 mb-1">
Email *
</label>
<input
type="email"
id="email"
name="email"
value={licenseForm.email}
onChange={handleLicenseInputChange}
required
className="w-full px-3 py-2 bg-gray-800 border border-gray-600 rounded-lg text-white focus:outline-none focus:border-green-500"
/>
</div>
<div>
<label htmlFor="company" className="block text-sm font-medium text-gray-300 mb-1">
Компания
</label>
<input
type="text"
id="company"
name="company"
value={licenseForm.company}
onChange={handleLicenseInputChange}
className="w-full px-3 py-2 bg-gray-800 border border-gray-600 rounded-lg text-white focus:outline-none focus:border-green-500"
/>
</div>
<div>
<label htmlFor="product" className="block text-sm font-medium text-gray-300 mb-1">
Продукт *
</label>
<select
id="product"
name="product"
value={licenseForm.product}
onChange={handleLicenseInputChange}
required
className="w-full px-3 py-2 bg-gray-800 border border-gray-600 rounded-lg text-white focus:outline-none focus:border-green-500"
>
<option value="">Выберите продукт</option>
<option value="Dr.Web Security Space">Dr.Web Security Space</option>
<option value="Dr.Web Enterprise Suite">Dr.Web Enterprise Suite</option>
<option value="Dr.Web Mobile Security">Dr.Web Mobile Security</option>
<option value="Dr.Web Gateway Security">Dr.Web Gateway Security</option>
<option value="Dr.Web Cloud">Dr.Web Cloud</option>
</select>
</div>
<div>
<label htmlFor="licenses" className="block text-sm font-medium text-gray-300 mb-1">
Количество лицензий *
</label>
<input
type="number"
id="licenses"
name="licenses"
value={licenseForm.licenses}
onChange={handleLicenseInputChange}
required
min="1"
className="w-full px-3 py-2 bg-gray-800 border border-gray-600 rounded-lg text-white focus:outline-none focus:border-green-500"
/>
</div>
<div>
<label htmlFor="message" className="block text-sm font-medium text-gray-300 mb-1">
Дополнительная информация
</label>
<textarea
id="message"
name="message"
value={licenseForm.message}
onChange={handleLicenseInputChange}
rows={3}
className="w-full px-3 py-2 bg-gray-800 border border-gray-600 rounded-lg text-white focus:outline-none focus:border-green-500"
placeholder="Укажите особые требования или вопросы..."
/>
</div>
<div className="flex space-x-4 pt-4">
<button
type="button"
onClick={handleCloseModal}
className="flex-1 px-4 py-2 bg-gray-600 text-white rounded-lg hover:bg-gray-700 transition-colors"
>
Отмена
</button>
<button
type="submit"
className="flex-1 px-4 py-2 bg-green-500 text-black rounded-lg hover:bg-green-600 transition-colors"
>
Отправить заявку
</button>
</div>
</form>
</div>
</div>
)}
{/* Consultation Modal */}
{isConsultationModalOpen && (
<div className="fixed inset-0 bg-black bg-opacity-30 flex items-center justify-center z-50 p-4">
<div className="bg-gray-900 rounded-lg p-8 max-w-md w-full relative border border-green-500/30">
<button
onClick={handleCloseModal}
className="absolute top-4 right-4 text-gray-400 hover:text-white text-2xl"
>
×
</button>
<h3 className="text-2xl font-bold mb-6 text-green-400">Получить консультацию</h3>
<form onSubmit={handleConsultationSubmit} className="space-y-4">
<div>
<label htmlFor="cons-name" className="block text-sm font-medium text-gray-300 mb-1">
Имя *
</label>
<input
type="text"
id="cons-name"
name="name"
value={consultationForm.name}
onChange={handleConsultationInputChange}
required
className="w-full px-3 py-2 bg-gray-800 border border-gray-600 rounded-lg text-white focus:outline-none focus:border-green-500"
/>
</div>
<div>
<label htmlFor="cons-email" className="block text-sm font-medium text-gray-300 mb-1">
Email *
</label>
<input
type="email"
id="cons-email"
name="email"
value={consultationForm.email}
onChange={handleConsultationInputChange}
required
className="w-full px-3 py-2 bg-gray-800 border border-gray-600 rounded-lg text-white focus:outline-none focus:border-green-500"
/>
</div>
<div>
<label htmlFor="cons-company" className="block text-sm font-medium text-gray-300 mb-1">
Компания
</label>
<input
type="text"
id="cons-company"
name="company"
value={consultationForm.company}
onChange={handleConsultationInputChange}
className="w-full px-3 py-2 bg-gray-800 border border-gray-600 rounded-lg text-white focus:outline-none focus:border-green-500"
/>
</div>
<div>
<label htmlFor="cons-message" className="block text-sm font-medium text-gray-300 mb-1">
Вопрос или задача *
</label>
<textarea
id="cons-message"
name="message"
value={consultationForm.message}
onChange={handleConsultationInputChange}
required
rows={4}
className="w-full px-3 py-2 bg-gray-800 border border-gray-600 rounded-lg text-white focus:outline-none focus:border-green-500"
placeholder="Опишите вашу задачу или вопрос по Dr.Web..."
/>
</div>
<div className="flex space-x-4 pt-4">
<button
type="button"
onClick={handleCloseModal}
className="flex-1 px-4 py-2 bg-gray-600 text-white rounded-lg hover:bg-gray-700 transition-colors"
>
Отмена
</button>
<button
type="submit"
className="flex-1 px-4 py-2 bg-green-500 text-black rounded-lg hover:bg-green-600 transition-colors"
>
Отправить
</button>
</div>
</form>
</div>
</div>
)}
</>
);
}

View File

@ -1,6 +1,108 @@
'use client';
import { useState, useEffect } from 'react';
import Navigation from '../components/Navigation';
export default function Electronics() {
const [selectedCategory, setSelectedCategory] = useState('all');
const [cartItems, setCartItems] = useState<Array<{
id: string;
name: string;
price: number;
quantity: number;
}>>([]);
const [isCalculatorOpen, setIsCalculatorOpen] = useState(false);
const [deliveryStatus, setDeliveryStatus] = useState(0);
const [hoveredProduct, setHoveredProduct] = useState<string | null>(null);
const [particles, setParticles] = useState<Array<{
id: number;
left: string;
top: string;
animationDelay: string;
animationDuration: string;
icon: string;
}>>([]);
const categories = [
{ id: 'all', name: 'Все товары', icon: '🛒', color: 'cyan' },
{ id: 'computers', name: 'Компьютеры', icon: '💻', color: 'blue' },
{ id: 'phones', name: 'Телефоны', icon: '📱', color: 'green' },
{ id: 'accessories', name: 'Аксессуары', icon: '🔌', color: 'purple' },
{ id: 'servers', name: 'Серверы', icon: '🖲️', color: 'orange' },
{ id: 'network', name: 'Сеть', icon: '🌐', color: 'teal' }
];
const products = [
{ id: '1', name: 'MacBook Pro 16"', price: 250000, category: 'computers', stock: 15, rating: 4.9 },
{ id: '2', name: 'iPhone 15 Pro', price: 120000, category: 'phones', stock: 25, rating: 4.8 },
{ id: '3', name: 'Dell XPS 13', price: 180000, category: 'computers', stock: 8, rating: 4.7 },
{ id: '4', name: 'Samsung Galaxy S24', price: 95000, category: 'phones', stock: 20, rating: 4.6 },
{ id: '5', name: 'Зарядное устройство 65W', price: 3500, category: 'accessories', stock: 50, rating: 4.5 },
{ id: '6', name: 'HP ProLiant DL380', price: 450000, category: 'servers', stock: 3, rating: 4.9 },
{ id: '7', name: 'Cisco Catalyst 9300', price: 320000, category: 'network', stock: 5, rating: 4.8 },
{ id: '8', name: 'Кабель USB-C 2м', price: 1200, category: 'accessories', stock: 100, rating: 4.4 }
];
const deliverySteps = [
{ name: 'Заказ получен', icon: '📋', completed: true },
{ name: 'Подтверждение', icon: '✅', completed: true },
{ name: 'Сборка', icon: '📦', completed: true },
{ name: 'Отправка', icon: '🚚', completed: false },
{ name: 'Доставка', icon: '🏠', completed: false }
];
// Генерация электронных частиц
useEffect(() => {
const icons = ['⚡', '🔋', '💾', '🔌', '📡', '💻', '📱', '🖥️'];
const newParticles = Array.from({ length: 15 }, (_, i) => ({
id: i,
left: `${Math.random() * 100}%`,
top: `${Math.random() * 100}%`,
animationDelay: `${Math.random() * 5}s`,
animationDuration: `${8 + Math.random() * 12}s`,
icon: icons[Math.floor(Math.random() * icons.length)]
}));
setParticles(newParticles);
}, []);
// Анимация прогресса доставки
useEffect(() => {
const interval = setInterval(() => {
setDeliveryStatus(prev => (prev + 1) % 100);
}, 100);
return () => clearInterval(interval);
}, []);
const filteredProducts = selectedCategory === 'all'
? products
: products.filter(p => p.category === selectedCategory);
const addToCart = (product: typeof products[0]) => {
setCartItems(prev => {
const existing = prev.find(item => item.id === product.id);
if (existing) {
return prev.map(item =>
item.id === product.id
? { ...item, quantity: item.quantity + 1 }
: item
);
}
return [...prev, { ...product, quantity: 1 }];
});
};
const getTotalPrice = () => {
return cartItems.reduce((sum, item) => sum + item.price * item.quantity, 0);
};
const formatPrice = (price: number) => {
return new Intl.NumberFormat('ru-RU', {
style: 'currency',
currency: 'RUB',
minimumFractionDigits: 0
}).format(price);
};
return (
<>
<Navigation />
@ -8,6 +110,25 @@ export default function Electronics() {
{/* Hero Section */}
<section className="min-h-screen flex items-center justify-center relative overflow-hidden pt-16">
<div className="absolute inset-0 bg-gradient-to-br from-cyan-900 via-black to-teal-900"></div>
{/* Анимированные электронные частицы */}
<div className="absolute inset-0">
{particles.map((particle) => (
<div
key={particle.id}
className="absolute text-2xl opacity-60 floating-particle"
style={{
left: particle.left,
top: particle.top,
animationDelay: particle.animationDelay,
animationDuration: particle.animationDuration
}}
>
{particle.icon}
</div>
))}
</div>
<div className="absolute inset-0 opacity-20">
<div className="absolute top-1/4 left-1/4 w-96 h-96 bg-cyan-500 rounded-full blur-3xl opacity-30"></div>
<div className="absolute bottom-1/4 right-1/4 w-96 h-96 bg-teal-500 rounded-full blur-3xl opacity-30"></div>
@ -20,128 +141,191 @@ export default function Electronics() {
<p className="text-xl md:text-2xl text-gray-300 mb-8 max-w-4xl mx-auto">
Комплексные поставки электронного оборудования для бизнеса и государственных организаций
</p>
{/* Интерактивные статистики */}
<div className="grid grid-cols-2 md:grid-cols-4 gap-4 mb-8">
<div className="glass-effect p-4 rounded-lg hover-glow transition-all duration-300 transform hover:scale-105">
<div className="text-3xl font-bold gradient-text">10K+</div>
<div className="text-sm text-gray-400">Товаров в наличии</div>
</div>
<div className="glass-effect p-4 rounded-lg hover-glow transition-all duration-300 transform hover:scale-105">
<div className="text-3xl font-bold gradient-text">24ч</div>
<div className="text-sm text-gray-400">Быстрая доставка</div>
</div>
<div className="glass-effect p-4 rounded-lg hover-glow transition-all duration-300 transform hover:scale-105">
<div className="text-3xl font-bold gradient-text">500+</div>
<div className="text-sm text-gray-400">Выигранных тендеров</div>
</div>
<div className="glass-effect p-4 rounded-lg hover-glow transition-all duration-300 transform hover:scale-105">
<div className="text-3xl font-bold gradient-text">99%</div>
<div className="text-sm text-gray-400">Довольных клиентов</div>
</div>
</div>
<div className="flex flex-col sm:flex-row gap-4 justify-center mb-8">
<button className="px-8 py-3 bg-cyan-500 text-black font-semibold rounded-lg hover-glow transition-all duration-300">
Каталог оборудования
<button
onClick={() => setIsCalculatorOpen(true)}
className="px-8 py-3 bg-cyan-500 text-black font-semibold rounded-lg hover-glow transition-all duration-300 transform hover:scale-105"
>
Калькулятор стоимости
</button>
<button className="px-8 py-3 glass-effect text-white font-semibold rounded-lg hover:bg-white/10 transition-all duration-300">
Получить КП
<button className="px-8 py-3 glass-effect text-white font-semibold rounded-lg hover:bg-white/10 transition-all duration-300 transform hover:scale-105">
Каталог товаров
</button>
</div>
<div className="flex flex-wrap justify-center gap-4 text-sm">
<div className="glass-effect px-4 py-2 rounded-full">
<div className="glass-effect px-4 py-2 rounded-full hover-glow transition-all duration-300">
<span className="text-cyan-400">44-ФЗ</span> Госзакупки
</div>
<div className="glass-effect px-4 py-2 rounded-full">
<div className="glass-effect px-4 py-2 rounded-full hover-glow transition-all duration-300">
<span className="text-teal-400">223-ФЗ</span> Корпоративные закупки
</div>
<div className="glass-effect px-4 py-2 rounded-full">
<div className="glass-effect px-4 py-2 rounded-full hover-glow transition-all duration-300">
<span className="text-green-400">B2B</span> Коммерческие поставки
</div>
</div>
</div>
</section>
{/* Product Categories */}
{/* Интерактивный каталог товаров */}
<section className="section-padding bg-gray-900/50">
<div className="max-w-7xl mx-auto px-4">
<div className="text-center mb-16">
<h2 className="text-4xl md:text-5xl font-bold mb-6">
Категории <span className="gradient-text">оборудования</span>
Интерактивный <span className="gradient-text">каталог</span>
</h2>
<p className="text-xl text-gray-300 max-w-3xl mx-auto">
От простых аксессуаров до сложного серверного оборудования
Выберите категорию и добавьте товары в корзину для расчета стоимости
</p>
</div>
{/* Фильтр категорий */}
<div className="flex flex-wrap justify-center gap-4 mb-12">
{categories.map((category) => (
<button
key={category.id}
onClick={() => setSelectedCategory(category.id)}
className={`px-6 py-3 rounded-lg font-semibold transition-all duration-300 transform hover:scale-105 ${
selectedCategory === category.id
? `bg-${category.color}-500 text-white shadow-lg hover-glow`
: 'glass-effect text-gray-300 hover:bg-white/10'
}`}
>
<span className="mr-2">{category.icon}</span>
{category.name}
</button>
))}
</div>
{/* Товары */}
<div className="grid md:grid-cols-2 lg:grid-cols-4 gap-8">
<div className="glass-effect p-6 rounded-lg hover-glow transition-all duration-300">
<div className="text-cyan-400 text-4xl mb-4">🔌</div>
<h3 className="text-lg font-bold mb-3">Аксессуары</h3>
<ul className="text-sm text-gray-300 space-y-1">
<li> Зарядные устройства</li>
<li> Кабели и переходники</li>
<li> Чехлы и защитные пленки</li>
<li> Подставки и держатели</li>
</ul>
{filteredProducts.map((product) => (
<div
key={product.id}
className="glass-effect p-6 rounded-lg hover-glow transition-all duration-500 transform hover:scale-105 hover:rotate-1 cursor-pointer"
onMouseEnter={() => setHoveredProduct(product.id)}
onMouseLeave={() => setHoveredProduct(null)}
>
<div className="relative">
<div className="text-4xl mb-4 text-center">
{product.category === 'computers' && '💻'}
{product.category === 'phones' && '📱'}
{product.category === 'accessories' && '🔌'}
{product.category === 'servers' && '🖲️'}
{product.category === 'network' && '🌐'}
</div>
<div className="glass-effect p-6 rounded-lg hover-glow transition-all duration-300">
<div className="text-teal-400 text-4xl mb-4">💻</div>
<h3 className="text-lg font-bold mb-3">Компьютеры и ноутбуки</h3>
<ul className="text-sm text-gray-300 space-y-1">
<li> Настольные ПК</li>
<li> Ноутбуки и ультрабуки</li>
<li> Планшеты</li>
<li> Моноблоки</li>
</ul>
{hoveredProduct === product.id && (
<div className="absolute inset-0 bg-gradient-to-r from-cyan-500/20 to-teal-500/20 rounded-lg animate-pulse"></div>
)}
</div>
<div className="glass-effect p-6 rounded-lg hover-glow transition-all duration-300">
<div className="text-blue-400 text-4xl mb-4">🖥</div>
<h3 className="text-lg font-bold mb-3">Периферия</h3>
<ul className="text-sm text-gray-300 space-y-1">
<li> Мониторы и проекторы</li>
<li> Принтеры и МФУ</li>
<li> Клавиатуры и мыши</li>
<li> Веб-камеры и микрофоны</li>
</ul>
<h3 className="text-lg font-bold mb-2">{product.name}</h3>
<div className="flex items-center gap-2 mb-2">
<div className="flex text-yellow-400">
{'★'.repeat(Math.floor(product.rating))}
{'☆'.repeat(5 - Math.floor(product.rating))}
</div>
<span className="text-sm text-gray-400">{product.rating}</span>
</div>
<div className="glass-effect p-6 rounded-lg hover-glow transition-all duration-300">
<div className="text-green-400 text-4xl mb-4">🌐</div>
<h3 className="text-lg font-bold mb-3">Сетевое оборудование</h3>
<ul className="text-sm text-gray-300 space-y-1">
<li> Маршрутизаторы</li>
<li> Коммутаторы</li>
<li> Точки доступа Wi-Fi</li>
<li> Сетевые кабели</li>
</ul>
<div className="flex justify-between items-center mb-4">
<span className="text-2xl font-bold gradient-text">
{formatPrice(product.price)}
</span>
<span className={`text-sm px-2 py-1 rounded ${
product.stock > 10 ? 'bg-green-500/20 text-green-400' :
product.stock > 0 ? 'bg-yellow-500/20 text-yellow-400' :
'bg-red-500/20 text-red-400'
}`}>
{product.stock > 0 ? `${product.stock} шт.` : 'Нет в наличии'}
</span>
</div>
<div className="glass-effect p-6 rounded-lg hover-glow transition-all duration-300">
<div className="text-purple-400 text-4xl mb-4">🖨</div>
<h3 className="text-lg font-bold mb-3">Офисная техника</h3>
<ul className="text-sm text-gray-300 space-y-1">
<li> Принтеры и сканеры</li>
<li> Копировальные аппараты</li>
<li> Ламинаторы</li>
<li> Уничтожители документов</li>
</ul>
<button
onClick={() => addToCart(product)}
disabled={product.stock === 0}
className="w-full px-4 py-2 bg-cyan-500 text-black font-semibold rounded-lg hover-glow transition-all duration-300 transform hover:scale-105 disabled:opacity-50 disabled:cursor-not-allowed"
>
Добавить в корзину
</button>
</div>
))}
</div>
</div>
</section>
{/* Трекер доставки */}
<section className="section-padding">
<div className="max-w-7xl mx-auto px-4">
<div className="text-center mb-16">
<h2 className="text-4xl md:text-5xl font-bold mb-6">
Трекер <span className="gradient-text">доставки</span>
</h2>
<p className="text-xl text-gray-300 max-w-3xl mx-auto">
Отслеживайте статус вашего заказа в реальном времени
</p>
</div>
<div className="glass-effect p-6 rounded-lg hover-glow transition-all duration-300">
<div className="text-red-400 text-4xl mb-4">📱</div>
<h3 className="text-lg font-bold mb-3">Мобильные устройства</h3>
<ul className="text-sm text-gray-300 space-y-1">
<li> Смартфоны</li>
<li> Планшеты</li>
<li> Электронные книги</li>
<li> Носимые устройства</li>
</ul>
<div className="max-w-4xl mx-auto">
<div className="glass-effect p-8 rounded-lg">
<div className="flex justify-between items-center mb-8">
<div>
<h3 className="text-xl font-bold mb-2">Заказ #12345</h3>
<p className="text-gray-400">Ожидаемая доставка: завтра до 18:00</p>
</div>
<div className="text-right">
<div className="text-2xl font-bold gradient-text">{deliveryStatus}%</div>
<div className="text-sm text-gray-400">Готовность</div>
</div>
</div>
<div className="glass-effect p-6 rounded-lg hover-glow transition-all duration-300">
<div className="text-yellow-400 text-4xl mb-4">🔊</div>
<h3 className="text-lg font-bold mb-3">Аудио и видео</h3>
<ul className="text-sm text-gray-300 space-y-1">
<li> Колонки и наушники</li>
<li> Микрофоны</li>
<li> Камеры и видеорегистраторы</li>
<li> Системы видеонаблюдения</li>
</ul>
{/* Прогресс бар */}
<div className="mb-8">
<div className="w-full bg-gray-700 rounded-full h-2">
<div
className="bg-gradient-to-r from-cyan-500 to-teal-500 h-2 rounded-full transition-all duration-300"
style={{ width: `${deliveryStatus}%` }}
></div>
</div>
</div>
<div className="glass-effect p-6 rounded-lg hover-glow transition-all duration-300">
<div className="text-orange-400 text-4xl mb-4">🖲</div>
<h3 className="text-lg font-bold mb-3">Серверное оборудование</h3>
<ul className="text-sm text-gray-300 space-y-1">
<li> Серверы и рабочие станции</li>
<li> Системы хранения данных</li>
<li> ИБП и стабилизаторы</li>
<li> Серверные шкафы</li>
</ul>
{/* Этапы доставки */}
<div className="flex justify-between">
{deliverySteps.map((step, index) => (
<div key={index} className="flex flex-col items-center text-center">
<div className={`w-12 h-12 rounded-full flex items-center justify-center mb-2 transition-all duration-300 ${
step.completed ? 'bg-green-500 text-white' : 'bg-gray-700 text-gray-400'
}`}>
<span className="text-xl">{step.icon}</span>
</div>
<span className={`text-sm ${step.completed ? 'text-green-400' : 'text-gray-400'}`}>
{step.name}
</span>
</div>
))}
</div>
</div>
</div>
</div>
@ -331,10 +515,190 @@ export default function Electronics() {
</div>
</section>
{/* Contact Section */}
{/* Калькулятор стоимости */}
{isCalculatorOpen && (
<div className="fixed inset-0 bg-black/50 backdrop-blur-sm z-50 flex items-center justify-center p-4">
<div className="glass-effect p-8 rounded-lg max-w-2xl w-full max-h-[90vh] overflow-y-auto">
<div className="flex justify-between items-center mb-6">
<h3 className="text-2xl font-bold gradient-text">Калькулятор стоимости</h3>
<button
onClick={() => setIsCalculatorOpen(false)}
className="text-gray-400 hover:text-white transition-colors text-2xl"
>
×
</button>
</div>
{cartItems.length === 0 ? (
<div className="text-center py-8">
<div className="text-4xl mb-4">🛒</div>
<p className="text-gray-400">Корзина пуста. Добавьте товары из каталога.</p>
</div>
) : (
<div>
<div className="space-y-4 mb-6">
{cartItems.map((item) => (
<div key={item.id} className="flex justify-between items-center p-4 bg-gray-800/50 rounded-lg">
<div>
<h4 className="font-semibold">{item.name}</h4>
<p className="text-sm text-gray-400">Количество: {item.quantity}</p>
</div>
<div className="text-right">
<div className="font-bold">{formatPrice(item.price * item.quantity)}</div>
<div className="text-sm text-gray-400">{formatPrice(item.price)} за шт.</div>
</div>
</div>
))}
</div>
<div className="border-t border-gray-700 pt-4">
<div className="flex justify-between items-center text-xl font-bold">
<span>Итого:</span>
<span className="gradient-text">{formatPrice(getTotalPrice())}</span>
</div>
<div className="flex justify-between items-center text-sm text-gray-400 mt-2">
<span>НДС 20%:</span>
<span>{formatPrice(getTotalPrice() * 0.2)}</span>
</div>
<div className="flex justify-between items-center text-sm text-gray-400 mt-1">
<span>Доставка:</span>
<span>{getTotalPrice() > 50000 ? 'Бесплатно' : formatPrice(2000)}</span>
</div>
</div>
<div className="mt-6 flex gap-4">
<button className="flex-1 px-6 py-3 bg-cyan-500 text-black font-semibold rounded-lg hover-glow transition-all duration-300">
Оформить заказ
</button>
<button
onClick={() => setCartItems([])}
className="px-6 py-3 glass-effect text-white font-semibold rounded-lg hover:bg-white/10 transition-all duration-300"
>
Очистить
</button>
</div>
</div>
)}
</div>
</div>
)}
{/* Корзина (фиксированная) */}
{cartItems.length > 0 && (
<div className="fixed bottom-4 right-4 z-40">
<button
onClick={() => setIsCalculatorOpen(true)}
className="glass-effect p-4 rounded-full hover-glow transition-all duration-300 transform hover:scale-110"
>
<div className="relative">
<span className="text-2xl">🛒</span>
<div className="absolute -top-2 -right-2 bg-cyan-500 text-black rounded-full w-6 h-6 flex items-center justify-center text-xs font-bold">
{cartItems.reduce((sum, item) => sum + item.quantity, 0)}
</div>
</div>
</button>
</div>
)}
{/* Интерактивная карта складов */}
<section className="section-padding bg-gray-900/50">
<div className="max-w-7xl mx-auto px-4">
<div className="text-center mb-16">
<h2 className="text-4xl md:text-5xl font-bold mb-6">
Наши <span className="gradient-text">склады</span>
</h2>
<p className="text-xl text-gray-300 max-w-3xl mx-auto">
Быстрая доставка из ближайшего склада
</p>
</div>
<div className="grid md:grid-cols-2 lg:grid-cols-3 gap-8">
{[
{ city: 'Москва', address: 'Варшавское шоссе, 125', stock: '8500+ товаров', delivery: '2-4 часа', load: 85 },
{ city: 'Санкт-Петербург', address: 'Индустриальный пр., 44', stock: '6200+ товаров', delivery: '4-6 часов', load: 72 },
{ city: 'Екатеринбург', address: 'Кольцовский тракт, 18', stock: '4800+ товаров', delivery: '6-8 часов', load: 91 },
{ city: 'Новосибирск', address: 'Красный пр., 220', stock: '3500+ товаров', delivery: '1-2 дня', load: 68 },
{ city: 'Казань', address: 'Оренбургский тракт, 85', stock: '2900+ товаров', delivery: '1-2 дня', load: 79 },
{ city: 'Нижний Новгород', address: 'Московское шоссе, 15', stock: '3200+ товаров', delivery: '1-2 дня', load: 83 }
].map((warehouse, index) => (
<div
key={index}
className="glass-effect p-6 rounded-lg hover-glow transition-all duration-300 transform hover:scale-105 cursor-pointer"
>
<div className="flex items-center gap-3 mb-4">
<div className="text-2xl">📍</div>
<div>
<h3 className="text-xl font-bold">{warehouse.city}</h3>
<p className="text-sm text-gray-400">{warehouse.address}</p>
</div>
</div>
<div className="space-y-2">
<div className="flex justify-between">
<span className="text-gray-400">Товаров:</span>
<span className="text-cyan-400 font-semibold">{warehouse.stock}</span>
</div>
<div className="flex justify-between">
<span className="text-gray-400">Доставка:</span>
<span className="text-teal-400 font-semibold">{warehouse.delivery}</span>
</div>
</div>
<div className="mt-4 w-full bg-gray-700 rounded-full h-2">
<div
className="bg-gradient-to-r from-cyan-500 to-teal-500 h-2 rounded-full transition-all duration-300"
style={{ width: `${warehouse.load}%` }}
></div>
</div>
<p className="text-xs text-gray-400 mt-1">Загруженность склада: {warehouse.load}%</p>
</div>
))}
</div>
</div>
</section>
{/* Анимированная схема подключения */}
<section className="section-padding">
<div className="max-w-7xl mx-auto px-4">
<div className="text-center mb-16">
<h2 className="text-4xl md:text-5xl font-bold mb-6">
Схема <span className="gradient-text">подключения</span>
</h2>
<p className="text-xl text-gray-300 max-w-3xl mx-auto">
Как работает наша система поставок
</p>
</div>
<div className="relative">
<div className="flex flex-col md:flex-row justify-between items-center gap-8">
{[
{ icon: '📋', title: 'Заявка', desc: 'Получаем вашу спецификацию' },
{ icon: '💰', title: 'Расчет', desc: 'Формируем коммерческое предложение' },
{ icon: '📦', title: 'Сборка', desc: 'Комплектуем заказ на складе' },
{ icon: '🚚', title: 'Доставка', desc: 'Доставляем в указанное место' },
{ icon: '✅', title: 'Приемка', desc: 'Подписываем документы' }
].map((step, index) => (
<div key={index} className="text-center relative">
<div className="glass-effect w-20 h-20 rounded-full flex items-center justify-center mx-auto mb-4 hover-glow transition-all duration-300 transform hover:scale-110">
<span className="text-3xl">{step.icon}</span>
</div>
<h3 className="text-lg font-bold mb-2">{step.title}</h3>
<p className="text-sm text-gray-400 max-w-32">{step.desc}</p>
{index < 4 && (
<div className="hidden md:block absolute top-10 left-full w-16 h-0.5 bg-gradient-to-r from-cyan-500 to-teal-500"></div>
)}
</div>
))}
</div>
</div>
</div>
</section>
{/* Contact Section */}
<section className="section-padding">
<div className="max-w-4xl mx-auto px-4 text-center">
<div className="glass-effect p-12 rounded-lg">
<div className="glass-effect p-12 rounded-lg hover-glow transition-all duration-300">
<h2 className="text-3xl font-bold mb-6">
Нужна поставка <span className="gradient-text">оборудования</span>?
</h2>
@ -342,10 +706,10 @@ export default function Electronics() {
Отправьте нам спецификацию подготовим коммерческое предложение в течение дня
</p>
<div className="flex flex-col sm:flex-row gap-4 justify-center">
<button className="px-8 py-3 bg-cyan-500 text-black font-semibold rounded-lg hover-glow transition-all duration-300">
<button className="px-8 py-3 bg-cyan-500 text-black font-semibold rounded-lg hover-glow transition-all duration-300 transform hover:scale-105">
Отправить спецификацию
</button>
<button className="px-8 py-3 glass-effect text-white font-semibold rounded-lg hover:bg-white/10 transition-all duration-300">
<button className="px-8 py-3 glass-effect text-white font-semibold rounded-lg hover:bg-white/10 transition-all duration-300 transform hover:scale-105">
Заказать звонок
</button>
</div>

View File

@ -76,7 +76,90 @@ body {
}
}
@keyframes drift {
/* Голографические эффекты */
@keyframes hologram {
0%, 100% {
transform: scale(1) rotateY(0deg);
opacity: 0.3;
}
50% {
transform: scale(1.02) rotateY(1deg);
opacity: 0.6;
}
}
.holographic-text {
position: relative;
text-shadow:
0 0 10px rgba(0, 255, 136, 0.5),
0 0 20px rgba(0, 255, 136, 0.3),
0 0 30px rgba(0, 255, 136, 0.2);
}
.holographic-text::before {
content: attr(data-text);
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: linear-gradient(45deg, transparent, rgba(0, 255, 136, 0.1), transparent);
animation: hologram-scan 3s infinite;
z-index: -1;
}
@keyframes hologram-scan {
0% {
transform: translateX(-100%);
}
100% {
transform: translateX(100%);
}
}
/* 3D сфера технологий */
@keyframes spin-slow {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
@keyframes spin-reverse {
from {
transform: rotate(360deg);
}
to {
transform: rotate(0deg);
}
}
.animate-spin-slow {
animation: spin-slow 20s linear infinite;
}
.animate-spin-reverse {
animation: spin-reverse 15s linear infinite;
}
/* Анимации для живых счетчиков */
@keyframes counter-glow {
0%, 100% {
box-shadow: 0 0 5px rgba(0, 255, 136, 0.3);
}
50% {
box-shadow: 0 0 20px rgba(0, 255, 136, 0.6);
}
}
.counter-active {
animation: counter-glow 2s ease-in-out infinite;
}
/* Интерактивные частицы */
@keyframes particle-drift {
0% {
transform: translate(0, 0) rotate(0deg);
}
@ -94,6 +177,128 @@ body {
}
}
.particle-interactive {
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
/* Анимации для кода */
@keyframes code-typing {
from {
width: 0;
}
to {
width: 100%;
}
}
.code-animation {
overflow: hidden;
white-space: nowrap;
animation: code-typing 2s steps(40, end);
}
/* Улучшенные эффекты для технологий */
@keyframes tech-orbit {
0% {
transform: translateZ(0px) rotateY(0deg);
}
100% {
transform: translateZ(0px) rotateY(360deg);
}
}
.tech-sphere-item {
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
.tech-sphere-item:hover {
transform: scale(1.2) !important;
z-index: 1000 !important;
}
/* Анимации для прогресс-баров */
@keyframes progress-fill {
from {
width: 0%;
}
to {
width: var(--target-width);
}
}
.progress-animated {
animation: progress-fill 2s ease-out forwards;
}
/* Эффект загрузки */
@keyframes loading-pulse {
0%, 100% {
opacity: 1;
transform: scale(1);
}
50% {
opacity: 0.5;
transform: scale(1.05);
}
}
.loading-effect {
animation: loading-pulse 1.5s ease-in-out infinite;
}
/* Улучшенные hover-эффекты */
@keyframes hover-lift {
0% {
transform: translateY(0) scale(1);
}
100% {
transform: translateY(-10px) scale(1.02);
}
}
.hover-lift:hover {
animation: hover-lift 0.3s ease-out forwards;
}
/* Анимации для интерактивного кода */
@keyframes code-highlight {
0% {
background-color: transparent;
}
50% {
background-color: rgba(0, 255, 136, 0.1);
}
100% {
background-color: transparent;
}
}
.code-highlight {
animation: code-highlight 1s ease-in-out;
}
/* Эффект матрицы */
@keyframes matrix-rain {
0% {
transform: translateY(-100vh);
opacity: 0;
}
10% {
opacity: 1;
}
90% {
opacity: 1;
}
100% {
transform: translateY(100vh);
opacity: 0;
}
}
.matrix-effect {
animation: matrix-rain 3s linear infinite;
}
/* Анимация падения блоков */
@keyframes fallAndBounce {
0% {
@ -178,7 +383,25 @@ body {
animation: shake 0.5s ease-in-out;
}
/* Стили для мобильных устройств */
@keyframes drift {
0% {
transform: translate(0, 0) rotate(0deg);
}
25% {
transform: translate(10px, -10px) rotate(90deg);
}
50% {
transform: translate(-5px, -20px) rotate(180deg);
}
75% {
transform: translate(-10px, -10px) rotate(270deg);
}
100% {
transform: translate(0, 0) rotate(360deg);
}
}
/* Responsive анимации */
@media (max-width: 768px) {
.section-padding {
padding: 40px 0;
@ -191,6 +414,25 @@ body {
.glass-effect {
backdrop-filter: blur(5px);
}
.holographic-text {
text-shadow:
0 0 5px rgba(0, 255, 136, 0.3),
0 0 10px rgba(0, 255, 136, 0.2);
}
.animate-spin-slow {
animation-duration: 30s;
}
.animate-spin-reverse {
animation-duration: 25s;
}
.tech-sphere-item {
font-size: 0.75rem;
padding: 0.25rem 0.5rem;
}
}
/* Стили для touch устройств */
@ -200,73 +442,21 @@ body {
}
.draggable-card:active {
transform: scale(1.05);
box-shadow: 0 10px 25px rgba(0, 255, 136, 0.3);
transform: scale(0.95);
}
}
/* Анимация появления блоков */
@keyframes slideInFromBottom {
0% {
opacity: 0;
transform: translateY(50px);
/* Анимации для уменьшения движения */
@media (prefers-reduced-motion: reduce) {
.holographic-text,
.animate-spin-slow,
.animate-spin-reverse,
.particle-interactive,
.tech-sphere-item {
animation: none;
}
100% {
opacity: 1;
transform: translateY(0);
}
}
.animate-slide-in {
animation: slideInFromBottom 0.6s ease-out;
}
/* Пульсирующий эффект для активных элементов */
@keyframes pulse-glow {
0%, 100% {
box-shadow: 0 0 5px rgba(0, 255, 136, 0.5);
}
50% {
box-shadow: 0 0 20px rgba(0, 255, 136, 0.8);
.hover-lift:hover {
transform: none;
}
}
.pulse-glow {
animation: pulse-glow 2s infinite;
}
/* Эффект падающих звездочек */
@keyframes fallingStar {
0% {
transform: translateY(-100vh) translateX(0) rotate(0deg);
opacity: 1;
}
100% {
transform: translateY(100vh) translateX(100px) rotate(360deg);
opacity: 0;
}
}
.falling-star {
animation: fallingStar 3s linear infinite;
}
/* Эффект волны при приземлении */
@keyframes ripple {
0% {
transform: scale(0);
opacity: 1;
}
100% {
transform: scale(4);
opacity: 0;
}
}
.ripple-effect {
position: absolute;
border-radius: 50%;
background: rgba(0, 255, 136, 0.3);
animation: ripple 0.6s linear;
pointer-events: none;
}

View File

@ -1,37 +1,524 @@
'use client';
import { useState, useEffect } from 'react';
import Navigation from './components/Navigation';
import InteractiveBlocks from './components/InteractiveBlocks';
export default function Home() {
const [mounted, setMounted] = useState(false);
const [liveCounters, setLiveCounters] = useState({
projects: 0,
clients: 0,
lines: 0,
uptime: 0
});
const [currentCodeExample, setCurrentCodeExample] = useState(0);
const [techSphereRotation, setTechSphereRotation] = useState(0);
const [mousePosition, setMousePosition] = useState({ x: 0, y: 0 });
// Инициализация
useEffect(() => {
setMounted(true);
}, []);
// Анимация счетчиков
useEffect(() => {
if (!mounted) return;
const targets = { projects: 127, clients: 45, lines: 50000, uptime: 99.9 };
const duration = 2000;
const steps = 50;
const stepDuration = duration / steps;
let currentStep = 0;
const interval = setInterval(() => {
currentStep++;
const progress = currentStep / steps;
setLiveCounters({
projects: Math.floor(targets.projects * progress),
clients: Math.floor(targets.clients * progress),
lines: Math.floor(targets.lines * progress),
uptime: Math.floor(targets.uptime * progress * 10) / 10
});
if (currentStep >= steps) {
clearInterval(interval);
}
}, stepDuration);
return () => clearInterval(interval);
}, [mounted]);
// Переключение примеров кода
useEffect(() => {
if (!mounted) return;
const interval = setInterval(() => {
setCurrentCodeExample(prev => (prev + 1) % codeExamples.length);
}, 4000);
return () => clearInterval(interval);
}, [mounted]);
// Вращение 3D-сферы
useEffect(() => {
if (!mounted) return;
const interval = setInterval(() => {
setTechSphereRotation(prev => (prev + 1) % 360);
}, 50);
return () => clearInterval(interval);
}, [mounted]);
// Отслеживание мыши
useEffect(() => {
if (!mounted) return;
const handleMouseMove = (e: MouseEvent) => {
setMousePosition({ x: e.clientX, y: e.clientY });
};
window.addEventListener('mousemove', handleMouseMove);
return () => window.removeEventListener('mousemove', handleMouseMove);
}, [mounted]);
const codeExamples = [
{
title: "React + TypeScript",
code: `const App: React.FC = () => {
const [data, setData] = useState<Data[]>([]);
useEffect(() => {
fetchData().then(setData);
}, []);
return <Dashboard data={data} />;
};`
},
{
title: "Node.js API",
code: `app.post('/api/users', async (req, res) => {
try {
const user = await User.create(req.body);
res.status(201).json(user);
} catch (error) {
res.status(400).json({ error });
}
});`
},
{
title: "Python ML",
code: `import tensorflow as tf
model = tf.keras.Sequential([
tf.keras.layers.Dense(128, activation='relu'),
tf.keras.layers.Dropout(0.2),
tf.keras.layers.Dense(10, activation='softmax')
])
model.compile(optimizer='adam', loss='sparse_categorical_crossentropy')`
}
];
const technologies = [
'React', 'Node.js', 'Python', 'TypeScript', 'Docker', 'AWS', 'PostgreSQL',
'MongoDB', 'Redis', 'Kubernetes', 'GraphQL', 'Next.js', 'Vue.js', 'Django',
'Express', 'FastAPI', 'Nginx', 'Linux', 'Git', 'Jenkins', 'Terraform'
];
if (!mounted) {
return (
<div className="min-h-screen bg-gradient-to-br from-black via-gray-900 to-black">
<Navigation />
<div className="flex items-center justify-center min-h-screen">
<div className="text-center">
<div className="w-16 h-16 border-4 border-green-400 border-t-transparent rounded-full animate-spin mx-auto mb-4"></div>
<p className="text-gray-400">Загрузка...</p>
</div>
</div>
</div>
);
}
return (
<div className="min-h-screen bg-gradient-to-br from-black via-gray-900 to-black">
<Navigation />
{/* Hero Section */}
<section className="relative section-padding pt-52">
<div className="max-w-6xl mx-auto px-6 text-center">
<h1 className="text-5xl md:text-7xl font-bold mb-8">
<span className="gradient-text">GUNDYREV</span>
{/* Hero Section с заголовком и интерактивными элементами */}
<section className="relative section-padding pt-32 overflow-hidden">
<div className="max-w-6xl mx-auto px-6 text-center relative z-10">
{/* Заголовок и описание */}
<div className="relative inline-block mb-8">
<h1 className="text-5xl md:text-7xl font-bold mb-8 relative">
<span className="gradient-text holographic-text">GUNDYREV</span>
<div className="absolute inset-0 gradient-text holographic-text animate-pulse opacity-30"></div>
</h1>
{/* Голографические линии */}
<div className="absolute -inset-4 opacity-20">
{[...Array(3)].map((_, i) => (
<div
key={i}
className="absolute inset-0 border border-green-400 rounded-lg"
style={{
animation: `hologram ${2 + i * 0.5}s ease-in-out infinite`,
animationDelay: `${i * 0.3}s`
}}
/>
))}
</div>
</div>
<p className="text-xl md:text-2xl text-gray-300 mb-12 max-w-3xl mx-auto">
Комплексные IT-решения для бизнеса. От разработки до поставки оборудования.
</p>
{/* Floating particles */}
{/* Живые счетчики под описанием */}
<div className="grid grid-cols-2 md:grid-cols-4 gap-6 mb-12">
<div className="glass-effect p-6 rounded-lg hover-glow transition-all duration-300">
<div className="text-3xl font-bold gradient-text mb-2">{liveCounters.projects}+</div>
<div className="text-gray-400 text-sm">Проектов</div>
<div className="w-full bg-gray-700 rounded-full h-1 mt-2">
<div
className="bg-gradient-to-r from-green-400 to-blue-400 h-1 rounded-full transition-all duration-2000"
style={{ width: `${(liveCounters.projects / 127) * 100}%` }}
/>
</div>
</div>
<div className="glass-effect p-6 rounded-lg hover-glow transition-all duration-300">
<div className="text-3xl font-bold gradient-text mb-2">{liveCounters.clients}+</div>
<div className="text-gray-400 text-sm">Клиентов</div>
<div className="w-full bg-gray-700 rounded-full h-1 mt-2">
<div
className="bg-gradient-to-r from-purple-400 to-pink-400 h-1 rounded-full transition-all duration-2000"
style={{ width: `${(liveCounters.clients / 45) * 100}%` }}
/>
</div>
</div>
<div className="glass-effect p-6 rounded-lg hover-glow transition-all duration-300">
<div className="text-3xl font-bold gradient-text mb-2">{liveCounters.lines.toLocaleString()}+</div>
<div className="text-gray-400 text-sm">Строк кода</div>
<div className="w-full bg-gray-700 rounded-full h-1 mt-2">
<div
className="bg-gradient-to-r from-cyan-400 to-teal-400 h-1 rounded-full transition-all duration-2000"
style={{ width: `${(liveCounters.lines / 50000) * 100}%` }}
/>
</div>
</div>
<div className="glass-effect p-6 rounded-lg hover-glow transition-all duration-300">
<div className="text-3xl font-bold gradient-text mb-2">{liveCounters.uptime}%</div>
<div className="text-gray-400 text-sm">Uptime</div>
<div className="w-full bg-gray-700 rounded-full h-1 mt-2">
<div
className="bg-gradient-to-r from-amber-400 to-orange-400 h-1 rounded-full transition-all duration-2000"
style={{ width: `${(liveCounters.uptime / 99.9) * 100}%` }}
/>
</div>
</div>
</div>
{/* Интерактивные частицы с реакцией на мышь */}
<div className="absolute inset-0 pointer-events-none">
{[...Array(20)].map((_, i) => (
{[...Array(30)].map((_, i) => {
const baseX = (i * 3.33) % 100;
const baseY = (i * 7.77) % 100;
const mouseInfluence = 50;
const dx = (mousePosition.x / window.innerWidth * 100) - baseX;
const dy = (mousePosition.y / window.innerHeight * 100) - baseY;
const distance = Math.sqrt(dx * dx + dy * dy);
const influence = Math.max(0, mouseInfluence - distance) / mouseInfluence;
return (
<div
key={i}
className="absolute w-1 h-1 bg-green-400 rounded-full floating-particle"
className="absolute w-1 h-1 bg-green-400 rounded-full transition-all duration-300"
style={{
left: `${Math.random() * 100}%`,
top: `${Math.random() * 100}%`,
animationDelay: `${Math.random() * 5}s`,
animationDuration: `${3 + Math.random() * 4}s`,
left: `${baseX + dx * influence * 0.3}%`,
top: `${baseY + dy * influence * 0.3}%`,
opacity: 0.3 + influence * 0.7,
transform: `scale(${1 + influence * 2})`,
boxShadow: `0 0 ${2 + influence * 8}px rgba(16, 185, 129, ${0.5 + influence * 0.5})`,
animation: `twinkle ${2 + (i % 3)}s ease-in-out infinite`,
animationDelay: `${i * 0.1}s`
}}
/>
);
})}
</div>
</div>
</section>
{/* Современная секция технологий */}
<section className="section-padding bg-gradient-to-b from-transparent to-gray-900/30">
<div className="max-w-7xl mx-auto px-6">
<div className="text-center mb-16">
<h2 className="text-4xl md:text-6xl font-bold mb-6 gradient-text">Наши технологии</h2>
<p className="text-xl text-gray-300 max-w-3xl mx-auto">
Мы используем передовые технологии для создания инновационных решений
</p>
</div>
{/* Категории технологий */}
<div className="grid md:grid-cols-2 lg:grid-cols-4 gap-8 mb-16">
{[
{
category: 'Frontend',
icon: '🎨',
color: 'from-purple-500 to-pink-500',
techs: ['React', 'Next.js', 'Vue.js', 'TypeScript', 'Tailwind CSS'],
description: 'Современные пользовательские интерфейсы'
},
{
category: 'Backend',
icon: '⚙️',
color: 'from-blue-500 to-cyan-500',
techs: ['Node.js', 'Python', 'Express', 'FastAPI', 'GraphQL'],
description: 'Мощные серверные решения'
},
{
category: 'Database',
icon: '🗄️',
color: 'from-green-500 to-emerald-500',
techs: ['PostgreSQL', 'MongoDB', 'Redis', 'MySQL', 'Elasticsearch'],
description: 'Надежное хранение данных'
},
{
category: 'DevOps',
icon: '🚀',
color: 'from-orange-500 to-red-500',
techs: ['Docker', 'Kubernetes', 'AWS', 'Jenkins', 'Terraform'],
description: 'Автоматизация и развертывание'
}
].map((category, categoryIndex) => (
<div
key={category.category}
className="glass-effect p-6 rounded-xl hover-glow transition-all duration-500 group hover:scale-105"
style={{
animationDelay: `${categoryIndex * 0.2}s`
}}
>
<div className={`w-16 h-16 bg-gradient-to-br ${category.color} rounded-full flex items-center justify-center text-2xl mb-4 mx-auto group-hover:scale-110 transition-transform duration-300`}>
{category.icon}
</div>
<h3 className="text-xl font-bold text-white mb-2 text-center">{category.category}</h3>
<p className="text-gray-400 text-sm text-center mb-4">{category.description}</p>
<div className="space-y-2">
{category.techs.map((tech, techIndex) => (
<div
key={tech}
className="bg-gray-800/50 px-3 py-2 rounded-lg text-sm text-gray-300 hover:bg-gray-700/50 transition-all duration-300 cursor-pointer hover:text-white"
style={{
animationDelay: `${(categoryIndex * 0.2) + (techIndex * 0.1)}s`
}}
onMouseEnter={(e) => {
e.currentTarget.style.transform = 'translateX(5px)';
e.currentTarget.style.boxShadow = '0 0 10px rgba(0, 255, 136, 0.3)';
}}
onMouseLeave={(e) => {
e.currentTarget.style.transform = 'translateX(0)';
e.currentTarget.style.boxShadow = 'none';
}}
>
{tech}
</div>
))}
</div>
</div>
))}
</div>
{/* Интерактивная диаграмма экспертизы */}
<div className="glass-effect p-8 rounded-xl mb-16">
<h3 className="text-2xl font-bold text-center mb-8 gradient-text">Уровень экспертизы</h3>
<div className="grid md:grid-cols-2 gap-8">
{[
{ skill: 'React Development', level: 95, color: 'from-blue-400 to-blue-600' },
{ skill: 'Node.js Backend', level: 90, color: 'from-green-400 to-green-600' },
{ skill: 'Cloud Infrastructure', level: 88, color: 'from-purple-400 to-purple-600' },
{ skill: 'Database Design', level: 92, color: 'from-cyan-400 to-cyan-600' },
{ skill: 'DevOps & CI/CD', level: 85, color: 'from-orange-400 to-orange-600' },
{ skill: 'Mobile Development', level: 80, color: 'from-pink-400 to-pink-600' }
].map((skill, index) => (
<div key={skill.skill} className="mb-6">
<div className="flex justify-between items-center mb-2">
<span className="text-white font-medium">{skill.skill}</span>
<span className="text-green-400 font-bold">{skill.level}%</span>
</div>
<div className="w-full bg-gray-700 rounded-full h-3 overflow-hidden">
<div
className={`h-full bg-gradient-to-r ${skill.color} rounded-full transition-all duration-2000 ease-out relative`}
style={{
width: mounted ? `${skill.level}%` : '0%',
animationDelay: `${index * 0.3}s`
}}
>
<div className="absolute inset-0 bg-white/20 animate-pulse"></div>
</div>
</div>
</div>
))}
</div>
</div>
{/* Облако технологий */}
<div className="relative h-80 glass-effect rounded-xl p-8 overflow-hidden">
<h3 className="text-2xl font-bold text-center mb-8 gradient-text">Облако технологий</h3>
<div className="relative h-full">
{technologies.map((tech, index) => {
const sizes = ['text-sm', 'text-base', 'text-lg', 'text-xl', 'text-2xl'];
const size = sizes[index % sizes.length];
const colors = [
'text-green-400', 'text-blue-400', 'text-purple-400',
'text-cyan-400', 'text-pink-400', 'text-yellow-400'
];
const color = colors[index % colors.length];
// Детерминированные позиции для облака
const x = (index * 17 + 13) % 85 + 5;
const y = (index * 23 + 29) % 70 + 10;
return (
<div
key={tech}
className={`absolute ${size} ${color} font-mono cursor-pointer hover:scale-125 transition-all duration-300 hover:text-white`}
style={{
left: `${x}%`,
top: `${y}%`,
transform: 'translate(-50%, -50%)',
animation: `float ${3 + (index % 4)}s ease-in-out infinite`,
animationDelay: `${index * 0.2}s`
}}
onMouseEnter={(e) => {
e.currentTarget.style.textShadow = '0 0 10px currentColor';
e.currentTarget.style.zIndex = '100';
}}
onMouseLeave={(e) => {
e.currentTarget.style.textShadow = 'none';
e.currentTarget.style.zIndex = '1';
}}
>
{tech}
</div>
);
})}
{/* Соединительные линии между технологиями */}
<svg className="absolute inset-0 w-full h-full pointer-events-none opacity-20">
{technologies.slice(0, 10).map((_, i) => {
const x1 = ((i * 17 + 13) % 85 + 5);
const y1 = ((i * 23 + 29) % 70 + 10);
const x2 = (((i + 1) * 17 + 13) % 85 + 5);
const y2 = (((i + 1) * 23 + 29) % 70 + 10);
return (
<line
key={i}
x1={`${x1}%`}
y1={`${y1}%`}
x2={`${x2}%`}
y2={`${y2}%`}
stroke="rgba(0, 255, 136, 0.3)"
strokeWidth="1"
className="animate-pulse"
style={{ animationDelay: `${i * 0.5}s` }}
/>
);
})}
</svg>
</div>
</div>
{/* Статистика технологий */}
<div className="grid md:grid-cols-3 gap-8 mt-16">
<div className="text-center glass-effect p-6 rounded-xl hover-glow transition-all duration-300">
<div className="text-4xl font-bold gradient-text mb-2">21+</div>
<div className="text-gray-400">Технологий в стеке</div>
</div>
<div className="text-center glass-effect p-6 rounded-xl hover-glow transition-all duration-300">
<div className="text-4xl font-bold gradient-text mb-2">5+</div>
<div className="text-gray-400">Лет опыта</div>
</div>
<div className="text-center glass-effect p-6 rounded-xl hover-glow transition-all duration-300">
<div className="text-4xl font-bold gradient-text mb-2">100%</div>
<div className="text-gray-400">Современные решения</div>
</div>
</div>
</div>
</section>
{/* Интерактивный код-редактор */}
<section className="section-padding">
<div className="max-w-6xl mx-auto px-6">
<div className="text-center mb-12">
<h2 className="text-4xl font-bold mb-6 gradient-text">Живой код</h2>
<p className="text-xl text-gray-300">Примеры нашего кода в реальном времени</p>
</div>
<div className="grid md:grid-cols-2 gap-8">
<div className="glass-effect p-6 rounded-lg">
<div className="flex items-center justify-between mb-4">
<h3 className="text-xl font-bold text-white">{codeExamples[currentCodeExample].title}</h3>
<div className="flex space-x-2">
<div className="w-3 h-3 bg-red-400 rounded-full"></div>
<div className="w-3 h-3 bg-yellow-400 rounded-full"></div>
<div className="w-3 h-3 bg-green-400 rounded-full"></div>
</div>
</div>
<div className="bg-gray-900 rounded-lg p-4 font-mono text-sm overflow-x-auto">
<pre className="text-gray-300">
<code>{codeExamples[currentCodeExample].code}</code>
</pre>
</div>
<div className="flex justify-center mt-4 space-x-2">
{codeExamples.map((_, index) => (
<button
key={index}
className={`w-3 h-3 rounded-full transition-all duration-300 ${
index === currentCodeExample ? 'bg-green-400' : 'bg-gray-600'
}`}
onClick={() => setCurrentCodeExample(index)}
/>
))}
</div>
</div>
<div className="space-y-6">
<div className="glass-effect p-6 rounded-lg hover-glow transition-all duration-300">
<h4 className="text-lg font-bold mb-3 text-green-400">🚀 Современные технологии</h4>
<p className="text-gray-300">
Используем последние версии фреймворков и библиотек для создания производительных приложений
</p>
</div>
<div className="glass-effect p-6 rounded-lg hover-glow transition-all duration-300">
<h4 className="text-lg font-bold mb-3 text-blue-400">🔧 Чистый код</h4>
<p className="text-gray-300">
Следуем принципам SOLID, используем TypeScript и покрываем код тестами
</p>
</div>
<div className="glass-effect p-6 rounded-lg hover-glow transition-all duration-300">
<h4 className="text-lg font-bold mb-3 text-purple-400"> Высокая производительность</h4>
<p className="text-gray-300">
Оптимизируем каждую строчку кода для максимальной скорости работы
</p>
</div>
</div>
</div>
</div>
</section>
{/* About Section */}

View File

@ -1,8 +1,43 @@
'use client';
import Navigation from '../../components/Navigation';
import { useState } from 'react';
export default function SecureTDocumentation() {
const [isSupportModalOpen, setIsSupportModalOpen] = useState(false);
const [supportForm, setSupportForm] = useState({
name: '',
email: '',
topic: '',
message: ''
});
const handleSupportClick = () => {
setIsSupportModalOpen(true);
document.body.style.overflow = 'hidden';
};
const handleCloseSupportModal = () => {
setIsSupportModalOpen(false);
document.body.style.overflow = 'unset';
};
const handleSupportInputChange = (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement>) => {
const { name, value } = e.target;
setSupportForm(prev => ({
...prev,
[name]: value
}));
};
const handleSupportSubmit = (e: React.FormEvent) => {
e.preventDefault();
// Здесь можно добавить логику отправки в поддержку
alert(`Спасибо за обращение, ${supportForm.name}! Мы ответим в течение 24 часов.`);
setSupportForm({ name: '', email: '', topic: '', message: '' });
setIsSupportModalOpen(false);
document.body.style.overflow = 'unset';
};
return (
<>
<Navigation />
@ -195,12 +230,12 @@ export default function SecureTDocumentation() {
Наша команда поддержки готова помочь вам разобраться с любыми вопросами
</p>
<div className="flex flex-col sm:flex-row gap-4 justify-center">
<a
href="mailto:support@secure-t.com"
className="px-8 py-3 bg-red-500 text-white font-semibold rounded-lg hover-glow transition-all duration-300"
<button
onClick={handleSupportClick}
className="px-8 py-3 bg-red-500 text-white font-semibold rounded-lg hover-glow transition-all duration-300 hover:bg-red-600 active:scale-95 cursor-pointer"
>
Написать в поддержку
</a>
</button>
<a
href="tel:+74951234567"
className="px-8 py-3 glass-effect text-white font-semibold rounded-lg hover:bg-white/10 transition-all duration-300"
@ -227,6 +262,108 @@ export default function SecureTDocumentation() {
</p>
</div>
</footer>
{/* Support Modal */}
{isSupportModalOpen && (
<div className="fixed inset-0 bg-black bg-opacity-30 flex items-center justify-center z-50 p-4">
<div className="bg-gray-900 rounded-lg p-8 max-w-md w-full relative border border-red-500/30">
<button
onClick={handleCloseSupportModal}
className="absolute top-4 right-4 text-gray-400 hover:text-white text-2xl"
>
×
</button>
<h3 className="text-2xl font-bold mb-6 gradient-text">Написать в поддержку</h3>
<form onSubmit={handleSupportSubmit} className="space-y-4">
<div>
<label htmlFor="name" className="block text-sm font-medium text-gray-300 mb-1">
Имя *
</label>
<input
type="text"
id="name"
name="name"
value={supportForm.name}
onChange={handleSupportInputChange}
required
className="w-full px-3 py-2 bg-gray-800 border border-gray-600 rounded-lg text-white focus:outline-none focus:border-red-500"
/>
</div>
<div>
<label htmlFor="email" className="block text-sm font-medium text-gray-300 mb-1">
Email *
</label>
<input
type="email"
id="email"
name="email"
value={supportForm.email}
onChange={handleSupportInputChange}
required
className="w-full px-3 py-2 bg-gray-800 border border-gray-600 rounded-lg text-white focus:outline-none focus:border-red-500"
/>
</div>
<div>
<label htmlFor="topic" className="block text-sm font-medium text-gray-300 mb-1">
Тема обращения *
</label>
<select
id="topic"
name="topic"
value={supportForm.topic}
onChange={handleSupportInputChange}
required
className="w-full px-3 py-2 bg-gray-800 border border-gray-600 rounded-lg text-white focus:outline-none focus:border-red-500"
>
<option value="">Выберите тему</option>
<option value="documentation">Вопросы по документации</option>
<option value="installation">Проблемы установки</option>
<option value="configuration">Настройка системы</option>
<option value="api">API и интеграция</option>
<option value="security">Вопросы безопасности</option>
<option value="other">Другое</option>
</select>
</div>
<div>
<label htmlFor="message" className="block text-sm font-medium text-gray-300 mb-1">
Сообщение *
</label>
<textarea
id="message"
name="message"
value={supportForm.message}
onChange={handleSupportInputChange}
required
rows={4}
className="w-full px-3 py-2 bg-gray-800 border border-gray-600 rounded-lg text-white focus:outline-none focus:border-red-500"
placeholder="Опишите вашу проблему или вопрос..."
/>
</div>
<div className="flex space-x-4 pt-4">
<button
type="button"
onClick={handleCloseSupportModal}
className="flex-1 px-4 py-2 bg-gray-600 text-white rounded-lg hover:bg-gray-700 transition-colors"
>
Отмена
</button>
<button
type="submit"
className="flex-1 px-4 py-2 bg-red-500 text-white rounded-lg hover:bg-red-600 transition-colors"
>
Отправить
</button>
</div>
</form>
</div>
</div>
)}
</>
);
}

View File

@ -1,6 +1,365 @@
'use client';
import { useState, useEffect } from 'react';
import Navigation from '../components/Navigation';
export default function SecureT() {
// Живые уведомления безопасности
const [securityAlerts, setSecurityAlerts] = useState<Array<{
id: number,
message: string,
type: 'threat' | 'scan' | 'update' | 'block',
timestamp: Date
}>>([]);
const [alertId, setAlertId] = useState(0);
// Дополнительные уведомления для разных углов
const [leftBottomAlerts, setLeftBottomAlerts] = useState<Array<{
id: number,
message: string,
type: 'critical' | 'warning' | 'info',
timestamp: Date
}>>([]);
const [rightBottomAlerts, setRightBottomAlerts] = useState<Array<{
id: number,
message: string,
type: 'encryption' | 'firewall' | 'backup',
timestamp: Date
}>>([]);
const [centerAlerts, setCenterAlerts] = useState<Array<{
id: number,
message: string,
type: 'system' | 'network' | 'data',
position: 'left' | 'right',
timestamp: Date
}>>([]);
// Анимированная статистика
const [stats, setStats] = useState({
threatsBlocked: 0,
systemsProtected: 0,
dataEncrypted: 0,
uptime: 0
});
// Интерактивная карта угроз
const [threatMap, setThreatMap] = useState<Array<{
id: number,
x: number,
y: number,
type: 'malware' | 'phishing' | 'ddos' | 'intrusion',
intensity: number
}>>([]);
// Состояние системы
const [systemStatus, setSystemStatus] = useState({
firewall: 'active',
encryption: 'active',
monitoring: 'active',
backup: 'active'
});
// Модальные окна
const [isSolutionsModalOpen, setIsSolutionsModalOpen] = useState(false);
const [isDocumentationModalOpen, setIsDocumentationModalOpen] = useState(false);
// Форма для решений
const [solutionsForm, setSolutionsForm] = useState({
name: '',
email: '',
company: '',
solution: '',
message: ''
});
// Форма для документации
const [documentationForm, setDocumentationForm] = useState({
name: '',
email: '',
company: '',
documentType: '',
message: ''
});
// Анимация статистики
useEffect(() => {
const targetStats = {
threatsBlocked: 2847,
systemsProtected: 156,
dataEncrypted: 99.8,
uptime: 99.97
};
const duration = 2000;
const steps = 60;
const stepDuration = duration / steps;
let currentStep = 0;
const interval = setInterval(() => {
currentStep++;
const progress = currentStep / steps;
const easeOut = 1 - Math.pow(1 - progress, 3);
setStats({
threatsBlocked: Math.floor(targetStats.threatsBlocked * easeOut),
systemsProtected: Math.floor(targetStats.systemsProtected * easeOut),
dataEncrypted: Math.floor(targetStats.dataEncrypted * easeOut * 10) / 10,
uptime: Math.floor(targetStats.uptime * easeOut * 100) / 100
});
if (currentStep >= steps) {
clearInterval(interval);
}
}, stepDuration);
return () => clearInterval(interval);
}, []);
// Живые уведомления безопасности
useEffect(() => {
const securityMessages = [
{ message: 'Заблокирована попытка SQL-инъекции', type: 'block' as const },
{ message: 'Обнаружена подозрительная сетевая активность', type: 'threat' as const },
{ message: 'Завершено сканирование на вирусы', type: 'scan' as const },
{ message: 'Обновлены правила файрвола', type: 'update' as const },
{ message: 'Заблокирован доступ к вредоносному домену', type: 'block' as const },
{ message: 'Обнаружена попытка брутфорса', type: 'threat' as const },
{ message: 'Выполнено резервное копирование данных', type: 'update' as const },
{ message: 'Заблокирован подозрительный трафик', type: 'block' as const }
];
const addAlert = () => {
const newAlert = {
id: alertId,
...securityMessages[Math.floor(Math.random() * securityMessages.length)],
timestamp: new Date()
};
setSecurityAlerts(prev => [newAlert, ...prev.slice(0, 4)]);
setAlertId(prev => prev + 1);
// Удаляем через 8 секунд
setTimeout(() => {
setSecurityAlerts(prev => prev.filter(alert => alert.id !== newAlert.id));
}, 8000);
};
const interval = setInterval(addAlert, 3000);
return () => clearInterval(interval);
}, [alertId]);
// Уведомления левый нижний угол
useEffect(() => {
const leftBottomMessages = [
{ message: 'Критическая уязвимость обнаружена', type: 'critical' as const },
{ message: 'Предупреждение: высокая нагрузка на сервер', type: 'warning' as const },
{ message: 'Информация: обновление политик безопасности', type: 'info' as const },
{ message: 'Критично: попытка несанкционированного доступа', type: 'critical' as const },
{ message: 'Предупреждение: превышен лимит подключений', type: 'warning' as const },
{ message: 'Информация: резервное копирование завершено', type: 'info' as const }
];
const addLeftBottomAlert = () => {
const newAlert = {
id: Math.random(),
...leftBottomMessages[Math.floor(Math.random() * leftBottomMessages.length)],
timestamp: new Date()
};
setLeftBottomAlerts(prev => [newAlert, ...prev.slice(0, 3)]);
setTimeout(() => {
setLeftBottomAlerts(prev => prev.filter(alert => alert.id !== newAlert.id));
}, 7000);
};
const interval = setInterval(addLeftBottomAlert, 4000);
return () => clearInterval(interval);
}, []);
// Уведомления правый нижний угол
useEffect(() => {
const rightBottomMessages = [
{ message: 'Шифрование данных: 256-bit AES активно', type: 'encryption' as const },
{ message: 'Файрвол: заблокировано 47 подключений', type: 'firewall' as const },
{ message: 'Резервное копирование: 98% завершено', type: 'backup' as const },
{ message: 'Шифрование: ключи успешно обновлены', type: 'encryption' as const },
{ message: 'Файрвол: новые правила применены', type: 'firewall' as const },
{ message: 'Резервирование: проверка целостности данных', type: 'backup' as const }
];
const addRightBottomAlert = () => {
const newAlert = {
id: Math.random(),
...rightBottomMessages[Math.floor(Math.random() * rightBottomMessages.length)],
timestamp: new Date()
};
setRightBottomAlerts(prev => [newAlert, ...prev.slice(0, 3)]);
setTimeout(() => {
setRightBottomAlerts(prev => prev.filter(alert => alert.id !== newAlert.id));
}, 6000);
};
const interval = setInterval(addRightBottomAlert, 3500);
return () => clearInterval(interval);
}, []);
// Центральные боковые уведомления
useEffect(() => {
const centerMessages = [
{ message: 'Системный мониторинг: все компоненты в норме', type: 'system' as const },
{ message: 'Сетевая активность: трафик в пределах нормы', type: 'network' as const },
{ message: 'Защита данных: все файлы зашифрованы', type: 'data' as const },
{ message: 'Системная диагностика: ошибок не обнаружено', type: 'system' as const },
{ message: 'Сетевая безопасность: периметр защищен', type: 'network' as const },
{ message: 'Целостность данных: проверка пройдена', type: 'data' as const }
];
const addCenterAlert = () => {
const positions = ['left', 'right'] as const;
const newAlert = {
id: Math.random(),
...centerMessages[Math.floor(Math.random() * centerMessages.length)],
position: positions[Math.floor(Math.random() * positions.length)],
timestamp: new Date()
};
setCenterAlerts(prev => [newAlert, ...prev.slice(0, 4)]);
setTimeout(() => {
setCenterAlerts(prev => prev.filter(alert => alert.id !== newAlert.id));
}, 5000);
};
const interval = setInterval(addCenterAlert, 2500);
return () => clearInterval(interval);
}, []);
// Обработчики для модальных окон
const handleSolutionsClick = () => {
setIsSolutionsModalOpen(true);
document.body.style.overflow = 'hidden';
};
const handleDocumentationClick = () => {
setIsDocumentationModalOpen(true);
document.body.style.overflow = 'hidden';
};
const handleCloseModal = () => {
setIsSolutionsModalOpen(false);
setIsDocumentationModalOpen(false);
document.body.style.overflow = 'unset';
};
const handleSolutionsInputChange = (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement>) => {
const { name, value } = e.target;
setSolutionsForm(prev => ({
...prev,
[name]: value
}));
};
const handleDocumentationInputChange = (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement>) => {
const { name, value } = e.target;
setDocumentationForm(prev => ({
...prev,
[name]: value
}));
};
const handleSolutionsSubmit = (e: React.FormEvent) => {
e.preventDefault();
alert(`Спасибо за заявку, ${solutionsForm.name}! Наш специалист свяжется с вами для обсуждения решения "${solutionsForm.solution}".`);
setSolutionsForm({ name: '', email: '', company: '', solution: '', message: '' });
handleCloseModal();
};
const handleDocumentationSubmit = (e: React.FormEvent) => {
e.preventDefault();
alert(`Спасибо за запрос, ${documentationForm.name}! Документация "${documentationForm.documentType}" будет отправлена на ${documentationForm.email}.`);
setDocumentationForm({ name: '', email: '', company: '', documentType: '', message: '' });
handleCloseModal();
};
// Интерактивная карта угроз
useEffect(() => {
const generateThreatPoint = () => {
const threatTypes = ['malware', 'phishing', 'ddos', 'intrusion'] as const;
return {
id: Math.random(),
x: Math.random() * 100,
y: Math.random() * 100,
type: threatTypes[Math.floor(Math.random() * threatTypes.length)],
intensity: Math.random() * 0.8 + 0.2
};
};
const updateThreatMap = () => {
setThreatMap(prev => {
const newPoints = Array.from({ length: 3 }, generateThreatPoint);
return [...newPoints, ...prev.slice(0, 12)];
});
};
const interval = setInterval(updateThreatMap, 2000);
return () => clearInterval(interval);
}, []);
// Создание CSS анимаций динамически
useEffect(() => {
const style = document.createElement('style');
style.textContent = `
@keyframes pulse-secure {
0%, 100% { opacity: 1; transform: scale(1); }
50% { opacity: 0.7; transform: scale(1.05); }
}
@keyframes slide-up {
from { transform: translateY(20px); opacity: 0; }
to { transform: translateY(0); opacity: 1; }
}
@keyframes slide-left {
from { transform: translateX(20px); opacity: 0; }
to { transform: translateX(0); opacity: 1; }
}
@keyframes slide-right {
from { transform: translateX(-20px); opacity: 0; }
to { transform: translateX(0); opacity: 1; }
}
@keyframes bounce-in {
0% { transform: scale(0.8) translateY(-10px); opacity: 0; }
50% { transform: scale(1.05) translateY(0); opacity: 0.8; }
100% { transform: scale(1) translateY(0); opacity: 1; }
}
@keyframes threat-pulse {
0%, 100% { transform: scale(1); opacity: 0.8; }
50% { transform: scale(1.2); opacity: 1; }
}
@keyframes secure-glow {
0%, 100% { box-shadow: 0 0 20px rgba(239, 68, 68, 0.3); }
50% { box-shadow: 0 0 30px rgba(239, 68, 68, 0.6); }
}
@keyframes critical-flash {
0%, 100% { border-color: rgba(239, 68, 68, 0.5); }
50% { border-color: rgba(239, 68, 68, 1); }
}
.animate-pulse-secure { animation: pulse-secure 2s ease-in-out infinite; }
.animate-slide-up { animation: slide-up 0.5s ease-out; }
.animate-slide-left { animation: slide-left 0.5s ease-out; }
.animate-slide-right { animation: slide-right 0.5s ease-out; }
.animate-bounce-in { animation: bounce-in 0.6s ease-out; }
.animate-threat-pulse { animation: threat-pulse 1.5s ease-in-out infinite; }
.animate-secure-glow { animation: secure-glow 3s ease-in-out infinite; }
.animate-critical-flash { animation: critical-flash 2s ease-in-out infinite; }
`;
document.head.appendChild(style);
return () => {
document.head.removeChild(style);
};
}, []);
return (
<>
<Navigation />
@ -8,6 +367,27 @@ export default function SecureT() {
{/* Hero Section */}
<section className="min-h-screen flex items-center justify-center relative overflow-hidden pt-16">
<div className="absolute inset-0 bg-gradient-to-br from-red-900 via-black to-orange-900"></div>
{/* Интерактивная карта угроз */}
<div className="absolute inset-0 opacity-30">
{threatMap.map((threat) => (
<div
key={threat.id}
className={`absolute w-3 h-3 rounded-full animate-threat-pulse ${
threat.type === 'malware' ? 'bg-red-500' :
threat.type === 'phishing' ? 'bg-yellow-500' :
threat.type === 'ddos' ? 'bg-purple-500' :
'bg-orange-500'
}`}
style={{
left: `${threat.x}%`,
top: `${threat.y}%`,
opacity: threat.intensity
}}
></div>
))}
</div>
<div className="absolute inset-0 opacity-20">
<div className="absolute top-1/4 left-1/4 w-96 h-96 bg-red-500 rounded-full blur-3xl opacity-30"></div>
<div className="absolute bottom-1/4 right-1/4 w-96 h-96 bg-orange-500 rounded-full blur-3xl opacity-30"></div>
@ -15,23 +395,219 @@ export default function SecureT() {
<div className="relative z-10 text-center max-w-6xl mx-auto px-4">
<h1 className="text-5xl md:text-7xl font-bold mb-6">
<span className="gradient-text">SECURE-T</span>
<span className="gradient-text animate-pulse-secure">SECURE-T</span>
</h1>
<p className="text-xl md:text-2xl text-gray-300 mb-8 max-w-4xl mx-auto">
Комплексные решения для информационной безопасности и защиты данных
</p>
{/* Живая статистика */}
<div className="grid grid-cols-2 md:grid-cols-4 gap-6 mb-8 max-w-4xl mx-auto">
<div className="glass-effect p-4 rounded-lg animate-secure-glow">
<div className="text-2xl font-bold text-red-400">{stats.threatsBlocked.toLocaleString()}</div>
<div className="text-sm text-gray-300">Угроз заблокировано</div>
</div>
<div className="glass-effect p-4 rounded-lg animate-secure-glow">
<div className="text-2xl font-bold text-orange-400">{stats.systemsProtected}</div>
<div className="text-sm text-gray-300">Систем защищено</div>
</div>
<div className="glass-effect p-4 rounded-lg animate-secure-glow">
<div className="text-2xl font-bold text-yellow-400">{stats.dataEncrypted}%</div>
<div className="text-sm text-gray-300">Данных зашифровано</div>
</div>
<div className="glass-effect p-4 rounded-lg animate-secure-glow">
<div className="text-2xl font-bold text-green-400">{stats.uptime}%</div>
<div className="text-sm text-gray-300">Время работы</div>
</div>
</div>
<div className="flex flex-col sm:flex-row gap-4 justify-center">
<button className="px-8 py-3 bg-red-500 text-white font-semibold rounded-lg hover-glow transition-all duration-300">
<button
onClick={handleSolutionsClick}
className="px-8 py-3 bg-red-500 text-white font-semibold rounded-lg hover-glow transition-all duration-300 animate-pulse-secure hover:bg-red-600 active:scale-95 cursor-pointer"
>
Наши решения
</button>
<a
href="/secure-t/documentation"
className="px-8 py-3 glass-effect text-white font-semibold rounded-lg hover:bg-white/10 transition-all duration-300 text-center"
<button
onClick={handleDocumentationClick}
className="px-8 py-3 glass-effect text-white font-semibold rounded-lg hover:bg-white/10 transition-all duration-300 active:scale-95 cursor-pointer"
>
Документация
</a>
</button>
</div>
</div>
{/* Живые уведомления безопасности - только в hero блоке */}
<div className="absolute top-20 right-4 z-50 space-y-2 max-w-sm">
{securityAlerts.map((alert) => (
<div
key={alert.id}
className={`p-4 rounded-lg border-l-4 glass-effect animate-slide-up ${
alert.type === 'threat' ? 'border-red-500 bg-red-900/20' :
alert.type === 'block' ? 'border-orange-500 bg-orange-900/20' :
alert.type === 'scan' ? 'border-blue-500 bg-blue-900/20' :
'border-green-500 bg-green-900/20'
}`}
>
<div className="flex items-start space-x-3">
<div className={`text-xl animate-pulse-secure ${
alert.type === 'threat' ? 'text-red-400' :
alert.type === 'block' ? 'text-orange-400' :
alert.type === 'scan' ? 'text-blue-400' :
'text-green-400'
}`}>
{alert.type === 'threat' ? '⚠️' :
alert.type === 'block' ? '🛡️' :
alert.type === 'scan' ? '🔍' : '✅'}
</div>
<div className="flex-1">
<p className="text-sm text-gray-300 font-medium">{alert.message}</p>
<p className="text-xs text-gray-500 mt-1">
{alert.timestamp.toLocaleTimeString()}
</p>
</div>
</div>
</div>
))}
</div>
{/* Статус системы - только в hero блоке */}
<div className="absolute top-20 left-4 z-50 space-y-2 max-w-xs">
<div className="glass-effect p-4 rounded-lg border border-red-500/30">
<h4 className="text-sm font-bold text-red-400 mb-3">Статус системы</h4>
<div className="space-y-2">
{Object.entries(systemStatus).map(([key, status]) => (
<div key={key} className="flex items-center justify-between">
<span className="text-xs text-gray-300 capitalize">
{key === 'firewall' ? 'Файрвол' :
key === 'encryption' ? 'Шифрование' :
key === 'monitoring' ? 'Мониторинг' : 'Резервирование'}
</span>
<div className={`w-2 h-2 rounded-full animate-pulse-secure ${
status === 'active' ? 'bg-green-400' : 'bg-red-400'
}`}></div>
</div>
))}
</div>
</div>
</div>
{/* Уведомления левый нижний угол - только в hero блоке */}
<div className="absolute bottom-4 left-4 z-50 space-y-2 max-w-sm">
{leftBottomAlerts.map((alert) => (
<div
key={alert.id}
className={`p-3 rounded-lg border-l-4 glass-effect animate-bounce-in ${
alert.type === 'critical' ? 'border-red-500 bg-red-900/20 animate-critical-flash' :
alert.type === 'warning' ? 'border-yellow-500 bg-yellow-900/20' :
'border-blue-500 bg-blue-900/20'
}`}
>
<div className="flex items-start space-x-3">
<div className={`text-lg animate-pulse-secure ${
alert.type === 'critical' ? 'text-red-400' :
alert.type === 'warning' ? 'text-yellow-400' :
'text-blue-400'
}`}>
{alert.type === 'critical' ? '🚨' :
alert.type === 'warning' ? '⚠️' : ''}
</div>
<div className="flex-1">
<p className="text-sm text-gray-300 font-medium">{alert.message}</p>
<p className="text-xs text-gray-500 mt-1">
{alert.timestamp.toLocaleTimeString()}
</p>
</div>
</div>
</div>
))}
</div>
{/* Уведомления правый нижний угол - только в hero блоке */}
<div className="absolute bottom-4 right-4 z-50 space-y-2 max-w-sm">
{rightBottomAlerts.map((alert) => (
<div
key={alert.id}
className={`p-3 rounded-lg border-l-4 glass-effect animate-slide-left ${
alert.type === 'encryption' ? 'border-purple-500 bg-purple-900/20' :
alert.type === 'firewall' ? 'border-orange-500 bg-orange-900/20' :
'border-green-500 bg-green-900/20'
}`}
>
<div className="flex items-start space-x-3">
<div className={`text-lg animate-pulse-secure ${
alert.type === 'encryption' ? 'text-purple-400' :
alert.type === 'firewall' ? 'text-orange-400' :
'text-green-400'
}`}>
{alert.type === 'encryption' ? '🔐' :
alert.type === 'firewall' ? '🔥' : '💾'}
</div>
<div className="flex-1">
<p className="text-sm text-gray-300 font-medium">{alert.message}</p>
<p className="text-xs text-gray-500 mt-1">
{alert.timestamp.toLocaleTimeString()}
</p>
</div>
</div>
</div>
))}
</div>
{/* Центральные боковые уведомления - только в hero блоке */}
<div className="absolute top-1/2 left-4 -translate-y-1/2 z-40 space-y-2 max-w-xs">
{centerAlerts.filter(alert => alert.position === 'left').map((alert) => (
<div
key={alert.id}
className={`p-3 rounded-lg border glass-effect animate-slide-right ${
alert.type === 'system' ? 'border-indigo-500 bg-indigo-900/20' :
alert.type === 'network' ? 'border-cyan-500 bg-cyan-900/20' :
'border-pink-500 bg-pink-900/20'
}`}
>
<div className="flex items-center space-x-2">
<div className={`text-lg animate-pulse-secure ${
alert.type === 'system' ? 'text-indigo-400' :
alert.type === 'network' ? 'text-cyan-400' :
'text-pink-400'
}`}>
{alert.type === 'system' ? '🖥️' :
alert.type === 'network' ? '🌐' : '📁'}
</div>
<div className="flex-1">
<p className="text-xs text-gray-300 font-medium">{alert.message}</p>
</div>
</div>
</div>
))}
</div>
<div className="absolute top-1/2 right-4 -translate-y-1/2 z-40 space-y-2 max-w-xs">
{centerAlerts.filter(alert => alert.position === 'right').map((alert) => (
<div
key={alert.id}
className={`p-3 rounded-lg border glass-effect animate-slide-left ${
alert.type === 'system' ? 'border-indigo-500 bg-indigo-900/20' :
alert.type === 'network' ? 'border-cyan-500 bg-cyan-900/20' :
'border-pink-500 bg-pink-900/20'
}`}
>
<div className="flex items-center space-x-2">
<div className={`text-lg animate-pulse-secure ${
alert.type === 'system' ? 'text-indigo-400' :
alert.type === 'network' ? 'text-cyan-400' :
'text-pink-400'
}`}>
{alert.type === 'system' ? '🖥️' :
alert.type === 'network' ? '🌐' : '📁'}
</div>
<div className="flex-1">
<p className="text-xs text-gray-300 font-medium">{alert.message}</p>
</div>
</div>
</div>
))}
</div>
</section>
{/* Solutions Section */}
@ -47,52 +623,82 @@ export default function SecureT() {
</div>
<div className="grid md:grid-cols-2 lg:grid-cols-3 gap-8">
<div className="glass-effect p-8 rounded-lg hover-glow transition-all duration-300">
<div className="text-red-400 text-4xl mb-4">🔐</div>
<div className="glass-effect p-8 rounded-lg hover-glow transition-all duration-300 group hover:scale-105">
<div className="text-red-400 text-4xl mb-4 group-hover:animate-pulse-secure">🔐</div>
<h3 className="text-xl font-bold mb-4">Криптографическая защита</h3>
<p className="text-gray-300">
Современные алгоритмы шифрования для защиты конфиденциальных данных
</p>
<div className="mt-4 opacity-0 group-hover:opacity-100 transition-opacity">
<button className="text-red-400 text-sm font-medium hover:text-red-300">
Подробнее
</button>
</div>
</div>
<div className="glass-effect p-8 rounded-lg hover-glow transition-all duration-300">
<div className="text-orange-400 text-4xl mb-4">🛡</div>
<div className="glass-effect p-8 rounded-lg hover-glow transition-all duration-300 group hover:scale-105">
<div className="text-orange-400 text-4xl mb-4 group-hover:animate-pulse-secure">🛡</div>
<h3 className="text-xl font-bold mb-4">Сетевая безопасность</h3>
<p className="text-gray-300">
Комплексная защита сетевой инфраструктуры от внешних угроз
</p>
<div className="mt-4 opacity-0 group-hover:opacity-100 transition-opacity">
<button className="text-orange-400 text-sm font-medium hover:text-orange-300">
Подробнее
</button>
</div>
</div>
<div className="glass-effect p-8 rounded-lg hover-glow transition-all duration-300">
<div className="text-yellow-400 text-4xl mb-4">📊</div>
<div className="glass-effect p-8 rounded-lg hover-glow transition-all duration-300 group hover:scale-105">
<div className="text-yellow-400 text-4xl mb-4 group-hover:animate-pulse-secure">📊</div>
<h3 className="text-xl font-bold mb-4">Мониторинг безопасности</h3>
<p className="text-gray-300">
Системы мониторинга и анализа инцидентов информационной безопасности
</p>
<div className="mt-4 opacity-0 group-hover:opacity-100 transition-opacity">
<button className="text-yellow-400 text-sm font-medium hover:text-yellow-300">
Подробнее
</button>
</div>
</div>
<div className="glass-effect p-8 rounded-lg hover-glow transition-all duration-300">
<div className="text-purple-400 text-4xl mb-4">🔍</div>
<div className="glass-effect p-8 rounded-lg hover-glow transition-all duration-300 group hover:scale-105">
<div className="text-purple-400 text-4xl mb-4 group-hover:animate-pulse-secure">🔍</div>
<h3 className="text-xl font-bold mb-4">Аудит безопасности</h3>
<p className="text-gray-300">
Проведение комплексного аудита систем информационной безопасности
</p>
<div className="mt-4 opacity-0 group-hover:opacity-100 transition-opacity">
<button className="text-purple-400 text-sm font-medium hover:text-purple-300">
Подробнее
</button>
</div>
</div>
<div className="glass-effect p-8 rounded-lg hover-glow transition-all duration-300">
<div className="text-blue-400 text-4xl mb-4"></div>
<div className="glass-effect p-8 rounded-lg hover-glow transition-all duration-300 group hover:scale-105">
<div className="text-blue-400 text-4xl mb-4 group-hover:animate-pulse-secure"></div>
<h3 className="text-xl font-bold mb-4">Интеграция систем</h3>
<p className="text-gray-300">
Интеграция решений безопасности с существующей IT-инфраструктурой
</p>
<div className="mt-4 opacity-0 group-hover:opacity-100 transition-opacity">
<button className="text-blue-400 text-sm font-medium hover:text-blue-300">
Подробнее
</button>
</div>
</div>
<div className="glass-effect p-8 rounded-lg hover-glow transition-all duration-300">
<div className="text-green-400 text-4xl mb-4">📚</div>
<div className="glass-effect p-8 rounded-lg hover-glow transition-all duration-300 group hover:scale-105">
<div className="text-green-400 text-4xl mb-4 group-hover:animate-pulse-secure">📚</div>
<h3 className="text-xl font-bold mb-4">Обучение персонала</h3>
<p className="text-gray-300">
Программы обучения сотрудников основам информационной безопасности
</p>
<div className="mt-4 opacity-0 group-hover:opacity-100 transition-opacity">
<button className="text-green-400 text-sm font-medium hover:text-green-300">
Подробнее
</button>
</div>
</div>
</div>
</div>
@ -108,44 +714,87 @@ export default function SecureT() {
</div>
<div className="grid md:grid-cols-4 gap-6">
<div className="glass-effect p-6 rounded-lg text-center hover-glow transition-all duration-300">
<h4 className="font-bold mb-2">AES-256</h4>
<p className="text-gray-300 text-sm">Шифрование данных</p>
{[
{ name: 'AES-256', desc: 'Шифрование данных', color: 'red' },
{ name: 'RSA-4096', desc: 'Асимметричное шифрование', color: 'orange' },
{ name: 'SHA-3', desc: 'Хеширование', color: 'yellow' },
{ name: 'PKI', desc: 'Инфраструктура ключей', color: 'green' },
{ name: 'SIEM', desc: 'Управление событиями', color: 'blue' },
{ name: 'DLP', desc: 'Защита от утечек', color: 'purple' },
{ name: 'WAF', desc: 'Веб-защита', color: 'pink' },
{ name: 'IDS/IPS', desc: 'Обнаружение вторжений', color: 'indigo' }
].map((tech, index) => (
<div
key={tech.name}
className="glass-effect p-6 rounded-lg text-center hover-glow transition-all duration-300 group hover:scale-105"
style={{ animationDelay: `${index * 0.1}s` }}
>
<h4 className="font-bold mb-2 group-hover:animate-pulse-secure">{tech.name}</h4>
<p className="text-gray-300 text-sm">{tech.desc}</p>
</div>
))}
</div>
</div>
</section>
{/* Full Documentation Block */}
<section className="section-padding bg-gradient-to-r from-red-900/20 to-orange-900/20">
<div className="max-w-4xl mx-auto px-4">
<div className="glass-effect p-12 rounded-lg text-center border border-red-500/30 animate-secure-glow">
<div className="text-red-400 text-6xl mb-6 animate-pulse-secure">📚</div>
<h2 className="text-4xl font-bold mb-6">
Полная <span className="gradient-text">документация</span>
</h2>
<p className="text-xl text-gray-300 mb-8 max-w-2xl mx-auto">
Получите доступ к полной технической документации SECURE-T с подробными руководствами,
примерами конфигураций и инструкциями по внедрению
</p>
<div className="flex flex-col sm:flex-row gap-4 justify-center mb-8">
<a
href="/docs/SECURE-T_Documentation.md"
target="_blank"
rel="noopener noreferrer"
className="px-8 py-4 bg-red-500 text-white font-semibold rounded-lg hover-glow transition-all duration-300 hover:bg-red-600 active:scale-95 flex items-center justify-center gap-2 animate-pulse-secure"
>
<span>📖</span>
Открыть документацию
</a>
<a
href="/docs/SECURE-T_Quick_Start.md"
target="_blank"
rel="noopener noreferrer"
className="px-8 py-4 glass-effect text-white font-semibold rounded-lg hover:bg-white/10 transition-all duration-300 flex items-center justify-center gap-2"
>
<span>🚀</span>
Быстрый старт
</a>
</div>
<div className="glass-effect p-6 rounded-lg text-center hover-glow transition-all duration-300">
<h4 className="font-bold mb-2">RSA-4096</h4>
<p className="text-gray-300 text-sm">Асимметричное шифрование</p>
<div className="grid md:grid-cols-3 gap-6 text-left">
<div className="glass-effect p-6 rounded-lg border border-red-500/20 group hover:scale-105 transition-all duration-300">
<div className="text-red-400 text-2xl mb-3 group-hover:animate-pulse-secure">🔧</div>
<h4 className="font-bold mb-2">Установка и настройка</h4>
<p className="text-gray-300 text-sm">
Пошаговые инструкции по установке и первоначальной настройке системы
</p>
</div>
<div className="glass-effect p-6 rounded-lg text-center hover-glow transition-all duration-300">
<h4 className="font-bold mb-2">SHA-3</h4>
<p className="text-gray-300 text-sm">Хеширование</p>
<div className="glass-effect p-6 rounded-lg border border-orange-500/20 group hover:scale-105 transition-all duration-300">
<div className="text-orange-400 text-2xl mb-3 group-hover:animate-pulse-secure"></div>
<h4 className="font-bold mb-2">Конфигурация</h4>
<p className="text-gray-300 text-sm">
Подробные примеры конфигураций для различных сценариев использования
</p>
</div>
<div className="glass-effect p-6 rounded-lg text-center hover-glow transition-all duration-300">
<h4 className="font-bold mb-2">PKI</h4>
<p className="text-gray-300 text-sm">Инфраструктура ключей</p>
<div className="glass-effect p-6 rounded-lg border border-yellow-500/20 group hover:scale-105 transition-all duration-300">
<div className="text-yellow-400 text-2xl mb-3 group-hover:animate-pulse-secure">🚀</div>
<h4 className="font-bold mb-2">API и интеграция</h4>
<p className="text-gray-300 text-sm">
Руководство по использованию API и интеграции с внешними системами
</p>
</div>
<div className="glass-effect p-6 rounded-lg text-center hover-glow transition-all duration-300">
<h4 className="font-bold mb-2">SIEM</h4>
<p className="text-gray-300 text-sm">Управление событиями</p>
</div>
<div className="glass-effect p-6 rounded-lg text-center hover-glow transition-all duration-300">
<h4 className="font-bold mb-2">DLP</h4>
<p className="text-gray-300 text-sm">Защита от утечек</p>
</div>
<div className="glass-effect p-6 rounded-lg text-center hover-glow transition-all duration-300">
<h4 className="font-bold mb-2">WAF</h4>
<p className="text-gray-300 text-sm">Веб-защита</p>
</div>
<div className="glass-effect p-6 rounded-lg text-center hover-glow transition-all duration-300">
<h4 className="font-bold mb-2">IDS/IPS</h4>
<p className="text-gray-300 text-sm">Обнаружение вторжений</p>
</div>
</div>
</div>
@ -242,6 +891,256 @@ export default function SecureT() {
</p>
</div>
</footer>
{/* Модальное окно "Наши решения" */}
{isSolutionsModalOpen && (
<div className="fixed inset-0 bg-black bg-opacity-75 flex items-center justify-center z-50 p-4">
<div className="bg-gray-900 rounded-lg p-8 max-w-md w-full max-h-[90vh] overflow-y-auto border border-red-500/30">
<div className="flex justify-between items-center mb-6">
<h2 className="text-2xl font-bold text-red-400">Наши решения SECURE-T</h2>
<button
onClick={handleCloseModal}
className="text-gray-400 hover:text-white text-2xl"
>
×
</button>
</div>
<form onSubmit={handleSolutionsSubmit} className="space-y-4">
<div>
<label className="block text-sm font-medium text-gray-300 mb-2">
Имя *
</label>
<input
type="text"
name="name"
value={solutionsForm.name}
onChange={handleSolutionsInputChange}
required
className="w-full px-3 py-2 bg-gray-800 border border-gray-600 rounded-md text-white focus:outline-none focus:ring-2 focus:ring-red-500"
/>
</div>
<div>
<label className="block text-sm font-medium text-gray-300 mb-2">
Email *
</label>
<input
type="email"
name="email"
value={solutionsForm.email}
onChange={handleSolutionsInputChange}
required
className="w-full px-3 py-2 bg-gray-800 border border-gray-600 rounded-md text-white focus:outline-none focus:ring-2 focus:ring-red-500"
/>
</div>
<div>
<label className="block text-sm font-medium text-gray-300 mb-2">
Компания
</label>
<input
type="text"
name="company"
value={solutionsForm.company}
onChange={handleSolutionsInputChange}
className="w-full px-3 py-2 bg-gray-800 border border-gray-600 rounded-md text-white focus:outline-none focus:ring-2 focus:ring-red-500"
/>
</div>
<div>
<label className="block text-sm font-medium text-gray-300 mb-2">
Интересующее решение *
</label>
<select
name="solution"
value={solutionsForm.solution}
onChange={handleSolutionsInputChange}
required
className="w-full px-3 py-2 bg-gray-800 border border-gray-600 rounded-md text-white focus:outline-none focus:ring-2 focus:ring-red-500"
>
<option value="">Выберите решение</option>
<option value="Криптографическая защита">Криптографическая защита</option>
<option value="Сетевая безопасность">Сетевая безопасность</option>
<option value="Мониторинг безопасности">Мониторинг безопасности</option>
<option value="Аудит безопасности">Аудит безопасности</option>
<option value="Интеграция систем">Интеграция систем</option>
<option value="Обучение персонала">Обучение персонала</option>
<option value="Комплексное решение">Комплексное решение</option>
</select>
</div>
<div>
<label className="block text-sm font-medium text-gray-300 mb-2">
Дополнительная информация
</label>
<textarea
name="message"
value={solutionsForm.message}
onChange={handleSolutionsInputChange}
rows={4}
className="w-full px-3 py-2 bg-gray-800 border border-gray-600 rounded-md text-white focus:outline-none focus:ring-2 focus:ring-red-500"
placeholder="Расскажите о ваших потребностях в области информационной безопасности..."
/>
</div>
<div className="flex gap-4 pt-4">
<button
type="submit"
className="flex-1 bg-red-500 text-white py-2 px-4 rounded-md hover:bg-red-600 transition-colors"
>
Отправить заявку
</button>
<button
type="button"
onClick={handleCloseModal}
className="flex-1 bg-gray-600 text-white py-2 px-4 rounded-md hover:bg-gray-700 transition-colors"
>
Отмена
</button>
</div>
</form>
</div>
</div>
)}
{/* Модальное окно "Документация" */}
{isDocumentationModalOpen && (
<div className="fixed inset-0 bg-black bg-opacity-75 flex items-center justify-center z-50 p-4">
<div className="bg-gray-900 rounded-lg p-8 max-w-md w-full max-h-[90vh] overflow-y-auto border border-red-500/30">
<div className="flex justify-between items-center mb-6">
<h2 className="text-2xl font-bold text-red-400">Документация SECURE-T</h2>
<button
onClick={handleCloseModal}
className="text-gray-400 hover:text-white text-2xl"
>
×
</button>
</div>
<div className="mb-6">
<h3 className="text-lg font-semibold text-orange-400 mb-4">Доступная документация:</h3>
<div className="space-y-3">
<div className="flex items-center space-x-3 p-3 bg-gray-800 rounded-lg">
<span className="text-2xl">📚</span>
<div>
<p className="text-white font-medium">Полная документация</p>
<p className="text-gray-400 text-sm">Техническое руководство</p>
</div>
</div>
<div className="flex items-center space-x-3 p-3 bg-gray-800 rounded-lg">
<span className="text-2xl">🚀</span>
<div>
<p className="text-white font-medium">Быстрый старт</p>
<p className="text-gray-400 text-sm">Руководство по установке</p>
</div>
</div>
<div className="flex items-center space-x-3 p-3 bg-gray-800 rounded-lg">
<span className="text-2xl"></span>
<div>
<p className="text-white font-medium">Примеры конфигураций</p>
<p className="text-gray-400 text-sm">Готовые настройки</p>
</div>
</div>
</div>
</div>
<form onSubmit={handleDocumentationSubmit} className="space-y-4">
<div>
<label className="block text-sm font-medium text-gray-300 mb-2">
Имя *
</label>
<input
type="text"
name="name"
value={documentationForm.name}
onChange={handleDocumentationInputChange}
required
className="w-full px-3 py-2 bg-gray-800 border border-gray-600 rounded-md text-white focus:outline-none focus:ring-2 focus:ring-red-500"
/>
</div>
<div>
<label className="block text-sm font-medium text-gray-300 mb-2">
Email *
</label>
<input
type="email"
name="email"
value={documentationForm.email}
onChange={handleDocumentationInputChange}
required
className="w-full px-3 py-2 bg-gray-800 border border-gray-600 rounded-md text-white focus:outline-none focus:ring-2 focus:ring-red-500"
/>
</div>
<div>
<label className="block text-sm font-medium text-gray-300 mb-2">
Компания
</label>
<input
type="text"
name="company"
value={documentationForm.company}
onChange={handleDocumentationInputChange}
className="w-full px-3 py-2 bg-gray-800 border border-gray-600 rounded-md text-white focus:outline-none focus:ring-2 focus:ring-red-500"
/>
</div>
<div>
<label className="block text-sm font-medium text-gray-300 mb-2">
Тип документации *
</label>
<select
name="documentType"
value={documentationForm.documentType}
onChange={handleDocumentationInputChange}
required
className="w-full px-3 py-2 bg-gray-800 border border-gray-600 rounded-md text-white focus:outline-none focus:ring-2 focus:ring-red-500"
>
<option value="">Выберите тип документации</option>
<option value="Полная документация">Полная документация</option>
<option value="Быстрый старт">Быстрый старт</option>
<option value="Примеры конфигураций">Примеры конфигураций</option>
<option value="API документация">API документация</option>
<option value="Руководство администратора">Руководство администратора</option>
<option value="Все документы">Все документы</option>
</select>
</div>
<div>
<label className="block text-sm font-medium text-gray-300 mb-2">
Комментарий
</label>
<textarea
name="message"
value={documentationForm.message}
onChange={handleDocumentationInputChange}
rows={3}
className="w-full px-3 py-2 bg-gray-800 border border-gray-600 rounded-md text-white focus:outline-none focus:ring-2 focus:ring-red-500"
placeholder="Укажите, для каких целей вам нужна документация..."
/>
</div>
<div className="flex gap-4 pt-4">
<button
type="submit"
className="flex-1 bg-red-500 text-white py-2 px-4 rounded-md hover:bg-red-600 transition-colors"
>
Получить документацию
</button>
<button
type="button"
onClick={handleCloseModal}
className="flex-1 bg-gray-600 text-white py-2 px-4 rounded-md hover:bg-gray-700 transition-colors"
>
Отмена
</button>
</div>
</form>
</div>
</div>
)}
</>
);
}

View File

@ -1,6 +1,121 @@
'use client';
import { useState, useEffect } from 'react';
import Navigation from '../components/Navigation';
export default function Solovey() {
const [isCallActive, setIsCallActive] = useState(false);
const [participants, setParticipants] = useState(3);
const [soundWaves, setSoundWaves] = useState<Array<{
id: number;
delay: string;
duration: string;
scale: number;
}>>([]);
const [networkNodes, setNetworkNodes] = useState<Array<{
id: number;
x: string;
y: string;
connected: boolean;
pulse: boolean;
}>>([]);
const [liveStats, setLiveStats] = useState({
activeUsers: 1247,
callsToday: 8934,
dataTransferred: 2.3,
uptime: 99.97
});
const [calculatorData, setCalculatorData] = useState({
employees: 50,
meetingsPerWeek: 10,
travelCostPerMeeting: 5000
});
const avatars = [
{ name: 'Анна', role: 'Менеджер', status: 'speaking', avatar: '👩‍💼' },
{ name: 'Михаил', role: 'Разработчик', status: 'listening', avatar: '👨‍💻' },
{ name: 'Елена', role: 'Дизайнер', status: 'muted', avatar: '👩‍🎨' },
{ name: 'Дмитрий', role: 'Аналитик', status: 'listening', avatar: '👨‍💼' },
{ name: 'Ольга', role: 'HR', status: 'speaking', avatar: '👩‍🏫' },
{ name: 'Алексей', role: 'CEO', status: 'listening', avatar: '👨‍🚀' }
];
// Генерация звуковых волн соловья
useEffect(() => {
const waves = Array.from({ length: 8 }, (_, i) => ({
id: i,
delay: `${i * 0.2}s`,
duration: `${2 + (i * 0.3)}s`,
scale: 0.5 + (i * 0.1)
}));
setSoundWaves(waves);
}, []);
// Генерация сетевых узлов
useEffect(() => {
const predefinedPositions = [
{ x: '25%', y: '30%' }, { x: '75%', y: '25%' }, { x: '15%', y: '60%' },
{ x: '85%', y: '70%' }, { x: '45%', y: '15%' }, { x: '55%', y: '85%' },
{ x: '30%', y: '45%' }, { x: '70%', y: '55%' }, { x: '20%', y: '75%' },
{ x: '80%', y: '40%' }, { x: '40%', y: '80%' }, { x: '60%', y: '20%' }
];
const nodes = predefinedPositions.map((pos, i) => ({
id: i,
x: pos.x,
y: pos.y,
connected: i % 3 !== 0, // 2 из 3 узлов подключены
pulse: i % 2 === 0 // каждый второй пульсирует
}));
setNetworkNodes(nodes);
}, []);
// Обновление живой статистики
useEffect(() => {
let counter = 0;
const patterns = [
{ users: 3, calls: 2, data: 0.05, uptime: 0.01 },
{ users: -1, calls: 1, data: 0.08, uptime: 0.02 },
{ users: 5, calls: 3, data: 0.03, uptime: -0.01 },
{ users: -2, calls: 1, data: 0.07, uptime: 0.01 },
{ users: 4, calls: 2, data: 0.04, uptime: 0.02 }
];
const interval = setInterval(() => {
const pattern = patterns[counter % patterns.length];
setLiveStats(prev => ({
activeUsers: Math.max(1200, prev.activeUsers + pattern.users),
callsToday: prev.callsToday + pattern.calls,
dataTransferred: prev.dataTransferred + pattern.data,
uptime: Math.min(99.99, Math.max(99.95, prev.uptime + pattern.uptime))
}));
counter++;
}, 3000);
return () => clearInterval(interval);
}, []);
const calculateSavings = () => {
const { employees, meetingsPerWeek, travelCostPerMeeting } = calculatorData;
const monthlyTravelCost = meetingsPerWeek * 4 * travelCostPerMeeting;
const yearlyTravelCost = monthlyTravelCost * 12;
const soloveyYearlyCost = employees * 1000; // примерная стоимость за пользователя в год
const savings = yearlyTravelCost - soloveyYearlyCost;
return { yearlyTravelCost, soloveyYearlyCost, savings };
};
const formatNumber = (num: number) => {
return new Intl.NumberFormat('ru-RU').format(Math.floor(num));
};
const formatCurrency = (num: number) => {
return new Intl.NumberFormat('ru-RU', {
style: 'currency',
currency: 'RUB',
minimumFractionDigits: 0
}).format(num);
};
return (
<>
<Navigation />
@ -8,6 +123,24 @@ export default function Solovey() {
{/* Hero Section */}
<section className="min-h-screen flex items-center justify-center relative overflow-hidden pt-16">
<div className="absolute inset-0 bg-gradient-to-br from-amber-900 via-black to-yellow-900"></div>
{/* Анимированные звуковые волны соловья */}
<div className="absolute inset-0 flex items-center justify-center">
{soundWaves.map((wave) => (
<div
key={wave.id}
className="absolute border-2 border-amber-500/30 rounded-full animate-ping"
style={{
width: `${100 + wave.id * 50}px`,
height: `${100 + wave.id * 50}px`,
animationDelay: wave.delay,
animationDuration: wave.duration,
transform: `scale(${wave.scale})`
}}
/>
))}
</div>
<div className="absolute inset-0 opacity-20">
<div className="absolute top-1/4 left-1/4 w-96 h-96 bg-amber-500 rounded-full blur-3xl opacity-30"></div>
<div className="absolute bottom-1/4 right-1/4 w-96 h-96 bg-yellow-500 rounded-full blur-3xl opacity-30"></div>
@ -16,20 +149,59 @@ export default function Solovey() {
<div className="relative z-10 text-center max-w-6xl mx-auto px-4">
<div className="mb-8">
<div className="inline-flex items-center space-x-4 mb-6">
<div className="w-16 h-16 bg-amber-500 rounded-full flex items-center justify-center">
<div className="w-16 h-16 bg-amber-500 rounded-full flex items-center justify-center relative">
<span className="text-black font-bold text-2xl">🐦</span>
{/* Анимированные звуковые линии */}
<div className="absolute -right-8 top-1/2 transform -translate-y-1/2">
{[...Array(4)].map((_, i) => (
<div
key={i}
className="w-1 bg-amber-400 rounded-full animate-pulse"
style={{
height: `${8 + i * 4}px`,
marginLeft: `${i * 3}px`,
animationDelay: `${i * 0.1}s`,
animationDuration: '1s'
}}
/>
))}
</div>
</div>
<h1 className="text-5xl md:text-7xl font-bold text-amber-400">Соловей</h1>
</div>
</div>
{/* Живая статистика */}
<div className="grid grid-cols-2 md:grid-cols-4 gap-4 mb-8">
<div className="glass-effect p-4 rounded-lg hover-glow transition-all duration-300">
<div className="text-2xl font-bold text-amber-400">{formatNumber(liveStats.activeUsers)}</div>
<div className="text-sm text-gray-400">Активных пользователей</div>
</div>
<div className="glass-effect p-4 rounded-lg hover-glow transition-all duration-300">
<div className="text-2xl font-bold text-yellow-400">{formatNumber(liveStats.callsToday)}</div>
<div className="text-sm text-gray-400">Звонков сегодня</div>
</div>
<div className="glass-effect p-4 rounded-lg hover-glow transition-all duration-300">
<div className="text-2xl font-bold text-green-400">{liveStats.dataTransferred.toFixed(1)} ТБ</div>
<div className="text-sm text-gray-400">Передано данных</div>
</div>
<div className="glass-effect p-4 rounded-lg hover-glow transition-all duration-300">
<div className="text-2xl font-bold text-blue-400">{liveStats.uptime.toFixed(2)}%</div>
<div className="text-sm text-gray-400">Время работы</div>
</div>
</div>
<p className="text-xl md:text-2xl text-gray-300 mb-8 max-w-4xl mx-auto">
Профессиональная платформа для видеосвязи и онлайн-встреч на вашем домене
</p>
<div className="flex flex-col sm:flex-row gap-4 justify-center mb-8">
<button className="px-8 py-3 bg-amber-500 text-black font-semibold rounded-lg hover-glow transition-all duration-300">
Попробовать демо
<button
onClick={() => setIsCallActive(!isCallActive)}
className="px-8 py-3 bg-amber-500 text-black font-semibold rounded-lg hover-glow transition-all duration-300 transform hover:scale-105"
>
{isCallActive ? 'Завершить демо' : 'Попробовать демо'}
</button>
<button className="px-8 py-3 glass-effect text-white font-semibold rounded-lg hover:bg-white/10 transition-all duration-300">
<button className="px-8 py-3 glass-effect text-white font-semibold rounded-lg hover:bg-white/10 transition-all duration-300 transform hover:scale-105">
Заказать внедрение
</button>
</div>
@ -42,6 +214,256 @@ export default function Solovey() {
</div>
</section>
{/* Живая демонстрация видеозвонка */}
<section className="section-padding bg-gray-900/50">
<div className="max-w-7xl mx-auto px-4">
<div className="text-center mb-16">
<h2 className="text-4xl md:text-5xl font-bold mb-6">
Живая <span className="text-amber-400">демонстрация</span>
</h2>
<p className="text-xl text-gray-300 max-w-3xl mx-auto">
Посмотрите, как выглядит интерфейс видеоконференции
</p>
</div>
<div className="max-w-5xl mx-auto">
<div className="glass-effect rounded-lg overflow-hidden p-6">
{/* Заголовок конференции */}
<div className="flex justify-between items-center mb-6 pb-4 border-b border-gray-700">
<div className="flex items-center gap-3">
<div className="w-3 h-3 bg-green-500 rounded-full animate-pulse"></div>
<span className="font-semibold">Еженедельная планерка</span>
<span className="text-sm text-gray-400">12:34</span>
</div>
<div className="flex items-center gap-2">
<span className="text-sm text-gray-400">Участников: {participants}</span>
<button
onClick={() => setParticipants(prev => Math.min(prev + 1, 6))}
className="px-3 py-1 bg-amber-500/20 text-amber-400 rounded text-sm hover:bg-amber-500/30 transition-colors"
>
+ Добавить
</button>
</div>
</div>
{/* Сетка участников */}
<div className={`grid gap-4 mb-6 ${
participants <= 2 ? 'grid-cols-1 md:grid-cols-2' :
participants <= 4 ? 'grid-cols-2 md:grid-cols-2' :
'grid-cols-2 md:grid-cols-3'
}`}>
{avatars.slice(0, participants).map((participant, index) => (
<div
key={index}
className={`relative bg-gray-800 rounded-lg aspect-video flex flex-col items-center justify-center transition-all duration-500 ${
participant.status === 'speaking' ? 'ring-2 ring-amber-500 scale-105' : ''
} ${isCallActive ? 'animate-fadeIn' : 'opacity-50'}`}
style={{ animationDelay: `${index * 0.2}s` }}
>
<div className="text-4xl mb-2">{participant.avatar}</div>
<div className="text-center">
<div className="font-semibold text-sm">{participant.name}</div>
<div className="text-xs text-gray-400">{participant.role}</div>
</div>
{/* Индикатор статуса */}
<div className="absolute bottom-2 right-2 flex items-center gap-1">
{participant.status === 'speaking' && (
<div className="flex gap-1">
{[...Array(3)].map((_, i) => (
<div
key={i}
className="w-1 bg-amber-500 rounded-full animate-pulse"
style={{
height: `${4 + i * 2}px`,
animationDelay: `${i * 0.1}s`
}}
/>
))}
</div>
)}
{participant.status === 'muted' && (
<div className="w-6 h-6 bg-red-500 rounded-full flex items-center justify-center">
<span className="text-xs">🔇</span>
</div>
)}
</div>
</div>
))}
</div>
{/* Панель управления */}
<div className="flex justify-center gap-4">
<button className="w-12 h-12 bg-gray-700 rounded-full flex items-center justify-center hover:bg-gray-600 transition-colors">
🎤
</button>
<button className="w-12 h-12 bg-gray-700 rounded-full flex items-center justify-center hover:bg-gray-600 transition-colors">
📹
</button>
<button className="w-12 h-12 bg-gray-700 rounded-full flex items-center justify-center hover:bg-gray-600 transition-colors">
🖥
</button>
<button className="w-12 h-12 bg-red-500 rounded-full flex items-center justify-center hover:bg-red-600 transition-colors">
📞
</button>
</div>
</div>
</div>
</div>
</section>
{/* 3D Сетевая визуализация */}
<section className="section-padding">
<div className="max-w-7xl mx-auto px-4">
<div className="text-center mb-16">
<h2 className="text-4xl md:text-5xl font-bold mb-6">
Сетевая <span className="text-amber-400">архитектура</span>
</h2>
<p className="text-xl text-gray-300 max-w-3xl mx-auto">
Распределенная система для надежной связи
</p>
</div>
<div className="relative h-96 glass-effect rounded-lg overflow-hidden">
<div className="absolute inset-0 bg-gradient-to-br from-amber-900/20 to-yellow-900/20">
{/* Сетевые узлы */}
{networkNodes.map((node) => (
<div key={node.id}>
<div
className={`absolute w-4 h-4 rounded-full transition-all duration-1000 ${
node.connected ? 'bg-green-500' : 'bg-red-500'
} ${node.pulse ? 'animate-pulse' : ''}`}
style={{ left: node.x, top: node.y }}
/>
{/* Соединительные линии */}
{node.connected && node.id < networkNodes.length - 1 && (
<svg
className="absolute inset-0 w-full h-full pointer-events-none"
style={{ zIndex: -1 }}
>
<line
x1={node.x}
y1={node.y}
x2={networkNodes[node.id + 1]?.x || '50%'}
y2={networkNodes[node.id + 1]?.y || '50%'}
stroke="rgba(245, 158, 11, 0.3)"
strokeWidth="1"
className="animate-pulse"
/>
</svg>
)}
</div>
))}
{/* Центральный сервер */}
<div className="absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2">
<div className="w-8 h-8 bg-amber-500 rounded-full flex items-center justify-center animate-pulse">
<span className="text-black font-bold">🖥</span>
</div>
<div className="text-center mt-2 text-sm text-amber-400 font-semibold">
Соловей Сервер
</div>
</div>
</div>
</div>
</div>
</section>
{/* Калькулятор экономии */}
<section className="section-padding bg-gray-900/50">
<div className="max-w-7xl mx-auto px-4">
<div className="text-center mb-16">
<h2 className="text-4xl md:text-5xl font-bold mb-6">
Калькулятор <span className="text-amber-400">экономии</span>
</h2>
<p className="text-xl text-gray-300 max-w-3xl mx-auto">
Рассчитайте экономию от внедрения видеосвязи
</p>
</div>
<div className="grid md:grid-cols-2 gap-12 items-center">
<div className="glass-effect p-8 rounded-lg">
<h3 className="text-xl font-bold mb-6">Параметры вашей компании</h3>
<div className="space-y-6">
<div>
<label className="block text-sm font-medium mb-2">Количество сотрудников</label>
<input
type="range"
min="10"
max="500"
value={calculatorData.employees}
onChange={(e) => setCalculatorData(prev => ({ ...prev, employees: parseInt(e.target.value) }))}
className="w-full h-2 bg-gray-700 rounded-lg appearance-none cursor-pointer"
/>
<div className="text-center mt-2 text-amber-400 font-bold">{calculatorData.employees}</div>
</div>
<div>
<label className="block text-sm font-medium mb-2">Встреч в неделю</label>
<input
type="range"
min="1"
max="50"
value={calculatorData.meetingsPerWeek}
onChange={(e) => setCalculatorData(prev => ({ ...prev, meetingsPerWeek: parseInt(e.target.value) }))}
className="w-full h-2 bg-gray-700 rounded-lg appearance-none cursor-pointer"
/>
<div className="text-center mt-2 text-amber-400 font-bold">{calculatorData.meetingsPerWeek}</div>
</div>
<div>
<label className="block text-sm font-medium mb-2">Стоимость командировки ()</label>
<input
type="range"
min="1000"
max="20000"
step="500"
value={calculatorData.travelCostPerMeeting}
onChange={(e) => setCalculatorData(prev => ({ ...prev, travelCostPerMeeting: parseInt(e.target.value) }))}
className="w-full h-2 bg-gray-700 rounded-lg appearance-none cursor-pointer"
/>
<div className="text-center mt-2 text-amber-400 font-bold">{formatCurrency(calculatorData.travelCostPerMeeting)}</div>
</div>
</div>
</div>
<div className="glass-effect p-8 rounded-lg">
<h3 className="text-xl font-bold mb-6">Ваша экономия</h3>
{(() => {
const savings = calculateSavings();
return (
<div className="space-y-4">
<div className="flex justify-between items-center p-4 bg-red-500/10 rounded-lg">
<span>Расходы на командировки в год:</span>
<span className="font-bold text-red-400">{formatCurrency(savings.yearlyTravelCost)}</span>
</div>
<div className="flex justify-between items-center p-4 bg-amber-500/10 rounded-lg">
<span>Стоимость Соловей в год:</span>
<span className="font-bold text-amber-400">{formatCurrency(savings.soloveyYearlyCost)}</span>
</div>
<div className="flex justify-between items-center p-4 bg-green-500/10 rounded-lg border-2 border-green-500">
<span className="font-bold">Экономия в год:</span>
<span className="font-bold text-green-400 text-xl">{formatCurrency(savings.savings)}</span>
</div>
<div className="text-center mt-6">
<div className="text-3xl font-bold text-green-400 mb-2">
{savings.savings > 0 ? Math.round(savings.yearlyTravelCost / savings.soloveyYearlyCost) : 0}x
</div>
<div className="text-sm text-gray-400">окупаемость инвестиций</div>
</div>
</div>
);
})()}
</div>
</div>
</div>
</section>
{/* Features Section */}
<section className="section-padding bg-gray-900/50">
<div className="max-w-7xl mx-auto px-4">

View File

@ -1,13 +1,291 @@
'use client';
import Navigation from '../components/Navigation';
import { useState, useEffect } from 'react';
export default function UXSoftware() {
const [isModalOpen, setIsModalOpen] = useState(false);
const [formData, setFormData] = useState({
name: '',
email: '',
message: ''
});
// Живые метрики UX
const [uxMetrics, setUxMetrics] = useState({
loadingSpeed: 0,
userSatisfaction: 0,
pageViews: 0,
bounceRate: 0
});
// Интерактивная карта серверов
const [serverMap, setServerMap] = useState<Array<{
id: number,
x: number,
y: number,
status: 'active' | 'busy' | 'maintenance',
location: string,
ping: number
}>>([]);
// Живая демонстрация UX улучшений
const [uxDemo, setUxDemo] = useState({
beforeSpeed: 3200,
afterSpeed: 850,
improvement: 0,
isAnimating: false
});
// Уведомления об улучшениях
const [uxNotifications, setUxNotifications] = useState<Array<{
id: number,
message: string,
type: 'speed' | 'ux' | 'performance',
timestamp: Date
}>>([]);
const [notificationId, setNotificationId] = useState(0);
// Анимация метрик UX
useEffect(() => {
const targetMetrics = {
loadingSpeed: 2.3,
userSatisfaction: 94.7,
pageViews: 15420,
bounceRate: 18.5
};
const duration = 2500;
const steps = 60;
const stepDuration = duration / steps;
let currentStep = 0;
const interval = setInterval(() => {
currentStep++;
const progress = currentStep / steps;
const easeOut = 1 - Math.pow(1 - progress, 3);
setUxMetrics({
loadingSpeed: Math.floor(targetMetrics.loadingSpeed * easeOut * 10) / 10,
userSatisfaction: Math.floor(targetMetrics.userSatisfaction * easeOut * 10) / 10,
pageViews: Math.floor(targetMetrics.pageViews * easeOut),
bounceRate: Math.floor(targetMetrics.bounceRate * easeOut * 10) / 10
});
if (currentStep >= steps) {
clearInterval(interval);
}
}, stepDuration);
return () => clearInterval(interval);
}, []);
// Инициализация карты серверов
useEffect(() => {
const servers = [
{ location: 'Москва', x: 65, y: 35, ping: 12 },
{ location: 'Санкт-Петербург', x: 63, y: 25, ping: 18 },
{ location: 'Нью-Йорк', x: 25, y: 40, ping: 85 },
{ location: 'Лондон', x: 52, y: 30, ping: 45 },
{ location: 'Токио', x: 85, y: 45, ping: 120 },
{ location: 'Сингапур', x: 80, y: 65, ping: 95 },
{ location: 'Франкфурт', x: 55, y: 32, ping: 38 },
{ location: 'Сидней', x: 88, y: 80, ping: 180 }
];
const initialServers = servers.map((server, index) => ({
id: index,
x: server.x,
y: server.y,
status: Math.random() > 0.8 ? 'maintenance' as const : Math.random() > 0.3 ? 'active' as const : 'busy' as const,
location: server.location,
ping: server.ping
}));
setServerMap(initialServers);
// Обновление статусов серверов
const interval = setInterval(() => {
setServerMap(prev => prev.map(server => ({
...server,
status: Math.random() > 0.9 ? 'maintenance' as const : Math.random() > 0.2 ? 'active' as const : 'busy' as const,
ping: server.ping + Math.floor(Math.random() * 20 - 10)
})));
}, 3000);
return () => clearInterval(interval);
}, []);
// Демонстрация UX улучшений
useEffect(() => {
const runDemo = () => {
setUxDemo(prev => ({ ...prev, isAnimating: true, improvement: 0 }));
setTimeout(() => {
setUxDemo(prev => {
if (!prev) return prev;
const improvement = Math.floor(((prev.beforeSpeed - prev.afterSpeed) / prev.beforeSpeed) * 100);
return { ...prev, improvement, isAnimating: false };
});
}, 2000);
};
const interval = setInterval(runDemo, 8000);
runDemo(); // Запускаем сразу
return () => clearInterval(interval);
}, []);
// Уведомления об улучшениях UX
useEffect(() => {
const uxMessages = [
{ message: 'Скорость загрузки страниц увеличена на 73%', type: 'speed' as const },
{ message: 'Время отклика сервера сокращено до 45ms', type: 'performance' as const },
{ message: 'Пользовательский опыт улучшен на 89%', type: 'ux' as const },
{ message: 'Оптимизированы изображения - экономия 2.1MB', type: 'performance' as const },
{ message: 'Интерактивность страницы повышена на 67%', type: 'ux' as const },
{ message: 'Кэширование ускорило загрузку на 54%', type: 'speed' as const }
];
const addNotification = () => {
const newNotification = {
id: notificationId,
...uxMessages[Math.floor(Math.random() * uxMessages.length)],
timestamp: new Date()
};
setUxNotifications(prev => [newNotification, ...prev.slice(0, 3)]);
setNotificationId(prev => prev + 1);
setTimeout(() => {
setUxNotifications(prev => prev.filter(notif => notif.id !== newNotification.id));
}, 6000);
};
const interval = setInterval(addNotification, 4000);
return () => clearInterval(interval);
}, [notificationId]);
// Создание CSS анимаций
useEffect(() => {
const style = document.createElement('style');
style.textContent = `
@keyframes ux-pulse {
0%, 100% { opacity: 1; transform: scale(1); }
50% { opacity: 0.8; transform: scale(1.1); }
}
@keyframes slide-in-ux {
from { transform: translateX(20px); opacity: 0; }
to { transform: translateX(0); opacity: 1; }
}
@keyframes server-ping {
0%, 100% { transform: scale(1); opacity: 0.7; }
50% { transform: scale(1.3); opacity: 1; }
}
@keyframes ux-glow {
0%, 100% { box-shadow: 0 0 20px rgba(59, 130, 246, 0.3); }
50% { box-shadow: 0 0 30px rgba(59, 130, 246, 0.6); }
}
@keyframes metric-count {
from { transform: translateY(10px); opacity: 0; }
to { transform: translateY(0); opacity: 1; }
}
.animate-ux-pulse { animation: ux-pulse 2s ease-in-out infinite; }
.animate-slide-in-ux { animation: slide-in-ux 0.5s ease-out; }
.animate-server-ping { animation: server-ping 2s ease-in-out infinite; }
.animate-ux-glow { animation: ux-glow 3s ease-in-out infinite; }
.animate-metric-count { animation: metric-count 0.6s ease-out; }
`;
document.head.appendChild(style);
return () => {
document.head.removeChild(style);
};
}, []);
const handleConsultationClick = () => {
setIsModalOpen(true);
document.body.style.overflow = 'hidden';
};
const handleCloseModal = () => {
setIsModalOpen(false);
document.body.style.overflow = 'unset';
};
const handleInputChange = (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
const { name, value } = e.target;
setFormData(prev => ({
...prev,
[name]: value
}));
};
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
alert(`Спасибо за заявку, ${formData.name}! Мы свяжемся с вами в ближайшее время.`);
setFormData({ name: '', email: '', message: '' });
setIsModalOpen(false);
document.body.style.overflow = 'unset';
};
return (
<>
<Navigation />
{/* Уведомления об улучшениях UX */}
<div className="fixed top-20 right-4 z-50 space-y-2 max-w-sm">
{uxNotifications.map((notification) => (
<div
key={notification.id}
className={`p-4 rounded-lg border-l-4 glass-effect animate-slide-in-ux ${
notification.type === 'speed' ? 'border-blue-500 bg-blue-900/20' :
notification.type === 'performance' ? 'border-green-500 bg-green-900/20' :
'border-purple-500 bg-purple-900/20'
}`}
>
<div className="flex items-start space-x-3">
<div className={`text-xl animate-ux-pulse ${
notification.type === 'speed' ? 'text-blue-400' :
notification.type === 'performance' ? 'text-green-400' :
'text-purple-400'
}`}>
{notification.type === 'speed' ? '⚡' :
notification.type === 'performance' ? '🚀' : '✨'}
</div>
<div className="flex-1">
<p className="text-sm text-gray-300 font-medium">{notification.message}</p>
<p className="text-xs text-gray-500 mt-1">
{notification.timestamp.toLocaleTimeString()}
</p>
</div>
</div>
</div>
))}
</div>
{/* Hero Section */}
<section className="min-h-screen flex items-center justify-center relative overflow-hidden pt-16">
<div className="absolute inset-0 bg-gradient-to-br from-blue-900 via-black to-purple-900"></div>
{/* Интерактивная карта серверов */}
<div className="absolute inset-0 opacity-30">
{serverMap.map((server) => (
<div
key={server.id}
className={`absolute w-4 h-4 rounded-full animate-server-ping cursor-pointer ${
server.status === 'active' ? 'bg-green-500' :
server.status === 'busy' ? 'bg-yellow-500' :
'bg-red-500'
}`}
style={{
left: `${server.x}%`,
top: `${server.y}%`
}}
title={`${server.location} - ${server.ping}ms`}
></div>
))}
</div>
<div className="absolute inset-0 opacity-20">
<div className="absolute top-1/3 left-1/3 w-96 h-96 bg-blue-500 rounded-full blur-3xl opacity-30"></div>
<div className="absolute bottom-1/3 right-1/3 w-96 h-96 bg-purple-500 rounded-full blur-3xl opacity-30"></div>
@ -15,11 +293,58 @@ export default function UXSoftware() {
<div className="relative z-10 text-center max-w-6xl mx-auto px-4">
<h1 className="text-5xl md:text-7xl font-bold mb-6">
Софт для улучшения <span className="gradient-text">UX</span>
Софт для улучшения <span className="gradient-text animate-ux-pulse">UX</span>
</h1>
<p className="text-xl md:text-2xl text-gray-300 mb-8 max-w-4xl mx-auto">
Программное обеспечение для повышения качества пользовательского опыта в сети интернет
</p>
{/* Живые метрики UX */}
<div className="grid grid-cols-2 md:grid-cols-4 gap-6 mb-8 max-w-4xl mx-auto">
<div className="glass-effect p-4 rounded-lg animate-ux-glow">
<div className="text-2xl font-bold text-blue-400 animate-metric-count">{uxMetrics.loadingSpeed}s</div>
<div className="text-sm text-gray-300">Скорость загрузки</div>
</div>
<div className="glass-effect p-4 rounded-lg animate-ux-glow">
<div className="text-2xl font-bold text-green-400 animate-metric-count">{uxMetrics.userSatisfaction}%</div>
<div className="text-sm text-gray-300">Удовлетворенность</div>
</div>
<div className="glass-effect p-4 rounded-lg animate-ux-glow">
<div className="text-2xl font-bold text-purple-400 animate-metric-count">{uxMetrics.pageViews.toLocaleString()}</div>
<div className="text-sm text-gray-300">Просмотры страниц</div>
</div>
<div className="glass-effect p-4 rounded-lg animate-ux-glow">
<div className="text-2xl font-bold text-yellow-400 animate-metric-count">{uxMetrics.bounceRate}%</div>
<div className="text-sm text-gray-300">Показатель отказов</div>
</div>
</div>
{/* Живая демонстрация улучшений */}
<div className="glass-effect p-6 rounded-lg mb-8 max-w-2xl mx-auto">
<h3 className="text-lg font-bold text-blue-400 mb-4">Демонстрация улучшений в реальном времени</h3>
<div className="grid grid-cols-2 gap-6">
<div className="text-center">
<div className="text-red-400 font-bold mb-2">До оптимизации</div>
<div className={`text-3xl font-bold ${uxDemo.isAnimating ? 'animate-ux-pulse' : ''}`}>
{uxDemo.beforeSpeed}ms
</div>
</div>
<div className="text-center">
<div className="text-green-400 font-bold mb-2">После оптимизации</div>
<div className={`text-3xl font-bold ${uxDemo.isAnimating ? 'animate-ux-pulse' : ''}`}>
{uxDemo.afterSpeed}ms
</div>
</div>
</div>
{uxDemo.improvement > 0 && (
<div className="mt-4 text-center">
<div className="text-blue-400 font-bold text-xl animate-metric-count">
Улучшение на {uxDemo.improvement}%!
</div>
</div>
)}
</div>
<div className="glass-effect p-4 rounded-lg inline-block mb-8">
<p className="text-sm text-gray-400">
* Данная страница носит информационный характер. Публичная оферта отсутствует.
@ -41,52 +366,70 @@ export default function UXSoftware() {
</div>
<div className="grid md:grid-cols-2 lg:grid-cols-3 gap-8">
<div className="glass-effect p-8 rounded-lg hover-glow transition-all duration-300">
<div className="text-blue-400 text-4xl mb-4">🚀</div>
<div className="glass-effect p-8 rounded-lg hover-glow transition-all duration-300 group hover:scale-105">
<div className="text-blue-400 text-4xl mb-4 group-hover:animate-ux-pulse">🚀</div>
<h3 className="text-xl font-bold mb-4">Ускорение соединения</h3>
<p className="text-gray-300">
Оптимизация сетевых маршрутов для повышения скорости загрузки контента
</p>
<div className="mt-4 opacity-0 group-hover:opacity-100 transition-opacity">
<div className="text-blue-400 text-sm font-medium">+73% скорости</div>
</div>
</div>
<div className="glass-effect p-8 rounded-lg hover-glow transition-all duration-300">
<div className="text-purple-400 text-4xl mb-4">🔒</div>
<div className="glass-effect p-8 rounded-lg hover-glow transition-all duration-300 group hover:scale-105">
<div className="text-purple-400 text-4xl mb-4 group-hover:animate-ux-pulse">🔒</div>
<h3 className="text-xl font-bold mb-4">Защита данных</h3>
<p className="text-gray-300">
Шифрование трафика для обеспечения конфиденциальности пользователей
</p>
<div className="mt-4 opacity-0 group-hover:opacity-100 transition-opacity">
<div className="text-purple-400 text-sm font-medium">AES-256 шифрование</div>
</div>
</div>
<div className="glass-effect p-8 rounded-lg hover-glow transition-all duration-300">
<div className="text-green-400 text-4xl mb-4">🌐</div>
<div className="glass-effect p-8 rounded-lg hover-glow transition-all duration-300 group hover:scale-105">
<div className="text-green-400 text-4xl mb-4 group-hover:animate-ux-pulse">🌐</div>
<h3 className="text-xl font-bold mb-4">Глобальный доступ</h3>
<p className="text-gray-300">
Доступ к контенту без географических ограничений
</p>
<div className="mt-4 opacity-0 group-hover:opacity-100 transition-opacity">
<div className="text-green-400 text-sm font-medium">50+ стран</div>
</div>
</div>
<div className="glass-effect p-8 rounded-lg hover-glow transition-all duration-300">
<div className="text-yellow-400 text-4xl mb-4"></div>
<div className="glass-effect p-8 rounded-lg hover-glow transition-all duration-300 group hover:scale-105">
<div className="text-yellow-400 text-4xl mb-4 group-hover:animate-ux-pulse"></div>
<h3 className="text-xl font-bold mb-4">Стабильность</h3>
<p className="text-gray-300">
Надежное соединение с минимальными разрывами связи
</p>
<div className="mt-4 opacity-0 group-hover:opacity-100 transition-opacity">
<div className="text-yellow-400 text-sm font-medium">99.9% uptime</div>
</div>
</div>
<div className="glass-effect p-8 rounded-lg hover-glow transition-all duration-300">
<div className="text-red-400 text-4xl mb-4">🛡</div>
<div className="glass-effect p-8 rounded-lg hover-glow transition-all duration-300 group hover:scale-105">
<div className="text-red-400 text-4xl mb-4 group-hover:animate-ux-pulse">🛡</div>
<h3 className="text-xl font-bold mb-4">Анонимность</h3>
<p className="text-gray-300">
Сокрытие реального IP-адреса для защиты приватности
</p>
<div className="mt-4 opacity-0 group-hover:opacity-100 transition-opacity">
<div className="text-red-400 text-sm font-medium">Zero-log политика</div>
</div>
</div>
<div className="glass-effect p-8 rounded-lg hover-glow transition-all duration-300">
<div className="text-cyan-400 text-4xl mb-4">📱</div>
<div className="glass-effect p-8 rounded-lg hover-glow transition-all duration-300 group hover:scale-105">
<div className="text-cyan-400 text-4xl mb-4 group-hover:animate-ux-pulse">📱</div>
<h3 className="text-xl font-bold mb-4">Кроссплатформенность</h3>
<p className="text-gray-300">
Поддержка всех популярных операционных систем и устройств
</p>
<div className="mt-4 opacity-0 group-hover:opacity-100 transition-opacity">
<div className="text-cyan-400 text-sm font-medium">10+ платформ</div>
</div>
</div>
</div>
</div>
@ -102,34 +445,72 @@ export default function UXSoftware() {
</div>
<div className="grid md:grid-cols-3 gap-8">
<div className="text-center">
<div className="glass-effect w-20 h-20 rounded-full flex items-center justify-center mx-auto mb-6">
<div className="text-center group">
<div className="glass-effect w-20 h-20 rounded-full flex items-center justify-center mx-auto mb-6 group-hover:animate-ux-pulse transition-all duration-300 group-hover:scale-110">
<span className="text-2xl font-bold gradient-text">1</span>
</div>
<h3 className="text-xl font-bold mb-4">Установка</h3>
<p className="text-gray-300">
<h3 className="text-xl font-bold mb-4 group-hover:text-blue-400 transition-colors">Установка</h3>
<p className="text-gray-300 group-hover:text-gray-200 transition-colors">
Простая установка программы на ваше устройство
</p>
<div className="mt-4 opacity-0 group-hover:opacity-100 transition-opacity">
<div className="text-blue-400 text-sm"> Скачать за 30 сек</div>
</div>
</div>
<div className="text-center">
<div className="glass-effect w-20 h-20 rounded-full flex items-center justify-center mx-auto mb-6">
<div className="text-center group">
<div className="glass-effect w-20 h-20 rounded-full flex items-center justify-center mx-auto mb-6 group-hover:animate-ux-pulse transition-all duration-300 group-hover:scale-110">
<span className="text-2xl font-bold gradient-text">2</span>
</div>
<h3 className="text-xl font-bold mb-4">Настройка</h3>
<p className="text-gray-300">
<h3 className="text-xl font-bold mb-4 group-hover:text-green-400 transition-colors">Настройка</h3>
<p className="text-gray-300 group-hover:text-gray-200 transition-colors">
Автоматическая настройка оптимальных параметров
</p>
<div className="mt-4 opacity-0 group-hover:opacity-100 transition-opacity">
<div className="text-green-400 text-sm"> Настройка за 1 мин</div>
</div>
</div>
<div className="text-center">
<div className="glass-effect w-20 h-20 rounded-full flex items-center justify-center mx-auto mb-6">
<div className="text-center group">
<div className="glass-effect w-20 h-20 rounded-full flex items-center justify-center mx-auto mb-6 group-hover:animate-ux-pulse transition-all duration-300 group-hover:scale-110">
<span className="text-2xl font-bold gradient-text">3</span>
</div>
<h3 className="text-xl font-bold mb-4">Использование</h3>
<p className="text-gray-300">
<h3 className="text-xl font-bold mb-4 group-hover:text-purple-400 transition-colors">Использование</h3>
<p className="text-gray-300 group-hover:text-gray-200 transition-colors">
Наслаждайтесь улучшенным интернет-опытом
</p>
<div className="mt-4 opacity-0 group-hover:opacity-100 transition-opacity">
<div className="text-purple-400 text-sm">🚀 Мгновенный эффект</div>
</div>
</div>
</div>
{/* Интерактивная схема процесса */}
<div className="mt-16 max-w-4xl mx-auto">
<div className="glass-effect p-8 rounded-lg">
<h3 className="text-xl font-bold text-center mb-8 text-blue-400">Процесс оптимизации в реальном времени</h3>
<div className="flex items-center justify-between">
<div className="flex-1 text-center">
<div className="w-12 h-12 bg-red-500 rounded-full mx-auto mb-2 animate-ux-pulse"></div>
<div className="text-sm text-gray-300">Медленное соединение</div>
</div>
<div className="flex-1 text-center">
<div className="text-2xl animate-ux-pulse"></div>
<div className="text-sm text-gray-300">Анализ</div>
</div>
<div className="flex-1 text-center">
<div className="w-12 h-12 bg-yellow-500 rounded-full mx-auto mb-2 animate-ux-pulse"></div>
<div className="text-sm text-gray-300">Оптимизация</div>
</div>
<div className="flex-1 text-center">
<div className="text-2xl animate-ux-pulse"></div>
<div className="text-sm text-gray-300">Улучшение</div>
</div>
<div className="flex-1 text-center">
<div className="w-12 h-12 bg-green-500 rounded-full mx-auto mb-2 animate-ux-pulse"></div>
<div className="text-sm text-gray-300">Быстрое соединение</div>
</div>
</div>
</div>
</div>
</div>
@ -144,48 +525,123 @@ export default function UXSoftware() {
Преимущества использования нашего <span className="gradient-text">ПО</span>
</h2>
<div className="space-y-6">
<div className="flex items-start space-x-4">
<div className="text-green-400 text-xl"></div>
<div className="flex items-start space-x-4 group hover:bg-gray-800/30 p-4 rounded-lg transition-all duration-300">
<div className="text-green-400 text-xl group-hover:animate-ux-pulse"></div>
<div>
<h4 className="font-semibold mb-2">Повышение производительности</h4>
<p className="text-gray-300">Оптимизация сетевых соединений для более быстрой работы</p>
<h4 className="font-semibold mb-2 group-hover:text-green-400 transition-colors">Повышение производительности</h4>
<p className="text-gray-300 group-hover:text-gray-200 transition-colors">Оптимизация сетевых соединений для более быстрой работы</p>
<div className="mt-2 opacity-0 group-hover:opacity-100 transition-opacity">
<span className="text-green-400 text-sm font-medium">🚀 До 73% быстрее</span>
</div>
</div>
</div>
<div className="flex items-start space-x-4">
<div className="text-green-400 text-xl"></div>
<div className="flex items-start space-x-4 group hover:bg-gray-800/30 p-4 rounded-lg transition-all duration-300">
<div className="text-green-400 text-xl group-hover:animate-ux-pulse"></div>
<div>
<h4 className="font-semibold mb-2">Защита конфиденциальности</h4>
<p className="text-gray-300">Надежное шифрование и защита персональных данных</p>
<h4 className="font-semibold mb-2 group-hover:text-purple-400 transition-colors">Защита конфиденциальности</h4>
<p className="text-gray-300 group-hover:text-gray-200 transition-colors">Надежное шифрование и защита персональных данных</p>
<div className="mt-2 opacity-0 group-hover:opacity-100 transition-opacity">
<span className="text-purple-400 text-sm font-medium">🔒 AES-256 шифрование</span>
</div>
</div>
</div>
<div className="flex items-start space-x-4">
<div className="text-green-400 text-xl"></div>
<div className="flex items-start space-x-4 group hover:bg-gray-800/30 p-4 rounded-lg transition-all duration-300">
<div className="text-green-400 text-xl group-hover:animate-ux-pulse"></div>
<div>
<h4 className="font-semibold mb-2">Простота использования</h4>
<p className="text-gray-300">Интуитивно понятный интерфейс и автоматические настройки</p>
<h4 className="font-semibold mb-2 group-hover:text-blue-400 transition-colors">Простота использования</h4>
<p className="text-gray-300 group-hover:text-gray-200 transition-colors">Интуитивно понятный интерфейс и автоматические настройки</p>
<div className="mt-2 opacity-0 group-hover:opacity-100 transition-opacity">
<span className="text-blue-400 text-sm font-medium"> Настройка за 1 минуту</span>
</div>
</div>
</div>
<div className="flex items-start space-x-4">
<div className="text-green-400 text-xl"></div>
<div className="flex items-start space-x-4 group hover:bg-gray-800/30 p-4 rounded-lg transition-all duration-300">
<div className="text-green-400 text-xl group-hover:animate-ux-pulse"></div>
<div>
<h4 className="font-semibold mb-2">Техническая поддержка</h4>
<p className="text-gray-300">Круглосуточная поддержка пользователей</p>
<h4 className="font-semibold mb-2 group-hover:text-yellow-400 transition-colors">Техническая поддержка</h4>
<p className="text-gray-300 group-hover:text-gray-200 transition-colors">Круглосуточная поддержка пользователей</p>
<div className="mt-2 opacity-0 group-hover:opacity-100 transition-opacity">
<span className="text-yellow-400 text-sm font-medium">🕒 24/7 поддержка</span>
</div>
</div>
</div>
</div>
</div>
<div className="glass-effect p-8 rounded-lg">
<h3 className="text-2xl font-bold mb-6 text-center">Свяжитесь с нами</h3>
<div className="glass-effect p-8 rounded-lg animate-ux-glow">
<h3 className="text-2xl font-bold mb-6 text-center gradient-text">Результаты использования</h3>
{/* Живая статистика производительности */}
<div className="space-y-6 mb-8">
<div className="group">
<div className="flex justify-between items-center mb-2">
<span className="text-gray-300 group-hover:text-gray-200 transition-colors">Скорость загрузки</span>
<span className="text-green-400 font-bold group-hover:animate-ux-pulse">+73%</span>
</div>
<div className="w-full bg-gray-700 rounded-full h-3 overflow-hidden">
<div className="bg-gradient-to-r from-green-500 to-green-400 h-3 rounded-full transition-all duration-1000 group-hover:animate-ux-pulse" style={{width: '73%'}}></div>
</div>
</div>
<div className="group">
<div className="flex justify-between items-center mb-2">
<span className="text-gray-300 group-hover:text-gray-200 transition-colors">Стабильность соединения</span>
<span className="text-blue-400 font-bold group-hover:animate-ux-pulse">+89%</span>
</div>
<div className="w-full bg-gray-700 rounded-full h-3 overflow-hidden">
<div className="bg-gradient-to-r from-blue-500 to-blue-400 h-3 rounded-full transition-all duration-1000 group-hover:animate-ux-pulse" style={{width: '89%'}}></div>
</div>
</div>
<div className="group">
<div className="flex justify-between items-center mb-2">
<span className="text-gray-300 group-hover:text-gray-200 transition-colors">Уровень защиты</span>
<span className="text-purple-400 font-bold group-hover:animate-ux-pulse">+95%</span>
</div>
<div className="w-full bg-gray-700 rounded-full h-3 overflow-hidden">
<div className="bg-gradient-to-r from-purple-500 to-purple-400 h-3 rounded-full transition-all duration-1000 group-hover:animate-ux-pulse" style={{width: '95%'}}></div>
</div>
</div>
<div className="group">
<div className="flex justify-between items-center mb-2">
<span className="text-gray-300 group-hover:text-gray-200 transition-colors">Удовлетворенность пользователей</span>
<span className="text-yellow-400 font-bold group-hover:animate-ux-pulse">+92%</span>
</div>
<div className="w-full bg-gray-700 rounded-full h-3 overflow-hidden">
<div className="bg-gradient-to-r from-yellow-500 to-yellow-400 h-3 rounded-full transition-all duration-1000 group-hover:animate-ux-pulse" style={{width: '92%'}}></div>
</div>
</div>
</div>
{/* Живая статистика пользователей */}
<div className="grid grid-cols-2 gap-4 mb-8">
<div className="text-center p-4 bg-gray-800/50 rounded-lg group hover:bg-gray-800/70 transition-all duration-300">
<div className="text-2xl font-bold text-green-400 animate-metric-count group-hover:animate-ux-pulse">2.1M+</div>
<div className="text-sm text-gray-300 group-hover:text-gray-200 transition-colors">Активных пользователей</div>
</div>
<div className="text-center p-4 bg-gray-800/50 rounded-lg group hover:bg-gray-800/70 transition-all duration-300">
<div className="text-2xl font-bold text-blue-400 animate-metric-count group-hover:animate-ux-pulse">99.9%</div>
<div className="text-sm text-gray-300 group-hover:text-gray-200 transition-colors">Время работы</div>
</div>
</div>
{/* Кнопка консультации */}
<div className="text-center">
<p className="text-gray-300 text-center mb-6">
Получите консультацию по внедрению решений для улучшения UX
</p>
<div className="text-center">
<button className="px-8 py-3 bg-blue-500 text-white font-semibold rounded-lg hover-glow transition-all duration-300">
Получить консультацию
<button
onClick={handleConsultationClick}
className="px-8 py-3 bg-gradient-to-r from-blue-600 to-purple-600 text-white font-semibold rounded-lg hover-glow transition-all duration-300 hover:from-blue-700 hover:to-purple-700 active:scale-95 cursor-pointer hover:shadow-lg hover:shadow-blue-500/25 animate-ux-glow"
>
<span className="flex items-center justify-center space-x-2">
<span>Получить консультацию</span>
<span className="text-lg">💬</span>
</span>
</button>
</div>
</div>
@ -222,6 +678,85 @@ export default function UXSoftware() {
</p>
</div>
</footer>
{/* Modal */}
{isModalOpen && (
<div className="fixed inset-0 bg-black bg-opacity-5 flex items-center justify-center z-50 p-4">
<div className="bg-gray-900 rounded-lg p-8 max-w-md w-full relative">
<button
onClick={handleCloseModal}
className="absolute top-4 right-4 text-gray-400 hover:text-white text-2xl"
>
×
</button>
<h3 className="text-2xl font-bold mb-6 gradient-text">Получить консультацию</h3>
<form onSubmit={handleSubmit} className="space-y-4">
<div>
<label htmlFor="name" className="block text-sm font-medium text-gray-300 mb-1">
Имя *
</label>
<input
type="text"
id="name"
name="name"
value={formData.name}
onChange={handleInputChange}
required
className="w-full px-3 py-2 bg-gray-800 border border-gray-600 rounded-lg text-white focus:outline-none focus:border-blue-500"
/>
</div>
<div>
<label htmlFor="email" className="block text-sm font-medium text-gray-300 mb-1">
Email *
</label>
<input
type="email"
id="email"
name="email"
value={formData.email}
onChange={handleInputChange}
required
className="w-full px-3 py-2 bg-gray-800 border border-gray-600 rounded-lg text-white focus:outline-none focus:border-blue-500"
/>
</div>
<div>
<label htmlFor="message" className="block text-sm font-medium text-gray-300 mb-1">
Сообщение
</label>
<textarea
id="message"
name="message"
value={formData.message}
onChange={handleInputChange}
rows={4}
className="w-full px-3 py-2 bg-gray-800 border border-gray-600 rounded-lg text-white focus:outline-none focus:border-blue-500"
placeholder="Расскажите о ваших потребностях..."
/>
</div>
<div className="flex space-x-4 pt-4">
<button
type="button"
onClick={handleCloseModal}
className="flex-1 px-4 py-2 bg-gray-600 text-white rounded-lg hover:bg-gray-700 transition-colors"
>
Отмена
</button>
<button
type="submit"
className="flex-1 px-4 py-2 bg-blue-500 text-white rounded-lg hover:bg-blue-600 transition-colors"
>
Отправить
</button>
</div>
</form>
</div>
</div>
)}
</>
);
}