12 KiB
Лабораторная работа № 8. Реализация функциональности оформления заказа
Реализуйте сохранение выбранных пользователем блюд, чтобы после обновления страницы выбор пользователя не сбрасывался. Добавьте страницу оформления заказа, где будет отображаться текущий состав заказа и форма ввода данных. Реализуйте возможность оформления заказа – отправку данных на сервер.
Порядок выполнения
-
Реализуйте сохранение данных о выбранных пользователем блюдах в localStorage, чтобы в последующем иметь возможность получить эти данные на странице "Оформить заказ". В localStorage должны храниться только идентификаторы выбранных блюд. Формат хранения данных выбирается на усмотрение студента.
-
Добавьте страницу "Оформить заказ". Внешний вид страницы представлен на макете ниже. Добавьте ссылку на эту страницу в навигационное меню. На странице "Оформить заказ" должно быть два раздела: "Состав заказа" и "Оформление заказа".
- В разделе "Состав заказа" должны быть отображены ранее добавленные пользователем в заказ блюда (список выбранных блюд нужно загрузить из localStorage, а данные для отображения – загрузить с сервера).
- Формат отображения блюд такой же, как на странице "Собрать ланч".
- Вместо кнопки "Добавить" в карточке блюда должна быть кнопка "Удалить", по нажатию на которую соответствующее блюдо удаляется из заказа (т. е. информация о нём удаляется из localStorage) и карточка удаляется со страницы.
- Если ни одно блюдо не выбрано, нужно отобразить пользователю текст "Ничего не выбрано. Чтобы добавить блюда в заказ, перейдите на страницу Собрать ланч.", где текст "Собрать ланч" – гиперссылка на соответствующую страницу.
- В разделе "Оформление заказа" должна отображаться форма оформления заказа, перенесённая со страницы "Собрать ланч".
- Выбранные пользователем блюда отображаются в левой части формы (см. макет выше), напротив каждого блюда отображается его стоимость.
- При удалении блюда из заказа в соответствующем ему пункте должен отобразиться текст "Не выбран" (или "Не выбрано" для "Главного блюда") и должна быть пересчитана итоговая стоимость заказа.
- Перед отправкой данных формы на сервер должна производиться проверка соответствия состава заказа одному из доступных комбо (см. задание к ЛР 6).
-
Внесите исправления в страницу "Собрать ланч": вместо формы оформления заказа разместите панель для перехода к оформлению заказа, в которой будет отображаться текущая стоимость добавленных в заказ блюд и ссылка "Перейти к оформлению", ведущая на страницу оформления заказа.
- Панель для перехода к оформлению заказа должна быть скрыта, если пользователь не добавил в заказ ни одного блюда.
- Ссылка "Перейти к оформлению" должна быть недоступна до тех пор, пока сосав заказа не удовлетворяет одному из доступных комбо (см. задание к ЛР 6).
- Для размещения элемента на странице используйте position: sticky.
- При добавлении очередного блюда в заказ, стоимость должна пересчитываться.
- При открытии страницы "Собрать ланч" должны учитываться данные текущего заказа, хранящиеся в localStorage (т. е. в меню должны быть выделены выбранные блюда, рассчитана и отображена текущая суммарная стоимость выбранных блюд и т. д.).
-
Реализуйте отправку данных заказа на сервер по нажатию на кнопку "Отправить".
- Запрос должен быть отправлен при помощи fetch.
- В случае возникновения ошибки при отправке запроса или его обработке на стороне сервера пользователю должно быть отображено уведомление об ошибке (можно использовать функцию alert или написать кастомное модальное окно – на ваше усмотрение).
- После успешного оформления заказа данные о выбранных блюдах из localStorage должны удаляться. Если не удалось оформить заказ – данные не удаляются.
Инструкция по работе с API
Для получения доступа к API необходимо пройти процедуру авторизации. Для авторизации нужно указать в качестве параметра запроса api_key значение уникального ключа, который выдаётся каждому пользователю. Ключ представляет собой идентификатор UUIDv4, который является случайным 16-байтным номером (например, 123e4567-e89b-12d3-a456-426655440000).
Обратите внимание, что параметр api_key всегда передаётся в строке запроса.
Пользователь может просматривать, редактировать и удалять только свои заказы. В один момент времени в базе данных может быть не более 10 заказов, созданных одним и тем же пользователем.
Если пользователь попробует совершить действие, не пройдя авторизацию, в качестве ответа на его запрос придёт сообщение:
{"error": "Для получения доступа к API необходимо пройти процедуру авторизации. Для этого нужно передать в запросе персональный API Key."}
При передаче параметров в POST- и PUT-запросах данные должны передаваться в теле запроса в формате application/json (нужно вручную сериализовать данные и установить значение заголовка Content-Type) или multipart/form-data (достаточно при отправке данных формы воспользоваться объектом FormData).
При оформлении заказа в запросе к серверу должны быть указаны значения обязательных полей:
| Название | Тип | Обязательное | Только для чтения | Примечание |
|---|---|---|---|---|
| id | Integer | Да | Устанавливается сервером. | |
| full_name | String | Да | ||
| String | Да | |||
| subscribe | Boolean | Нет | Допустимы значения 0 и 1. | |
| phone | String | Да | ||
| delivery_address | String | Да | ||
| delivery_type | String | Да | Допустимы значения "now" и "by_time". | |
| delivery_time | Time | Нет | Значение передаётся в формате HH:MM. Доступное время доставки: с 7:00 до 23:00 с шагом 5 минут. Не должно быть пустым, если delivery_type=by_time. Не должно быть раньше текущего времени. |
|
| comment | String | Нет | ||
| soup_id | Integer | Нет | Обязательность поля зависит от состава комбо. | |
| main_course_id | Integer | Нет | Обязательность поля зависит от состава комбо. | |
| salad_id | Integer | Нет | Обязательность поля зависит от состава комбо. | |
| drink_id | Integer | Да | ||
| dessert_id | Integer | Нет | ||
| created_at | DateTime | Да | Устанавливается сервером. | |
| updated_at | DateTime | Да | Устанавливается сервером. | |
| student_id | Integer | Да | Устанавливается сервером. |
Доступные пользователю действия представлены в таблице:
| Действие | Метод и путь | Формат ответа | Примечание |
|---|---|---|---|
| Получить данные всех блюд | GET /labs/api/dishes | JSON [{item1},{item2},...{itemN}] | |
| Получить данные конкретного блюда | GET /labs/api/dishes/{int:dish_id} | JSON {Item} | Вместо {int:dish_id} нужно подставить целое число – идентификатор блюда. |
| Получить данные всех заказов | GET /labs/api/orders | JSON [{item1},{item2},...{itemN}] | |
| Получить данные конкретного заказа | GET /labs/api/orders/{int:order_id} | JSON {Item} | Вместо {int:order_id} нужно подставить целое число – идентификатор заказа. |
| Создать новый заказ | POST /labs/api/orders | JSON {newItem} | Нужно передать значения всех обязательных полей. |
| Изменить заказ | PUT /labs/api/orders/{int:order_id} | JSON {updateItem} | Вместо {int:order_id} нужно подставить целое число – идентификатор заказа. Достаточно передать только значения изменившихся полей. |
| Удалить заказ | DELETE /labs/api/orders/{int:order_id} | JSON {Item} | Вместо {int:order_id} нужно подставить целое число – идентификатор заказа. |
Материалы для изучения
localStorage [Doka] Получение данных с сервера [MDN] Работа с JSON [MDN] Промисы, async/await [Learn JS] async/await [Doka] Использование промисов [MDN] Fetch [Learn JS] Fetch API [MDN] fetch() [Doka] Cross-Origin Resource Sharing (CORS) [MDN]