-
Currency Converter / Конвертер валют (React, Redux Toolkit, Axios, i18n, MUI)
-
Hotel Booking / Бронирование отеля (React, Formik + Yup, SCSS)
-
SmartTV App / Приложение для SmartTV (React, TypeScript, SCSS)
-
Игра в города / Cities Word Chain (React, TypeScript, Tailwind):
Все команды запускаются из корня проекта:
# Шаг 1 — Клонируем репозиторий
$ https://github.com/M4XPRD/Test-Tasks
# Шаг 2 — Устанавливаем зависимости нужного проекта
$ make install-02
$ make install-05
# Шаг 3 — Запускаем нужный проект
$ make start-02
$ make start-05
# Если у вас yarn, то перед командой пишем "y"
$ make y-install-03
$ make y-start-05
# Открываем папку с проектом в IDE:
# 1. Переходим в корневую папку React-приложения
$ cd *folder name*
# 2. Устанавливаем зависимости
$ npm install
# 3. Запуск
$ npm run start
Если у вас VSCode и в конвертере валют TypeScript выдаёт ошибку Parsing error: Cannot read file '.../tsconfig.json'.eslint
, то нужно сделать следующее:
- Создать в общем корне всех проектов папку
.vscode
- Добавить в папку
.vscode
файлsettings.json
- В файл добавить следующий код:
{
"eslint.workingDirectories": [
{
"mode": "auto"
}
]
}
На сайте UniPage есть подборка интересных языковых курсов. У каждого курса есть цена, которая является диапазоном.
Например:
- от 100 до 200 рублей;
- от 500 рублей;
- до 400 рублей.
Пользователю сайта нужно найти подходящие ему курсы. Для этого есть фильтр, где пользователь может задать подходящий ему диапазон цен.
Опишите, как можно отфильтровать список курсов, чтобы выдались только подходящие по цене? Реализуйте на JavaScript (или TypeScript) функцию, проводящую такую фильтрацию.
// Список курсов
let courses = [
{ name: "Courses in England", prices: [0, 100] },
{ name: "Courses in Germany", prices: [500, null] },
{ name: "Courses in Italy", prices: [100, 200] },
{ name: "Courses in Russia", prices: [null, 400] },
{ name: "Courses in China", prices: [50, 250] },
{ name: "Courses in USA", prices: [200, null] },
{ name: "Courses in Kazakhstan", prices: [56, 324] },
{ name: "Courses in France", prices: [null, null] },
];
// Варианты цен (фильтры), которые ищет пользователь
let requiredRange1 = [null, 200];
let requiredRange2 = [100, 350];
let requiredRange3 = [200, null];
// [подходящие курсы для каждого варианта фильтра]
Дополнительно, вы также можете реализовать алгоритм сортировки курсов по цене.
Выполненная задача находится в файле filterCources.js
.
Фильтр можно сделать:
- По цене в радиусе, например
[200, 350]
или[null, 200]
- По минимальной и максимальной цене (дополнительное задание)
2. Simple Page / Простая страничка (React Router/Redux)
• /
- главная страница
• /profile
– страница профиля
На главной странице нужно ввести логин и пароль: login – developer21, password – 123456. Если введены логин/пароль верно, то можно нажать на кнопку «Войти» (если нет, то она должна быть отключена, то есть disabled)
После нажатия на кнопку «Войти», должно пользователя перенаправить на страницу профиля, где в теге h1 должен быть отображен логин.
Для хранения / отображения логина, нужно использовать Redux, для маршрутизации - React-Router.
Проект тестового задания необходимо выложить в публичный репозиторий GitHub.
Актуальный деплой здесь.
- Решил модифицировать и чуть усложнить задачу, поэтому есть 3 страницы:
/
- главная,/login
и страница с ошибкой404
- На странице
/login
при нажатии на Get your login here! можно увидеть секретный логин для входа. Сделано для большей интерактивности - Добавлена полноценная realtime-валидация формы с помощью
Formik
- Все страницы переключаются без перезагрузки и работают через
React-Router
- Всё состояние работает через
Redux-Toolkit
- Настроен
ESLint
по стандарту Airbnb - Добавлены
focus
для каждогоinput
- Уделил внимание CSS-оформлению и адаптивности на разных устройствах
3. Currency Converter / Конвертер валют (React, Redux Toolkit, Axios, i18n)
Напишите SPA для конвертирования валют. Для получения текущих курсов найдите и используйте любое отрытое API.
Приложение должно состоять из двух страниц:
-
Конвертер из одной валюты в другую. На этой странице должно быть текстовое поле, в которое можно ввести текст в виде
15 USD in RUB
и получить результат. -
Страница с текущими курсами валют. На этой странице пользователь должен видеть «свежие» курсы валют относительно базовой валюты — например, если базовая валюта — рубль, то пользователь видит, что 1 USD = 63.49 RUB, а 1 EUR = 72.20. По-умолчанию у пользователя должна определяться базовая валюта, которую он может настроить.
- Хорошо продуманный интерфейс и внешний вид
- Тесты
- Максимальная скорость работы приложения (как при загрузке приложения, так и при конвертировании валют)
- Для реализации используйте любые библиотеки, которые считаете уместными
Актуальный деплой здесь.
- Всё написано на
TypeScript
- Есть 3 страницы:
/
- главная страница с конвертером,/currencies
- страница со всеми доступными курсами валют и страница с404
- На главной странице конвертер успешно переводит любую доступную валюту из списка
- На странице
/currencies
можно выбрать базовую валюту и посмотреть список курсов по этой валюте - Особое внимание уделил дизайну, интерфейсу и адаптивности для всех доступных в
Chrome DevTools
устройствах - Настроен
ESLint
по стандарту Airbnb - Доступ к API по валютам сделан через
Axios
- В качестве CSS-фреймворка выбран
MUI
- Дополнительно настроил анимации загрузки и ошибки
- Всё состояние организовано через
Redux-Toolkit
, а переключения языков черезReact-Context
- Страницы переключаются через
React-Router
- Добавлена библиотека
i18next
для организации текстов - Добавлен английский язык и кнопка переключения с
EN
наRU
- Добавлено несколько простых тестов
4. Todo App / Список дел (React, TypeScript, SCSS, BEM)
Сделайте Todo-приложение, позволяющее управлять текущим списком дел.
- Поле для ввода новой задачи
- Списки всех задач, невыполненных и выполненных задач (по отдельности)
Пример внешнего вида приложения:
Требования к коду:
- Приложение создано с использованием TypeScript, React и React Hooks
- Ключевая на ваш взгляд функциональность обязательно покрыта тестами
- Проект должен запускаться командой npm i && npm run start
- Проект доступен на GitHub Pages/Vercel/etc.
- Библиотеки на ваше усмотрение
Актуальный деплой здесь.
- Для наименования классов использовал методологию БЭМ
- CSS написан с помощью SCSS
- Приложение адаптировано под мобильные телефоны, планшеты и ПК
- Всё написано на TypeScript
- Добавлены тесты для каждого компонента, протестирована общая функциональность и рендер
5. Hotel Booking / Бронирование отеля (React, Formik + Yup, SCSS)
Форма состоит из двух шагов. На первом шаге рассчитывается стоимость проживания, на втором заполняются ĸонтаĸты для связи.
Переход ĸо следующему шагу возможен тольĸо при ĸорреĸтном заполнении теĸущего.
– Количество взрослых (числовое, мин. значение: 1)
– Количество детей от 5 до 12 лет (числовое)
– Количество детей до 5 лет (числовое). На одного взрослого допустимо не более 3 детей из этой ĸатегории
– Тип номера (Эĸоном/Стандарт/Люĸс)
– Количество ночей (числовое, мин. значение: 1)
– Страховĸа (вĸл/выĸл)
– Фамилия (теĸстовое, обязательное)
– Имя (теĸстовое, обязательное)
– Отчество (теĸстовое)
– Номер телефона (теĸстовое, обязательное, форма телефона +7XXXXXXXX-XX)
– Дата рождения (дата, обязательное)
На третьем шаге выводится информация о подтверждении заĸаза и ĸнопĸа оплаты.
По нажатию ĸнопĸи оплаты нужно сымитировать отправĸу данных на сервер (формат JSON, в ответ достаточно любого сообщения по таймауту) и вывести эĸран об успешной оплате заĸаза с ĸнопĸой перехода ĸ новому заĸазу (ведет ĸ шагу 1 с пустой формой).
Стоимость заĸаза зависит от ĸоличества гостей разных возрастов, типа номера и ĸоличества ночей:
– Стоимость ночи в номере «Эĸоном»: 1800 рублей
– Стоимость ночи в номере «Стандарт»: 2800 рублей
– Стоимость ночи в номере «Люĸс»: 4000 рублей
– Детям 5-12 лет предоставляется сĸидĸа в размере 50% от взрослой стоимости
– Детям до 5 лет проживание предоставляется бесплатно
– Страховĸа добавляет 10% ĸ общей стоимости заĸаза
Стоимость заĸаза должна пересчитываться сразу при изменении связанных с ней значений.
При наличии в форме ошибоĸ, переход ĸ следующему шагу должен быть заблоĸирован, поĸа ошибĸи не будут исправлены.
Пользователю должен быть предоставлен вывод ошибоĸ в понятном виде.
Будет учитываться аĸĸуратность верстĸи и адаптив, умение работать с состоянием и реаĸтивностью, а таĸ же базовый подход ĸ архитеĸтуре. Пиĸтограммы элементов ввода можно выбрать на усмотрение ĸандидата или оставить нативные.
Селеĸты и дейтпиĸер можно оставить нативные.
Можно использовать сторонние библиотеĸи UI-ĸомпонентов, CSS- фреймворĸи и препроцессоры.
При размерах эĸрана >640px форма остается в ĸонтейнере шириной 640px по центру эĸрана.
Одним из способов:
– Проект, который можно скачать и запустить
– Либо развёрнутый в гитхабе/гитлабе проект
Актуальный деплой Vercel прямо здесь.
- Всё написано на React с использованием Formik + Yup
- Весь HTML/CSS написан без сторонних UI-библиотек
- В проекте сделан упор на масштабируемость и расширяемость, всё разделено на маленькие модули
- При событии
onSubmit
срабатывает имитация отправки данных на сервер с помощьюfetch
- Добавлена анимация искуственного ожидания отправки данных, чтобы всё выглядело реалистичнее
- Проект полностью адаптирован под мобильные телефоны и любые разрешения экранов
6. SmartTV App / Приложение для SmartTV (React, TypeScript, SCSS)
Необходимо создать упрощенную демо-версию микросайта для SmartTV. Посмотреть пример работы механики можно здесь.
Ссылка на макет.
Микросайт состоит из серии экранов:
- Промо-видео с баннером (верстать не обязательно).
- Экран ввода номера (с экранной клавиатурой).
- Финальный инфо-экран.
Необходимо реализовать вёрстку экранов микросайта, а также навигацию и механизм ввода номера при помощи экранной клавиатуры.
Кнопка «Подтвердить номер» должна становиться доступной для выбора (enabled) только при полностью введенном номере и согласии с обработкой ПД.
Валидацию номера проводить не нужно, достаточно проверять, что номер введен полностью.
Неинтерактивные статичные элементы (включая текст) разрешается не верстать, а использовать как часть (фоновой) картинки.
Для первого экрана добавить видео (отрывок около минуты длиной, к примеру отсюда и баннер, появляющийся через 5 секунд от начала проигрывания ролика.
Навигация должна осуществляться также и с клавиатуры:
- Стрелки для навигации между кнопками (включая кнопки “закрыть”, “подтвердить”);
- Цифры и Backspace для быстрого ввода номера;
- Enter для выбора кнопки;
- Используйте React (использование TypeScript будет плюсом).
- Если сочтете нужным, можете использовать сторонние библиотеки.
- Разрешение микросайта фиксированное, 1280х720.
На выходе ожидается:
- Ссылка на Github/Gitlab с осмысленной историей коммитов.
- Ссылка на развернутую версию микросайта.
- Переход из экрана с видео и баннером должен паузить видео. Переход обратно должен продолжать воспроизведение.
- Добавить валидацию номера при помощи открытого сервиса.
- На экране с микросайтом добавьте таймер закрытия по бездействию. Если пользователь ничего не делает 10 секунд, то интерактив закрывается и происходит переход на промо-видео с баннером.
Актуальный деплой Vercel прямо здесь.
- Всё написано на React + TypeScript
- Главная особенность проекта — навигация по панели ввода номера телефона и активное использование хуков
- Все дополнительные задания выполнены: переход с паузой, валидация и таймер закрытия
7. Игра в города / Cities Word Chain (React + TypeScript, Tailwind CSS)
Необходимо разработать "легкую" версию онлайн-игры в "Города".
В качестве аппонента, мы предлагаем тебе написать функцию (искуственный интеллект, если можно так это назвать), которая будет брать города из заготовленного списка (список городов прилагается в репозитории). Главное не забудь учитывать правила игры – города не могут повторяться.
Для имитации живого игрока нужно написать функцию так, чтобы ответ от нее приходил с задержкой.
В репозитории есть макет Figma, в котором ты можешь найти финальный дизайн для игры. Обрати внимание на отступы, выравнивания по центру, на размерности.
В первой вкладке расположен макет, во второй tailwindcss конфигурация (она соответсвует конфигурации по умолчанию).
Все размеры в макете подходят под размеры tailwind-классов. Например: максимальная ширина окна - 576px, соответствует классу max-w-xl.
Для работы над текстом в первом слайде рекомендую использовать класс .prose
из tailwind плагина Typography.
Так же необходимо реализовать таймер обратного отсчета, по умолчанию на 2 минуты. Если игрок или функция "ИИ" не успеет дать нужный ответ, мы можем определить победителя и проигравшего.
Для более качественной работы необходимо добавить валидацию вводимых городов на существование (1), по первой букве (2) и на повторение (3). (для упрощения проверяй существование города по имеющимуся списку городов)
- React 18 (можно с Next, можно без)
- Tailwind
- Использование Typescript в проекте будет жирным плюсом
Роутинг делать не обязательно, если тебе будет достаточно работы в одном родительском компоненте.
Pixel Perfect оценивать не будем, но жирным плюсом будет, если классы из tailwind будут верно подобраны и подходить под размеры макета.
Решение должно быть выложено в публичном репозитории на github, чтобы можно было его проверить.
В остальном требований к проекту нет, можно использовать любые вспомогательные библиотеки на твой вкус (такие как day.js для работы с датой и тд). Будет плюсом, если ты умеешь обходится без "готовых React компонентов".
Деплой приложения.
- Приложение построено в стеке
React
+TypeScript
- Для хранения состояния использован
React Context
- Весь CSS написан с помощью
Tailwind
- Игра адаптирована для любых разрешений экрана
- Игра имеет сложную логику обработки городов и бота, который реагирует на ответ пользователя с интервалом от 3 до 7 секунд, имитируя человека
- Победить можно двумя путями: достичь момента, когда города на определённую букву закончатся или победить по времени. В случае с ботом проиграть можно только первым путём
- После окончания игры бот прекращает свою работу и при начале новой игры все данные обнуляются
8. Исторические даты / Historical Dates (React + TypeScript, Styled-Components, GSAP, Swiper)
Исторические даты — это SPA, в котором можно посмотреть на памятные даты различных событий в 6 категориях, происходившие за последние 16 лет.
Реализовать следующий блок в соответствии с макетом.
Блок содержит информацию о временных отрезках, в каждом из которых существует несколько событий.
При переключении временных отрезков изменяются соответствующие числа и под ними показывается новый слайдер, который содержит подробную информацию по ключевым событиям на активном временном отрезке.
Возможно существование от 2 до 6 временных отрезков. Все интерактивные точки на окружности располагаются на одинаковом расстоянии друг от друга.
Все существующие в макете линии — это не разметочная сетка, а часть верстки.
- Необходимо использовать
Typescript
- Можно использовать
React.js
или нативныйJS
на Ваш выбор - В случае использования нативного JS, можно воспользоваться любым удобным для Вас
HTML-шаблонизатором
или обычным HTML - Стилизация с использованием
SASS/SCSS
(В случае работы сReact.js
, возможно использованиеstyled-components
) - Для работы со слайдерами необходимо использовать библиотеку
Swiper
- Для реализации JS-анимаций можно использовать библиотеку
GSAP
- Не использовать
JQuery
- Не использовать
Bootstrap
,Tailwind
и т.п. - Не использовать библиотеки с готовыми UI-компонентами такие, как
MaterialUI
,AntDesign
и т.п.
Деплой приложения.
- Приложение построено в стеке
React
+TypeScript
- Для хранения состояния использован
React Context
- Визуал получится на чистом CSS с использованеим
styled-components
- Приложение полностью адаптировано под большинство устройст, включая Galaxy Fold
- Для слайдера использована библиотека
Swiper
- Для анимаций переключения категорий дат использован
GSAP