Тестовое задание на React. Так же буду использовать: Next.js App Router TypeScript SCSS Modules TanStack Query Zustand
- Next.js 14 (App Router) + React 18
- TypeScript (strict)
- TanStack Query v5 — загрузка и кэширование данных
- Zustand — глобальное состояние корзины + персист в
localStorage(ключshop.cart) - SCSS Modules — стили
- ESLint (
next/core-web-vitals)
npm install # установить зависимости
npm run dev # дев-сервер (http://localhost:3000)
npm run build # прод-сборка + проверка типов и линта
npm start # запуск прод-сборкиsrc/
app/ # страницы: /, /cart, /product/[id], layout, Providers
components/<name>/ # компонент в папке: index.tsx + index.module.scss
store/cartStore.ts # Zustand-стор корзины
services/api.ts # псевдо-API с задержкой 250 мс
services/productUtils.ts, promoCodes.ts
types.ts # доменные типы (Product, Size, CartItem, ...)
- Данные: каталог и карточка товара через
useQuery(['products'],['categories'],['product', id],['sizes'], зависимый['category', id]). Лоадинг/эрроры — из квери, без ручных стейтов. - Карточка товара: URL — единственный источник истины (параметры
color/sizeчерезuseSearchParams+router.replace). Выбор не хранится в стейте; недоступные размеры блокируются, галерея сбрасывается при смене цвета (key). - Корзина: Zustand. Элемент уникален по
productId::colorId::sizeId, количество минимум 1, итоги — селекторselectTotals. Персист пишет плоский массив вshop.cart(совместим со старым форматом). Гидрируется после монтирования (без SSR-рассинхрона). - Промокоды:
SALE10(−10%),FIXED100(−100 ₽) вsrc/services/promoCodes.ts.
Чек-лист по ТЗ: Нужно сделать 3 страницы: ✅ Список товаров; Детальная страница товара; Корзина;
Список товаров (начальная страница) ✅ Показать товары с картинкой, названием и ценой (остальное по желанию). По клику на товар - переход на карточку товара. Реализовать поиск, фильтры, сортировку: поиск по названию (строка) фильтр "в наличии" - у товара есть хотя бы один цвет с хотя бы одним доступным размером. сортировка по цене asc/decs - цену товара брать как минимальную из его цветов.
Карточка товара (детальная страница) ✅ Вывести информацию о товаре. Просмотр изображений через переключение без использования сторонних библиотек. Реализовать выбор цвета. Реализовать выбор размера: показывать список всех размеров как отдельные кнопки. недоступные размеры для выбранного цвета должны быть заблокированными. Добавление в корзину можно сделать по кнопке в количестве одной штуки за раз. Если товара нет - показать экран "Товар не найден" + ссылка назад.
Корзина ✅ Кнопка перехода в корзину должна быть на каждой странице. Вывод суммы количества добавленных товаров и их стоимости в кнопку перехода на страницу корзины. Корзина хранит уникальные позиции в связке продукт + цвет + размер. Корзина должна сохраняться в localStorage и восстанавливаться при перезагрузке страницы. Для каждой позиции поддерживается количество: при добавлении уже существующей позиции увеличиваем количество на 1. в корзине можно менять количество (минимум 1) и удалять позицию. На странице показывать: список добавленных позиций: изображение, название товара, выбранный цвет, выбранный размер, цена, количество, сумму стоимости позиции. общую сумму всех позиций.
UX ✅ Не должно быть runtime‑ошибок в обычных сценариях и особенно при старте проекта. Проверяйте, пожалуйста, перед отправкой своей работы. При переходах/действиях пользователь должен видеть адекватные состояния (загрузка/ошибка/пусто и т.п.).
Состояние в URL ✅ Сохранять выбранный color и size на детальной странице в url и восстанавливать состояние при открытии ссылки.
Промокод ✅ Поле применения промокода - в корзине пересчитывается стоимость товаров с отображением скидки. Формат промокода и формат скидки (процентная/фиксированная) - произвольные.
Если тестовые реально проверяются, спасибо что прочитал код. Вроде бы сделал все необходимое
Мои контакты: тел. +79922178123 ТГ: @Korrtek