Стек: 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
Карточка товара
interface IProduct{
id: string;
description: string;
image: string;
title: string;
category: string;
price: number | null;
}
Данные карточки, используемые в корзине
type TProductInfo = Pick<IProduct, 'title' | 'price'>;
Интерфейс приложения
export interface IAppState {
catalog: IProduct[];
basket: IProduct[];
preview: string | null;
order: IOrder | null;
}
Интерфейс для работы с первой формой оформления заказа (выбор способа оплаты и ввод адреса)
export interface IOrderForm {
payment: string;
address: string;
}
Ошибки первой формы оформления заказа
export type OrderFormErrors = Partial<Record<keyof IOrderForm, string>>;
Интерфейс для работы со второй формой оформления заказа (для контактной информации)
export interface IContactsForm {
email: string;
phone: string;
}
Ошибки второй формы оформления заказа
export type ContactsFormErrors = Partial<Record<keyof IContactsForm, string>>;
Интерфейс для отправки данных на сервер
export type IOrder = IOrderForm & IContactsForm & {items: string[], total: number};
Интерфейс данных с сервера об успешном заказе
export interface IOrderResult {
id: string[];
total: number;
}
Ошибки в формах при оформлении заказа
export type FormErrors = ContactsFormErrors & OrderFormErrors;
Код приложения разделен на слои согласно парадигме MVP:
- слой представления, отвечает за отображение данных на странице,
- слой данных, отвечает за хранение и изменение данных
- презентер, отвечает за связь представления и данных.
Содержит в себе базовую логику отправки запросов. В конструктор передается базовый адрес сервера и опциональный объект с заголовками запросов. Методы:
get- выполняет GET запрос на переданный в параметрах ендпоинт и возвращает промис с объектом, которым ответил серверpost- принимает объект с данными, которые будут переданы в JSON в теле запроса, и отправляет эти данные на ендпоинт переданный как параметр при вызове метода. По умолчанию выполняетсяPOSTзапрос, но метод запроса может быть переопределен заданием третьего параметра при вызове.
Брокер событий позволяет отправлять события и подписываться на события, происходящие в системе. Класс используется в презентере для обработки событий и в слоях приложения для генерации событий.
Основные методы, реализуемые классом описаны интерфейсом IEvents:
on- подписка на событиеemit- инициализация событияtrigger- возвращает функцию, при вызове которой инициализируется требуемое в параметрах событие
Принимает в конструктор экземпляр класса Api и предоставляет методы реализующие взаимодействие с бэкендом сервиса.
- getProductList - вывести карточки на страницу
- getProductItem - показать карточку в модальном окне
- orderProducts - получить заказ
Класс отвечает за хранение и логику работы с карточками товаров.
Конструктор класса принимает инстант брокера событий\
В полях класса хранятся следующие данные:
- catalog: IProduct[] - массив объектов карточек с товарами
- order: IOrder - заказ для отправки на сервер
- events: IEvents - экземпляр класса
EventEmitterдля инициации событий при изменении данных. - preview: string | null - индификатор выбравнной карточки для просмотра подробной информации о ней.
- formErrors: FormErrors - массив ошибок форм при оформлении заказа.
- setCatalog(items: IProduct[]) - метод сохранения массива объектов карточек с товарами.
- getItem(id: string): IProduct - метод получения массива объектов карточек с товарами.
- setPreview(item: IProduct) - метод сохранения выбранной карточки для детального просмотра.
- addItem(item: IProduct) - метод добавления карточки в корзину.
- removeItem(item: string) - метод удаления карточки из корзины.
- getTotal() - метод получения общей стоимости карточек в корзине.
- getBasket(): string[] - метод получения карточки из корзины.
- setOrderField(field: keyof IOrderForm, value: string) - метод сохранения данных с 1-ой формы заказа.
- validateOrder() - метод проверки введённых данных в первую форму.
- setContactsField(field: keyof IContactsForm, value: string) - метод сохранения данных с формы с контакной информацией.
- validateContacts() - метод проверки введённых данных в форму контактов.
- isItemInBasket(id:string):boolean - проверка наличия карточки в корзине.
- clearBasket() - метод отчистки корзины.
Класс с базовой моделью, чтобы можно было отличить от простых объектов с данными.\
- events: IEvents - экземпляр класса
EventEmitterдля инициации событий при изменении данных.
Так же класс имеет общий метод для взаимодействия с данными моделей.
- emitChanges - метод сообщения об изменении
Класс с базовым компонентом.\
Методы класса описывают инструментарий для работы с DOM в дочерних компонентах.
- toggleClass(element: HTMLElement, className: string, force?: boolean) - метод переключения класса.
- setText(element: HTMLElement, value: unknown) - метод установки текстового содержимого. setDisabled(element: HTMLElement, state: boolean) - метод смены статуса блокировки.
- setHidden(element: HTMLElement) - метод сокрытия элемента.
- setVisible(element: HTMLElement) - метод показа элемента.содержимого.
- setImage(element: HTMLImageElement, src: string, alt?: string) - метод установки изображения с алтернативным текстом.
- render(data?: Partial): HTMLElement - метод возврата корневого DOM-элемента.
Все классы представления отвечают за отображение внутри контейнера (DOM-элемент) передаваемых в них данных.
Реализует модальное окно. Так же предоставляет методы open и close для управления отображением модального окна.Устанавливает слушатели на клавиатуру, для закрытия модального окна по клику на оверлей и кнопку-крестик для закрытия попапа. Метод render позволяет обновить отображение модального окна.
- constructor(container: HTMLElement, protected events: IEvents) Конструктор принимает элемент, по которому в разметке страницы будет идентифицировано модальное окно и экземпляр класса
EventEmitterдля возможности инициации событий.
Поля класса
- content: HTMLElement - элемент модального окна
- closeButton - кнопка закрытия модального окна
- events: IEvents - брокер событий
Предназначен для реализации модального окна, сообщающего об успешном оформлении заказа.
Поля класса:
- close: HTMLElement - Кнопка подтверждения
- actions: ISuccessActions - функция, на выполнение которой запрашивается подтверждение
Интерфейс функции:
interface ISuccessActions {
onClick: () => void;
}
Интерфейс модального окна подтверждения с общей суммой заказа
interface ISuccess {
total: number;
}
Расширяет класс Form. Предназначен для реализации модального окна с формой содержащей поля ввода способа оплаты. При сабмите инициирует событие передавая в него объект с данными из полей ввода формы. При изменении данных в полях ввода инициирует событие изменения данных. Предоставляет методы управления активностью кнопки сохранения.\
Поля класса:
- cardBtn: HTMLButtonElement - кнопка выбора оплаты "Онлайн".
- cashBtn: HTMLButtonElement - кнопка выбора оплаты "При получении".
Методы:
- set address(value: string) - сеттер сохранения введённого адреса.
- set payment(value: string) - сеттер выбранного пользователем способа оплаты.
Расширяет класс Form. Предназначен для реализации модального окна с формой содержащей поля ввода контактной информации. При сабмите инициирует событие передавая в него объект с данными из полей ввода формы. При изменении данных в полях ввода инициирует событие изменения данных. Предоставляет методы управления активностью кнопки сохранения.\
Поля класса:
- formErrors: HTMLSpanElement - элемент строки, для вывода ошибок валидации.
- orderButton: HTMLButtonElement - кнопка завершения оформления заказа.
Методы:
- set email(value: string) - сеттер записи в объект заказа электронной почты.
- set phone(value: string) - сеттер для сохранения номера телефона пользователя.
Базовый класс, который отвечает за отображение информации продукта, задавая в карточке продукта различные варианты представления информации, например, данные названия, изображения, категории, описания, стоимости, наличия в корзине. Класс используется для отображения продуктов на странице сайта. В конструктор класса передается контейнер в который вложена карточка, что позволяет при необходимости формировать карточки разных вариантов верстки. В классе устанавливаются слушатели на все интерактивные элементы, в результате взаимодействия с которыми пользователя генерируются соответствующие события.
Поля класса содержат элементы разметки элементов карточки. Конструктор, кроме контейнера принимает функцию для инициации событий.\
Интерфейс функции для иницации событий с карточкой:
interface IProductCard {
onClick: (event: MouseEvent) => void;
}
Интерфейс базовой карточки:
export interface ICard<T> {
title: string;
price: number;
category?: string;
description?: string;
image?: string;
}
Методы:
- set id(value: string) - сеттер сохранения id товара
- get id(): string - геттер возвращает уникальный id карточки
- set title(value: string) - сеттер сохранения названия товара
- get title(): string - метод возвращения названия карточки
- set price(value: number | null) - сеттер для показа цены карточки
- setColor(category: string) - метод для установки цвета элемента с категорией товара.
Расширяет базовый класс Card и отвечает за отображение карточки на главной странице. Имеет сеттеры для показа категории и для показа картинки товара.
Расширяет класс Card. Предназначен для реализации отображения товара с описанием. При открытии модального окна получает данные описания, которое нужно показать.\
Поля класса:
- categoryElement: HTMLElement - элемент разметки для вывода категории продукта
- descriptionElement: HTMLElement - элемент разметки для вывода описания продукта
- imageElement: HTMLImageElement - элемент разметки с изображением
И методы:
- inBasket() - метод изменения состояния кнопки добавления карточки в корзину
- buyNot() - метод блокировки кнопки добавления бесценной карточки в корзину
- а также сеттеры для изображения, описания и категории карточки.
Класс Cardявляется базовым для этого класса. Созданный класс нужен для реализации отображения товара в корзине.\
Интерфейс карточки в корзине:
export interface IProductBasket {
сount: number;
status: boolean;
}
Поля класса:
- count: HTMLElement - элемент для отображения номера товара в корзине
И методы:
- set count(value: number) - сеттер для отображения номера карточки.
Отвечает за представление корзины, содержит кнопку для перехода к оформлению заказа и отображение суммы всех стоимостей товаров в корзине. Принимает в конструктор контейнер - элемент разметки блока корзины и экземпляр EventEmitter для инициации событий при нажатии пользователем на кнопки. Устанавливает в конструкторе слушатели на все кнопки, при срабатывании которых генерируются соответствующие события.
В полях класса содержатся ссылки на все элементы разметки блока.
Интерфейс отображения корзины:
interface IBasketView {
items: HTMLElement[];
total: number;
selected: boolean;
}
Поля класса:
- list: HTMLElement - элемент-контейнер для отображения списка товаров
- total: HTMLElement - элемент для вывода общей стоимости корзины
- button: HTMLButtonElement - элемент для кнопки перехода к оформлению заказа.
Методы:
- set total(total: number) - устанавливает данные суммы цен всех товаров в корзине
- set items - метод для обновления разметки карточки в корзине.
Класс для представления главной страницы сайта, содержит кнопку для перехода к корзине пользователя, счётчик товаров в корзине, каталог товаров. В конструктор данного класса передаётся контейнер - элемент разметки блока страницы сайта и экземпляр EventEmitter для инициации событий при нажатии пользователем на кнопки. Устанавливает в конструкторе слушатели на все кнопки, при срабатывании которых генерируются соответствующие события.
В полях класса содержатся ссылки на все элементы разметки блока.
Интерфейс отображения главной страницы:
interface IPage {
counter: number;
catalog: HTMLElement[];
locked: boolean;
}
Поля класса:
- counter: HTMLElement - элемент-счётчик для отображения количества товаров в корзине
- catalog: HTMLElement -элемент-контейнер для списка товаров
- wrapper: HTMLElement -элемент-контейнер для скрываемой части сайта
- basket: HTMLButtonElement - элемент для кнопки открытия корзины.
Методы:
- set counter(total: number) - устанавливает данные о количестве товаров в корзине
- set catalog(items: HTMLElement[]) - устанавливает карточки в контейнер каталога
- set locked(value: boolean) - метод для проверки блокировки страницы.
Принимает в конструктор экземпляр класса Api и предоставляет методы реализующие взаимодействие с бэкендом сервиса.
Код, описывающий взаимодействие представления и данных между собой находится в файле index.ts, выполняющем роль презентера.
Взаимодействие осуществляется за счет событий генерируемых с помощью брокера событий и обработчиков этих событий, описанных в index.ts
В index.ts сначала создаются экземпляры всех необходимых классов, а затем настраивается обработка событий.
Список всех событий, которые могут генерироваться в системе:\
items:changed- изменение массива товаровcard:select- выбор карточки для открытия в модельном окнеpreview:changed- изменение в открытом модбном окне карточки с описаниемbasket:open- открытие корзиныbasket:changed- изменение состояния корзиныbasket:delete- изменение количества товаров в корзине (удаление товара)order:open- открытие модального окна с первой формой заказаformErrors:change- изменение валидности полей формыorder:change- изменение состояния полей 1-ой формы заказаorder-part:change- изменение данных в форме с данными о способе оплаты пользователя/^order\..*:change/- изменение одного из полей 1-ой формыorder:submit- сохранение данных первой формы и переход к следующей формеformContactsErrors:change- изменение состояния валидации формы с контактной информациейcontacts-part:change- изменение данных в форме с данными электронной почты пользователя/^contacts\..*:change/- изменение одного из полей формы с контактной информациейcontacts:submit- сохранение данных 2-ой формы заказа и переход к подтверждению успешного завершения оформления заказаmodal:open- открытие модального окнаmodal:close- закрытие модального окна.