Skip to content

Feature Home Search Calendar

TravelAgency Team Bot edited this page Oct 23, 2026 · 2 revisions

Фича: единая строка поиска и календарь диапазона на главной

Статус: сделано. Эпик: UX/UI аудит сайта. Документация: Фронтенд. Задача: #248. PR: #257. Критерии: комментарий к #248.

Бизнес и сценарии

Гость на главной видит одинаковые поля «Куда?» и «Когда?», выбирает место из подсказок направлений и диапазон дат в календаре в цветах сайта, нажимает «Найти» и попадает в каталог с уже знакомыми параметрами адреса. Пустой поиск открывает страницу «Туры» без query. Набор ключей каталога и поведение фильтров на странице каталога не меняются.

Простой пример: в «Куда?» выбрано «Бали», в календаре отмечено 1 ноября 2026, нажато «Найти». Адрес становится /tours?direction=dir-bali&dateFrom=2026-11-01. Диапазон 12-20 ноября 2026 добавляет dateTo=2026-11-20. Повтор того же дня пишет равные dateFrom и dateTo.

  • Сценарии: пустые поля → /tours; только место → direction или country; только даты → dateFrom/dateTo; место и один день → dateFrom без dateTo; место и диапазон → обе границы; незнакомый текст места уходит в country; ошибка загрузки направлений оставляет свободный ввод.
  • Входит: единая вёрстка полей на главной, подсказки из GET /catalog/directions, календарь диапазона, правила query для главной, тесты vitest.
  • Не входит: форма операторского поиска из #138, замена нативных «С» и «По» на странице каталога, отдельный справочник городов, параметр «± N дней».
  • Критерии приёмки: полный список в комментарии к #248 (поля и кнопка, «Куда?», «Когда?», отправка, клавиатура и доступность, телефон, что не меняется, тесты).

Архитектура

  • Модель данных: без изменений. Направления уже отдаёт Catalog (DirectionDto: Id, Name, Country, Description). Фильтр туров уже принимает DateFrom и DateTo (включительно).
  • API: используется существующий GET /catalog/directions. Новых эндпоинтов нет. Адрес каталога с главной: direction, country, dateFrom, dateTo по правилам ниже; priceMin, priceMax, category, sort главная не задаёт.
  • Контракты между сервисами: не затрагиваются.
  • Интерфейс: SearchBar на главной (HeroSection). Поля одной высоты: подпись 12px, значение 16px Inter, цвет значения dark. До 768px колонка и нижняя панель для подсказок и календаря, с 768px ряд и два месяца. «Когда?» не <input type="date">, а кнопка с диалогом DateRangeCalendar в цветах sand, cream, primary, dark. Прошедшие дни относительно календарной даты Europe/Moscow на главной недоступны; сегодня доступен; верхняя граница 2100-12-31. Текст даты: 12 ноя, с 12 по 20 ноя, с 28 окт по 3 ноя, с 28 дек 2026 по 3 янв 2027 (месяцы из фиксированного списка без точки).
  • Правила query (resolveHomeSearch / catalogPath в catalogQuery.ts):
    • один выбранный день: только dateFrom (yyyy-MM-dd);
    • диапазон или повтор того же дня: dateFrom и dateTo;
    • пустые поля: /tours без query;
    • сопоставление места: normalizePlace / matchPlace (точное имя → direction, точная страна или свободный текст → country, оба ключа сразу не ставятся).
  • Ключевые файлы: SearchBar.tsx, DateRangeCalendar.tsx, homeCalendar.ts, catalogQuery.ts (resolveHomeSearch), HeroSection.tsx. Пакет date-fns уже в зависимостях, новый календарный пакет не добавляется.
  • Влияние на существующий код: страница каталога по-прежнему читает dateFrom/dateTo и показывает нативные «С»/«По»; карточки направлений и остальные секции главной без изменений вёрстки.

Решения

Вопрос Варианты Выбрано Почему Дата
Выбор даты на главной нативный input type="date"; свой календарь одного дня; календарь диапазона календарь диапазона API уже фильтрует обе включительные границы; один день сохраняет прежнее поведение (только dateFrom) 2026-10-19
Источник подсказок «Куда?» отдельный справочник городов; только GET /catalog/directions только направления (name и country) отдельного справочника нет; Description в список не выводится 2026-10-19
Подпись даты маска dd.mm.yyyy; d MMM из date-fns; фиксированный список коротких месяцев фиксированный список янв фев мар апр мая июн июл авг сен окт ноя дек d MMM с локалью ru даёт «нояб.» и «окт.»; год только если годы границ разные; дефиса и тире нет 2026-10-19
Календарь на фильтре каталога подключить сразу; отложить отложить (#138 на удержании) в этом изменении только строка главной; тот же компонент можно взять позже 2026-10-19
«Сегодня» и прошедшие дни локальная полночь машины; Europe/Moscow календарная дата Europe/Moscow иначе граница суток зависит от пояса CI и браузера; правило только для главной 2026-10-19

Разбиение

Подзадача Раздел страницы Задача Статус
Единая строка поиска, подсказки, календарь диапазона, query и тесты Архитектура, Тест-кейсы #248 / #257 сделано
Календарь на фильтрах каталога вне скоупа #138 (удержание) не в этой фиче
Форма операторского поиска вне скоупа #138 не в этой фиче

Тест-кейсы

№ Предусловие Шаги Ожидаемый результат Уровень
ТК-1 главная, направления загружены пустые «Куда?» и «Когда?», «Найти» переход на /tours без query unit
ТК-2 точное имя направления «Бали» место «Бали», день 2026-11-01, «Найти» /tours?direction=dir-bali&dateFrom=2026-11-01 unit
ТК-3 выбран начало диапазона дни 12 и 20 ноября 2026 в адресе dateFrom=2026-11-12 и dateTo=2026-11-20 unit
ТК-4 выбран один день дважды повтор 1 ноября 2026 dateFrom и dateTo равны 2026-11-01 unit
ТК-5 в поле места есть текст «Очистить» текст сброшен, список закрыт, переход не выполняется; direction/country не пишутся unit
ТК-6 подсказки открыты ввод с ё/е, разным регистром, крайними пробелами совпадения находятся; не больше 8 строк; пустой результат: «Ничего не найдено» unit
ТК-7 календарь открыт, сегодня по Москве клик по вчерашнему дню день недоступен и не выбирается; сегодня доступен unit
ТК-8 календарь или подсказки открыты Enter на выделенной строке/дне; Esc значение выбирается без отправки формы; Esc закрывает и возвращает фокус в поле unit
ТК-9 форматы подписи один день; тот же месяц; разные месяцы; разные годы 12 ноя; с 12 по 20 ноя; с 28 окт по 3 ноя; с 28 дек 2026 по 3 янв 2027 unit
ТК-10 страница каталога адреса с dateFrom/dateTo, перевёрнутый диапазон чипы и нативные «С»/«По» как раньше; перевёрнутый диапазон не запускает загрузку unit (без смены смысла)

Тесты: HomePage.test.tsx, SearchBar.test.tsx, catalogQuery.test.ts. TourCatalogPage.test.tsx по смыслу не меняется.

Главная

Действующая документация

Система

API

Сервисы

Как реализовано

Справочное

Фичи

Планы

Clone this wiki locally