import { menuEnum } from "../constants/index.js"; import { fetchData, downloadBook, searchByAuthor } from "../requests/index.js"; export default class BookSection { subElements = []; element; constructor({ url = "", label = "" } = {}) { this.url = url; this.label = label; this.render(); } get template() { return `
`; } initialize() { this.initEventListeners(); } initEventListeners() { const booksListener = document.querySelector(".main-book__wrapper"); booksListener.addEventListener("click", (event) => { let id, title; const isLike = event.target.closest("[data-like]"); const isMenu = event.target.closest("[data-menu]"); const isAction = event.target.closest("[data-action]"); const isLink = event.target.closest("[data-link]"); const isAuthor = event.target.closest("[data-author]"); switch (true) { case !!isAction: id = isAction.dataset.action; const { authorid, bookid } = isAction.parentNode.parentNode.dataset || {}; this.makeAction({ id, authorid, bookid }); break; case !!isLike: this.makeLike(isLike); break; case !!isMenu: this.openMenu(isMenu); break; case !!isLink: id = isLink.dataset.bookid; title = isLink.dataset.title; let format = isLink.dataset.format.toLowerCase(); downloadBook({ id, title, format }); break; case !!isAuthor: id = isAuthor.dataset.author; this.update({ isByAuthor: true, id }); default: this.closeMenu(); break; } }); } destroyEventListeners() {} getBookBody(data) { return (data || []) .map( ({ id, authors, description, format, genres, imageUrl, title, series, subseries, year, tags, isFavorite, }) => { const { name, id: authorid } = authors[0] || "Неизвестно"; return `
cover ${name || ""}
${year || "Год неизвестен"}
${title || "Название неизвестно"} ${series || ""} ${subseries || ""}
${description || "Нет описания"}
`; } ) .join(""); } getEmptyBody() { return `
Ничего не найдено
`; } getMenuBody() { return menuEnum .map(({ label, id }) => { return `
  • ${label}
  • `; }) .join(""); } getTags(tags) { return (tags || []) .map(({ id, name }) => { return `#${name}`; }) .join(""); } openMenu(element) { this.closeMenu(); element.classList.remove("main-book__menu_closed"); const divElement = document.createElement("ul"); divElement.innerHTML = this.getMenuBody(); element.append(divElement); element.classList.add("main-book__menu_opened"); } closeMenu() { const elements = document.querySelectorAll(".main-book__menu_opened"); if (elements && elements.length) { for (const subElement of elements) { subElement.firstElementChild.remove(); subElement.classList.remove("main-book__menu_opened"); subElement.classList.add("main-book__menu_closed"); } } } async makeAction({ id, authorid, bookid }) { this.element.classList.add("blur", "spinner"); if (menuEnum[id].action) { const data = await menuEnum[id].action({ id, authorid, bookid }); } else { alert("Напиши меня"); } this.element.classList.remove("spinner"); this.closeMenu() } makeLike(element) { const { bookid: likedBookId } = element.dataset || {}; this.makeAction({ id: 0, authorid: "", bookid: likedBookId }); element.classList.add("liked"); } async update(params) { this.element.classList.add("blur", "spinner"); let data = []; if (params?.isByAuthor) { data = await searchByAuthor({ id: params.id }); } else { const query = params; data = await fetchData({ query, url: this.url }); } console.log("data", data); if (data && Object.values(data).length) { this.subElements.body.innerHTML = this.getBookBody(data); this.initialize(); } else { this.subElements.body.innerHTML = this.getEmptyBody(); } this.element.classList.remove("spinner"); } getSubElements(element) { const result = {}; const elements = element.querySelectorAll("[data-element]"); for (const subElement of elements) { const name = subElement.dataset.element; result[name] = subElement; } return result; } render() { const divElement = document.createElement("div"); divElement.innerHTML = this.template; this.element = divElement.firstElementChild; this.subElements = this.getSubElements(this.element); } remove() { if (this.element) { this.element.remove(); destroyEventListeners(); } } destroy() { this.remove(); this.element = null; } }