Int_Prog/лаб3/lab3/public/scripts/admin.js
2024-01-19 01:24:45 +04:00

269 lines
11 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { createObject } from "./api/createObject.js";
import { delObject } from "./api/delObject.js";
import { fetchAllCategories } from "./api/fetchAllCategoeies.js";
import { fetchAllProducts } from "./api/fetchAllProducts.js";
import { fetchAllRestaurantTypes } from "./api/fetchAllRestaurantTypes.js";
import { updateObject } from "./api/updateObject.js";
import { configurateObject } from "./helpers/configurateObject.js";
import { validateModalForm } from "./helpers/formValidate.js";
import { getBase64Image } from "./helpers/getBase64Image.js";
import { getHTMLCategorySelectOption } from "./helpers/getHTMLCategorySelectOption.js";
import { getHTMLRow } from "./helpers/getHTMLRow.js";
import { resetForm } from "./helpers/resetForm.js";
import { form, modal, parent } from "./variables.js";
//? ПЕРЕМЕННЫЕ
let products;
let restaurantTypes;
let categories;
//? СТАРТ ВСЕГО-ВСЕГО
async function start() {
getAllRestarauntType();
getAllCategories();
drawAllProducts();
}
if (parent) {
start();
}
//? ПОЛУЧЕНИЕ ВСЕХ ОБЪЕКТОВ
async function getAllRestarauntType() {
try {
// Получаю все категории массивом
const data = await fetchAllRestaurantTypes();
for (const object of data) {
// Создают <option></option> для каждой отдельной категории
form.fieldRestaurantTypeSelect.innerHTML += getHTMLCategorySelectOption(object.name, object.id);
}
restaurantTypes = data;
} catch (err) {
console.log(err);
}
}
async function getAllCategories() {
try {
// Получаю все категории массивом
const data = await fetchAllCategories();
for (const object of data) {
// Создают <option></option> для каждой отдельной категории
form.fieldCategorySelect.innerHTML += getHTMLCategorySelectOption(object.name, object.id);
}
// Назначаю в переменную полученные категории
categories = data;
} catch (err) {
console.log(err);
}
}
async function drawAllProducts() {
try {
// Получаю все продукты
const data = await fetchAllProducts();
for (const product of data) {
// Ищу категорию объекта
const category = categories.find(category => category.id === product.categoryId);
// Ищу тип ресторана
const restaurantType = restaurantTypes.find(type => type.id === product.restaurantTypeId);
// Создаем строку в таблице
parent.innerHTML += getHTMLRow(product, category.name, restaurantType.name);
}
// Продукты грузим в переменную
products = data;
} catch (err) {
console.log(err);
}
}
//? УДАЛЕНИЕ ОБЪЕКТА
async function deleteObject(currentDeleteButton) {
// e - это кнопка, по которой нажали
try {
// Если админ НЕ хочет удалять товар - то мы досрочно заканчиваем функцию
if (!confirm("Вы правда хотите удалить этот объект?")) return;
// Получаю элемент строки в таблице
const row = currentDeleteButton.parentElement.parentElement;
// Достаю id продукта для удаления
const id = row.dataset.id;
// Удаляю объект из БД
await delObject(id);
// Удаление строки из таблицы
row.remove();
} catch (error) {
console.log(error);
}
}
// Чтобы работала кнопка Delete
window.deleteObject = deleteObject;
// Флаг для понимания, модалка для обновления или для создания
let isEditModal = true;
// Нужно чтобы насильно модалку закрыть
const modalObject = new bootstrap.Modal(modal.root);
if (modal.root && modal.submitButton) {
// Обработка превьюшки фотографии
form.fieldPhoto.addEventListener('change', (event) => {
const file = event.target.files[0];
if (!file) return;
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = () => {
// reader.result - моя фотографии в base64
// Мы ставим её в превью
form.fieldPhotoPreview.src = reader.result;
};
});
};
//? РЕДАКТИРОВАНИЕ И СОЗДАНИЕ
//? Открытие модалки
if (modal.root && modal.submitButton) {
modal.root.addEventListener('show.bs.modal', event => {
// event.relatedTarget.dataset.type - атрибут кнопки, на которую мы нажали (добавить или редактировать)
// Проверяю, что кнопка, на которую я нажала, это кнопка создания объекта
if (event.relatedTarget.dataset.type === "add") {
isEditModal = false;
modal.title.innerHTML = "Создать объект";
modal.submitButton.innerHTML = "Создать";
return;
} else {
modal.title.innerHTML = "Обновить объект";
modal.submitButton.innerHTML = "Обновить";
isEditModal = true;
}
// Если модалка для редактирования, то мы должны подтащить продукт
// Получаем кнопку Edit, на которую нажали
const button = event.relatedTarget;
// Получаем id продукта, к которому привязана кнопка
const id = +button.getAttribute('data-bs-whatever');
// Достаю продукт из массив всех продуктов по моему id
const product = products.find(product => product.id === id);
// Заполняем инпуты и т.д.
form.fieldName.value = product.name;
form.fieldPrice.value = product.price;
form.fieldPhotoPreview.src = product.photo;
form.fieldPhotoPreview.alt = product.name;
form.fieldCategorySelect.value = product.categoryId;
form.fieldRestaurantTypeSelect.value = product.restaurantTypeId;
form.fieldInfo.value = product.info;
// В кнопку "Обновить" вшиваю id товара, который обновляем
modal.submitButton.dataset.id = id;
});
// Закрыли модалку - очистили форму
modal.root.addEventListener('hide.bs.modal', () => {
resetForm();
});
// Создание товара - обязаны вставить фото
// Обновление товара:
// 1. Фото оставить старое
// 2. Обновить фото
//? Обновление и создание объекта
// Обработчик события для кнопки submit (создаем или обновляем)
modal.submitButton.addEventListener('click', async function (e) {
try {
if (!validateModalForm(isEditModal)) {
alert("Ошибка в форме: не все поля заполнены");
return;
}
// Если мы редактируем товар, то мы получаем его id из кнопки submit,
// т.к. для put запроса нам нужен id
// if (isEditModal) return +modal.submitButton.dataset.id
// else return null
const id = isEditModal ? +modal.submitButton.dataset.id : null; // null - ничто
// Получаем фотографию товара
const objectPhotoInputFiles = form.fieldPhoto.files;
// Создаёт объект продукта (+ для конвертации строки в число)
const object = configurateObject(id, form.fieldName.value, +form.fieldCategorySelect.value,
+form.fieldPrice.value, form.fieldInfo.value, +form.fieldRestaurantTypeSelect.value);
// Если кол-во фотографии > 0, т.е. мы её загрузили
// (при создании или если при редактировании мы изменили фото)
if (objectPhotoInputFiles.length > 0) {
const file = objectPhotoInputFiles[0];
// Получаем фото в base64
const base64Image = await getBase64Image(file);
// Загружаем фото в объект
object.photo = base64Image;
} else {
// Если мы обновляем товар, то мы достаем его предыдущее фото (если мы его не обновили, см. выше)
// И загрузили его в объект
object.photo = products.find(product => product.id === id).photo;
}
// Конвертирую объект в JSON-формат
const objectJSON = JSON.stringify(object);
// Если мы обновляем товар, то вызываем соответствующую функцию
if (isEditModal) await updateObjectFunc(id, objectJSON);
else await addObject(objectJSON);
// Если всё ок - закрываем модалку и стираем данные из формы
modalObject.hide();
resetForm();
} catch (error) {
console.log(error);
}
});
};
async function updateObjectFunc(id, objectJSON) {
// По id достаём строку, которую обновляем
const row = document.querySelector(`tr[data-id="${id}"]`);
// Делаем запрос на сервер и обновляем там объект
const object = await updateObject(id, objectJSON);
// Теперь нужно обновить строку в таблице
// Получаем объект категории
const objectCategory = categories.find(category => category.id === object.categoryId);
// Ищу тип ресторана
const restaurantType = restaurantTypes.find(type => type.id === object.restaurantTypeId);
// Создаем новую строку из новых данных и заменяем ей старую
row.innerHTML = getHTMLRow(object, objectCategory.name, restaurantType.name);
// Обновляем в глобальном массиве объект продукта
products = products.map(product => (product.id === id ? object : product));
}
async function addObject(objectJSON) {
// Делаем запрос на создание объекта
const object = await createObject(objectJSON);
// Получаем категорию
const objectCategory = categories.find(category => category.id === object.categoryId);
// Ищу тип ресторана
const restaurantType = restaurantTypes.find(type => type.id === object.restaurantTypeId);
// Добавляем строку в таблицу
parent.innerHTML += getHTMLRow(object, objectCategory.name, restaurantType.name);
// Добавляем новый продукт в общий массив
products.push(object);
}