diff --git a/klasa.js b/klasa.js index 304e10e..0afc6c9 100644 --- a/klasa.js +++ b/klasa.js @@ -496,6 +496,7 @@ class IdmHotspot{ this.handleAddToFav = this.handleAddToFav.bind(this); this.handleShowSecondImage = this.handleShowSecondImage.bind(this); this.handleHideSecondImage = this.handleHideSecondImage.bind(this); + this.handleSelectVersion = this.handleSelectVersion.bind(this); this.init(); } @@ -595,14 +596,20 @@ class IdmHotspot{ * Tworzy markup dla pojedynczego produktu. */ markupProduct(prod){ - // IDM DO POPRAWKI - const prodExchangedData = app_shop?.fn?.getOmnibusDetails?.({productData: prod}) || app_shop.fn?.idmGetOmnibusDetails({productData: prod}); - // markup pojedynczego produktu let singleMarkup = ""; singleMarkup += `
${this.markupAddToBasket(prod)} - - `; - - return singleMarkup; + `; } markupAdditional(prod){ @@ -659,7 +663,7 @@ class IdmHotspot{ return `` } @@ -1051,6 +1055,17 @@ class IdmHotspot{ } } + + handleSelectVersion(e){ + e.preventDefault(); + const closestVersion = e.target.closest(".product__version_single:not(.--active)"); + const prodEl = e.target.closest(".product"); + + if(!closestVersion || !prodEl) return; + + this.reloadProduct(prodEl, closestVersion.dataset.productId); + } + /** * Lazy-load hotspotu – wczytuje dane dopiero, gdy element pojawi się w viewportcie. */ @@ -1089,6 +1104,7 @@ class IdmHotspot{ /** * Ustawia jednakową wysokość elementów (np. nazw lub cen). */ + setHeight(options){ const { selector, selectors, container } = options || {} if ((!selector && !selectors) || !container) return @@ -1110,6 +1126,48 @@ class IdmHotspot{ if (selector) adjustAllHeights(selector) if (selectors?.length) selectors.forEach(adjustAllHeights) } + + /** + * Przeładowanie pojedynczego produktu + */ + async reloadProduct(prodEl, newProdId){ + try{ + prodEl.classList.add("--loading"); + const res = await fetch(`/graphql/v1/`, { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: IDM_PRODUCT_GQL(`productId: ${newProdId}`), + }); + const data = await res.json(); + + const productData = data?.data?.product?.product; + if(!productData) throw new Error("Nie udało się pobrać danych o produkcie"); + + + const prodHTML = this.markupProductInnerHTML(productData); + + prodEl.dataset.id = newProdId; + prodEl.innerHTML = prodHTML; + if(productData.price.price[this.priceType].value === 0) prodEl.classList.add("--phone"); + else prodEl.classList.remove("--phone"); + + this.initSingleEvent(prodEl); + this.setHeight({ + selectors: [ + `#${this.id} .product__prices`, + `#${this.id} .product__name`, + ], + container: `#${this.id} .products__wrapper`, + }); + }catch(err){ + Alertek?.Error(idmHotspotTextObject["Błąd przy pobieraniu danych"]); + console.error(err); + }finally{ + prodEl.classList.remove("--loading"); + } + } // ======================================================== // INICJALIZACJA // ======================================================== @@ -1237,12 +1295,13 @@ class IdmHotspot{ addToBasketEl?.querySelector(".idm-products-banner__qty-input")?.addEventListener("input",this.handleQuantityInputChange); } } - // Add to Favorites + // Dodaj do ulubionych if(this.options?.addToFavorites && typeof this.addToFavFn === "function") prodEl.querySelector(".product__favorite")?.addEventListener("click", this.handleAddToFav); - // Compare + + // Porównanie if(this.options?.addToCompare) prodEl.querySelector(".idm-products-banner__compare-btn")?.addEventListener("click", this.handleAddToCompare); - // Second image on hover + // Hover drugie zdjęcie if(this.options?.showSecondImage){ const prodIconEl = prodEl.querySelector(".product__icon"); if(prodIconEl.querySelector(".product__image.--second")){ @@ -1250,6 +1309,9 @@ class IdmHotspot{ prodIconEl?.addEventListener("mouseleave", this.handleHideSecondImage); } } + + // Wybór wersji + if(this.options?.selectVersion) prodEl.querySelector(".product__versions")?.addEventListener("click", this.handleSelectVersion); } /** diff --git a/ramka.txt b/ramka.txt index 9f87225..0267e75 100644 --- a/ramka.txt +++ b/ramka.txt @@ -1,6 +1,6 @@ 1. Ramka -- wybór rozmiaru/wersji?? +- wybór rozmiaru/wersji?? Wykluczenie powtarzających się wersji wersja max 5 zdjęć i później + może???? - zakres cen????????????? diff --git a/style.less b/style.less index 1b99d7f..57e443a 100644 --- a/style.less +++ b/style.less @@ -226,7 +226,20 @@ // WERSJE -.idm__hotspot:has(.product__versions){ +@keyframes idmPulseOpacity { + 0%, 100% { + opacity: 0.4; + } + 50% { + opacity: 0.6; + } +} + +.idm__hotspot .product.--loading{ + animation: idmPulseOpacity 3s infinite; +} +.idm__hotspot .product:has(.product__versions){ + --idm-hotspot-version-height: 55px; .product__versions{ display: grid; grid-template-columns: repeat(5, 1fr); @@ -237,6 +250,24 @@ padding: 0.3rem 1rem; position: absolute; top: 0; + + + height: var(--idm-hotspot-version-height); + align-items: center; + } + .product__version_single{ + display: flex; + border-radius: 8px; + overflow: hidden; + border: 1px solid #ccc; + transition: border 0.2s; + &:hover{ + border-color: #111; + } + &.--active{ + border-color: var(--primary-color, #111); + box-shadow: 0 0 1px 1px var(--primary-color, #111); + } } .product__content_wrapper{ position: relative; @@ -244,9 +275,9 @@ .label_icons, .product__versions{ transition: all 0.2s; } - .product:hover{ + &:hover{ .product__versions, .label_icons{ - transform: translateY(-100%); + transform: translateY(calc(-1 * var(--idm-hotspot-version-height))); } .product__versions{ clip-path: inset(0 0 0 0);