Files
gov/components/Scaling.tsx

131 lines
6.6 KiB
TypeScript
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import React 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]">&gt;&gt;</span> Федеральный Масштаб
</li>
<li className="flex items-center gap-3">
<span className="text-[#ff4b4b]">&gt;&gt;</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;