Выбор периода

Сделай выбор даты отчёта: календарь на месяц и над ним ряд быстрых вариантов «Сегодня», «Вчера», «Неделя назад», при нажатии на которые дата подставляется в календарь. Выбранная дата отдаётся наружу через колбэк onChange.

date-range__docs-rules__claude-code__claude-opus-5__1 · 23.09.2026, 21:55:59 мск

Проверки пройдены
Доки + правила · claude-opus-5 · Claude Code
Контекст до задачи~23 785
Токенов на прогон50 324
Цена$0.291
Ошибок компилятора0

Первый вызов модели получил 49 054 токена входа, включая системный промпт Claude Code. Контекст до задачи — оценка по длине текста, для русского текста она занижает число токенов в полтора-два раза.

Компилятор

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

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

  • inline-styleСтроки 47, 51, 81
    Инлайновые стили вместо классов и токенов библиотеки
Компоненты библиотеки

JxCalendar, JxChip

Ожидались JxCalendar, JxChip · покрытие 100%

Контекст

Доки (llms-full.txt, ~22548) · Правила (jinx-ui, ~1083)

Вход 2 · выход 1 270 · из кэша 8 233 · в кэш 40 819 · 14 с

Рендер

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

tsx93 строки
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
import { useCallback, useState } from 'react';
import { JxCalendar, JxChip } from '@jinx-ui/react';

interface ReportDatePickerProps {
  value?: Date | null;
  defaultValue?: Date | null;
  onChange?: (value: Date | null) => void;
  locale?: string;
}

const startOfDay = (date: Date): Date =>
  new Date(date.getFullYear(), date.getMonth(), date.getDate());

const shiftDays = (days: number): Date => {
  const base = startOfDay(new Date());
  base.setDate(base.getDate() + days);
  return base;
};

const presets: Array<{ id: string; label: string; offset: number }> = [
  { id: 'today', label: 'Сегодня', offset: 0 },
  { id: 'yesterday', label: 'Вчера', offset: -1 },
  { id: 'week-ago', label: 'Неделя назад', offset: -7 },
];

const isSameDay = (a: Date | null, b: Date | null): boolean =>
  a != null && b != null && startOfDay(a).getTime() === startOfDay(b).getTime();

export default function ReportDatePicker({
  value,
  defaultValue = null,
  onChange,
  locale = 'ru-RU',
}: ReportDatePickerProps) {
  const [internal, setInternal] = useState<Date | null>(defaultValue);
  const selected = value !== undefined ? value : internal;

  const select = useCallback(
    (next: Date | null) => {
      if (value === undefined) setInternal(next);
      onChange?.(next);
    },
    [onChange, value],
  );

  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
      <div
        role="group"
        aria-label="Быстрый выбор даты отчёта"
        style={{ display: 'flex', flexWrap: 'wrap', gap: 8 }}
      >
        {presets.map((preset) => {
          const presetDate = shiftDays(preset.offset);
          const active = isSameDay(selected, presetDate);
          return (
            <JxChip
              key={preset.id}
              role="button"
              tabIndex={0}
              aria-pressed={active}
              active={active}
              onClick={() => select(shiftDays(preset.offset))}
              onKeyDown={(event) => {
                if (event.key === 'Enter' || event.key === ' ') {
                  event.preventDefault();
                  select(shiftDays(preset.offset));
                }
              }}
            >
              {preset.label}
            </JxChip>
          );
        })}
      </div>

      <JxCalendar locale={locale} value={selected} onValueChange={select} />

      <p
        aria-live="polite"
        style={{ margin: 0, color: 'var(--jx-text-2)', fontFamily: 'var(--jx-font-sans)' }}
      >
        {selected
          ? `Дата отчёта: ${selected.toLocaleDateString(locale, {
              day: 'numeric',
              month: 'long',
              year: 'numeric',
            })}`
          : 'Дата не выбрана — нажмите вариант выше или день в календаре.'}
      </p>
    </div>
  );
}