Skip to content

Lchii/web-larek-frontend

Repository files navigation

Проектная работа "Веб-ларек"

Стек: 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

Данные и типы данных, используемые в приложении

Товар

export interface IProduct {
  id: string;
  description: string;
  image: string;
  title: string;
  category: string;
  price: number | null;
}

Данные для оформления заказа

export interface IOrder {
  payment: string;
  email: string;
  phone: string;
  address: string;
  total: number;
  items: string[];
}

Данные, хранящиеся в модели

export interface IModel {
	catalog: IProduct[];
	preview: string | null;
	basket: Map<string, number>;
	order: IOrder;
}

Данные карточки, отображающейся в корзине

export type TBasketCard = Pick<IProduct, 'id' | 'title' | 'price'>

Данные для заказа, приходящие от пользователя

export type TOrderData = Pick<IOrder, 'payment' | 'address' | 'email' | 'phone'>;

Сообщения об ошибках в формах

export type FormErrors = Partial<Record<keyof IOrder, string>>;

Данные, возвращаемые сервером после успешного оформления заказа

export interface IOrderResult {
	id: string;
	total: number;
}

Архитектура приложения

Код приложения разделен на слои согласно парадигме MVP:

  • слой данных (Model), отвечает за хранение и изменение данных
  • слой представления (View), отвечает за отображение данных на странице
  • презентер (Presenter), отвечает за связь представления и данных.

Базовый код

Класс Api

Содержит в себе базовую логику отправки запросов. В конструктор передается базовый адрес сервера и опциональный объект с заголовками запросов.

  • constructor(baseUrl: string, options: RequestInit = {})

Методы:

  • get - выполняет GET запрос на переданный в параметрах ендпоинт и возвращает промис с объектом, которым ответил сервер
  • post - принимает объект с данными, которые будут переданы в JSON в теле запроса, и отправляет эти данные на ендпоинт, переданный как параметр при вызове метода. По умолчанию выполняется POST запрос, но метод запроса может быть переопределен заданием третьего параметра при вызове.

Класс EventEmitter

Брокер событий позволяет отправлять события и подписываться на события, происходящие в системе. Класс используется в презентере для обработки событий и в слоях приложения для генерации событий. Конструктор не принимает никаких параметров.

Основные методы, реализуемые классом, описаны интерфейсом IEvents:

  • on - подписка на событие
  • emit - инициализация события
  • trigger - возвращает функцию, при вызове которой инициализируется требуемое в параметрах событие

Абстрактный класс Model

Базовая модель, которая позволяет установить исходные данные в класс и отличить ее от простых объектов с данными.
Конструктор принимает объект, в котором все свойства заданного типа являются необязательными, и инстант брокера событий.

  • constructor(data: Partial, protected events: IEvents)

Методы:

  • emitChanges(event: string, payload?: object) - сообщает всем, что модель изменилась

Класс Component

Базовый компонент, который позволяет работать с DOM-элементами.
Конструктор принимает контейнер с разметкой.

  • constructor(protected readonly container: HTMLElement)

Методы:

  • toggleClass(element: HTMLElement, className: string, force?: boolean) - переключает класс
  • setDisabled(element: HTMLElement, state: boolean) - меняет статус блокировки
  • render(data?: Partial): HTMLElement - возвращает корневой DOM-элементами

Слой данных

Класс AppState

Класс наследуется от Model c типом IModel, отвечает за хранение и логику работы с данными приложения.\

В полях класса хранятся следующие данные:

  • catalog: IProduct[] - массив объектов карточек
  • preview: string - id карточки, выбранной для просмотра в модальном окне
  • basket: Map<string, number> - словарь с товарами, добавленными в корзину, где ключом является id товара, а значением - цена
  • order: IOrder - объект, содержащий данные, необходимые для оформления заказа
  • orderFormErrors: FormErrors - ошибки, возникающие в форме заказа
  • contactsFormErrors: FormErrors - ошибки, возникающие в форме контактов

