Стек: HTML, SCSS, TS, Webpack
Структура проекта:
- src/ — исходные файлы проекта
- src/components/ — папка с JS компонентами
- src/components/base/ — папка с базовым кодом
Важные файлы:
- src/pages/index.html — HTML-файл главной страницы
- src/types/index.ts — файл с типами
- src/index.ts — точка входа приложения
- src/scss/styles.scss — корневой файл стилей
- src/utils/constants.ts — файл с константами
- src/utils/utils.ts — файл с утилитами
Для установки и запуска проекта необходимо выполнить команды
npm install
npm run start
или
yarn
yarn start
npm run build
или
yarn build
Приложение основано на паттерне проектирования MVP (Model-View-Presenter).
В рамках этой архитектуры:
- Модель (Model) отвечает за хранение данных.
- Представление (View) отображает данные и реагирует на события пользователя.
- Презентер (Presenter) обрабатывает пользовательские события, запрашивает данные из API и обновляет модель.
1. Слой модели:
1.1. BasketModel
Хранит состояние корзины.
Поля:
-
basket: BasketItemUI[] - массив товаров в корзине.
-
total: string - общая стоимость корзины в форматированной строке "1000 синапсов".
-
formatter: Formatter - объект для форматирования данных.
Методы:
-
getBasket(): BasketItemUI[] - возвращает текущее состояние корзины.
Задача: управление локальным состоянием корзины. -
addItemToBasket(product: BasketItemUI): void — добавляет товар в локальную корзину.
Задача: обновить состояние корзины на клиенте. -
removeItemFromBasket(id: string): void; - удаляет товар из корзины.
Задача: обновить состояние корзины на клиенте. -
getTotalPrice(): string - возвращает общую стоимость корзины в форматированном виде.
Задача: рассчитать и отобразить стоимость всех товаров.
1.2. OrderModel
Хранит данные формы заказа.
Поля:
- formatter: Formatter - объект для форматирования статусов и цен.
- orderData: UserAPI | null — данные пользователя, оформляющего заказ.
Методы:
setOrderData(user: UserAPI): void Задача: сохраняет данные формы заказа.
validateOrder(): string[] — проверяет корректность данных заказа.
Задача: убедиться, что данные корректны перед оформлением заказа.
createOrder(basket: BasketItemUI[]): OrderUI | null Задача: сформировать объект заказа, используя данные корзины..
1.3. ProductModel
Поля:
- products: ProductUI[] — массив товаров.
- apiClient: ApiClient - объект для взаимодействия с API.
Методы:
-
setProducts(products: ProductUI[]): void Задача: сохранить список товаров.
-
getProductById(id: string): ProductUI | undefined - получает данные конкретного товара.
Задача: получать данные конкретного товара по ID.
2. Слой представления:
2.1. BasketView
Поля:
- container: HTMLElement - DOM-элемент, где отображается корзина.
Методы:
-
renderBasket(items: BasketItemUI[], total: string): void - отображает список товаров и общую стоимость.
Задача: отрисовать корзину на основе переданных данных. -
showEmptyBasketMessage(): void Задача: информировать пользователя о том, что корзина пуста.
2.2. OrderView Поля:
- formContainer: HTMLElement - DOM-элемент, где отображается форма заказа.
Методы:
-
renderOrderForm(): void
Задача: отображает форму. -
showFormErrors(errors: string[]): void
Задача: отображает ошибки валидации формы.
2.3. ProductView
Поля:
- galleryContainer: HTMLElement - DOM-элемент для списка товаров.
- detailsContainer: HTMLElement - DOM-элемент для деталей товара.
Методы:
- renderProductList(products: ProductUI[]): void - отображает список товаров. Задача: отрисовать каталог товаров.
- renderProductDetails(product: ProductUI): void - отображает подробную информацию о товаре. Задача: показать информацию выбранного товара.
2.4 SuccessMessageView
Методы:
render(message: string): void
Задача: отображает сообщение об успешной оплате.
3. Слой презентера:
3.1 BasketPresenter Обрабатывает корзину.
Поля:
- model: BasketModel
- view: BasketView
- apiClient: ApiClient
Методы:
- init(): void — загружает данные корзины.
- handleAddToBasket(product: BasketItemUI): void — добавляет товар.
- handleRemoveFromBasket(productId: string): void — удаляет товар.
3.2 OrderPresenter
Обрабатывает заказ.
Поля:
- model: OrderModel
- view: OrderView
- apiClient: ApiClient
Методы:
- handleSubmit(data: Partial): void олучает данные из OrderModel и BasketModel, затем передает их в apiClient.sendOrder(orderData)
3.3 ProductPresenter Обрабатывает каталог.
Поля:
- model: ProductModel
- view: ProductView
- apiClient: ApiClient
Методы:
- init(): void — загружает каталог.
- handleSelectProduct(id: string): void — отображает детали товара.
-
product:addToBasket
Описание: Пользователь добавляет товар в корзину. Обработчик: BasketPresenter.handleAddToBasket(product) -
basket:removeItem
Описание: Пользователь удаляет товар из корзины. Обработчик: BasketPresenter.handleRemoveFromBasket(productId) -
order:submitted
Описание: Пользователь отправляет заказ. Обработчик: OrderPresenter.handleSubmit(data)
В рамках архитектуры приложения некоторые сущности имеют модель данных и представления, другим же достаточно только представления.
- Класс EventEmitter
Модель данных: управляет состоянием зарегистрированных событий и их обработчиков - регистрация слушателей событий (on), удаление слушателей (off), генерация событий (emit).
Представление: фактически отсутствует, но опосредованно участвует через управление событиями между различными частями приложения.
interface EventEmitter {
on(event: string, listener: (...args: any[]) => void): void;
off(event: string, listener: (...args: any[]) => void): void;
emit(event: string, ...args: any[]): void;
}- Класс Modal
Модель данных: состояние модального окна (открыто/закрыто), текущий контент.
Представление: отвечает за отображение модального окна и динамическое наполнение контента.
interface Modal {
open(content: HTMLElement): void;
close(): void;
setTitle(title: string): void;
}- Класс Card
Модель данных: данные о товаре (название, цена, категория, изображение).
interface Card {
renderCard(product: ProductUI): HTMLElement;
}Представление: создание и обновление отображения карточек для каталога, корзины и модальных окон.
- Класс Basket
Модель данных: содержимое корзины (список товаров, их количество, общая стоимость).
Представление: отображает содержимое корзины, кнопки удаления и оформление заказа.
interface BasketModel {
getBasket(): BasketItemUI[];
addItemToBasket(productId: string): Promise<void>;
removeItemFromBasket(productId: string): Promise<void>;
getTotalPrice(): string;
}- Класс OrderForm
Модель данных: состояние формы (введённые данные, ошибки валидации, текущий этап).
Представление: управляет отображением полей, ошибок и переходами между этапами оформления.
interface OrderModel {
getOrder(user: UserAPI, basket: BasketItemUI[]): OrderUI;
}-
Компонент Header
Представление: отображает логотип и счётчик товаров в корзине.
Связь с моделью: получает данные о количестве товаров из модели Basket. -
Компонент Gallery
Представление: отображает карточки товаров.
Связь с моделью: получает данные о товарах из класса Card. -
Компонент SuccessMessage
Представление: отображает сообщение об успешном оформлении заказа.
Связь с моделью: использует данные об итогах заказа из модели OrderForm.
Шаблоны предоставляют структуру для динамически генерируемого контента. Используются для создания карточек (card-catalog, card-basket), корзины (basket), форм заказа (order, contacts), а также сообщений о завершении (success). Шаблоны наполняются данными через соответствующие классы и вставляются в DOM. Они динамически наполняются данными из соответствующих моделей (Card, Basket, OrderForm) через представление.