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

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

date-range__readme__claude-code__claude-opus-5__1 · 23.09.2026, 20:09:16 мск

Проверки пройдены
README · claude-opus-5 · Claude Code
Контекст до задачи~798
Токенов на прогон11 774
Цена$0.068
Ошибок компилятора0

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

Компилятор

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

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

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

JxButton, JxCalendar

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

Контекст

README (README.md, ~644)

Вход 2 · выход 2 242 · из кэша 8 233 · в кэш 1 297 · 23 с

Рендер

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

tsx89 строк
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
import { useMemo, useState } from 'react';
import { JxButton, JxCalendar } from '@jinx-ui/react';

type ReportDatePickerProps = {
  value?: Date;
  defaultValue?: Date;
  onChange?: (date: Date) => void;
};

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

const addDays = (date: Date, amount: number) => {
  const result = startOfDay(date);
  result.setDate(result.getDate() + amount);
  return result;
};

const isSameDay = (a: Date, b: Date) => startOfDay(a).getTime() === startOfDay(b).getTime();

export default function ReportDatePicker({
  value,
  defaultValue,
  onChange,
}: ReportDatePickerProps) {
  const [internalValue, setInternalValue] = useState<Date>(() =>
    startOfDay(defaultValue ?? new Date()),
  );

  const selected = value ? startOfDay(value) : internalValue;

  const presets = useMemo(() => {
    const today = startOfDay(new Date());
    return [
      { id: 'today', label: 'Сегодня', date: today },
      { id: 'yesterday', label: 'Вчера', date: addDays(today, -1) },
      { id: 'week-ago', label: 'Неделя назад', date: addDays(today, -7) },
    ];
  }, []);

  const select = (next: Date) => {
    const day = startOfDay(next);
    if (value === undefined) {
      setInternalValue(day);
    }
    onChange?.(day);
  };

  return (
    <div
      style={{
        display: 'flex',
        flexDirection: 'column',
        gap: 'var(--jx-space-3)',
      }}
    >
      <div
        role="group"
        aria-label="Быстрый выбор даты отчёта"
        style={{ display: 'flex', flexWrap: 'wrap', gap: 'var(--jx-space-2)' }}
      >
        {presets.map((preset) => {
          const active = isSameDay(selected, preset.date);
          return (
            <JxButton
              key={preset.id}
              size="sm"
              variant={active ? 'primary' : 'secondary'}
              aria-pressed={active}
              onClick={() => select(preset.date)}
            >
              {preset.label}
            </JxButton>
          );
        })}
      </div>

      <JxCalendar
        aria-label="Дата отчёта"
        value={selected}
        onValueChange={(next: Date | null) => {
          if (next) {
            select(next);
          }
        }}
      />
    </div>
  );
}