// src/components/ScreenThree/index.tsx import styled from "styled-components"; import { s_f_Text18_400 as Text18_400, Text24_700 as Text24_700, s_Text40_700 as Text40_700, s_Text14_400 as Text14_400, } from "../Typography"; import TradingViewChart from "./TradingViewChart"; import { useSingleton } from "cms/factory"; import { AsyncReveal } from "../AsyncReveal"; /* ===================== TYPES ===================== */ type StatCard = { id: string; value: string; label: string; color?: string | null; order: number; }; type IndexItem = { id: string; text: string; order: number; }; type ScreenThree = { id: string; title?: string | null; description?: string | null; footnote?: string | null; statCards: StatCard[]; indexes: IndexItem[]; }; /* ===================== GQL SELECTION ===================== */ const SELECTION = ` id title description footnote statCards(orderBy: { order: asc }) { id value label color order } indexes(orderBy: { order: asc }) { id text order } `; /* ===================== UTILS ===================== */ function chunkInto(arr: T[], size: number): T[][] { const out: T[][] = []; for (let i = 0; i < arr.length; i += size) out.push(arr.slice(i, i + size)); return out; } /* ===================== STYLES ===================== */ const ScreenSecondBlock = styled.div` width: 100%; max-width: 1380px; padding: 64px 10px; margin: 0 auto; display: flex; justify-content: center; @media (max-width: 768px) { padding: 48px 10px; } `; const ContentCard = styled.div` width: 90%; max-width: 1200px; background: #fff; border-radius: 16px; display: flex; flex-direction: column; @media (max-width: 768px) { width: 100%; } `; const HeaderRow = styled.div` display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 48px; @media (max-width: 768px) { flex-direction: column-reverse; align-items: flex-start; gap: 12px; margin-bottom: 32px; } `; const TitleBlock = styled.div` max-width: 720px; display: flex; flex-direction: column; `; const ChartAndStats = styled.div` display: flex; gap: 32px; align-items: stretch; @media (max-width: 768px) { flex-direction: column; display: block; } `; const ChartWrapper = styled.div` flex: 1; border: 1px solid #F5F8FB; border-radius: 8px; @media (max-width: 768px) { width: 100%; height: 436px; /* фиксированная высота вместо min-height */ margin-bottom:32px; } `; const StatsWrapper = styled.div` display: flex; flex-direction: column; gap: 24px; align-items: stretch; @media (max-width: 768px) { width: 100%; gap: 16px; } `; const StatCardRow = styled.div` display: flex; flex-direction: row; gap: 24px; align-items: stretch; @media (max-width: 768px) { width: 100%; flex-direction: column; } `; const StatCardBox = styled.div` background: #F5F8FB; border-radius: 12px; padding: 33px 32px; text-align: left; display: flex; flex-direction: column; width: min-content; min-height: 188px; @media (max-width: 768px) { min-height: auto; width: 100%; } `; const IndexesBlock = styled.div` border-radius: 12px; ul { margin-top: 12px; padding-left: 20px; list-style-type: disc; list-style-position: outside; } li { margin: 6px 0; } @media (max-width: 768px) { margin-top: 0; } `; /* ===================== COMPONENT ===================== */ function ScreenThree() { const { data: s3, loading, error } = useSingleton( "ScreenThreeSection", SELECTION ); const cardGroups = chunkInto(s3?.statCards ?? [], 2); const indexes: IndexItem[] = s3?.indexes ?? []; return ( {/* Заголовок + описание */} {s3?.title ? (
{s3.title}
) : null} {s3?.description ? ( "), }} /> ) : null}
{/* График — оставляем как есть */} {/* Карточки + индексы из CMS */} {/* Карточки — группами по 2 */} {cardGroups.map((row: StatCard[], ri: number) => ( {row.map((card: StatCard) => ( {card.value ? ( {card.value} ) : null} {card.label ? ( {card.label} ) : null} ))} ))} {/* Индексы */} {indexes.length > 0 ? ( FRHC is a part of indexes:
    {indexes.map((it: IndexItem) => (
  • {it.text}
  • ))}
) : null} {/* Сноска */} {s3?.footnote ? ( {s3.footnote} ) : null}
); } export default ScreenThree;