Так же класс предоставляет набор методов для взаимодействия с этими данными:

  • setCatalog(items: IProduct[]): void - устанавливает набор карточек в каталог
  • setPreview(item: Product): void - устанавливает id текущей выбранной карточки
  • toggleProductState(id: string, price: number | null): void - переключает состояние товара в корзине
  • isProductInBasket(id: string): boolean - проверяет, есть ли товар в корзине
  • getBasketCounter(): number - возвращает количество товаров в корзине
  • getBasketItems(): TBasketCard[] - возвращает состав корзины
  • getTotal(): number - возвращает итоговую сумму корзины
  • clearBasket(): void - очищает корзину
  • setOrderItems(): void - переносит товары из корзины в заказ
  • setOrderTotal(): void - переносит в заказ итоговую сумму
  • setOrderField(field: keyof TOrderData, value: string): void - устанавливает значение полей в заказ
  • validateOrder(): boolean - валидирует форму заказа
  • validateContacts(): boolean - валидирует форму контактов

Класс Product

Класс наследуется от Model с типом IProduct, отвечает за хранения данных товара.
В полях класса хранятся следующие данные:

  • id: string - идентификатор товара
  • description: string - описание товара
  • image: string - изображение товара
  • title: string - название товара
  • category: string - категория товара
  • price: number | null - цена товара

Класс Order

Класс наследуется от Model с типом IOrder, отвечает за хранения данных заказа.
В полях класса хранятся следующие данные:

  • payment: 'card' | 'cash' - способ оплаты (онлайн или при получении)
  • email: string - адрес электронной почты
  • phone: string - номер телефона
  • address: string - адрес доставки
  • total: number - итоговая сумма заказа
  • items: string[] - состав заказа (выбранные товары)

Слой представления

Все классы представления отвечают за отображение внутри контейнера (DOM-элемент) передаваемых в них данных.

Класс Page

Класс наследуется от Component с типом IPage и реализует страницу сайта. Конструктор принимает контейнер модального окна и экземпляр класса EventEmitter для возможности инициации событий.

  • constructor(container: HTMLElement, protected events: IEvents)

Поля класса:

  • counter: HTMLElement - счетчик товаров в корзине
  • catalog: HTMLElement - каталог
  • wrapper: HTMLElement - обертка страницы
  • basket: HTMLElement - корзина

Методы:

  • сеттеры для полей класса

Класс Modal

Класс наследуется от Component с типом IModalData и реализует модальное окно. Предоставляет методы open и close для управления отображением модального окна, а также метод render для отрисовки окна. Устанавливает слушатели на клик в оверлей и кнопку-крестик для закрытия попапа. Конструктор принимает контейнер модального окна и экземпляр класса EventEmitter для возможности инициации событий.

  • constructor(container: HTMLElement, protected events: IEvents)

Поля класса:

  • closeButton: HTMLButtonElement - кнопка закрытия
  • content: HTMLElement - область с контентом модального окна

Класс Form

Класс наследуется от Component с типом IFormState и реализует элемент формы. Предоставляет метод onInputChange, имитирующий события при изменении полей формы, метод render для установки значений и получения контейнера, а также сеттеры полей класса. Конструктор принимает контейнер с разметкой формы и экземпляр класса EventEmitter для возможности инициации событий.

  • constructor(protected container: HTMLFormElement, protected events: IEvents)

Поля класса:

  • submit: HTMLButtonElement - кнопка отправки формы
  • errors: HTMLElement - ошибки валидации полей формы

Класс Basket

Класс наследуется от Component с типом IBasketView и реализует корзину. Предоставляет сеттеры для полей items и total и геттер для поля button. Конструктор принимает контейнер с разметкой корзины и экземпляр класса EventEmitter.

  • constructor(container: HTMLElement, protected events: EventEmitter)

Поля класса:

  • list: HTMLElement - список товаров
  • total: HTMLElement - итоговая сумма
  • button: HTMLButtonElement - кнопка оформления

Класс Success

Класс наследуется от Component с типом ISuccess и реализует окно с сообщением об успешном оформлении заказа. Устанавливает слушатель на кнопку внутри окна, при нажатии на которую можно продолжить покупки. Предоставляет сеттер для поля total. Конструктор принимает контейнер в разметкой окна и функцию-обработчик для кнопки.

  • constructor(container: HTMLElement, actions: ISuccessActions)

Поля класса:

  • close: HTMLElement - кнопка закрытия
  • total: HTMLElement - итоговая сумма покупок

Класс Card

