47 lines
6.1 KiB
JavaScript
47 lines
6.1 KiB
JavaScript
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};
|