diff --git a/README.md b/README.md index 4185e4f..1946dda 100644 --- a/README.md +++ b/README.md @@ -58,6 +58,7 @@ Warto gdzieś później zapisać nową nazwę klasy np w opisie komponentu, albo - Nie znaleziono kontenera - Nie znaleziono metody graphql - Najniższa cena +- Drugie Zdjęcie ### Przykłady UŻYCIA ### ##### Jedna ramka - obiekt ###### @@ -84,33 +85,44 @@ new IdmHotspot({ * @property {string} title - Tytuł ramki. * @property {string} classes - Dodatkowe klasy CSS. * @property {object[]} [products] - tablica produktów z układem danych takich jak w graphql. Opcjonalne, pod specjalne funkcjonalności. + + * @property {object} placement - Określa, gdzie wstawić ramkę (required). * @property {string} placement.selector - Selektor miejsca osadzenia. * @property {string} placement.insert - Pozycja wstawienia względem selektora (np. "afterbegin", "beforeend"). - * @property {object} source - Dane źródłowe dla hotspotu (required). + + + * @property {object} source - Dane źródłowe dla hotspotu. * @property {string} [source.hotspotType] - Typ hotspotu (np. "promotion"). * @property {number[]} [source.productsId] - Tablica ID produktów. * @property {number} [source.productsMenu] - Identyfikator menu produktów. + + * @property {object} query - Dane zapytania, nadpisują source (DEV). * @property {string} query.string - Zapytanie w formacie GraphQL. * @property {Function} query.graphFn - Funkcja do pobierania danych. + + * @property {object} options - Ustawienia dla hotspotu (required). * @property {boolean} [options.lazy] - Czy wczytywać w trybie lazy. * @property {boolean} [options.devMode] - Czy wczytywać ramki tylko dla stron z dev=true. + * @property {boolean} [options.omnibusTooltip] - Czy wyświetlać omnibusa w formie tooltip + * @property {Function} [options.callbackFn] - Funkcja callback która dzieje się po wywołaniu wszystkiego włącznie ze swiperem + * @property {boolean} [options.addToFavorites] - Czy włączać dodawanie do ulubionych(DZIAŁA TYLKO PO ZMIANACH SZABLONOWYCH) * @property {boolean} [options.addToCompare] - Czy włączać dodawanie do porównywania * @property {boolean|string} [options.addToBasket] - Obsługa koszyka: * - true = włącz * - false = wyłącz * - "range" = dodaj z zakresem + * @property {boolean|object} options.swiper - Slider: * - true = aktywny * - false = nieaktywny * - object = konfiguracja Swiper * @property {boolean} [options.swiperScrollbar] - Czy włączać scrollbar w swiperze - DO DZIAŁANIA WYMAGA WŁĄCZONEGO SWIPERA - * @property {Function} [options.callbackFn] - Funkcja callback która dzieje się po wywołaniu wszystkiego włącznie ze swiperem - * @property {boolean} [options.omnibusTooltip] - Czy wyświetlać omnibusa w formie tooltip * @property {boolean} [options.showOpinions] - Czy wyświetlać opinie o produkcie w formie gwiazdek nad nazwą + * @property {boolean} [options.showSecondImage] - Czy wyświetlać drugie zdjęcie na hover * * @type {Hotspot[]} */ diff --git a/klasa.js b/klasa.js index 6aa36e3..b8b2c4e 100644 --- a/klasa.js +++ b/klasa.js @@ -31,6 +31,7 @@ const idmHotspotTextObject = { []: , []: , []: , + []: , }; // STRING // const idmHotspotTextObject = { @@ -240,7 +241,18 @@ const IDM_PRODUCT_GQL = (args) => JSON.stringify({ }); // ADD TO BASKET const IDM_HOTSPOT_ADD_TO_BASKET = (t, e, a) => JSON.stringify({ - query: `mutation {\n addProductsToBasket(ProductInput: {id: ${t}, size: "${e}", quantity: ${a}}) {\n status\n results {\n status\n error {\n code\n message\n }\n productCode\n productId\n sizeId\n quantity\n quantityAvailable\n }\n clientDetailsInBasket {\n id\n login\n firstname\n lastname\n participationPartnerProgram\n usesVat\n email\n isWholesaler\n isWholesalerOrder\n clientIdUpc\n }\n }\n }` + query: `mutation { + addProductsToBasket(ProductInput: {id: ${t}, size: "${e}", quantity: ${a}}) { + status + results { + status + error { + code + message + } + } + } + }` }); ///////////////////////////////////////// // JS @@ -420,6 +432,7 @@ class IdmHotspot{ // POKAZANIE showOpinions: false, + showSecondImage: false, // DODAWANIE addToBasket: true, // true, false, "range" @@ -468,6 +481,8 @@ class IdmHotspot{ this.handleQuantityInputChange = this.handleQuantityInputChange.bind(this); this.handleAddToCompare = this.handleAddToCompare.bind(this); this.handleAddToFav = this.handleAddToFav.bind(this); + this.handleShowSecondImage = this.handleShowSecondImage.bind(this); + this.handleHideSecondImage = this.handleHideSecondImage.bind(this); this.init(); } @@ -619,14 +634,17 @@ class IdmHotspot{ - ${prod.name} + ${prod.name} `; else if(prod?.iconSmall) markup += ` - ${prod.name} + ${prod.name} `; - else markup += `${prod.name}` + else markup += `${prod.name}`; + + if(this.options?.showSecondImage && prod.enclosuresImages?.[1]?.url) markup += `${prod.name} - ${idmHotspotTextObject[`; + return markup; } @@ -941,6 +959,22 @@ class IdmHotspot{ input.value = current.toFixed(precision); } + /** + * Obsługuje Pokazywanie zdjęcia na hover + */ + handleShowSecondImage(e){ + const prodIconEl = e.target.closest(".product__icon"); + if(!prodIconEl) return; + + prodIconEl.classList.add("--toggle-icon"); + } + + handleHideSecondImage(e){ + const prodIconEl = e.target.closest(".product__icon"); + if(!prodIconEl) return; + + prodIconEl.classList.remove("--toggle-icon"); + } /** * Walidacja zmian ilości w polu input. */ @@ -1129,28 +1163,27 @@ class IdmHotspot{ // DODAWANIE DO KOSZYKA if(this.options?.addToBasket){ const addToBasketEl = prodEl.querySelector("form.add_to_basket"); - if(!addToBasketEl) return; - addToBasketEl.addEventListener("submit", this.handleAddToBasket); + addToBasketEl?.addEventListener("submit", this.handleAddToBasket); // + - if(this?.options?.addToBasket === "range"){ - addToBasketEl.querySelector(".idm-products-banner__qty")?.addEventListener("click",this.handleQuantityButtonClick); - addToBasketEl.querySelector(".idm-products-banner__qty-input")?.addEventListener("input",this.handleQuantityInputChange); + addToBasketEl?.querySelector(".idm-products-banner__qty")?.addEventListener("click",this.handleQuantityButtonClick); + addToBasketEl?.querySelector(".idm-products-banner__qty-input")?.addEventListener("input",this.handleQuantityInputChange); } } - // Tooltip - // if(this.options?.omnibusTooltip){ - // const tooltipEl = prodEl.querySelector(".idm_tooltip"); - - // tooltipEl.addEventListener("click", ()=>{ - // this.showTooltip(tooltipEl); - // }) - // } - // Add to Favorites if(this.options?.addToFavorites && typeof this.addToFavFn === "function") prodEl.querySelector(".product__favorite")?.addEventListener("click", this.handleAddToFav); // Compare if(this.options?.addToCompare) prodEl.querySelector(".idm-products-banner__compare-btn")?.addEventListener("click", this.handleAddToCompare); + + // Second image on hover + if(this.options?.showSecondImage){ + const prodIconEl = prodEl.querySelector(".product__icon"); + if(prodIconEl.querySelector(".product__image.--second")){ + prodIconEl?.addEventListener("mouseover", this.handleShowSecondImage); + prodIconEl?.addEventListener("mouseleave", this.handleHideSecondImage); + } + } } /** diff --git a/ramka.txt b/ramka.txt index 32468b4..c075c70 100644 --- a/ramka.txt +++ b/ramka.txt @@ -9,12 +9,20 @@ - stary szablon - cena za kg - blokowanie dodawania do koszyka jeśli ilość jest maksymalna +- informacje o producencie albo serri gdzieś nad produktem +- czy zapisywać wszystkie hotspoty do jakiegoś app_shop.fn.idmHotspots = {"#idmMainHotspot1": {}} - własne klasy -- aplikacja do zarządania dodatkiem od obiektów hotspot Stara ramka - getProductXML=t -- slick \ No newline at end of file +- slick + + + +cos: any[] = [] + +cos ?? '' +cos?? false \ No newline at end of file diff --git a/style.less b/style.less index d335fa2..9a0868a 100644 --- a/style.less +++ b/style.less @@ -1,3 +1,7 @@ +.idm__hotspot .btn.add_to_basket__link{ + margin-top: 0; +} + .idm__hotspot .add_to_basket{ display: flex; } @@ -151,7 +155,7 @@ opacity: 0.6; } } - +/* COMPARE */ .idm-products-banner__compare-btn{ .idm-products-banner__compare-icon{ height: 100%; @@ -173,7 +177,10 @@ opacity: 0.6; } } - +.idm-products-banner__compare-btn.--success { + display: flex; + align-items: end; +} /* opinions */ .product__opinions{ @@ -187,4 +194,30 @@ } .product__opinions .icon-star:not(.--active)::before{ content: "\f006"; -} \ No newline at end of file +} + +/* second image */ +.product__image.--second{ + position: absolute; + left: 50%; + top: 50%; + transform: translate(-50%, -50%); +} + +.product__icon{ + .product__image{ + transition: opacity .25s; + } + .product__image.--second{ + opacity: 0; + } + + &.--toggle-icon:has(.product__image.--second){ + .product__image.--first{ + opacity: 0; + } + .product__image.--second{ + opacity: 1; + } + } +}