Класс наследуется от Component с типом IProduct Отвечает за отображение карточки, задавая в карточке данные названия, цены товара, которые присутсвуют во всех представлениях карточек. Класс используется как базовый для более специализированных отображений. В конструктор класса передается DOM элемент темплейта, что позволяет при необходимости формировать карточки разных вариантов верстки. В классе устанавливаются слушатель на кнопку добавления товара в корзину или на клик по контейнеру, если кнопки в представлении нет.
Поля класса содержат элементы разметки элементов карточки. Конструктор, кроме темплейта принимает экземпляр EventEmitter для инициации событий и имя блока.\

  • constructor(blockName: string, container: HTMLElement, actions?: ICardActions)

Методы:

  • геттеры и сеттеры для полей класса

Класс CatalogItem

Класс наследуется от Card и отвечает за отображение карточки в каталоге, задавая также категорию и изображение. В конструктор передается контейнер с разметкой и функция-обработчик.

  • constructor(container: HTMLElement, actions?: ICardActions)

Методы:

  • геттеры и сеттеры для полей класса

Класс PreviewItem

Расширяет класс CatalogItem, добавляя поле с описанием товара, которое используется в отображении превью карточки.

Класс BasketItem

Класс наследуется от Card и отвечает за отображение карточки в корзине. В конструктор передается контейнер с разметкой и функция-обработчик.

  • constructor(container: HTMLElement, actions?: ICardActions)

Методы:

  • геттер для поля index

Класс Order

Класс наследуется от Form с типом IOrder Отвечает за блок сайта с информацией о заказе, содержит поля для хранения данных о заказе. Принимает в конструктор контейнер с разметкой, экземпляр EventEmitter и функцию-обработчик.

  • constructor(container: HTMLFormElement, events: IEvents, actions?: IOrderActions)

Поля класса:

  • card: HTMLButtonElement - кнопка для выбора оплаты онлайн
  • cash: HTMLButtonElement - кнопка для выбора оплаты при получении

Методы:

  • switchPayment(): void - переключает состояние кнопок для выбора способа оплаты
  • геттеры и сеттеры для полей класса

Класс Contacts

Класс наследуется от Form с типом IOrder Содержит поля для хранения контактов клиента. Принимает в конструктор контейнер с разметкой формы и экземпляр EventEmitter.

  • constructor(container: HTMLFormElement, events: IEvents)

Методы:

  • сеттеры для полей класса

Слой коммуникации

Класс AppApi

Расширяет класс Api и реализует интерфейс IAppApi и предоставляет методы реализующие взаимодействие с бэкендом сервиса.
Принимает в конструктор cdn, базовый url и заголовки.

  • constructor(cdn: string, baseUrl: string, options?: RequestInit)

Взаимодействие компонентов

Код, описывающий взаимодействие представления и данных между собой находится в файле index.ts, выполняющем роль презентера.
Взаимодействие осуществляется за счет событий генерируемых с помощью брокера событий и обработчиков этих событий, описанных в index.ts
В index.ts сначала создаются экземпляры всех необходимых классов, а затем настраивается обработка событий.

Список всех событий, которые могут генерироваться в системе:
События изменения данных (генерируются классами моделями данных)

  • items:changed - установка каталога
  • preview:changed - изменение id выбранной для просмотра карточки
  • basket:changed - изменение состава корзины
  • order:ready - готовность заказа
  • orderFormErrors:changed - изменение набора ошибок в форме заказа
  • contactsFormErrors:changed - изменение набора ошибок в форме контактов

События, возникающие при взаимодействии пользователя с интерфейсом (генерируются классами, отвечающими за представление)

  • card:select - выбор карточки для отображения в модальном окне
  • basket:open - открытие модального окна с корзиной
  • order:open - открытие модального окна с формой для заполнения данных о заказе
  • order:changed - изменение полей в форме заказа
  • order:submit - отправка формы с информацией о заказе
  • contacts:changed - изменение полей в форме контактов
  • contacts:submit - отправка формы с информацией о контактах
  • success:open - открытие модального окна с информацией об успешном оформлении заказа
  • modal:open - открытие модального окна
  • modal:close - закрытие модального окна

About

Фронтенд проекта "Веб Ларёк"

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published