Подписка с уведомлением

Сделай форму подписки на рассылку с полем для почты и кнопкой «Подписаться». После отправки поле очищается, а в углу экрана появляется уведомление «Готово» с текстом, что письмо отправлено.

subscribe-toast__mcp__claude-code__claude-opus-5__1 · 24.09.2026, 13:24:45 мск

Проверки пройдены
MCP · claude-opus-5 · Claude Code
Контекст до задачи~2 405
Токенов на прогон31 617
Цена$0.081
Ошибок компилятора0

Первый вызов модели получил 12 459 токенов входа, включая системный промпт Claude Code; вызовов модели 2, каждый отправлял разговор заново, и самый большой получил 17 850 токенов. Контекст до задачи — оценка по длине текста, для русского текста она занижает число токенов в полтора-два раза.

Компилятор

Ошибок нет: все компоненты и пропсы существуют.

Линтер и покрытие

  • inline-styleСтроки 31, 45, 46, 49
    Инлайновые стили вместо классов и токенов библиотеки
Компоненты библиотеки

JxButton, JxInputField, JxToastViewport

Ожидались JxInputField, JxButton, JxToastViewport · покрытие 100%

Вызовы инструментов · 5
  1. get_rules({"task":"ui"}) → ~1247 токенов
  2. get_component_api({"name":"JxInputField"}) → ~484 токенов
  3. get_component_api({"name":"JxButton"}) → ~539 токенов
  4. get_component_api({"name":"JxToast"}) → ~318 токенов
  5. get_component_api({"name":"JxToastViewport"}) → ~478 токенов
Контекст

Инструменты (search_components,get_component_api,get_component_examples,list_design_tokens,get_docs,get_rules, ~1213)

Вход 4 · выход 1 308 · из кэша 24 472 · в кэш 5 833 · 14 с

Рендер

Код компонента

tsx75 строк
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
import { FormEvent, useState } from 'react';
import { JxButton, JxInputField, JxToastViewport, useJxToastQueue } from '@jinx-ui/react';

export default function NewsletterSubscribeForm() {
  const toasts = useJxToastQueue();
  const [email, setEmail] = useState('');
  const [touched, setTouched] = useState(false);

  const isValid = /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email.trim());
  const errorText = touched && !isValid ? 'Укажите корректный адрес, например name@example.com' : undefined;

  const submit = (event: FormEvent<HTMLFormElement>) => {
    event.preventDefault();
    setTouched(true);
    if (!isValid) return;

    const address = email.trim();
    toasts.push({
      title: 'Готово',
      message: `Письмо с подтверждением отправлено на ${address}`,
      variant: 'success',
    });
    setEmail('');
    setTouched(false);
  };

  return (
    <form
      onSubmit={submit}
      noValidate
      style={{
        display: 'flex',
        flexDirection: 'column',
        gap: '16px',
        maxWidth: '420px',
        padding: '24px',
        background: 'var(--jx-surface)',
        border: '1px solid var(--jx-border)',
        borderRadius: 'var(--jx-r-lg)',
        boxShadow: 'var(--jx-shadow-sm)',
        fontFamily: 'var(--jx-font-sans)',
        color: 'var(--jx-text)',
      }}
    >
      <div style={{ display: 'flex', flexDirection: 'column', gap: '4px' }}>
        <h2 style={{ margin: 0, fontFamily: 'var(--jx-font-display)', fontSize: '20px' }}>
          Подписка на рассылку
        </h2>
        <p style={{ margin: 0, color: 'var(--jx-text-2)', fontSize: '14px' }}>
          Раз в неделю присылаем обновления библиотеки. Отписаться можно в один клик.
        </p>
      </div>

      <JxInputField
        label="Электронная почта"
        type="email"
        name="email"
        required
        autoComplete="email"
        placeholder="name@example.com"
        value={email}
        onChange={(event) => setEmail(event.target.value)}
        onBlur={() => setTouched(true)}
        errorText={errorText}
        helperText={errorText ? undefined : 'Адрес используем только для рассылки'}
      />

      <JxButton type="submit" variant="primary" disabled={email.trim().length === 0}>
        Подписаться
      </JxButton>

      <JxToastViewport items={toasts.items} onDismiss={toasts.dismiss} position="top-right" />
    </form>
  );
}