- ✅ React: обязательно, другие библиотеки и фреймворки не принимаем
- ✅ Стили: допускается Tailwind, CSS Modules, SASS/SCSS или чистый CSS. Самостоятельно написанные стили оцениваются выше, чем использование готовых utility-фреймворков
- ✅ TypeScript: желательно, но не обязательно
- ✅ Стейт-менеджеры: опционально, если будете использовать, разрешается к использованию только zustand
- ✅ Сборка: webpack, rspack, vite
- ❌ Библиотеки компонентов (antd, MaterialUI, shadcnui и т.д.)
Разработать компонент выбора города с поддержкой мобильной и десктопной версии с адаптивными стилями (макет). На странице располагается кнопка "Выбрать город" и название текущего выбранного города рядом с ней. По нажатию открывается модальное окно с иерархическим выбором: Федеральный округ → Область (регион) → Город.
Тестовые данные для отображения находятся в файле geo.json (см. вхождение с "name": "Россия"). Необходимо реализовать имитацию запроса к серверу, ответом которого будут данные из этого файла.
Cookie cityId — хранит id выбранного города. Наличие или отсутствие этой cookie определяет состояние компонента: отображается ли название города на странице, и в каком состоянии открывается модальное окно. При завершении выбора (клик по терминальному узлу) cookie обновляется, модальное окно закрывается, на странице отрисовывается название выбранного города.
Структура данных (файл geo.json):
GeoNode {
"id": number,
"name": string,
"type": "country" | "federal_district" | "region" | "city",
"count"?: number,
"children"?: GeoNode[]
}Терминальный узел — узел, у которого отсутствует поле children или массив children пуст. Такой узел является конечной опцией для выбора: клик по нему в любой колонке завершает процесс. Терминальный узел может встретиться не только среди городов — например, регион без дочерних городов тоже будет терминальным, и его можно выбрать напрямую из колонки регионов.
Если город не выбран, вместо названия выводится текст "Город не выбран". Если выбран — отображается название соответствующего города. По нажатию на кнопку "Выбрать город" открывается модальное окно.
Модальное окно содержит до трёх колонок, каждая из которых отображает узлы определённого уровня дерева. Колонки раскрываются последовательно слева направо: выбор элемента в текущей колонке открывает следующую колонку с его children. Если элемент является терминальным узлом — выбор завершается.
После выбора элемента в колонке, где уже был сделан выбор, выбор во всех колонках правее сбрасывается. Повторный клик на уже выбранный элемент не меняет состояние.
Если город уже выбран при открытии модального окна, происходит автоматический выбор с подсветкой — все родительские колонки раскрыты и соответствующие элементы выделены.
Отображает узлы с "type": "federal_district". Это первая видимая колонка при открытии модального окна. При выборе элемента в соседней колонке справа отрисовываются GeoNode из его поля children (регионы).
Отображает узлы с "type": "region" — дочерние элементы выбранного федерального округа. При выборе элемента в соседней колонке справа отрисовываются GeoNode из его поля children (города).
Отображает узлы с "type": "city" — дочерние элементы выбранного региона. Все города в этой колонке являются терминальными узлами, поэтому выбор любого из них завершает процесс.
Особенности этой колонки:
- Топ-3 города. В верхней части колонки отображаются 3 города с наибольшим значением поля
count(количество объявлений). Эти кнопки кликабельны и работают так же, как остальные элементы колонки. - Алфавитная сортировка. Элементы колонки отсортированы по алфавиту.
- Группировка по первой букве. У первого города на каждую букву алфавита слева от названия (внутри кнопки) выводится эта буква. У последующих городов с той же первой буквой буква не отрисовывается.
- Выделение жирным. Города, у которых значение
countпревышает30000, отображаются жирным шрифтом.
В модальном окне есть текстовое поле "Название города", которое является фильтром по колонке с городами. Фильтрация производится по вхождению подстроки, регистронезависимая. Фильтрация затрагивает только колонку с городами — остальные колонки отображают родительские узлы найденных городов.
На мобильных устройствах вместо одновременного отображения всех колонок выводится только текущая активная колонка. Навигация между колонками осуществляется посредством кнопки "Назад" на экране и при нажатии на нетерминальный узел (переход к следующей колонке).
Если ты чувствуешь в себе силы и у тебя осталось время, то в качестве дополнительного задания можно добавить какой-то дополнительный функционал, например:
- в тестовых данных есть колонка со Страной
country. Можно вывести её (макет), но т.к. ширина модального окна строго ограничена для desktop, придется придумать механизм для переключения между колонкой Страны и Федерального округа - для мобильной версии можно реализовать навигацию назад по колонкам через нативный механизм браузера (жест "Назад") — с помощью сторонних библиотек или встроенных средств. Для колонки, где не отрисована кнопка "Назад", жест должен закрывать модальное окно
- для колонки Региона можно добавить отображение строчного топа городов (макет): города отсортированы по полю
count, рядом с названием города выведено это значение. При нажатии на город в таком режиме происходит его выбор, а при выборе региона — открывается стандартная колонка с городами - написать тесты
- собрать проект в Docker
Или придумать что-то своё, инициатива приветствуется, но не забывай, что это доп.задание, и к нему следует приступать, когда основной функционал реализован, а у тебя ещё осталось время и силы.