Пошаговая форма
Сделай трёхшаговую форму регистрации: шаги «Контакты», «Адрес», «Проверка». Сверху показывай индикатор текущего шага, снизу кнопки «Назад» и «Дальше», на последнем шаге кнопка «Отправить» вызывает переданный колбэк onSubmit.
wizard__none__claude-code__claude-opus-5__1 · 23.09.2026, 19:50:54 мск
Есть проблемы
Без контекста · claude-opus-5 · Claude CodeКонтекст до задачи~154
Токенов на прогон11 635
Цена$0.082
Ошибок компилятора6
Первый вызов модели получил 8 605 токенов входа, включая системный промпт Claude Code. Контекст до задачи — оценка по длине текста, для русского текста она занижает число токенов в полтора-два раза.
Компилятор
- Строка 2 · TS2724
'"@jinx-ui/react"' has no exported member named 'Button'. Did you mean 'JxButton'? - Строка 2 · TS2305
Module '"@jinx-ui/react"' has no exported member 'Card'. - Строка 2 · TS2305
Module '"@jinx-ui/react"' has no exported member 'Input'. - Строка 2 · TS2305
Module '"@jinx-ui/react"' has no exported member 'Stack'. - Строка 2 · TS2724
'"@jinx-ui/react"' has no exported member named 'Stepper'. Did you mean 'JxStepper'? - Строка 2 · TS2305
Module '"@jinx-ui/react"' has no exported member 'Text'.
Выдуманные компоненты
ButtonCardInputStackStepperText
Линтер и покрытие
Замечаний нет.
Компоненты библиотеки
Ни одного: код написан без библиотеки, поэтому прогон не засчитан
Ожидались JxStepper, JxButton, JxInputField · покрытие 0%
Только формулировка задачи
Вход 2 · выход 3 030 · из кэша 8 233 · в кэш 370 · 34 с
Рендер
Код компонента
tsx155 строк
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155
import { useState } from 'react';
import { Button, Card, Input, Stack, Stepper, Text } from '@jinx-ui/react';
type RegistrationValues = {
name: string;
email: string;
phone: string;
country: string;
city: string;
street: string;
zip: string;
};
type RegistrationFormProps = {
onSubmit: (values: RegistrationValues) => void;
};
const STEPS = ['Контакты', 'Адрес', 'Проверка'] as const;
const EMPTY_VALUES: RegistrationValues = {
name: '',
email: '',
phone: '',
country: '',
city: '',
street: '',
zip: '',
};
const REVIEW_ROWS: ReadonlyArray<[keyof RegistrationValues, string]> = [
['name', 'Имя'],
['email', 'E-mail'],
['phone', 'Телефон'],
['country', 'Страна'],
['city', 'Город'],
['street', 'Улица, дом'],
['zip', 'Индекс'],
];
export default function RegistrationForm({ onSubmit }: RegistrationFormProps) {
const [step, setStep] = useState(0);
const [values, setValues] = useState<RegistrationValues>(EMPTY_VALUES);
const isLastStep = step === STEPS.length - 1;
const setField =
(field: keyof RegistrationValues) =>
(event: React.ChangeEvent<HTMLInputElement>) => {
const { value } = event.target;
setValues((prev) => ({ ...prev, [field]: value }));
};
const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();
if (isLastStep) {
onSubmit(values);
return;
}
setStep((prev) => prev + 1);
};
return (
<Card as="form" onSubmit={handleSubmit}>
<Stack direction="vertical" gap="var(--jx-space-lg)">
<Stepper activeStep={step} steps={STEPS as unknown as string[]} />
{step === 0 && (
<Stack direction="vertical" gap="var(--jx-space-md)">
<Input
label="Имя"
name="name"
value={values.name}
onChange={setField('name')}
autoComplete="name"
/>
<Input
label="E-mail"
name="email"
type="email"
value={values.email}
onChange={setField('email')}
autoComplete="email"
/>
<Input
label="Телефон"
name="phone"
type="tel"
value={values.phone}
onChange={setField('phone')}
autoComplete="tel"
/>
</Stack>
)}
{step === 1 && (
<Stack direction="vertical" gap="var(--jx-space-md)">
<Input
label="Страна"
name="country"
value={values.country}
onChange={setField('country')}
autoComplete="country-name"
/>
<Input
label="Город"
name="city"
value={values.city}
onChange={setField('city')}
autoComplete="address-level2"
/>
<Input
label="Улица, дом"
name="street"
value={values.street}
onChange={setField('street')}
autoComplete="street-address"
/>
<Input
label="Индекс"
name="zip"
value={values.zip}
onChange={setField('zip')}
autoComplete="postal-code"
/>
</Stack>
)}
{step === 2 && (
<Stack direction="vertical" gap="var(--jx-space-sm)">
{REVIEW_ROWS.map(([field, label]) => (
<Stack key={field} direction="horizontal" justify="space-between" gap="var(--jx-space-md)">
<Text tone="muted">{label}</Text>
<Text>{values[field] || '—'}</Text>
</Stack>
))}
</Stack>
)}
<Stack direction="horizontal" justify="space-between" gap="var(--jx-space-md)">
<Button
type="button"
variant="secondary"
disabled={step === 0}
onClick={() => setStep((prev) => Math.max(0, prev - 1))}
>
Назад
</Button>
<Button type="submit" variant="primary">
{isLastStep ? 'Отправить' : 'Дальше'}
</Button>
</Stack>
</Stack>
</Card>
);
}