Skip to content

Repository files navigation

Магазин (мини-каталог товаров)

Тестовое задание на 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

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages