131 lines
6.6 KiB
TypeScript
Executable File
131 lines
6.6 KiB
TypeScript
Executable File
|
||
import React from 'react';
|
||
import SectionWrapper from './SectionWrapper';
|
||
import { motion } from 'framer-motion';
|
||
import MapSVG from './MapSVG';
|
||
import { Globe } from 'lucide-react';
|
||
import { SectionProps } from '../types';
|
||
|
||
const Scaling: React.FC<SectionProps> = ({ onOpenModal }) => {
|
||
const cities = [
|
||
{ x: 20, y: 35, label: 'КАЗАНЬ' },
|
||
{ x: 80, y: 45, label: 'ЕКАТЕРИНБУРГ' },
|
||
{ x: 70, y: 75, label: 'НОВОСИБИРСК' },
|
||
];
|
||
|
||
const handleOpenMap = () => {
|
||
if (onOpenModal) {
|
||
onOpenModal({
|
||
title: 'Стратегия Масштабирования',
|
||
type: 'list',
|
||
theme: 'light',
|
||
content: {
|
||
items: [
|
||
'Этап 1 (2025): Пилотное внедрение в Башкортостане.',
|
||
'Этап 2 (2026): Тиражирование в ПФО (Татарстан, Самара).',
|
||
'Этап 3 (2027): Выход на федеральный уровень, интеграция с платформой Гостех.',
|
||
'Экспорт: Поставка коробочных решений для стран БРИКС.',
|
||
]
|
||
}
|
||
});
|
||
}
|
||
};
|
||
|
||
return (
|
||
<SectionWrapper id="scaling" transitionEffect="slide">
|
||
<div className="max-w-7xl mx-auto px-6 md:px-12 w-full flex-grow flex flex-col justify-center">
|
||
<div className="flex flex-col lg:flex-row gap-12 lg:gap-16 items-center h-full">
|
||
<motion.div
|
||
className="w-full lg:w-1/2 flex flex-col justify-center h-auto"
|
||
initial={{ opacity: 0, x: -50 }}
|
||
whileInView={{ opacity: 1, x: 0 }}
|
||
viewport={{ once: true }}
|
||
transition={{ duration: 0.8, ease: [0.645, 0.045, 0.355, 1.000] }}
|
||
>
|
||
<div className="flex items-center gap-2 mb-4">
|
||
<div className="w-2 h-2 bg-[#000000]"></div>
|
||
<span className="text-[#0000000] font-mono text-xs tracking-widest">06. МАСШТАБИРОВАНИЕ</span>
|
||
</div>
|
||
<h3 className="text-4xl md:text-6xl lg:text-7xl font-black text-theme-main mb-8 tracking-tighter leading-none">
|
||
ЭКСПОРТНЫЙ <br/> <span className="text-theme-muted">ПОТЕНЦИАЛ</span>
|
||
</h3>
|
||
<p className="text-theme-muted text-lg mb-8">
|
||
Cоздим продукт с высокой добавленной стоимостью. Успешный опыт Башкортостана будет упакован для масштабирования на уровне страны.
|
||
</p>
|
||
<ul className="space-y-4 font-mono text-xs text-theme-main uppercase tracking-wide mb-8">
|
||
<li className="flex items-center gap-3">
|
||
<span className="text-[#ff4b4b]">>></span> Федеральный Масштаб
|
||
</li>
|
||
<li className="flex items-center gap-3">
|
||
<span className="text-[#ff4b4b]">>></span> Новая статья доходов в республике
|
||
</li>
|
||
</ul>
|
||
|
||
<button
|
||
onClick={handleOpenMap}
|
||
className="flex items-center gap-3 text-theme-main font-bold uppercase tracking-widest text-xs border border-theme px-6 py-3 rounded-sm hover:bg-theme-main hover:text-white transition-all w-fit group"
|
||
>
|
||
<Globe className="w-4 h-4 group-hover:rotate-12 transition-transform" />
|
||
Карта Экспансии
|
||
</button>
|
||
</motion.div>
|
||
|
||
<motion.div
|
||
className="w-full lg:w-1/2 relative h-[300px] md:h-[400px] lg:h-[500px] border border-theme bg-theme-card overflow-hidden"
|
||
initial={{ opacity: 0, scale: 0.95 }}
|
||
whileInView={{ opacity: 1, scale: 1 }}
|
||
viewport={{ once: true }}
|
||
transition={{ delay: 0.2, duration: 0.8, ease: [0.645, 0.045, 0.355, 1.000] }}
|
||
>
|
||
{/* SVG Map Container */}
|
||
<div className="absolute inset-0 flex items-center justify-center opacity-30 mix-blend-multiply pointer-events-none">
|
||
<div className="w-full h-full p-8 grayscale contrast-125">
|
||
<MapSVG />
|
||
</div>
|
||
</div>
|
||
|
||
{/* Animated Connections */}
|
||
<svg className="absolute inset-0 w-full h-full z-10 pointer-events-none">
|
||
<defs>
|
||
<marker id="arrow" markerWidth="10" markerHeight="10" refX="10" refY="3" orient="auto" markerUnits="strokeWidth">
|
||
<path d="M0,0 L0,6 L9,3 z" fill="#ff4b4b" />
|
||
</marker>
|
||
</defs>
|
||
{cities.map((city, i) => (
|
||
<motion.line
|
||
key={i}
|
||
x1="50%" y1="50%"
|
||
x2={`${city.x}%`} y2={`${city.y}%`}
|
||
stroke="#ff4b4b"
|
||
strokeWidth="1"
|
||
strokeDasharray="4 4"
|
||
initial={{ pathLength: 0, opacity: 0 }}
|
||
whileInView={{ pathLength: 1, opacity: 1 }}
|
||
transition={{ duration: 1.5, delay: 0.5 + i * 0.3, ease: [0.645, 0.045, 0.355, 1.000] }}
|
||
/>
|
||
))}
|
||
</svg>
|
||
|
||
{/* Cities */}
|
||
<div className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-4 h-4 bg-theme-main rounded-full z-20 shadow-[0_0_15px_currentColor]"></div>
|
||
{cities.map((city, i) => (
|
||
<motion.div
|
||
key={i}
|
||
initial={{ opacity: 0, scale: 0 }}
|
||
whileInView={{ opacity: 1, scale: 1 }}
|
||
transition={{ delay: 1 + i * 0.3, ease: "backOut" }}
|
||
className="absolute z-20 w-3 h-3 bg-[#ff4b4b] rounded-full"
|
||
style={{ left: `${city.x}%`, top: `${city.y}%`, transform: 'translate(-50%, -50%)' }}
|
||
>
|
||
<span className="absolute top-4 left-1/2 -translate-x-1/2 font-mono text-[10px] text-theme-main bg-theme-card px-1 border border-theme">{city.label}</span>
|
||
</motion.div>
|
||
))}
|
||
</motion.div>
|
||
</div>
|
||
</div>
|
||
</SectionWrapper>
|
||
);
|
||
};
|
||
|
||
export default Scaling;
|