146 lines
6.5 KiB
TypeScript
146 lines
6.5 KiB
TypeScript
|
|
|
|||
|
|
import React from 'react';
|
|||
|
|
import SectionWrapper from './SectionWrapper';
|
|||
|
|
import { BarChart, Bar, XAxis, YAxis, Tooltip, ResponsiveContainer, Cell } from 'recharts';
|
|||
|
|
import { motion } from 'framer-motion';
|
|||
|
|
import { ListPlus } from 'lucide-react';
|
|||
|
|
import { SectionProps } from '../types';
|
|||
|
|
|
|||
|
|
// 1. Функция-помощник для окончаний (балл, балла, баллов)
|
|||
|
|
const getNoun = (number: number, one: string, two: string, five: string) => {
|
|||
|
|
let n = Math.abs(number);
|
|||
|
|
n %= 100;
|
|||
|
|
if (n >= 5 && n <= 20) {
|
|||
|
|
return five;
|
|||
|
|
}
|
|||
|
|
n %= 10;
|
|||
|
|
if (n === 1) {
|
|||
|
|
return one;
|
|||
|
|
}
|
|||
|
|
if (n >= 2 && n <= 4) {
|
|||
|
|
return two;
|
|||
|
|
}
|
|||
|
|
return five;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
const data = [
|
|||
|
|
{ name: 'Москва', value: 95 },
|
|||
|
|
{ name: 'Белгородская', value: 94 },
|
|||
|
|
{ name: 'Башкортостан', value: 93 },
|
|||
|
|
{ name: 'Татарстан', value: 92 },
|
|||
|
|
{ name: 'ХМАО', value: 90 },
|
|||
|
|
];
|
|||
|
|
|
|||
|
|
const Leadership: React.FC<SectionProps> = ({ onOpenModal }) => {
|
|||
|
|
|
|||
|
|
const handleOpenRating = () => {
|
|||
|
|
if (onOpenModal) {
|
|||
|
|
onOpenModal({
|
|||
|
|
title: 'Индекс цифровизации (ТОП-10)',
|
|||
|
|
type: 'table',
|
|||
|
|
theme: 'light',
|
|||
|
|
content: {
|
|||
|
|
headers: ['Позиция', 'Регион', 'Баллы', 'Динамика'],
|
|||
|
|
rows: [
|
|||
|
|
['1', 'Москва', '95.4', '+0.2'],
|
|||
|
|
['2', 'Белгородская область', '94.1', '+1.5'],
|
|||
|
|
['3', 'Республика Башкортостан', '93.8', '+4.2'],
|
|||
|
|
['4', 'Республика Татарстан', '92.5', '-0.5'],
|
|||
|
|
['5', 'ХМАО - Югра', '90.3', '+0.8'],
|
|||
|
|
['6', 'Московская область', '88.9', '+1.1'],
|
|||
|
|
['7', 'Санкт-Петербург', '87.4', '-1.2'],
|
|||
|
|
['8', 'Тульская область', '86.2', '+0.5'],
|
|||
|
|
['9', 'Калужская область', '85.1', '+0.3'],
|
|||
|
|
['10', 'Челябинская область', '84.8', '+2.0']
|
|||
|
|
]
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
return (
|
|||
|
|
<SectionWrapper id="leadership" transitionEffect="paint-ripple">
|
|||
|
|
<div className="max-w-7xl mx-auto px-6 md:px-12 w-full h-full flex flex-col justify-center">
|
|||
|
|
<div className="flex flex-col lg:flex-row-reverse gap-12 lg:gap-16 items-center h-full">
|
|||
|
|
<motion.div
|
|||
|
|
className="w-full lg:w-1/2 flex flex-col justify-center"
|
|||
|
|
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], delay: 0.8 }} // Delayed content to wait for ripple
|
|||
|
|
>
|
|||
|
|
<div className="flex items-center gap-2 mb-4">
|
|||
|
|
<div className="w-2 h-2 bg-[#20e3b2]"></div>
|
|||
|
|
<span className="text-[#20e3b2] font-mono text-xs tracking-widest">04. РЕЙТИНГ</span>
|
|||
|
|
</div>
|
|||
|
|
<h3 className="text-4xl md:text-6xl lg:text-7xl font-black text-theme-main mb-6 tracking-tighter leading-none">
|
|||
|
|
IT ЛИДЕР <br/><span className="text-theme-muted">В РОССИИ</span>
|
|||
|
|
</h3>
|
|||
|
|
<p className="text-theme-muted text-base md:text-lg mb-8">
|
|||
|
|
ОТ ЦИФРОВИЗАЦИИ К ИНТЕЛЛЕКТУАЛЬНОЙ ВЛАСТИ <br/> Башкортостан станет технологическим донором для регионов РФ. Мы сформируем федеральный стандарт ГосТехИИ.
|
|||
|
|
</p>
|
|||
|
|
<div className="flex gap-8 md:gap-12 font-mono mb-8">
|
|||
|
|
<div>
|
|||
|
|
<div className="text-3xl md:text-5xl font-bold text-theme-main mb-2">TOP-3</div>
|
|||
|
|
<div className="text-xs text-theme-muted uppercase tracking-wider">Стратегия 2030</div>
|
|||
|
|
</div>
|
|||
|
|
<div>
|
|||
|
|
<div className="text-3xl md:text-5xl font-bold text-[#20e3b2] mb-2">#1</div>
|
|||
|
|
<div className="text-xs text-theme-muted uppercase tracking-wider">Приволжский ФО</div>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<button
|
|||
|
|
onClick={handleOpenRating}
|
|||
|
|
className="flex items-center gap-2 text-theme-main font-bold uppercase tracking-widest text-xs hover:text-[#20e3b2] transition-colors w-fit"
|
|||
|
|
>
|
|||
|
|
<ListPlus className="w-5 h-5" />
|
|||
|
|
Развернуть рейтинг
|
|||
|
|
</button>
|
|||
|
|
|
|||
|
|
</motion.div>
|
|||
|
|
|
|||
|
|
<motion.div
|
|||
|
|
className="w-full lg:w-1/2 h-[300px] md:h-[400px] lg:h-[500px] bg-theme-card border border-theme p-4 md:p-8 relative"
|
|||
|
|
initial={{ opacity: 0, scale: 0.9 }}
|
|||
|
|
whileInView={{ opacity: 1, scale: 1 }}
|
|||
|
|
viewport={{ once: true }}
|
|||
|
|
transition={{ delay: 1.0, duration: 0.8, ease: [0.645, 0.045, 0.355, 1.000] }}
|
|||
|
|
>
|
|||
|
|
<ResponsiveContainer width="100%" height="100%">
|
|||
|
|
<BarChart data={data} layout="vertical" margin={{ top: 10, right: 10, left: 10, bottom: 10 }}>
|
|||
|
|
<XAxis type="number" hide />
|
|||
|
|
<YAxis
|
|||
|
|
dataKey="name"
|
|||
|
|
type="category"
|
|||
|
|
tick={{ fill: 'var(--text-muted)', fontSize: 12, fontFamily: 'JetBrains Mono' }}
|
|||
|
|
width={100}
|
|||
|
|
axisLine={false}
|
|||
|
|
tickLine={false}
|
|||
|
|
/>
|
|||
|
|
<Tooltip
|
|||
|
|
separator=""
|
|||
|
|
cursor={{fill: 'var(--bg-color)', opacity: 0.5}}
|
|||
|
|
contentStyle={{ backgroundColor: 'var(--bg-color)', borderColor: 'var(--border-color)', color: 'var(--text-main)', fontFamily: 'JetBrains Mono' }}
|
|||
|
|
itemStyle={{ color: 'var(--text-main)' }}
|
|||
|
|
formatter={(value: any) => [
|
|||
|
|
`${value} ${getNoun(Number(value), 'балл', 'балла', 'баллов')}`,
|
|||
|
|
''
|
|||
|
|
]}
|
|||
|
|
/>
|
|||
|
|
<Bar dataKey="value" barSize={20}>
|
|||
|
|
{data.map((entry, index) => (
|
|||
|
|
<Cell key={`cell-${index}`} fill={entry.name === 'Башкортостан' ? '#20e3b2' : '#555'} />
|
|||
|
|
))}
|
|||
|
|
</Bar>
|
|||
|
|
</BarChart>
|
|||
|
|
</ResponsiveContainer>
|
|||
|
|
</motion.div>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</SectionWrapper>
|
|||
|
|
);
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
export default Leadership;
|