import { useState } from 'react' import { calculatorCopy, calculatorFields, calculatorResults } from '../data/content' import { useReveal } from '../hooks/useReveal' import { cx } from '../lib/cx' const money = new Intl.NumberFormat('ru-RU', { maximumFractionDigits: 0 }) const decimal = new Intl.NumberFormat('ru-RU', { minimumFractionDigits: 1, maximumFractionDigits: 1 }) type FieldKey = (typeof calculatorFields)[number]['key'] /** * Values are held as strings, not numbers: clearing a field has to leave it * empty while the visitor retypes, and coercing on every keystroke would snap * it back to 0. Anything that is not a positive finite number reads as 0 and * blanks the dependent results. */ const initialValues = Object.fromEntries( calculatorFields.map((field) => [field.key, String(field.initial)]), ) as Record function toNumber(raw: string): number { const value = Number(raw.replace(/\s/g, '').replace(',', '.')) return Number.isFinite(value) && value > 0 ? value : 0 } const rubles = (value: number) => (value ? `${money.format(value)} ₽` : '—') export function RevenueCalculator() { const { ref, revealClass } = useReveal() const [values, setValues] = useState(initialValues) const courses = toNumber(values.courses) const averageCheck = toNumber(values.averageCheck) const investment = toNumber(values.investment) const month = courses && averageCheck ? Math.round(courses * averageCheck) : 0 const year = month * 12 const payback = month && investment ? investment / month : null const roi = month && investment ? ((year - investment) / investment) * 100 : null const results: Record<(typeof calculatorResults)[number]['key'], string> = { month: rubles(month), year: rubles(year), payback: payback === null ? '—' : `${decimal.format(payback)} мес.`, roi: roi === null || !Number.isFinite(roi) ? '—' : `${money.format(Math.round(roi))}%`, } return (
{calculatorCopy.eyebrow}

{calculatorCopy.title}

{calculatorCopy.lead}

{calculatorFields.map((field) => (
setValues((current) => ({ ...current, [field.key]: event.target.value })) } className="h-[46px] w-full rounded-[11px] border border-teal-bright/[0.42] bg-white px-[13px] text-[clamp(17px,1.85vw,22px)] font-[850] tabular-nums text-[#071f35] outline-none transition-[border-color,box-shadow] duration-200 focus:border-teal-bright focus:shadow-[0_0_0_3px_rgb(69_228_215/0.12)] narrow:h-[44px] narrow:text-[18px]" /> {field.hint}
))}
{calculatorResults.map((result) => (
{result.label} {results[result.key]} {result.hint}
))}

Как читать расчёт: {calculatorCopy.caption}

) }