Files
PIbd-23_Baryshev_D.A._Inter…/dist/assets/controller-BsNF2rMP.js
2025-09-26 21:15:37 +04:00

47 lines
6.1 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.
class h{constructor(){this.apiUrl="http://localhost:3000"}async request(t,e={}){const s=await fetch(`${this.apiUrl}${t}`,{...e,headers:{"Content-Type":"application/json",...e.headers}});if(!s.ok)throw new Error(`HTTP error! status: ${s.status}`);return await s.json()}async getLikesItems(){try{return await this.request("/likes")}catch(t){return console.error("Ошибка при получении избранного:",t),[]}}async addToLikes(t){try{if(!(await this.getLikesItems()).find(i=>i.id===t.id))return await(await fetch(`${this.apiUrl}/likes`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)})).json()}catch(e){console.error("Ошибка при добавлении в избранное:",e)}}async removeFromLikes(t){try{await fetch(`${this.apiUrl}/likes/${t}`,{method:"DELETE"})}catch(e){console.error("Ошибка при удалении из избранного:",e)}}async moveToBasket(t){try{await(await fetch(`${this.apiUrl}/basket`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({...t,quantity:1,addedAt:new Date().toISOString()})})).json(),await this.removeFromLikes(t.id)}catch(e){console.error("Ошибка при переносе товара в корзину:",e)}}}class m{constructor(){this.likesContainer=document.getElementById("likesContainer"),this.emptyLikesElement=document.querySelector(".empty-likes")}showLikes(t){if(!this.likesContainer)return;if(!t||t.length===0){this.showEmptyLikes();return}this.hideEmptyLikes();const e=t.map(s=>this.createLikesItemHTML(s)).join("");this.likesContainer.innerHTML=`
<h2 class="mb-4 text-center">Избранное</h2>
<div class="row g-3">${e}</div>
`}createLikesItemHTML(t){return`
<div class="col-md-4">
<div class="card h-100 border-0 shadow like-item" data-id="${t.id}">
<img src="${t.image}" class="card-img-top" alt="${t.name}">
<div class="card-body">
<h5 class="card-title">${t.name}</h5>
<p class="card-text">${t.description}</p>
<!-- ✅ Добавляем Category и Condition -->
<div class="row">
<div class="col-6">
<h6 class="mb-1">Category:</h6>
<p class="card-text">${t.category||"-"}</p>
</div>
<div class="col-6">
<h6 class="mb-1">Condition:</h6>
<p class="card-text">${t.condition||"-"}</p>
</div>
</div>
</div>
<div class="card-footer bg-transparent">
<div class="d-flex justify-content-between align-items-end">
<!-- Цена слева -->
<span class="fw-bold text-muted fs-3 price-large">$${t.price}</span>
<!-- Кнопки справа -->
<div class="d-flex flex-column gap-1">
<button class="btn btn-sm btn-outline-primary move-to-basket-btn">
<i class="bi bi-cart-plus"></i> В корзину
</button>
<button class="btn btn-sm btn-outline-danger remove-like-btn">
<i class="bi bi-trash"></i> Удалить
</button>
</div>
</div>
</div>
`}showEmptyLikes(){this.emptyLikesElement&&(this.emptyLikesElement.style.display="block"),this.likesContainer&&(this.likesContainer.innerHTML="")}hideEmptyLikes(){this.emptyLikesElement&&(this.emptyLikesElement.style.display="none")}showNotification(t,e="success"){const s=document.createElement("div");s.className=`alert alert-${e==="success"?"success":"danger"} alert-dismissible fade show`,s.style.cssText="position: fixed; top: 20px; right: 20px; z-index: 1050; min-width: 300px;",s.innerHTML=`
${t}
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
`,document.body.appendChild(s),setTimeout(()=>{s.parentNode&&s.remove()},3e3)}}class p{constructor(t,e){this.model=t,this.view=e,this.init()}async init(){window.location.pathname.includes("likes.html")&&(await this.loadLikes(),this.setupLikesEventListeners()),window.location.pathname.includes("catalog.html")&&this.setupCatalogEventListeners()}async loadLikes(){const t=await this.model.getLikesItems();this.view.showLikes(t)}setupLikesEventListeners(){document.addEventListener("click",async t=>{const e=t.target.closest(".like-item");if(!e)return;const s=e.dataset.id;if(t.target.closest(".remove-like-btn")&&(await this.model.removeFromLikes(s),this.view.showNotification("Товар удален из избранного"),await this.loadLikes()),t.target.closest(".move-to-basket-btn")){const o=(await this.model.getLikesItems()).find(a=>a.id===s);o&&(await this.model.moveToBasket(o),this.view.showNotification("Товар перенесен в корзину"),await this.loadLikes())}})}setupCatalogEventListeners(){document.addEventListener("click",async t=>{const e=t.target.closest(".card");if(e&&t.target.closest(".like-btn")){const s=this.extractProductData(e);s&&(await this.model.addToLikes(s),this.view.showNotification("Товар добавлен в избранное!"))}})}extractProductData(t){var e,s;try{const i=t.querySelector(".card-title").textContent,o=t.querySelector(".text-muted").textContent.replace("$",""),a=t.querySelector(".card-text").textContent,r=t.querySelector("img").src,c=((e=t.querySelector(".col-6:nth-child(1) p"))==null?void 0:e.textContent.trim())||"",l=((s=t.querySelector(".col-6:nth-child(2) p"))==null?void 0:s.textContent.trim())||"";return{id:btoa(`${i}-${o}`).substring(0,8),name:i.trim(),price:parseFloat(o),description:a.trim(),image:r,category:c,condition:l}}catch(i){return console.error("Ошибка при извлечении данных товара:",i),null}}}export{m as L,p as a,h as b};