Небольшое учебное приложение «Книжный магазин» на React + Redux Toolkit. Данные каталога и корзины сохраняются в LocalStorage.
- React (Vite)
- Redux Toolkit + react-redux
- Vitest (тесты)
- ESLint
npm i
npm run devОткройте адрес, который выведет Vite (обычно http://localhost:5173).
npm run dev # запуск в режиме разработки
npm run build # сборка
npm run preview # предпросмотр сборки
npm run lint # eslint
npm run test # vitest (watch)
npm run test:run # vitest (single run)
npm run test:ui # vitest UIКнига в каталоге содержит поля:
title: stringauthor: stringisbn: string— уникальный идентификаторprice: numberflagOutOfStock: boolean— снята с продажи / недоступна
isbn: stringquantity: number
Каталог хранится в LocalStorage.
- При старте приложения:
- если в LocalStorage есть данные — каталог загружается из хранилища;
- если хранилище пустое — используется стартовый набор (seed) из 10 книг, затем он сохраняется в LocalStorage.
Операции каталога:
- Добавить книгу в каталог (с валидацией).
- Снять книгу с продажи / вернуть книгу в продажу (
flagOutOfStock). - Обновить цену книги.
Валидации при добавлении/обновлении:
title,author,isbn,priceне пустые.title,author,isbn— строки.isbnуникальный.isbnдолжен содержать 10–12 символов.price— число (пример:99.99).
Корзина нужна для формирования заказа из книг, которые:
- существуют в каталоге,
- доступны к продаже (
flagOutOfStock !== true).
Операции корзины:
- Добавить книгу в корзину:
- минимальное количество —
1; - если книга уже есть в корзине — увеличиваем количество.
- Удалить книгу из корзины.
- Уменьшить количество:
- если стало
0— позиция удаляется.
- Увеличить количество до
99. - Очистить корзину.
Агрегаты (итоги корзины):
- totalUniqueIsbn — количество уникальных ISBN
- totalQty — общее количество экземпляров
- totalPrice — суммарная стоимость
Пользователь может оформить заказ из корзины.
Правило валидности позиции для заказа:
- книга должна быть найдена в каталоге (ISBN существует),
- книга должна быть доступна к продаже (
flagOutOfStock !== true).
Поведение при оформлении:
- если все позиции валидны — заказ создаётся (на текущем этапе можно сохранять в LocalStorage / store).
- если есть невалидные позиции (книги нет или она outOfStock) — такие позиции исключаются из заказа и показывается уведомление.
- если после исключения валидных позиций не осталось — заказ не создаётся, показывается ошибка.
После успешного оформления заказа корзина очищается.
Ключи хранения описаны в src/constants/storageKeys.js:
bookshop.catalog.v1— каталогbookshop.cart.v1— корзина
src/entities/*— доменные сущности и чистые функции (без Redux и UI)src/features/*— логика фич (slice, thunks, selectors, persistence)src/ui/*— компоненты UIsrc/store/store.js— конфигурация Redux store