Repository navigation
Feature Tour Gallery
Статус: сделано. Эпик: UX/UI аудит сайта. Документация: Фронтенд, Картинки. Задача: #247. PR: #258. Разбор: комментарий 6269657275.
Гость на странице тура видит основное фото и ленту миниатюр: все доступные кадры показаны, выбранный кадр отмечен рамкой без сдвига сетки, недоступный файл даёт аккуратную заглушку, подпись на основном фото не обрезается по краю значимой части.
Простой пример: тур с четырьмя изображениями (счётчик «1 / 4»). Все четыре миниатюры загружены; клик по второй меняет основное фото и переносит рамку выбора, соседние миниатюры не смещаются.
- Сценарии: все миниатюры загружены; ошибка загрузки одного файла (заглушка вместо значка битой картинки); выбор миниатюры на ширинах 390, 768 и 1280 px; подпись на основном фото читаема.
- Входит: вёрстка
TourGalleryи обработка ошибки вResponsiveTourImageна публичной странице тура. - Не входит: изменение API Media, загрузка новых файлов, кабинет менеджера как отдельный экран (публичные адреса медиа уже отдают 200 webp).
- Критерии приёмки (из #247 и комментария «Дальше»):
- на туре с 4 фото все 4 миниатюры отображаются;
- недоступный файл даёт заглушку, а не значок битой картинки;
- выбранная миниатюра не смещает ленту на 390, 768 и 1280 px;
- лента имеет отступ под кольцо выбора либо кольцо рисуется
outline/ring-inset; - блок основного фото в пропорции 16:9 или с
object-contain, без сильной обрезки краёв 16:9 исходников.
- Модель данных: без изменений. Изображения тура уже приходят из Catalog; адреса строит фронтенд (
/api/v1/media/files/{id}/w200|w800|w1600). - API: без новых эндпоинтов. На проверке публичные
w200/w800/w1600отвечали 200image/webp. - Контракты между сервисами: не затрагиваются.
- Интерфейс:
-
TourGallery: основное фото в блокеaspect-[16/9]сobject-contain; лента миниатюрflex gap-2 overflow-x-auto p-1; выбранная миниатюра сring-2 ring-offset-2— отступ ленты не даёт кольцу обрезаться. -
ResponsiveTourImage: приonErrorвместо<img>песочная заглушка (bg-sand); то же на карточках каталога и в избранном. - Высота варианта
galleryвmedia.ts: 1600×900 (9/16). СкелетTourDetailPageсовпадает с кадром 16:9.
-
- Ключевые файлы:
TourGallery.tsx,ResponsiveTourImage.tsx,src/utils/media.ts. - Влияние на существующий код: только фронтенд галереи на
TourDetailPage; бэкенд и Media не меняются.
Воспроизведение (комментарий 6269657275):
- воспроизведено: обрезка кольца выбранной миниатюры лентой; обрезка основного фото (
aspect-[16/10]+object-coverна 16:9); - не воспроизведено на той проверке: пустые миниатюры 2–4 (URL отдавали 200 webp); заглушка при ошибке всё равно нужна, потому что
onErrorотсутствует.
| Вопрос | Варианты | Выбрано | Почему | Дата |
|---|---|---|---|---|
| Рамка выбранной миниатюры | оставить ring без отступа; padding ленты под кольцо; outline / ring-inset
|
padding ленты p-1 под кольцо |
ring-offset выходит за кнопку и обрезается overflow ленты |
2026-10-23 |
| Ошибка загрузки картинки | оставить браузерный значок; заглушка через onError
|
заглушка при ошибке в ResponsiveTourImage
|
при сбое Media нет запасного UI | 2026-10-19 |
| Пропорции основного фото |
aspect-[16/10] + object-cover; aspect 16:9; object-contain
|
16:9 и object-contain
|
исходники 16:9; 16/10 с object-cover резал края и подпись |
2026-10-23 |
| Битые миниатюры 2–4 как отдельный баг Media | чинить Media; только фронт | фронт (заглушка); Media на проверке отдавал 200 | симптом на проверке не подтверждён, защита на клиенте всё равно нужна | 2026-10-19 |
| Подзадача | Раздел страницы | Задача | Статус |
|---|---|---|---|
| Исправление галереи: кольцо, заглушка, пропорции основного фото | Архитектура, Тест-кейсы | #247 / #258 | сделано |
Одной задачи #247 достаточно: баг-фикс уже оформлен как одна подзадача.
| № | Предусловие | Шаги | Ожидаемый результат | Уровень |
|---|---|---|---|---|
| ТК-1 | тур с 4 фото, ширина 1280 | открыть страницу тура | все 4 миниатюры видны, изображения загружены | вручную на dev / e2e |
| ТК-2 | то же, ширина 768 | открыть страницу, прокрутить ленту при необходимости | 4 миниатюры доступны, лента ровная | вручную на dev |
| ТК-3 | то же, ширина 390 | открыть страницу | 4 миниатюры доступны (при необходимости горизонтальный скролл ленты), сетка без сдвигов | вручную на dev |
| ТК-4 | первая миниатюра выбрана; 390 / 768 / 1280 | осмотреть рамку выбора | кольцо полностью видно, соседние миниатюры не смещены | вручную на dev |
| ТК-5 | вторая миниатюра | клик по второй | основное фото сменилось, рамка на второй, лента не прыгает | вручную на dev / unit |
| ТК-6 | подмена ответа картинки на ошибку (или битый URL) | загрузить страницу / сменить кадр | заглушка вместо значка битой картинки | unit / вручную |
| ТК-7 | исходник основного фото 16:9 с подписью у края | открыть основное фото | подпись не обрезана критично; блок 16:9 или object-contain
|
вручную на dev |
| ТК-8 | счётчик «1 / 4» | переключить все кадры | счётчик и основное фото согласованы с выбранной миниатюрой | вручную на dev |
Тесты: tourImages.test.tsx, TourDetailPage.test.tsx, media.test.ts.
Система
API
Сервисы
Как реализовано
Справочное
- Эпик: модель туров под импорт
- Эпик: подключение туроператоров
- Эпик: полный цикл бронирования
- Эпик: мелкие доработки и заметки
- Эпик: профили и настройки
- Эпик: UX/UI аудит сайта
- Эпик: отзывы клиентов
- Эпик: визуальный редизайн
- Эпик: ИИ-агенты на сайте
- Фича: почему выбирают нас
- Фича: витрина туров на главной
- Фича: раздел администрирования
- Фича: карточки собеседника в чате
- Фича: профиль клиента
- Фича: поиск и календарь на главной
- Фича: профиль менеджера
- Фича: аккаунт и сервер профиля
- Фича: видимость полей группами
- Фича: явные неготовые элементы
- Фича: галерея на странице тура
- Фича: единые поля дат
- Шаблон эпика
- Шаблон фичи