import React, { useMemo, useState } from 'react' import { Box, Button, Grid, GridItem, Heading, NumberInput, NumberInputInput, Stat, StatHelpText, StatLabel, StatValueText, Text, VStack, } from '@chakra-ui/react' import type { ABTestMetrics } from '../../__data__/types' import { compareVariants } from '../../utils/analytics' interface VariantFormState { submissionRate: number completionRate: number retryRate: number timeToFirstSubmission: number sessionDuration: number satisfactionScore?: number } const createVariantState = (): VariantFormState => ({ submissionRate: 0, completionRate: 0, retryRate: 0, timeToFirstSubmission: 0, sessionDuration: 0, satisfactionScore: undefined, }) const buildMetrics = (variant: 'A' | 'B', state: VariantFormState): ABTestMetrics => ({ variant, submissionRate: state.submissionRate, completionRate: state.completionRate, retryRate: state.retryRate, timeToFirstSubmission: state.timeToFirstSubmission, sessionDuration: state.sessionDuration, satisfactionScore: state.satisfactionScore, }) const MetricInput = ({ label, value, onChange, suffix, }: { label: string value: number onChange: (value: number) => void suffix?: string }) => ( {label} onChange(Number.isNaN(val) ? 0 : val)}> {suffix && ( {suffix} )} ) export const ABTestPanel = () => { const [variantA, setVariantA] = useState(createVariantState) const [variantB, setVariantB] = useState(createVariantState) const [comparison, setComparison] = useState | null>(null) const handleCompare = () => { const metricsA = buildMetrics('A', variantA) const metricsB = buildMetrics('B', variantB) setComparison(compareVariants(metricsA, metricsB)) } const hasData = useMemo( () => Object.values(variantA).some((value) => value !== 0) || Object.values(variantB).some((value) => value !== 0), [variantA, variantB], ) return ( A/B тест: сравнение вариантов Вариант A setVariantA((prev) => ({ ...prev, submissionRate: value }))} suffix="Процент пользователей, отправивших хотя бы одно решение" /> setVariantA((prev) => ({ ...prev, completionRate: value }))} /> setVariantA((prev) => ({ ...prev, retryRate: value }))} /> setVariantA((prev) => ({ ...prev, timeToFirstSubmission: value }))} /> setVariantA((prev) => ({ ...prev, sessionDuration: value }))} /> Вариант B setVariantB((prev) => ({ ...prev, submissionRate: value }))} /> setVariantB((prev) => ({ ...prev, completionRate: value }))} /> setVariantB((prev) => ({ ...prev, retryRate: value }))} /> setVariantB((prev) => ({ ...prev, timeToFirstSubmission: value }))} /> setVariantB((prev) => ({ ...prev, sessionDuration: value }))} /> {comparison && ( Результат сравнения Δ Submission Rate {comparison.submissionRateDiff.toFixed(1)}% Положительное значение — рост у варианта B Δ Completion Rate {comparison.completionRateDiff.toFixed(1)}% Положительное значение — рост у варианта B Победитель Вариант {comparison.winner} Основано на сравнении коэффициента завершения )} ) }