diff --git a/klasa.js b/klasa.js index 2be5c00..46addfc 100644 --- a/klasa.js +++ b/klasa.js @@ -2,37 +2,56 @@ // TEXT // LITERAŁY const idmHotspotTextObject = { - ["Kod rabatowy"]: , - ["Okazja"]: , - ["Promocja"]: , - ["Bestseller"]: , - ["Nowość"]: , - ["Ilość"]: , - ["Porównaj"]: , - ["Dodaj do ulubionych"]: , - ["Najniższa cena"]: , - ["Najniższa cena z 30 dni przed obniżką"]: , - ["Zwiększ ilość"]: , - ["Zmniejsz ilość"]: , - ["Najniższa cena produktu w okresie 30 dni przed wprowadzeniem obniżki"]: , - ["Cena regularna"]: , - ["Cena bez kodu"]: , - ["Cena nadchodząca od"]: , - ["Coś poszło nie tak podczas dodawania do koszyka. Spróbuj ponownie lub odśwież stronę"]: , - ["Nie znaleziono produktów"]: , - ["Błąd przy pobieraniu danych"]: , - ["Kliknij, by przejść do formularza kontaktu"]: , - ["Cena na telefon"]: , - ["Dodany"]: , - ["Wystąpił błąd"]: , - ["Do koszyka"]: , - ["Maksymalna liczba sztuk tego towaru które możesz dodać do koszyka to:"]: , - ["Minimalna liczba sztuk tego towaru które możesz dodać do koszyka to:"]: , - ["Wystąpił błąd z inicjalizacją. Proszę odśwież stronę"]: , - ["Nie znaleziono kontenera"]: , - ["Nie znaleziono metody graphql"]: , - ["Drugie Zdjęcie"]: , - ["Zobacz więcej"]: , + ["Kod rabatowy"]: , + ["Okazja"]: , + ["Promocja"]: , + ["Bestseller"]: , + ["Nowość"]: , + ["Ilość"]: , + ["Porównaj"]: , + ["Dodaj do ulubionych"]: , + ["Najniższa cena"]: , + ["Najniższa cena z 30 dni przed obniżką"]: ( + + ), + ["Zwiększ ilość"]: , + ["Zmniejsz ilość"]: , + ["Najniższa cena produktu w okresie 30 dni przed wprowadzeniem obniżki"]: ( + + ), + ["Cena regularna"]: , + ["Cena bez kodu"]: , + ["Cena nadchodząca od"]: , + ["Coś poszło nie tak podczas dodawania do koszyka. Spróbuj ponownie lub odśwież stronę"]: + ( + + ), + ["Nie znaleziono produktów"]: , + ["Błąd przy pobieraniu danych"]: ( + + ), + ["Kliknij, by przejść do formularza kontaktu"]: ( + + ), + ["Cena na telefon"]: , + ["Dodany"]: , + ["Wystąpił błąd"]: , + ["Do koszyka"]: , + ["Maksymalna liczba sztuk tego towaru które możesz dodać do koszyka to:"]: ( + + ), + ["Minimalna liczba sztuk tego towaru które możesz dodać do koszyka to:"]: ( + + ), + ["Wystąpił błąd z inicjalizacją. Proszę odśwież stronę"]: ( + + ), + ["Nie znaleziono kontenera"]: , + ["Nie znaleziono metody graphql"]: ( + + ), + ["Drugie Zdjęcie"]: , + ["Zobacz więcej"]: , }; // STRING @@ -225,7 +244,8 @@ const IDM_PRODUCT_QUERY = (priceType) => `id } ${IDM_PRICE_QUERY(priceType)}`; // 1. products -const IDM_PRODUCTS_GQL = (args, priceType = "gross") => JSON.stringify({ +const IDM_PRODUCTS_GQL = (args, priceType = "gross") => + JSON.stringify({ query: `{ products(${args}){ took @@ -233,11 +253,12 @@ const IDM_PRODUCTS_GQL = (args, priceType = "gross") => JSON.stringify({ ${IDM_PRODUCT_QUERY(priceType)} } } -}` -}); +}`, + }); // 2. hotspots -const IDM_HOTSPOTS_GQL = (args, priceType = "gross") => JSON.stringify({ +const IDM_HOTSPOTS_GQL = (args, priceType = "gross") => + JSON.stringify({ query: `{ hotspots(${args}){ took @@ -247,21 +268,23 @@ const IDM_HOTSPOTS_GQL = (args, priceType = "gross") => JSON.stringify({ ${IDM_PRODUCT_QUERY(priceType)} } } -}` -}); +}`, + }); // 3. single product -const IDM_PRODUCT_GQL = (args, priceType = "gross") => JSON.stringify({ +const IDM_PRODUCT_GQL = (args, priceType = "gross") => + JSON.stringify({ query: `{ product(${args}){ product{ ${IDM_PRODUCT_QUERY(priceType)} } } - }` -}); + }`, + }); // ADD TO BASKET -const IDM_HOTSPOT_ADD_TO_BASKET = (t, e, a) => JSON.stringify({ +const IDM_HOTSPOT_ADD_TO_BASKET = (t, e, a) => + JSON.stringify({ query: `mutation { addProductsToBasket(ProductInput: {id: ${t}, size: "${e}", quantity: ${a}}) { status @@ -273,129 +296,174 @@ const IDM_HOTSPOT_ADD_TO_BASKET = (t, e, a) => JSON.stringify({ } } } - }` -}); + }`, + }); ///////////////////////////////////////// // JS app_shop.fn.idmGetOmnibusDetails = (options) => { const { - productData, sizeId, priceType = app_shop.vars.priceType, + productData, + sizeId, + priceType = app_shop.vars.priceType, } = options || {}; if (!productData) return false; - const sizeData = productData.sizes.find((size) => size.id === sizeId) || productData; + const sizeData = + productData.sizes.find((size) => size.id === sizeId) || productData; if (!sizeData?.price) return false; const classes = { add: [], - remove: ['--omnibus', '--omnibus-short', '--omnibus-code', '--omnibus-code-short', '--omnibus-new-price', '--omnibus-higher'], + remove: [ + "--omnibus", + "--omnibus-short", + "--omnibus-code", + "--omnibus-code-short", + "--omnibus-new-price", + "--omnibus-higher", + ], }; const activeLabel = {}; - const omnibusPrice = sizeData.price?.omnibusPriceDetails?.unit?.[priceType]?.formatted || sizeData.price.omnibusPrice[priceType]?.formatted; + const omnibusPrice = + sizeData.price?.omnibusPriceDetails?.unit?.[priceType]?.formatted || + sizeData.price.omnibusPrice[priceType]?.formatted; if (!omnibusPrice) { return { classes, }; } // Omnibus - classes.add.push('--omnibus'); - classes.remove = classes.remove.filter((item) => item !== '--omnibus'); + classes.add.push("--omnibus"); + classes.remove = classes.remove.filter((item) => item !== "--omnibus"); const sellBy = productData?.unit?.sellBy; - const unitMaxPrice = sizeData?.price?.unit?.[priceType]?.formatted && sizeData.price.max?.[priceType]?.value ? format_price(parseFloat(sizeData.price.max?.[priceType]?.value) * parseFloat(sellBy), { - mask: app_shop.vars.currency_format, - currency: app_shop.vars?.currency?.symbol, - currency_space: app_shop.vars.currency_space, - currency_before_price: app_shop.vars.currency_before_value, - }) : false; + const unitMaxPrice = + sizeData?.price?.unit?.[priceType]?.formatted && + sizeData.price.max?.[priceType]?.value + ? format_price( + parseFloat(sizeData.price.max?.[priceType]?.value) * + parseFloat(sellBy), + { + mask: app_shop.vars.currency_format, + currency: app_shop.vars?.currency?.symbol, + currency_space: app_shop.vars.currency_space, + currency_before_price: app_shop.vars.currency_before_value, + } + ) + : false; const maxPrice = unitMaxPrice || sizeData.price.max?.[priceType]?.formatted; // Skrócona wersja omnibusa if (!maxPrice || maxPrice === omnibusPrice) { - classes.add.push('--omnibus-short'); - classes.remove = classes.remove.filter((item) => item !== '--omnibus-short'); + classes.add.push("--omnibus-short"); + classes.remove = classes.remove.filter( + (item) => item !== "--omnibus-short" + ); } // Aktywny kod rabatowy - if (app_shop.vars.omnibus?.rebateCodeActivate && sizeData.price?.rebateCodeActive) { - classes.add.push('--omnibus-code'); - activeLabel.rebateCodeActive = `${omnibusDetailsTxt?.['Kod rabatowy']}`; - classes.remove = classes.remove.filter((item) => item !== '--omnibus-code'); + if ( + app_shop.vars.omnibus?.rebateCodeActivate && + sizeData.price?.rebateCodeActive + ) { + classes.add.push("--omnibus-code"); + activeLabel.rebateCodeActive = `${omnibusDetailsTxt?.["Kod rabatowy"]}`; + classes.remove = classes.remove.filter((item) => item !== "--omnibus-code"); } // Skrócona wersja omnibusa, gdy aktywny kod rabatowy - const beforeRebatePrice = sizeData.price.beforeRebateDetails?.unit?.[priceType]?.formatted || sizeData.price.beforeRebate[priceType]?.formatted; - if (app_shop.vars.omnibus?.rebateCodeActivate && beforeRebatePrice === omnibusPrice && sizeData.price?.rebateCodeActive) { - classes.add.push('--omnibus-code-short'); - classes.remove = classes.remove.filter((item) => item !== '--omnibus-code-short'); + const beforeRebatePrice = + sizeData.price.beforeRebateDetails?.unit?.[priceType]?.formatted || + sizeData.price.beforeRebate[priceType]?.formatted; + if ( + app_shop.vars.omnibus?.rebateCodeActivate && + beforeRebatePrice === omnibusPrice && + sizeData.price?.rebateCodeActive + ) { + classes.add.push("--omnibus-code-short"); + classes.remove = classes.remove.filter( + (item) => item !== "--omnibus-code-short" + ); } // Nadchodząca cena - const newDate = sizeData.price.omnibusPriceDetails?.newPriceEffectiveUntil?.formatted; + const newDate = + sizeData.price.omnibusPriceDetails?.newPriceEffectiveUntil?.formatted; if (newDate && maxPrice) { - classes.add.push('--omnibus-new-price'); - classes.remove = classes.remove.filter((item) => item !== '--omnibus-new-price'); + classes.add.push("--omnibus-new-price"); + classes.remove = classes.remove.filter( + (item) => item !== "--omnibus-new-price" + ); } // Cena omnibusa wyższa niż cena sprzedaży - const higher = sizeData.price.omnibusPriceDetails?.omnibusPriceIsHigherThanSellingPrice; + const higher = + sizeData.price.omnibusPriceDetails?.omnibusPriceIsHigherThanSellingPrice; if (higher) { - classes.add.push('--omnibus-higher'); - classes.remove = classes.remove.filter((item) => item !== '--omnibus-higher'); + classes.add.push("--omnibus-higher"); + classes.remove = classes.remove.filter( + (item) => item !== "--omnibus-higher" + ); } // label okazja if ((!higher || newDate) && !activeLabel?.rebateCodeActive) { - activeLabel.bargain = `${omnibusDetailsTxt?.['Okazja']}`; + activeLabel.bargain = `${omnibusDetailsTxt?.["Okazja"]}`; } // label promocja if (Object.keys(activeLabel)?.length === 0) { - activeLabel.bargain = `${omnibusDetailsTxt?.['Promocja']}`; + activeLabel.bargain = `${omnibusDetailsTxt?.["Promocja"]}`; } - let omnibusPercentSign = ''; + let omnibusPercentSign = ""; if (higher) { - omnibusPercentSign = '-'; + omnibusPercentSign = "-"; } else if (sizeData.price.omnibusPriceDetails?.youSavePercent !== 0) { - omnibusPercentSign = '+'; + omnibusPercentSign = "+"; } const omnibusPercent = `${omnibusPercentSign}${sizeData.price.omnibusPriceDetails?.youSavePercent}%`; const omnibus = { price: omnibusPrice, visible: true, percent: omnibusPercent, - html: `${omnibusDetailsTxt['Najniższa cena produktu w okresie 30 dni przed wprowadzeniem obniżki']}: ${omnibusPrice}${omnibusPercent}`, + html: `${omnibusDetailsTxt["Najniższa cena produktu w okresie 30 dni przed wprowadzeniem obniżki"]}: ${omnibusPrice}${omnibusPercent}`, }; - const max = (maxPrice) ? { - max: { - price: maxPrice, - visible: true, - percent: `-${sizeData.price.youSavePercent}%`, - html: `${omnibusDetailsTxt['Cena regularna']}: + const max = maxPrice + ? { + max: { + price: maxPrice, + visible: true, + percent: `-${sizeData.price.youSavePercent}%`, + html: `${omnibusDetailsTxt["Cena regularna"]}: ${maxPrice}-${sizeData.price.youSavePercent}%`, - }, - } : {}; + }, + } + : {}; - const beforeRebate = (beforeRebatePrice) ? { - beforeRebate: { - price: beforeRebatePrice, - visible: !!classes.add.includes('--omnibus-code'), - percent: `-${sizeData.price.beforeRebateDetails?.youSavePercent}%`, - html: `${omnibusDetailsTxt['Cena bez kodu']}: + const beforeRebate = beforeRebatePrice + ? { + beforeRebate: { + price: beforeRebatePrice, + visible: !!classes.add.includes("--omnibus-code"), + percent: `-${sizeData.price.beforeRebateDetails?.youSavePercent}%`, + html: `${omnibusDetailsTxt["Cena bez kodu"]}: ${beforeRebatePrice} -${sizeData.price.beforeRebateDetails?.youSavePercent}%`, - }, - } : {}; + }, + } + : {}; - const newPriceEffectiveUntil = (newDate) ? { - newPriceEffectiveUntil: { - date: newDate, - price: maxPrice, - visible: !!classes.add.includes('--omnibus-new-price'), - html: `${omnibusDetailsTxt['Cena nadchodząca od']} + const newPriceEffectiveUntil = newDate + ? { + newPriceEffectiveUntil: { + date: newDate, + price: maxPrice, + visible: !!classes.add.includes("--omnibus-new-price"), + html: `${omnibusDetailsTxt["Cena nadchodząca od"]} ${newDate}: ${maxPrice}`, - }, - } : {}; + }, + } + : {}; const omnibusLabel = { omnibusLabel: { - name: Object.keys(activeLabel)?.[0] || '', + name: Object.keys(activeLabel)?.[0] || "", html: activeLabel[Object.keys(activeLabel)?.[0]], }, }; @@ -417,11 +485,12 @@ app_shop.fn.idmGetOmnibusDetails = (options) => { * Pobiera dane przez GraphQL, renderuje produkty, obsługuje dodawanie do koszyka, * inicjuje Swipera, ustawia wysokości, nasłuchuje zdarzeń i wykonuje lazy loading. */ -class IdmHotspot{ +class IdmHotspot { // ============================ // DOMYŚLNE USTAWIENIA SWIPERA // ============================ - static idmDefaultSwiperConfig = { // true, false, obiekt z opcjami swipera + static idmDefaultSwiperConfig = { + // true, false, obiekt z opcjami swipera loop: false, autoHeight: false, spaceBetween: 16, @@ -429,113 +498,132 @@ class IdmHotspot{ centeredSlides: true, centeredSlidesBounds: true, breakpoints: { - 550: { - slidesPerView: 2, - centeredSlides: true, - centeredSlidesBounds: true, - }, - 757:{ - slidesPerView: 3, - }, - 979: { - slidesPerView: 4, - centeredSlides: false, - }, + 550: { + slidesPerView: 2, + centeredSlides: true, + centeredSlidesBounds: true, + }, + 757: { + slidesPerView: 3, + }, + 979: { + slidesPerView: 4, + centeredSlides: false, + }, }, // navigation: { // nextEl: `#${this.id} .swiper-button-next`, // prevEl: `#${this.id} .swiper-button-prev`, // }, - } + }; // ============================ // DOMYŚLNE OPCJE HOTSPOTA // ============================ static idmDefaultHotspotOptions = { - cssVariables: { - version: { - columnDesktop: 5, - columnTablet: 4, - columnMobile: 4, - }, - nameClamp: null// 2, + cssVariables: { + version: { + columnDesktop: 5, + columnTablet: 4, + columnMobile: 4, }, - options: { - limit: 8, - lazy: true, - devMode: false, - callbackFn: ()=>{}, - omnibusTooltip: false, - // switchImage: false, + nameClamp: null, // 2, + }, + options: { + limit: 8, + lazy: true, + devMode: false, + callbackFn: () => {}, + omnibusTooltip: false, + // switchImage: false, - // POKAZANIE - showOpinions: false, - showProducer: false, // false, true, "img", "link", "img-link" - showSeries: false, // false, true, "link" - showSecondImage: false, + // POKAZANIE + showOpinions: false, + showProducer: false, // false, true, "img", "link", "img-link" + showSeries: false, // false, true, "link" + showSecondImage: false, - // DODAWANIE - addToBasket: true, // true, false, "range" - addToFavorites: false, // Wymaga zmian szablonowych - addToCompare: false, + // DODAWANIE + addToBasket: true, // true, false, "range" + addToFavorites: false, // Wymaga zmian szablonowych + addToCompare: false, - // WYBÓR - selectSize: false, - selectVersion: false, + // WYBÓR + selectSize: false, + selectVersion: false, - // SWIPER - swiper: true, - swiperScrollbar: false, - }, - } + // SWIPER + swiper: true, + swiperScrollbar: false, + }, + }; /** * Konstruktor * @param {object} object - Dane konfiguracyjne hotspotu */ - constructor({id, title, classes, placement, source, query, options = {}, banner, hotspotEl, products, cssVariables}){ - this.id = id || ""; - this.title = title || ""; - this.classes = classes || ""; - this.placement = placement || {}; - this.source = source || {}; - this.query = query || {}; - // this.type = type; - this.products = products || null; - this.productsVersions = []; + constructor({ + id, + title, + classes, + placement, + source, + query, + options = {}, + banner, + hotspotEl, + products, + cssVariables, + }) { + const defaultOptions = this.getDefaultHotspotOptions(); - this.hotspotEl = hotspotEl || null; + this.id = id || ""; + this.title = title || ""; + this.classes = classes || ""; + this.placement = placement || {}; + this.source = source || {}; + this.query = query || {}; + // this.type = type; + this.products = products || null; + this.productsVersions = []; - // Merge defaults - this.options = { - ...IdmHotspot.idmDefaultHotspotOptions.options, - ...options, - }; - this.cssVariables = { - ...IdmHotspot.idmDefaultHotspotOptions.cssVariables, - ...cssVariables, - }; + this.hotspotEl = hotspotEl || null; + // Merge defaults + this.options = { + ...defaultOptions.options, + ...options, + }; + this.cssVariables = { + ...defaultOptions.cssVariables, + ...cssVariables, + }; - this.banner = banner || false - - // this.hotspots = {}; - this.priceType = app_shop?.vars?.priceType || "gross"; + this.banner = banner || false; + // this.hotspots = {}; + this.priceType = app_shop?.vars?.priceType || "gross"; - // bind this do funkcji eventowych - this.handleAddToBasket = this.handleAddToBasket.bind(this); - this.handleQuantityButtonClick = this.handleQuantityButtonClick.bind(this); - 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.handleSelectVersion = this.handleSelectVersion.bind(this); - this.handleSelectSize = this.handleSelectSize.bind(this); - this.init(); + // bind this do funkcji eventowych + this.handleAddToBasket = this.handleAddToBasket.bind(this); + this.handleQuantityButtonClick = this.handleQuantityButtonClick.bind(this); + 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.handleSelectVersion = this.handleSelectVersion.bind(this); + this.handleSelectSize = this.handleSelectSize.bind(this); + this.init(); } - - + // ======================================================== + // GET DEFAULTS + // ======================================================== + getDefaultSwiperOptions() { + return IdmHotspot.idmDefaultSwiperConfig; + } + getDefaultHotspotOptions() { + return IdmHotspot.idmDefaultHotspotOptions; + } // ======================================================== // ASYNC – POBIERANIE DANYCH Z GRAPHQL @@ -543,113 +631,125 @@ class IdmHotspot{ /** * Przygotowuje funkcję i zapytanie GraphQL w zależności od typu danych. */ - getQueryData(){ + getQueryData() { let graphFn, query; let queryMarkup = ""; let additionalQuery = ""; - if(this.source?.hotspotsType){ + if (this.source?.hotspotsType) { graphFn = IDM_HOTSPOTS_GQL; queryMarkup += `hotspot: ${this.source.hotspotsType}, limit: ${this.options.limit}`; - }else{ + } else { graphFn = IDM_PRODUCTS_GQL; - if(this.source?.productsId){ + if (this.source?.productsId) { queryMarkup += `productsId: [${this.source.productsId}],`; - } - if(this.source?.productsMenu){ + } + if (this.source?.productsMenu) { queryMarkup += `navigation: ${this.source.productsMenu},`; } - if(this.source?.producersId){ + if (this.source?.producersId) { queryMarkup += `producers: [${this.source.producersId}],`; } - if(this.source?.seriesId){ + if (this.source?.seriesId) { queryMarkup += `series: [${this.source.seriesId}],`; } - if(this.source?.parametersId){ - queryMarkup += `parameters: [${this.source.parametersId.reduce((acc,val)=> acc + `{id: ${val}}`,"")}],`; + if (this.source?.parametersId) { + queryMarkup += `parameters: [${this.source.parametersId.reduce( + (acc, val) => acc + `{id: ${val}}`, + "" + )}],`; } - if(this.source?.priceRange){ - queryMarkup += `priceRange: {from: ${+this.source.priceRange?.from || 0}, to: ${+this.source.priceRange?.to || 0}},`; + if (this.source?.priceRange) { + queryMarkup += `priceRange: {from: ${ + +this.source.priceRange?.from || 0 + }, to: ${+this.source.priceRange?.to || 0}},`; } - if(this.options.limit) additionalQuery += `, settingsInput: {limit: ${this.options.limit}}` + if (this.options.limit) + additionalQuery += `, settingsInput: {limit: ${this.options.limit}}`; } - query = `searchInput: { ${queryMarkup} }${additionalQuery}` + query = `searchInput: { ${queryMarkup} }${additionalQuery}`; return [graphFn, query]; } - /** + /** * Ustawia dane zapytania GraphQL wewnątrz instancji. */ - setQueryData(){ - const [graphFn, queryString] = this.getQueryData(); - this.query.graphFn = graphFn; - this.query.string = queryString; + setQueryData() { + const [graphFn, queryString] = this.getQueryData(); + this.query.graphFn = graphFn; + this.query.string = queryString; } /** * Pobiera dane hotspotu z API GraphQL. */ - async getHotspotData(){ - if(this.products) return; - try{ + async getHotspotData() { + if (this.products) return; + try { let products; - if(this.source?.link){ + if (this.source?.link) { products = await this.xmlGetData(); - }else{ + } else { const res = await fetch(`/graphql/v1/`, { method: "POST", headers: { - "Content-Type": "application/json", + "Content-Type": "application/json", }, body: this.query.graphFn(this.query.string, this.priceType), }); const data = await res.json(); - products = data?.data?.[this.query.graphFn === IDM_HOTSPOTS_GQL ? "hotspots" : "products"]?.products; + products = + data?.data?.[ + this.query.graphFn === IDM_HOTSPOTS_GQL ? "hotspots" : "products" + ]?.products; this.title = this.title || data?.data?.hotspots?.name || ""; } - if(!products || !products.length) throw new Error(idmHotspotTextObject["Nie znaleziono produktów"]); + if (!products || !products.length) + throw new Error(idmHotspotTextObject["Nie znaleziono produktów"]); this.products = products; - }catch(err){ + } catch (err) { console.error(idmHotspotTextObject["Błąd przy pobieraniu danych"], err); return null; } - } + } - // ======================================================== + // ======================================================== // MARKUP – TWORZENIE HTML PRODUKTÓW // ======================================================== /** * Tworzy markup dla wszystkich produktów w hotspotcie. */ - markup(){ - let markup = ""; - this.products.forEach((prod)=>{ - markup += this.markupProduct(prod); - }) - return markup; + markup() { + let markup = ""; + this.products.forEach((prod) => { + markup += this.markupProduct(prod); + }); + return markup; } /** - * Tworzy markup dla pojedynczego produktu. - */ - markupProduct(prod){ - // markup pojedynczego produktu - let singleMarkup = ""; - singleMarkup += ` -
+ * Tworzy markup dla pojedynczego produktu. + */ + markupProduct(prod) { + // markup pojedynczego produktu + let singleMarkup = ""; + singleMarkup += ` +
${this.markupProductInnerHTML(prod)}
`; - - return singleMarkup; + + return singleMarkup; } - markupProductInnerHTML(prod){ + markupProductInnerHTML(prod) { return ``; } - markupAdditional(prod){ + markupAdditional(prod) { return ` ${this.markupCompare(prod)} ${this.markupFavorite(prod)} `; } - markupCompare(prod){ - if(!this.options?.addToCompare) return ""; + markupCompare(prod) { + if (!this.options?.addToCompare) return ""; return `` + `; } - markupFavorite(prod){ - if(!this.options?.addToFavorites || typeof this.addToFavFn !== "function" || this.hotspotEl.closest(".modal")) return ""; - + markupFavorite(prod) { + if ( + !this.options?.addToFavorites || + typeof this.addToFavFn !== "function" || + this.hotspotEl.closest(".modal") + ) + return ""; + return ` + data-product-size="${prod.sizes?.[0]?.id || "uniw"}" aria-label="${ + idmHotspotTextObject["Dodaj do ulubionych"] + }"> `; } - markupVersions(prod){ - if(!this.options?.selectVersion) return ""; - if(!prod.group?.versions || prod.group?.versions?.length < 2 ) return `
`; - - // let MAX_VERSION_AMOUNT = 5; - // if(app_shop.vars.view > 2){ - // MAX_VERSION_AMOUNT = this.cssVariables.version.columnDesktop; - // }else if(app_shop.vars.view === 2){ - // MAX_VERSION_AMOUNT = this.cssVariables.version.columnTablet; - // }else if(app_shop.vars.view === 1){ - // MAX_VERSION_AMOUNT = this.cssVariables.version.columnMobile; - // } + markupVersions(prod) { + if (!this.options?.selectVersion) return ""; + if (!prod.group?.versions || prod.group?.versions?.length < 2) + return `
`; const sortedVersions = prod.group.versions.sort(function (a, b) { if (a.name < b.name) { @@ -720,191 +823,282 @@ class IdmHotspot{ return 1; } return 0; - }) + }); - let productVersionsMarkup = sortedVersions.reduce((acc, val, index)=>{ - // if(index + 1 > MAX_VERSION_AMOUNT) return acc; - - // if(index + 1 === MAX_VERSION_AMOUNT && prod.group.versions.length > MAX_VERSION_AMOUNT) - // return acc + ` - // +${(prod.group.versions.length - MAX_VERSION_AMOUNT) + 1} - // `; + let productVersionsMarkup = sortedVersions.reduce((acc, val, index) => { + return ( + acc + + `${
+          val.name
+        }` + ); + }, ""); - return acc + `${val.name}`; - },""); - - const desktopMoreLength = (prod.group.versions.length - this.cssVariables.version.columnDesktop) + 1; - const tabletMoreLength = (prod.group.versions.length - this.cssVariables.version.columnTablet) + 1; - const mobileMoreLength = (prod.group.versions.length - this.cssVariables.version.columnMobile) + 1; + const desktopMoreLength = + prod.group.versions.length - this.cssVariables.version.columnDesktop + 1; + const tabletMoreLength = + prod.group.versions.length - this.cssVariables.version.columnTablet + 1; + const mobileMoreLength = + prod.group.versions.length - this.cssVariables.version.columnMobile + 1; return `` +
`; } - - markupImage(prod){ - let markup = ""; - if(prod.iconSmallSecond && prod.iconSecond) markup +=` + + markupImage(prod) { + let markup = ""; + if (prod.iconSmallSecond && prod.iconSecond) + markup += ` ${prod.name} `; - else if(prod?.iconSmall) markup += ` + else if (prod?.iconSmall) + markup += ` ${prod.name} `; - else markup += `${prod.name}`; + else + markup += `${prod.name}`; - if(this.options?.showSecondImage && prod.enclosuresImages?.[1]?.url) markup += `${prod.name} - ${idmHotspotTextObject[`; + if (this.options?.showSecondImage && prod.enclosuresImages?.[1]?.url) + markup += `${prod.name} - ${idmHotspotTextObject[`; - return markup; + return markup; } - markupLabel(prod){ - let labelMarkup = "" - // labele zones - if(prod.zones?.find(zone => zone ==="bestseller")) labelMarkup += `${idmHotspotTextObject["Bestseller"]}`; - if(prod.zones?.find(zone => zone ==="news")) labelMarkup += `${idmHotspotTextObject["Nowość"]}`; + markupLabel(prod) { + let labelMarkup = ""; + // labele zones + if (prod.zones?.find((zone) => zone === "bestseller")) + labelMarkup += `${idmHotspotTextObject["Bestseller"]}`; + if (prod.zones?.find((zone) => zone === "news")) + labelMarkup += `${idmHotspotTextObject["Nowość"]}`; - const omnibusPrice = prod.price?.omnibusPriceDetails?.unit?.[this.idmPriceType]?.formatted || prod.price.omnibusPrice[this.idmPriceType]?.formatted; - if(omnibusPrice){ - const newDate = prod.price.omnibusPriceDetails?.newPriceEffectiveUntil?.formatted; - const higher = prod.price.omnibusPriceDetails?.omnibusPriceIsHigherThanSellingPrice; - if (app_shop.vars.omnibus?.rebateCodeActivate && prod.price?.rebateCodeActive) { - labelMarkup += `${idmHotspotTextObject["Kod rabatowy"]}`; - }else if ((!higher || newDate) && !activeLabel?.rebateCodeActive) { - labelMarkup += `${idmHotspotTextObject["Okazja"]}`; - }else { - labelMarkup += `${idmHotspotTextObject["Promocja"]}`; - } + const omnibusPrice = + prod.price?.omnibusPriceDetails?.unit?.[this.idmPriceType]?.formatted || + prod.price.omnibusPrice[this.idmPriceType]?.formatted; + if (omnibusPrice) { + const newDate = + prod.price.omnibusPriceDetails?.newPriceEffectiveUntil?.formatted; + const higher = + prod.price.omnibusPriceDetails?.omnibusPriceIsHigherThanSellingPrice; + if ( + app_shop.vars.omnibus?.rebateCodeActivate && + prod.price?.rebateCodeActive + ) { + labelMarkup += `${idmHotspotTextObject["Kod rabatowy"]}`; + } else if ((!higher || newDate) && !activeLabel?.rebateCodeActive) { + labelMarkup += `${idmHotspotTextObject["Okazja"]}`; + } else { + labelMarkup += `${idmHotspotTextObject["Promocja"]}`; } + } - return labelMarkup; + return labelMarkup; } - markupOpinions(prod){ - if(!this.options?.showOpinions) return ""; + markupOpinions(prod) { + if (!this.options?.showOpinions) return ""; return `
- - - - - + + + + +
- ${prod.opinion.rating.toFixed(2)} / 5.00 -
` + ${prod.opinion.rating.toFixed( + 2 + )} / 5.00 + `; } - - markupProducer(prod){ - if(!this.options.showProducer) return ""; + markupProducer(prod) { + if (!this.options.showProducer) return ""; - const isImgIncluded = typeof this.options.showProducer === "string" && this.options.showProducer?.includes("img"); - const isLinkIncluded = typeof this.options.showProducer === "string" && this.options.showProducer?.includes("link"); + const isImgIncluded = + typeof this.options.showProducer === "string" && + this.options.showProducer?.includes("img"); + const isLinkIncluded = + typeof this.options.showProducer === "string" && + this.options.showProducer?.includes("link"); - if( - (!prod?.producer?.name && (typeof this.options.showProducer === "boolean" || isLinkIncluded)) - || + if ( + (!prod?.producer?.name && + (typeof this.options.showProducer === "boolean" || isLinkIncluded)) || (!prod?.producer?.searchIcons?.icon && isImgIncluded) - ) return `
`; - - let producerMarkup = isLinkIncluded && prod.producer?.link ? `` : ``; return producerMarkup; } - markupSeries(prod){ - if(!this.options.showSeries) return ""; - if(!prod?.series?.name) return `
`; - + markupSeries(prod) { + if (!this.options.showSeries) return ""; + if (!prod?.series?.name) return `
`; + let seriesMarkup = ""; - if(this.options.showSeries === "link" && prod.series.link){ - seriesMarkup = ` + if (this.options.showSeries === "link" && prod.series.link) { + seriesMarkup = ` ${prod.series.name} - ` - }else if(typeof this.options.showSeries === "boolean" || !prod.series.link){ + `; + } else if ( + typeof this.options.showSeries === "boolean" || + !prod.series.link + ) { seriesMarkup = `
${prod.series.name} -
` + `; } - return seriesMarkup + return seriesMarkup; } + markupPrice(prod, sizeId = false) { + let priceRoot = prod.price; - markupPrice(prod, sizeId=false){ - let priceRoot = prod.price; + const getOmnibusDetailsObject = { productData: prod }; + // Znalezienie ceny wybranego rozmiaru + if (this.options?.selectSize) { + const currentSizeId = + sizeId || + prod.sizes?.find((size) => size.amount !== 0)?.id || + prod.sizes?.size?.[0]?.id; - const getOmnibusDetailsObject = {productData: prod}; - // Znalezienie ceny wybranego rozmiaru - if(this.options?.selectSize){ - const currentSizeId = sizeId || prod.sizes?.find(size=>size.amount!==0)?.id || prod.sizes?.size?.[0]?.id; + priceRoot = + prod.sizes.find((size) => size.id === currentSizeId)?.price || + priceRoot; + getOmnibusDetailsObject.sizeId = currentSizeId; + } - priceRoot = prod.sizes.find(size=>size.id === currentSizeId)?.price || priceRoot; - getOmnibusDetailsObject.sizeId = currentSizeId; - }; + const prodExchangedData = + app_shop?.fn?.getOmnibusDetails?.(getOmnibusDetailsObject) || + app_shop.fn?.idmGetOmnibusDetails(getOmnibusDetailsObject); + const price = priceRoot.price[this.priceType]; + const unit = prod.unit; + const pointsPrice = prod?.points; + const convertedPrice = + priceRoot?.unitConvertedPrice?.[this.priceType]?.formatted; - const prodExchangedData = app_shop?.fn?.getOmnibusDetails?.(getOmnibusDetailsObject) || app_shop.fn?.idmGetOmnibusDetails(getOmnibusDetailsObject); - const price = priceRoot.price[this.priceType]; - const unit = prod.unit; - const pointsPrice = prod?.points; - const convertedPrice = priceRoot?.unitConvertedPrice?.[this.priceType]?.formatted; - - return ` -
- + return ` +
+ ${price.formatted} / - ${unit?.sellBy} - ${unit?.sellBy > 1 ? unit?.plural : unit?.singular} + ${unit?.sellBy} + ${ + unit?.sellBy > 1 ? unit?.plural : unit?.singular + } - ${convertedPrice && prod.unit?.unitConvertedFormat ? `(${convertedPrice} / ${prod.unit?.unitConvertedFormat})` : ""} + ${ + convertedPrice && prod.unit?.unitConvertedFormat + ? `(${convertedPrice} / ${prod.unit?.unitConvertedFormat})` + : "" + } - ${pointsPrice ? `${pointsPrice} pkt.` : ""} - ${price.value === 0 ? `${idmHotspotTextObject["Cena na telefon"]}` : ""} - ${prodExchangedData?.beforeRebate?.visible ? `${prodExchangedData?.beforeRebate?.html}` : ""} - ${prodExchangedData?.newPriceEffectiveUntil?.visible ? `${prodExchangedData?.newPriceEffectiveUntil?.html}` : ""} + ${ + pointsPrice + ? `${pointsPrice} pkt.` + : "" + } + ${ + price.value === 0 + ? `${idmHotspotTextObject["Cena na telefon"]}` + : "" + } + ${ + prodExchangedData?.beforeRebate?.visible + ? `${prodExchangedData?.beforeRebate?.html}` + : "" + } + ${ + prodExchangedData?.newPriceEffectiveUntil?.visible + ? `${prodExchangedData?.newPriceEffectiveUntil?.html}` + : "" + } ${this.markupOmnibus(prodExchangedData?.omnibus)} - ${prodExchangedData?.max?.visible ? `${prodExchangedData?.max?.html}` : ""} + ${ + prodExchangedData?.max?.visible + ? `${prodExchangedData?.max?.html}` + : "" + }
`; } - /** + /** * Tworzy znacznik HTML dla omnibusa. - * - * @param {object} omnibus - dane omnibusa - * @param {string} omnibus.html - kod html zwykłego omnibusa - * @param {string} omnibus.percent - % przeceny omnibusa - * @param {string} omnibus.price - cena omnibusa - * @param {boolean} omnibus.visible - czy omnibus jest widoczny - * @returns {string} Zwraca HTML dla sekcji omnibusa lub pusty string, jeśli niewidoczny. - */ - - markupOmnibus(omnibus){ - if(!omnibus?.visible) return ""; + * + * @param {object} omnibus - dane omnibusa + * @param {string} omnibus.html - kod html zwykłego omnibusa + * @param {string} omnibus.percent - % przeceny omnibusa + * @param {string} omnibus.price - cena omnibusa + * @param {boolean} omnibus.visible - czy omnibus jest widoczny + * @returns {string} Zwraca HTML dla sekcji omnibusa lub pusty string, jeśli niewidoczny. + */ - if(!this.options.omnibusTooltip) return `${omnibus?.html}`; - else return ` + markupOmnibus(omnibus) { + if (!omnibus?.visible) return ""; + + if (!this.options.omnibusTooltip) + return `${omnibus?.html}`; + else + return ` ${idmHotspotTextObject["Najniższa cena"]}: ${omnibus.price} @@ -917,34 +1111,57 @@ class IdmHotspot{ `; } - markupAddToBasket(prod){ + markupAddToBasket(prod) { let markup = ""; - if(!this.options.addToBasket) return markup; - - const prodCurrentSizeAmount = this.options.selectSize ? prod.sizes.find(size=>size.amount !== 0).amount : prod.sizes[0].amount; - const prodTotalAmount = this.options.selectSize ? this.getProdTotalAmount(prod) : prodCurrentSizeAmount; - + if (!this.options.addToBasket) return markup; + + const prodCurrentSizeAmount = this.options.selectSize + ? prod.sizes.find((size) => size.amount !== 0).amount + : prod.sizes[0].amount; + const prodTotalAmount = this.options.selectSize + ? this.getProdTotalAmount(prod) + : prodCurrentSizeAmount; + /* Sprawdzanie czy hotpsot znajduje się w formularzu */ - const addToBasketHTMLTag = this.isClosestForm ? "div" : "form"; + const addToBasketHTMLTag = this.isClosestForm ? "div" : "form"; - // link do produktu jak nie jest to zwykły produkt - const buttonMarkup = `` + `; - - if(prod.type !== "product" || prodTotalAmount === 0) markup = `Zobacz produkt`; - else if(this.options.addToBasket === "range") // +- - markup = `<${addToBasketHTMLTag} class="add_to_basket --range" ${this.isClosestForm ? "" : `action="/basketchange.php" type="post"`}> - - + if (prod.type !== "product" || prodTotalAmount === 0) + markup = `Zobacz produkt`; + else if (this.options.addToBasket === "range") + // +- + markup = `<${addToBasketHTMLTag} class="add_to_basket --range" ${ + this.isClosestForm ? "" : `action="/basketchange.php" type="post"` + }> + + ${this.markupSize(prod)}
- + - +
${buttonMarkup} `; - else // Zwykłe dodanie do koszyka - markup = ` - <${addToBasketHTMLTag} class="add_to_basket" ${this.isClosestForm ? "" : `action="/basketchange.php" type="post"`}> - - + // Zwykłe dodanie do koszyka + else + markup = ` + <${addToBasketHTMLTag} class="add_to_basket" ${ + this.isClosestForm ? "" : `action="/basketchange.php" type="post"` + }> + + ${this.markupSize(prod)} - + ${buttonMarkup} `; - return markup; + return markup; } - markupSize(prod){ + markupSize(prod) { // return ``; - if(!this.options?.selectSize || prod.sizes.length === 1) return ``; + if (!this.options?.selectSize || prod.sizes.length === 1) + return ``; - const sizesName = `${this.id}-${prod.id}`; let selectedDefault = false; return ` - +
- ${prod.sizes.reduce((acc, val, index)=>{ - const inputId = `${sizesName}-${val.id}`; + ${prod.sizes.reduce((acc, val, index) => { + const inputId = `${sizesName}-${val.id}`; - const isSelected = !selectedDefault && val?.amount !== 0 ? true : false; - if(isSelected) selectedDefault = true; + const isSelected = !selectedDefault && val?.amount !== 0 ? true : false; + if (isSelected) selectedDefault = true; - return acc + ` + return ( + acc + + ` ` - }, "")} + ); + }, "")}
`; } - markupHotspotContainer(){ - return `
+ markupHotspotContainer() { + return `
${this.markupHotspotInnerDiv()}
`; } - markupHotspotInnerDiv(){ + markupHotspotInnerDiv() { return `
- ${this?.title ? ` + ${ + this?.title + ? `

${this.title}

- ` : ""} + ` + : "" + } ${this.markupHotspotSwiperContainer()} -
` +
`; } - markupHotspotSwiperContainer(productsHTML=""){ + markupHotspotSwiperContainer(productsHTML = "") { return `
${productsHTML || this.markupSkeleton()} @@ -1030,16 +1277,13 @@ class IdmHotspot{
`; } - - - // SKELETONS MARKUPS - markupSkeleton(){ + markupSkeleton() { let skeletonMarkup = ""; // Tworzenie skeletonow - for(let i = 0; i <= this.options.limit; i++){ + for (let i = 0; i <= this.options.limit; i++) { skeletonMarkup += this.markupSingleSkeleton(); } @@ -1049,22 +1293,36 @@ class IdmHotspot{
`; } - markupSingleSkeleton(){ + markupSingleSkeleton() { return `
- ${this.options.showSeries ? `
` : ""} - ${this.options.showOpinions ? `
` : ""} + ${ + this.options.showSeries + ? `
` + : "" + } + ${ + this.options.showOpinions + ? `
` + : "" + }
- ${this.options.addToBasket ? `
` : ""} + ${ + this.options.addToBasket + ? `
` + : "" + }
- ` + `; } // Banner - markupBannerContainer({html, position}){ - return `
${html}
` + markupBannerContainer({ html, position }) { + return `
${html}
`; } // ======================================================== @@ -1074,12 +1332,14 @@ class IdmHotspot{ /** * Obsługuje dodanie produktu do koszyka (GraphQL). */ - async handleAddToBasket(e){ - const formEl = e.target.closest(`${this.isClosestForm ? "div" : "form"}.add_to_basket`); - if(!formEl) return; - try{ + async handleAddToBasket(e) { + const formEl = e.target.closest( + `${this.isClosestForm ? "div" : "form"}.add_to_basket` + ); + if (!formEl) return; + try { // pobieranie danych i elementów - formEl.classList.add("--loading") + formEl.classList.add("--loading"); const buttonEl = formEl.querySelector(".add_to_basket__button"); e.preventDefault(); @@ -1089,65 +1349,76 @@ class IdmHotspot{ // dodanie do koszyka const res = await fetch(`/graphql/v1/`, { - method: "POST", - headers: { + method: "POST", + headers: { "Content-Type": "application/json", - }, - body: IDM_HOTSPOT_ADD_TO_BASKET(id, size, number) + }, + body: IDM_HOTSPOT_ADD_TO_BASKET(id, size, number), }); const data = await res.json(); // Błąd - if(data?.data?.addProductsToBasket?.status !== "success") throw new Error(data); - else{ - localStorage.setItem('addedtoBasket', true); + if (data?.data?.addProductsToBasket?.status !== "success") + throw new Error(data); + else { + localStorage.setItem("addedtoBasket", true); // Obsługiwanie sukcesu - app_shop.fn?.menu_basket_cache?.(); + app_shop.fn?.menu_basket_cache(); await app_shop.graphql.trackingEvents(res); buttonEl.classList.add("--success"); - + // STRONA KOSZYKA - if(typeof app_shop.fn?.basket?.reloadForm === "function"){ - const existingBasketBlockQuantity = document.querySelector(`.basket__block[data-product-id="${id}"][data-product-size="${size}"] input.buy__more_input.quantity__input[type="number"]`); - + if (typeof app_shop.fn?.basket?.reloadForm === "function") { + const existingBasketBlockQuantity = document.querySelector( + `.basket__block[data-product-id="${id}"][data-product-size="${size}"] input.buy__more_input.quantity__input[type="number"]` + ); + // Dodanie do ilości produktu jeśli już był dodany do koszyka - if(existingBasketBlockQuantity) existingBasketBlockQuantity.value = +existingBasketBlockQuantity.value + number; - + if (existingBasketBlockQuantity) + existingBasketBlockQuantity.value = + +existingBasketBlockQuantity.value + number; + // Przeładowanie koszyka na stronie basketedit.html app_shop.fn?.basket?.reloadForm(); } buttonEl.innerHTML = `${buttonEl.dataset.success}`; - setTimeout(()=>{ - buttonEl.innerHTML = `${buttonEl.dataset.text}`; - buttonEl.classList.remove("--success"); + setTimeout(() => { + buttonEl.innerHTML = `${buttonEl.dataset.text}`; + buttonEl.classList.remove("--success"); }, 3000); } - }catch(err){ - console.error(err); - Alertek.Error(idmHotspotTextObject["Coś poszło nie tak podczas dodawania do koszyka. Spróbuj ponownie lub odśwież stronę"]); - buttonEl.innerHTML = `${buttonEl.dataset.error}`; - buttonEl.classList.add("--error") - setTimeout(()=>{ - buttonEl.classList.remove("--error") - buttonEl.innerHTML = `${buttonEl.dataset.text}`; - }, 3000); - }finally{ - formEl.classList.remove("--loading") + } catch (err) { + console.error(err); + Alertek.Error( + idmHotspotTextObject[ + "Coś poszło nie tak podczas dodawania do koszyka. Spróbuj ponownie lub odśwież stronę" + ] + ); + buttonEl.innerHTML = `${buttonEl.dataset.error}`; + buttonEl.classList.add("--error"); + setTimeout(() => { + buttonEl.classList.remove("--error"); + buttonEl.innerHTML = `${buttonEl.dataset.text}`; + }, 3000); + } finally { + formEl.classList.remove("--loading"); } } - /** + /** * Obsługuje dodanie produktu do Porównania */ - async handleAddToCompare(e){ + async handleAddToCompare(e) { const compareBtnEl = e.target.closest(".idm-products-banner__compare-btn"); const compareId = compareBtnEl?.dataset?.compareId; if (!compareBtnEl || !compareId) return; e.preventDefault(); try { compareBtnEl.classList.add("--loading"); - const compareUrl = `/${app_shop?.vars?.language?.symbol || "pl"}/settings.html?comparers=add&product=${compareId}`; + const compareUrl = `/${ + app_shop?.vars?.language?.symbol || "pl" + }/settings.html?comparers=add&product=${compareId}`; const res = await fetch(compareUrl); console.log(res); @@ -1170,19 +1441,21 @@ class IdmHotspot{ }, 2000); } catch (err) { console.error(err); - Alertek.Error(`${idmHotspotTextObject["Coś poszło nie tak. Spróbuj ponownie później"]}`); + Alertek.Error( + `${idmHotspotTextObject["Coś poszło nie tak. Spróbuj ponownie później"]}` + ); } finally { compareBtnEl.classList.remove("--loading"); } } - /** + /** * Obsługuje dodanie produktu do Listy zakupowej */ - handleAddToFav(e){ + handleAddToFav(e) { const favEl = e.target.closest(".product__favorite"); - if(!favEl) return; + if (!favEl) return; this.addToFavFn([[favEl.dataset.productId, favEl.dataset.productSize]]); } @@ -1190,10 +1463,11 @@ class IdmHotspot{ /** * Obsługuje kliknięcia w przyciski +/− przy wyborze ilości. */ - handleQuantityButtonClick(e){ - if(e.target.classList.contains("idm-products-banner__qty-input")) return e.target.select(); + handleQuantityButtonClick(e) { + if (e.target.classList.contains("idm-products-banner__qty-input")) + return e.target.select(); const wrapper = e.target.closest(".idm-products-banner__qty"); - + const input = wrapper.querySelector(".idm-products-banner__qty-input"); const step = parseFloat(wrapper.dataset.sellBy || "1"); const precision = parseInt(wrapper.dataset.precision || "0"); @@ -1202,33 +1476,35 @@ class IdmHotspot{ if (e.target.classList.contains("idm-products-banner__qty-increase")) { current += step; - if (current > max){ + if (current > max) { current = max; - this.rangeMaxAlert(max) + this.rangeMaxAlert(max); } - } else if (e.target.classList.contains("idm-products-banner__qty-decrease")) { + } else if ( + e.target.classList.contains("idm-products-banner__qty-decrease") + ) { current -= step; - if (current < step){ + if (current < step) { current = step; - this.rangeMinAlert(step) - } + this.rangeMinAlert(step); + } } input.value = current.toFixed(precision); } - /** + /** * Obsługuje Pokazywanie zdjęcia na hover */ - handleShowSecondImage(e){ + handleShowSecondImage(e) { const prodIconEl = e.target.closest(".product__icon"); - if(!prodIconEl) return; + if (!prodIconEl) return; prodIconEl.classList.add("--toggle-icon"); } - handleHideSecondImage(e){ + handleHideSecondImage(e) { const prodIconEl = e.target.closest(".product__icon"); - if(!prodIconEl) return; + if (!prodIconEl) return; prodIconEl.classList.remove("--toggle-icon"); } @@ -1236,80 +1512,90 @@ class IdmHotspot{ * Walidacja zmian ilości w polu input. */ - handleQuantityInputChange(e){ - if(e.target.value > +e.target.max){ - this.rangeMaxAlert(e.target.max) - e.target.value = +e.target.max - }else if(e.target.value < +e.target.min){ - this.rangeMinAlert(e.target.min) + handleQuantityInputChange(e) { + if (e.target.value > +e.target.max) { + this.rangeMaxAlert(e.target.max); + e.target.value = +e.target.max; + } else if (e.target.value < +e.target.min) { + this.rangeMinAlert(e.target.min); e.target.value = +e.target.min; } } - - handleSelectVersion(e){ - if(e.target.closest(".product__version_more")) return; + handleSelectVersion(e) { + if (e.target.closest(".product__version_more")) return; e.preventDefault(); - const closestVersion = e.target.closest(".product__version_single:not(.--active)"); + const closestVersion = e.target.closest( + ".product__version_single:not(.--active)" + ); const prodEl = e.target.closest(".product"); - if(!closestVersion || !prodEl) return; + if (!closestVersion || !prodEl) return; this.reloadProduct(prodEl, closestVersion.dataset.productId); } - handleSelectSize(e){ + handleSelectSize(e) { const inputEl = e.target.closest("input[type='radio']"); - if(!inputEl) return; + if (!inputEl) return; //1. Zmiana Wybranego inputa const sizeId = inputEl?.dataset?.value; - const hiddenSizeInputEl = e.target.closest("form.add_to_basket")?.querySelector("input.product__add_size"); + const hiddenSizeInputEl = e.target + .closest("form.add_to_basket") + ?.querySelector("input.product__add_size"); - if(!hiddenSizeInputEl || !sizeId) return inputEl.checked = false; + if (!hiddenSizeInputEl || !sizeId) return (inputEl.checked = false); hiddenSizeInputEl.value = sizeId; // 2. Zmiana ceny const productEl = e.target.closest(".product.hotspot__product"); - const productData = this.searchForProductData(+productEl?.dataset.id) - const currSizeData = productData?.sizes.find(size=>size.id === sizeId); - if(!currSizeData || !productData) return; + const productData = this.searchForProductData(+productEl?.dataset.id); + const currSizeData = productData?.sizes.find((size) => size.id === sizeId); + if (!currSizeData || !productData) return; const priceEl = productEl.querySelector(".product__prices"); - if(!priceEl) return; + if (!priceEl) return; priceEl.outerHTML = this.markupPrice(productData, sizeId); this.setHeightDefault(); // 3. Zmiana maksymalnej ilości produktu dozwolonego do kupienia dla range - if(this.options.addToBasket === "range"){ + if (this.options.addToBasket === "range") { const qtyContainer = productEl.querySelector(".idm-products-banner__qty"); - const qtyInput = qtyContainer?.querySelector("input.idm-products-banner__qty-input"); - if(!qtyContainer || !qtyInput) return console.error("Brak elementów qty"); - + const qtyInput = qtyContainer?.querySelector( + "input.idm-products-banner__qty-input" + ); + if (!qtyContainer || !qtyInput) + return console.error("Brak elementów qty"); qtyContainer.dataset.max = currSizeData.amount; qtyInput.max = currSizeData.amount; - if(qtyInput.value > currSizeData.amount) qtyInput.value = currSizeData.amount - (currSizeData.amount % +qtyInput.step); + if (qtyInput.value > currSizeData.amount) + qtyInput.value = + currSizeData.amount - (currSizeData.amount % +qtyInput.step); } } - /** + /** * Lazy-load hotspotu – wczytuje dane dopiero, gdy element pojawi się w viewportcie. */ handleObserveHotspotOnce() { if (!this.hotspotEl) return; - const observer = new IntersectionObserver((entries, obs) => { - entries.forEach(entry => { - if (entry.isIntersecting) { - this.fillHotspot(); // run your callback - obs.disconnect(); // stop observing after first trigger - } - }); - }, { root: null, rootMargin: "0px", threshold: 0.1 }); + const observer = new IntersectionObserver( + (entries, obs) => { + entries.forEach((entry) => { + if (entry.isIntersecting) { + this.fillHotspot(); // run your callback + obs.disconnect(); // stop observing after first trigger + } + }); + }, + { root: null, rootMargin: "0px", threshold: 0.1 } + ); observer.observe(this.hotspotEl); } @@ -1318,30 +1604,40 @@ class IdmHotspot{ // USTAWIANIE ZMIENNYCH CSS DLA RAMKI // ======================================================== // Ustawia się je w dwa sposoby - jako zmienne css przypisywane do ramki + jako dodaktowy tag style - cssSetAllVariables(){ + cssSetAllVariables() { this.cssVariableVersionColumnCount(); this.cssVariableNameClamp(); } - cssSetAllTags(){ + cssSetAllTags() { this.cssInsertStyleTag(); } - cssVariableNameClamp(){ - if(this.cssVariables?.nameClamp) this.cssSetVariable("--hotspot-name-clamp", this.cssVariables.nameClamp); + cssVariableNameClamp() { + if (this.cssVariables?.nameClamp) + this.cssSetVariable("--hotspot-name-clamp", this.cssVariables.nameClamp); } - cssVariableVersionColumnCount(){ - if(!this.options?.selectVersion) return false; - this.cssSetVariable("--version-desktop-columns", this.cssVariables?.version?.columnDesktop || 5) - this.cssSetVariable("--version-tablet-columns", this.cssVariables?.version?.columnTablet || 4) - this.cssSetVariable("--version-mobile-columns", this.cssVariables?.version?.columnMobile || 4) + cssVariableVersionColumnCount() { + if (!this.options?.selectVersion) return false; + this.cssSetVariable( + "--version-desktop-columns", + this.cssVariables?.version?.columnDesktop || 5 + ); + this.cssSetVariable( + "--version-tablet-columns", + this.cssVariables?.version?.columnTablet || 4 + ); + this.cssSetVariable( + "--version-mobile-columns", + this.cssVariables?.version?.columnMobile || 4 + ); } - cssSetVariable(name, value){ + cssSetVariable(name, value) { this.hotspotEl.style.setProperty(name, value); } - cssVersionColumnStyle(){ + cssVersionColumnStyle() { return ` @media (max-width: 756px){ #${this.hotspotEl.id}.hotspot__wrapper.idm__hotspot .product__version_single:nth-of-type(n + ${this.cssVariables?.version?.columnMobile}){ @@ -1358,53 +1654,61 @@ class IdmHotspot{ display: none; } } - ` + `; } - cssSkeletonStyle(){ + cssSkeletonStyle() { let skeletonStyles = ""; const skeletonStylesObj = {}; // Budowanie skeletona w zależności od ustawień hotspota - if(this.options.swiper){ + if (this.options.swiper) { skeletonStylesObj[0] = this.options.swiper?.slidesPerView; - for (const [key, value] of Object.entries(this.options.swiper.breakpoints)) { - if(value.slidesPerView) skeletonStylesObj[key] = value.slidesPerView + for (const [key, value] of Object.entries( + this.options.swiper.breakpoints + )) { + if (value.slidesPerView) skeletonStylesObj[key] = value.slidesPerView; } - }else{ + } else { // mobile 2 skeletonStylesObj[0] = 2; // desktop + tablet 4 skeletonStylesObj[757] = 4; } - for (const [key, value] of Object.entries(skeletonStylesObj)) { let style = ` - #${this.hotspotEl.id}.hotspot__wrapper.idm__hotspot.--hotspot-loading .idm_hotspot__skeleton_product{ + #${ + this.hotspotEl.id + }.hotspot__wrapper.idm__hotspot.--hotspot-loading .idm_hotspot__skeleton_product{ width: ${(1 / value) * 100}% } - ` - skeletonStyles += key === 0 ? style : ` + `; + skeletonStyles += + key === 0 + ? style + : ` @media (min-width: ${key}px){ ${style} } - ` + `; } return skeletonStyles; } - cssInsertStyleTag(){ - this.hotspotEl.insertAdjacentHTML("beforeend", ` + cssInsertStyleTag() { + this.hotspotEl.insertAdjacentHTML( + "beforeend", + ` `) + ` + ); } - - cssSetAll(){ + cssSetAll() { this.cssSetAllVariables(); this.cssSetAllTags(); } @@ -1412,108 +1716,117 @@ class IdmHotspot{ // FUNKCJE POMOCNICZE // ======================================================== - getProdTotalAmount(prod){ - return prod.sizes.reduce((acc, val) => val.amount === -1 || acc === -1 ? -1 : acc + val.amount, 0); + getProdTotalAmount(prod) { + return prod.sizes.reduce( + (acc, val) => (val.amount === -1 || acc === -1 ? -1 : acc + val.amount), + 0 + ); } /** * Wyświetla alert o maksymalnej ilości produktu. */ - rangeMaxAlert(max){ - Alertek.Error(`${idmHotspotTextObject["Maksymalna liczba sztuk tego towaru które możesz dodać do koszyka to:"]} ${max}`) + rangeMaxAlert(max) { + Alertek.Error( + `${idmHotspotTextObject["Maksymalna liczba sztuk tego towaru które możesz dodać do koszyka to:"]} ${max}` + ); } /** * Wyświetla alert o minimalnej ilości produktu. */ - rangeMinAlert(min){ - Alertek.Error(`${idmHotspotTextObject["Minimalna liczba sztuk tego towaru które możesz dodać do koszyka to:"]} ${min}`) + rangeMinAlert(min) { + Alertek.Error( + `${idmHotspotTextObject["Minimalna liczba sztuk tego towaru które możesz dodać do koszyka to:"]} ${min}` + ); } /** * Ustawia jednakową wysokość elementów (np. nazw lub cen). */ - - setHeight(options){ - const { selector, selectors, container } = options || {} - if ((!selector && !selectors) || !container) return - const containerElement = document.querySelector(container) - if (!containerElement) return + setHeight(options) { + const { selector, selectors, container } = options || {}; + if ((!selector && !selectors) || !container) return; - const adjustAllHeights = itemSelector => { - const targets = containerElement.querySelectorAll(itemSelector) - if (!targets.length) return + const containerElement = document.querySelector(container); + if (!containerElement) return; - targets.forEach(el => (el.style.minHeight = '')) + const adjustAllHeights = (itemSelector) => { + const targets = containerElement.querySelectorAll(itemSelector); + if (!targets.length) return; - const max = Math.max(...[...targets].map(el => el.offsetHeight || 0)) + targets.forEach((el) => (el.style.minHeight = "")); - targets.forEach(el => (el.style.minHeight = `${max}px`)) - } + const max = Math.max(...[...targets].map((el) => el.offsetHeight || 0)); - if (selector) adjustAllHeights(selector) - if (selectors?.length) selectors.forEach(adjustAllHeights) + targets.forEach((el) => (el.style.minHeight = `${max}px`)); + }; + + if (selector) adjustAllHeights(selector); + if (selectors?.length) selectors.forEach(adjustAllHeights); } - setHeightDefault(){ + setHeightDefault() { this.setHeight({ selectors: [ - `#${this.id} .product__prices`, - `#${this.id} .product__name`, - `#${this.id} .product__series`, - `#${this.id} .product__producer`, + `#${this.id} .product__prices`, + `#${this.id} .product__name`, + `#${this.id} .product__series`, + `#${this.id} .product__producer`, ], container: `#${this.id} .products__wrapper`, }); } - /** * Przeładowanie pojedynczego produktu */ - async reloadProduct(prodEl, newProdId){ - try{ + async reloadProduct(prodEl, newProdId) { + try { prodEl.classList.add("--loading"); let productData = this.searchForProductData(newProdId); - if(!productData){ + if (!productData) { const res = await fetch(`/graphql/v1/`, { method: "POST", headers: { - "Content-Type": "application/json", + "Content-Type": "application/json", }, body: IDM_PRODUCT_GQL(`productId: ${newProdId}`, this.priceType), }); const data = await res.json(); productData = data?.data?.product?.product; - if(productData) this.productsVersions.push(productData); + if (productData) this.productsVersions.push(productData); } - if(!productData) throw new Error("Nie udało się pobrać danych o produkcie"); - + 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"); + if (productData.price.price[this.priceType].value === 0) + prodEl.classList.add("--phone"); else prodEl.classList.remove("--phone"); this.initSingleEvent(prodEl); this.setHeightDefault(); - }catch(err){ + } catch (err) { Alertek?.Error(idmHotspotTextObject["Błąd przy pobieraniu danych"]); console.error(err); - }finally{ + } finally { prodEl.classList.remove("--loading"); } } - - searchForProductData(searchedId){ + searchForProductData(searchedId) { let productData; - productData = this.products.find(prod=>prod.id === +searchedId) || this.productsVersions.find(prod=>prod.id === +searchedId) || null; + productData = + this.products.find((prod) => prod.id === +searchedId) || + this.productsVersions.find((prod) => prod.id === +searchedId) || + null; return productData; } @@ -1521,335 +1834,463 @@ class IdmHotspot{ // ======================================================== // XML to GraphQL // ======================================================== - xmlGetGrossNetPrices({priceNode, name}){ + xmlGetGrossNetPrices({ priceNode, name }) { return { - gross: { - value: priceNode?.getAttribute(`${name}`) !== null ? +priceNode.getAttribute(`${name}`) : undefined, - formatted: priceNode?.getAttribute(`${name}_formatted`), - }, - net: { - value: priceNode?.getAttribute(`${name}_net`) !== null ? +priceNode.getAttribute(`${name}_net`) : undefined, - formatted: priceNode?.getAttribute(`${name}_net_formatted`), - } - } + gross: { + value: + priceNode?.getAttribute(`${name}`) !== null + ? +priceNode.getAttribute(`${name}`) + : undefined, + formatted: priceNode?.getAttribute(`${name}_formatted`), + }, + net: { + value: + priceNode?.getAttribute(`${name}_net`) !== null + ? +priceNode.getAttribute(`${name}_net`) + : undefined, + formatted: priceNode?.getAttribute(`${name}_net_formatted`), + }, + }; } - xmlGetPriceFromNode(priceNode){ + xmlGetPriceFromNode(priceNode) { const priceObj = { - price: { - gross: { - value: priceNode?.getAttribute("value") !== null ? +priceNode.getAttribute("value") : undefined, - formatted: priceNode?.getAttribute("price_formatted"), - }, - net: { - value: priceNode?.getAttribute("price_net") !== null ? +priceNode.getAttribute("price_net") : undefined, - formatted: priceNode?.getAttribute("price_net_formatted"), - } + price: { + gross: { + value: + priceNode?.getAttribute("value") !== null + ? +priceNode.getAttribute("value") + : undefined, + formatted: priceNode?.getAttribute("price_formatted"), }, - rebateCodeActive: priceNode?.getAttribute("rebate_code_active") === "y" ? true : false, - omnibusPrice: { - ...this.xmlGetGrossNetPrices({priceNode, name: "omnibus_price"}) + net: { + value: + priceNode?.getAttribute("price_net") !== null + ? +priceNode.getAttribute("price_net") + : undefined, + formatted: priceNode?.getAttribute("price_net_formatted"), }, - // depositPrice: {}, - // depositPriceUnit: {}, - // totalDepositPrice: {}, - // totalDepositPriceUnit: {}, - omnibusPriceDetails: { - // unit: {}, - youSave: { - ...this.xmlGetGrossNetPrices({priceNode, name: "omnibus_yousave"}) - }, - youSavePercent: priceNode?.getAttribute("price_net") !== null ? +priceNode.getAttribute("omnibus_yousave_percent") : undefined, - omnibusPriceIsHigherThanSellingPrice: priceNode?.getAttribute("omnibus_price_is_higher_than_selling_price") === "true" ? true : false, - // newPriceEffectiveUntil: {}, - }, - tax: { - // worth: {}, - vatPercent: priceNode?.getAttribute("tax") !== null ? +priceNode.getAttribute("tax") : undefined, - // vatString: "" - }, - beforeRebate: { - ...this.xmlGetGrossNetPrices({priceNode, name: "beforerebate"}) - }, - // beforeRebateDetails: { - // youSave: { - - // }, - // youSavePercent: "", - // unit: {} - // }, - // crossedPrice: {}, - youSave: { - ...this.xmlGetGrossNetPrices({priceNode, name: "yousave"}) - }, - youSavePercent: priceNode?.getAttribute("yousave_percent") !== null ? +priceNode.getAttribute("yousave_percent") : undefined, + }, + rebateCodeActive: + priceNode?.getAttribute("rebate_code_active") === "y" ? true : false, + omnibusPrice: { + ...this.xmlGetGrossNetPrices({ priceNode, name: "omnibus_price" }), + }, + // depositPrice: {}, + // depositPriceUnit: {}, + // totalDepositPrice: {}, + // totalDepositPriceUnit: {}, + omnibusPriceDetails: { // unit: {}, - max: { - ...this.xmlGetGrossNetPrices({priceNode, name: "maxprice"}) + youSave: { + ...this.xmlGetGrossNetPrices({ priceNode, name: "omnibus_yousave" }), }, - // maxPriceUnit: {}, - // suggested: {}, - unitConvertedPrice: { - ...this.xmlGetGrossNetPrices({priceNode, name: "unit_converted_price"}) + youSavePercent: + priceNode?.getAttribute("price_net") !== null + ? +priceNode.getAttribute("omnibus_yousave_percent") + : undefined, + omnibusPriceIsHigherThanSellingPrice: + priceNode?.getAttribute( + "omnibus_price_is_higher_than_selling_price" + ) === "true" + ? true + : false, + // newPriceEffectiveUntil: {}, + }, + tax: { + // worth: {}, + vatPercent: + priceNode?.getAttribute("tax") !== null + ? +priceNode.getAttribute("tax") + : undefined, + // vatString: "" + }, + beforeRebate: { + ...this.xmlGetGrossNetPrices({ priceNode, name: "beforerebate" }), + }, + // beforeRebateDetails: { + // youSave: { + + // }, + // youSavePercent: "", + // unit: {} + // }, + // crossedPrice: {}, + youSave: { + ...this.xmlGetGrossNetPrices({ priceNode, name: "yousave" }), + }, + youSavePercent: + priceNode?.getAttribute("yousave_percent") !== null + ? +priceNode.getAttribute("yousave_percent") + : undefined, + // unit: {}, + max: { + ...this.xmlGetGrossNetPrices({ priceNode, name: "maxprice" }), + }, + // maxPriceUnit: {}, + // suggested: {}, + unitConvertedPrice: { + ...this.xmlGetGrossNetPrices({ + priceNode, + name: "unit_converted_price", + }), + }, + // rebateNumber: {}, + lastPriceChangeDate: priceNode?.getAttribute("last_price_change_date"), + // advancePrice: {}, + promotionDuration: { + promotionTill: { + date: { + date: priceNode + ?.getAttribute("last_price_change_date") + ?.split("-")?.[2], + month: priceNode + ?.getAttribute("last_price_change_date") + ?.split("-")?.[1], + year: priceNode + ?.getAttribute("last_price_change_date") + ?.split("-")?.[0], + // weekDay: "", + // formatted: "" + }, + time: { + hour: priceNode?.getAttribute("promotiontillhour")?.split(":")?.[0], + minutes: priceNode + ?.getAttribute("promotiontillhour") + ?.split(":")?.[1], + seconds: priceNode + ?.getAttribute("promotiontillhour") + ?.split(":")?.[2], + }, + // timestamp: "" }, - // rebateNumber: {}, - lastPriceChangeDate: priceNode?.getAttribute("last_price_change_date"), - // advancePrice: {}, - promotionDuration: { - promotionTill: { - date: { - date: priceNode?.getAttribute("last_price_change_date")?.split("-")?.[2], - month: priceNode?.getAttribute("last_price_change_date")?.split("-")?.[1], - year: priceNode?.getAttribute("last_price_change_date")?.split("-")?.[0], - // weekDay: "", - // formatted: "" - }, - time: { - hour: priceNode?.getAttribute("promotiontillhour")?.split(":")?.[0], - minutes: priceNode?.getAttribute("promotiontillhour")?.split(":")?.[1], - seconds: priceNode?.getAttribute("promotiontillhour")?.split(":")?.[2], - }, - // timestamp: "" - }, - // discountTill: {}, - // distinguishedTill: {}, - // specialTill: {}, - }, - // subscriptionPrice: {}, + // discountTill: {}, + // distinguishedTill: {}, + // specialTill: {}, + }, + // subscriptionPrice: {}, }; return priceObj; } - xmlGetTraitsFromNode(node){ + xmlGetTraitsFromNode(node) { const awardedParameters = []; - node.querySelectorAll(":scope > trait").forEach(trait=>{ - const currParameter = awardedParameters.find(param=>param.id === trait.getAttribute("groupid")) || { - id: trait.getAttribute("groupid"), - name: trait.getAttribute("groupdescription"), - // description: "", - values: [], - // contextValue: "", - // search: { - // icon: "", - // }, - } + node.querySelectorAll(":scope > trait").forEach((trait) => { + const currParameter = awardedParameters.find( + (param) => param.id === trait.getAttribute("groupid") + ) || { + id: trait.getAttribute("groupid"), + name: trait.getAttribute("groupdescription"), + // description: "", + values: [], + // contextValue: "", + // search: { + // icon: "", + // }, + }; - currParameter.values.push({ - id: trait.getAttribute("traitid"), - name: trait.getAttribute("traitid"), - link: trait.getAttribute("link"), - // description: "", - // search: { - // icon: "" - // } - }) + currParameter.values.push({ + id: trait.getAttribute("traitid"), + name: trait.getAttribute("traitid"), + link: trait.getAttribute("link"), + // description: "", + // search: { + // icon: "" + // } + }); - - if(currParameter.values.length === 1) awardedParameters.push(currParameter); + if (currParameter.values.length === 1) + awardedParameters.push(currParameter); }); - return awardedParameters; } - async xmlGetData(){ - if(!this.source?.link) return null; - try{ - const res = await fetch(`${this.source?.link}${this.source?.link.includes("?") ? "&getProductXML=t" : "?getProductXML=t"}`); + async xmlGetData() { + if (!this.source?.link) return null; + try { + const res = await fetch( + `${this.source?.link}${ + this.source?.link.includes("?") + ? "&getProductXML=t" + : "?getProductXML=t" + }` + ); const str = await res.text(); const xml = new window.DOMParser().parseFromString(str, "text/xml"); const now = new Date(); const allProducts = xml.querySelectorAll("product"); - if(allProducts.length === 0) throw new Error("Nie znaleziono produktów"); - + if (allProducts.length === 0) throw new Error("Nie znaleziono produktów"); + const data = []; + allProducts.forEach((prod, index) => { + if (this.options.limit <= index) return; - allProducts.forEach((prod, index)=>{ - if(this.options.limit <= index) return; + // NODES + const priceNode = prod.querySelector(":scope >price"); + const firmNode = prod.querySelector(":scope > firm"); + const categoryNode = prod.querySelector(":scope > category"); + const seriesNode = prod.querySelector(":scope > series"); + const commentsNode = prod.querySelector(":scope > comments"); + const sizesNode = prod.querySelector(":scope > sizes"); + const versionsNode = prod.querySelector(":scope > versions"); - // NODES - const priceNode = prod.querySelector(":scope >price"); - const firmNode = prod.querySelector(":scope > firm"); - const categoryNode = prod.querySelector(":scope > category"); - const seriesNode = prod.querySelector(":scope > series"); - const commentsNode = prod.querySelector(":scope > comments"); - const sizesNode = prod.querySelector(":scope > sizes"); - const versionsNode = prod.querySelector(":scope > versions"); + // STREFY + const zones = []; - // STREFY - const zones = []; + if (prod.getAttribute("promo") === "yes") zones.push("promotion"); + if (prod.getAttribute("discount") === "yes") zones.push("discount"); + if (prod.getAttribute("distinguished") === "yes") + zones.push("distinguished"); + if (prod.getAttribute("special") === "yes") zones.push("special"); + if (prod.getAttribute("new") === "yes") zones.push("new"); + if (prod.getAttribute("bestseller") === "yes") zones.push("bestseller"); + if (prod.getAttribute("subscription") === "yes") + zones.push("subscription"); - if(prod.getAttribute("promo") === "yes") zones.push("promotion"); - if(prod.getAttribute("discount") === "yes") zones.push("discount"); - if(prod.getAttribute("distinguished") === "yes") zones.push("distinguished"); - if(prod.getAttribute("special") === "yes") zones.push("special"); - if(prod.getAttribute("new") === "yes") zones.push("new"); - if(prod.getAttribute("bestseller") === "yes") zones.push("bestseller"); - if(prod.getAttribute("subscription") === "yes") zones.push("subscription"); - - // ZDJĘCIA - const enclosuresImages = []; - prod.querySelectorAll(":scope > enclosures > images > enclosure").forEach(img=>{ - enclosuresImages.push({ - position: img.getAttribute("position"), - type: img.getAttribute("type"), - typeSecond: img.getAttribute("type_second"), - url: img.getAttribute("url"), - urlSecond: img.getAttribute("url_second"), - width: img.getAttribute("width"), - height: img.getAttribute("height"), - iconUrl: img.getAttribute("icon"), - iconUrlSecond: img.getAttribute("icon_second"), - iconWidth: img.getAttribute("icon_width"), - iconHeight: img.getAttribute("icon_height"), - mediumUrl: img.getAttribute("medium"), - mediumUrlSecond: img.getAttribute("medium_second"), - mediumWidth: img.getAttribute("medium_width"), - mediumHeight: img.getAttribute("medium_height"), - }) - }) - - // SIZES - const sizes = []; - sizesNode.querySelectorAll(":scope > size").forEach(size=>{ - const availabilityNode = size.querySelector(":scope > availability"); - const shippingTimeNode = availabilityNode.querySelector(":scope > shipping_time"); - const sizePriceNode = size.querySelector(":scope > price"); - const weightNode = size.querySelector(":scope > weight"); - - sizes.push({ - id: size?.getAttribute("type"), - name: size?.getAttribute("name"), - code: size?.getAttribute("code"), - codeProducer: size?.getAttribute("code_producer"), - codeExtern: size?.getAttribute("code_extern"), - amount: size?.getAttribute("amount") !== null ? +size.getAttribute("amount") : undefined, - amount_mo: size?.getAttribute("amount_mo") !== null ? +size.getAttribute("amount_mo") : undefined, - amount_mw: size?.getAttribute("amount_mw") !== null ? +size.getAttribute("amount_mw") : undefined, - amount_mp: size?.getAttribute("amount_mp") !== null ? +size.getAttribute("amount_mp") : undefined, - weight: weightNode?.getAttribute("g") !== null ? +weightNode.getAttribute("g") : undefined, - availability: { - visible: availabilityNode?.getAttribute("visible") === "y" ? true : false, - description: availabilityNode?.getAttribute("status_description"), - status: availabilityNode?.getAttribute("status"), - icon: availabilityNode?.getAttribute("status_gfx"), - deliveryDate: shippingTimeNode?.getAttribute("today") === "true" ? `${now.getFullYear()}-${now.getMonth() + 1}-${now.getDate().toString().padStart(2, 0)}` : availabilityNode?.getAttribute("delivery_date"), - minimumStockOfProduct: availabilityNode?.getAttribute("minimum_stock_of_product"), - // descriptionTel: "", - // iconTel: "", - }, - shipping: { - today: shippingTimeNode?.getAttribute("today") === "true" ? true : false, - }, - price: this.xmlGetPriceFromNode(sizePriceNode), - // amountWholesale: "", - }) - }) - - // VERSIONS - const versions = []; - versionsNode.querySelectorAll(":scope > version").forEach(ver=>{ - versions.push({ - id: ver?.getAttribute("id") !== null ? +ver?.getAttribute("id") : undefined, - name: ver?.getAttribute("name"), - icon: ver?.getAttribute("gfx"), - iconSecond: ver?.getAttribute("gfx_second"), - iconSmall: ver?.getAttribute("gfx_small"), - iconSmallSecond: ver?.getAttribute("gfx_small_second"), - productIcon: ver?.getAttribute("icon"), - productIconSecond: ver?.getAttribute("icon_second"), - productIconSmall: ver?.getAttribute("icon_small"), - productIconSmallSecond: ver?.getAttribute("icon_small_second"), - link: ver?.getAttribute("link"), - // parameterValues: [], - }); + // ZDJĘCIA + const enclosuresImages = []; + prod + .querySelectorAll(":scope > enclosures > images > enclosure") + .forEach((img) => { + enclosuresImages.push({ + position: img.getAttribute("position"), + type: img.getAttribute("type"), + typeSecond: img.getAttribute("type_second"), + url: img.getAttribute("url"), + urlSecond: img.getAttribute("url_second"), + width: img.getAttribute("width"), + height: img.getAttribute("height"), + iconUrl: img.getAttribute("icon"), + iconUrlSecond: img.getAttribute("icon_second"), + iconWidth: img.getAttribute("icon_width"), + iconHeight: img.getAttribute("icon_height"), + mediumUrl: img.getAttribute("medium"), + mediumUrlSecond: img.getAttribute("medium_second"), + mediumWidth: img.getAttribute("medium_width"), + mediumHeight: img.getAttribute("medium_height"), + }); }); - // DATA - const typeParts = prod?.getAttribute("product_type").split("_"); - data.push({ - id: prod?.getAttribute("id") !== null ? +prod?.getAttribute("id") : undefined, - type: typeParts[1] === "item" ? typeParts[0] : typeParts[1], - code: prod?.getAttribute("code"), - name: prod.querySelector(":scope > name")?.textContent, - versionName: prod.querySelector(":scope > versions")?.getAttribute("name"), - description: prod.querySelector(":scope > description")?.textContent, - // longDescription: prod.querySelector("vlongdescription")?.textContent, - // longDescriptionSections: "", - link: prod?.getAttribute("link"), - zones, - icon: prod.querySelector(":scope > icon")?.textContent, - iconSecond: prod.querySelector(":scope > icon_second")?.textContent, - iconSmall: prod.querySelector(":scope > icon_small")?.textContent, - iconSmallSecond: prod.querySelector(":scope > icon_small_second")?.textContent, - price: this.xmlGetPriceFromNode(priceNode), - unit: { - id: sizesNode?.getAttribute("unit_id"), - name: sizesNode?.getAttribute("unit"), - singular: sizesNode?.getAttribute("unit_single"), - plural: sizesNode?.getAttribute("unit_plural"), - fraction: sizesNode?.getAttribute("unit_fraction"), - sellBy: sizesNode?.getAttribute("unit_sellby") !== null ? +sizesNode?.getAttribute("unit_sellby") : undefined, - precision: sizesNode?.getAttribute("unit_precision") !== null ? +sizesNode?.getAttribute("unit_precision") : undefined, - unitConvertedFormat: sizesNode?.getAttribute("unit_converted_format"), - }, - producer: { - id: firmNode?.getAttribute("id") !== null ? +firmNode?.getAttribute("id") : undefined, - name: firmNode?.getAttribute("name"), - link: firmNode?.getAttribute("productslink"), - searchIcons: { - icon: firmNode?.getAttribute("icon"), - }, - // projectorIcons: {}, - }, - category: { - id: categoryNode?.getAttribute("id") !== null ? +categoryNode?.getAttribute("id") : undefined, - name: categoryNode?.getAttribute("name"), - link: categoryNode?.getAttribute("productslink") - }, - group: { - id: versionsNode?.getAttribute("id") !== null ? +versionsNode?.getAttribute("id") : undefined, - name: versionsNode?.getAttribute("name"), - displayAll: versionsNode?.getAttribute("display_all") === "true" ? true : false, - link: versionsNode?.getAttribute("link"), - versions, - groupParameters: this.xmlGetTraitsFromNode(versionsNode.querySelector(":scope > groupParameters")) - }, - opinion: { - rating: commentsNode?.getAttribute("avg") !== null ? +commentsNode?.getAttribute("avg") : undefined, - count: commentsNode?.getAttribute("count") !== null ? +commentsNode?.getAttribute("count") : undefined, - link: commentsNode?.getAttribute("link") - }, - enclosuresImages, - // enclosuresAttachments: [], - series: { - id: seriesNode?.getAttribute("id") !== null ? +seriesNode?.getAttribute("id") : undefined, - name: seriesNode?.getAttribute("name"), - link: seriesNode?.getAttribute("link") - }, - awardedParameters: this.xmlGetTraitsFromNode(prod.querySelector(":scope > traits")), - // parameteresWithContext: [], - sizes, - points: priceNode?.getAttribute("points") !== null ? +priceNode?.getAttribute("points") : undefined, - pointsReceive: priceNode?.getAttribute("points_recive") !== null ? +priceNode?.getAttribute("points_recive") : undefined, - // subscription: {}, - // bundled: [], - // responsibleEntity: {}, - }) - }) + // SIZES + const sizes = []; + sizesNode.querySelectorAll(":scope > size").forEach((size) => { + const availabilityNode = size.querySelector(":scope > availability"); + const shippingTimeNode = availabilityNode.querySelector( + ":scope > shipping_time" + ); + const sizePriceNode = size.querySelector(":scope > price"); + const weightNode = size.querySelector(":scope > weight"); + + sizes.push({ + id: size?.getAttribute("type"), + name: size?.getAttribute("name"), + code: size?.getAttribute("code"), + codeProducer: size?.getAttribute("code_producer"), + codeExtern: size?.getAttribute("code_extern"), + amount: + size?.getAttribute("amount") !== null + ? +size.getAttribute("amount") + : undefined, + amount_mo: + size?.getAttribute("amount_mo") !== null + ? +size.getAttribute("amount_mo") + : undefined, + amount_mw: + size?.getAttribute("amount_mw") !== null + ? +size.getAttribute("amount_mw") + : undefined, + amount_mp: + size?.getAttribute("amount_mp") !== null + ? +size.getAttribute("amount_mp") + : undefined, + weight: + weightNode?.getAttribute("g") !== null + ? +weightNode.getAttribute("g") + : undefined, + availability: { + visible: + availabilityNode?.getAttribute("visible") === "y" + ? true + : false, + description: availabilityNode?.getAttribute("status_description"), + status: availabilityNode?.getAttribute("status"), + icon: availabilityNode?.getAttribute("status_gfx"), + deliveryDate: + shippingTimeNode?.getAttribute("today") === "true" + ? `${now.getFullYear()}-${now.getMonth() + 1}-${now + .getDate() + .toString() + .padStart(2, 0)}` + : availabilityNode?.getAttribute("delivery_date"), + minimumStockOfProduct: availabilityNode?.getAttribute( + "minimum_stock_of_product" + ), + // descriptionTel: "", + // iconTel: "", + }, + shipping: { + today: + shippingTimeNode?.getAttribute("today") === "true" + ? true + : false, + }, + price: this.xmlGetPriceFromNode(sizePriceNode), + // amountWholesale: "", + }); + }); + + // VERSIONS + const versions = []; + versionsNode.querySelectorAll(":scope > version").forEach((ver) => { + versions.push({ + id: + ver?.getAttribute("id") !== null + ? +ver?.getAttribute("id") + : undefined, + name: ver?.getAttribute("name"), + icon: ver?.getAttribute("gfx"), + iconSecond: ver?.getAttribute("gfx_second"), + iconSmall: ver?.getAttribute("gfx_small"), + iconSmallSecond: ver?.getAttribute("gfx_small_second"), + productIcon: ver?.getAttribute("icon"), + productIconSecond: ver?.getAttribute("icon_second"), + productIconSmall: ver?.getAttribute("icon_small"), + productIconSmallSecond: ver?.getAttribute("icon_small_second"), + link: ver?.getAttribute("link"), + // parameterValues: [], + }); + }); + + // DATA + const typeParts = prod?.getAttribute("product_type").split("_"); + data.push({ + id: + prod?.getAttribute("id") !== null + ? +prod?.getAttribute("id") + : undefined, + type: typeParts[1] === "item" ? typeParts[0] : typeParts[1], + code: prod?.getAttribute("code"), + name: prod.querySelector(":scope > name")?.textContent, + versionName: prod + .querySelector(":scope > versions") + ?.getAttribute("name"), + description: prod.querySelector(":scope > description")?.textContent, + // longDescription: prod.querySelector("vlongdescription")?.textContent, + // longDescriptionSections: "", + link: prod?.getAttribute("link"), + zones, + icon: prod.querySelector(":scope > icon")?.textContent, + iconSecond: prod.querySelector(":scope > icon_second")?.textContent, + iconSmall: prod.querySelector(":scope > icon_small")?.textContent, + iconSmallSecond: prod.querySelector(":scope > icon_small_second") + ?.textContent, + price: this.xmlGetPriceFromNode(priceNode), + unit: { + id: sizesNode?.getAttribute("unit_id"), + name: sizesNode?.getAttribute("unit"), + singular: sizesNode?.getAttribute("unit_single"), + plural: sizesNode?.getAttribute("unit_plural"), + fraction: sizesNode?.getAttribute("unit_fraction"), + sellBy: + sizesNode?.getAttribute("unit_sellby") !== null + ? +sizesNode?.getAttribute("unit_sellby") + : undefined, + precision: + sizesNode?.getAttribute("unit_precision") !== null + ? +sizesNode?.getAttribute("unit_precision") + : undefined, + unitConvertedFormat: sizesNode?.getAttribute( + "unit_converted_format" + ), + }, + producer: { + id: + firmNode?.getAttribute("id") !== null + ? +firmNode?.getAttribute("id") + : undefined, + name: firmNode?.getAttribute("name"), + link: firmNode?.getAttribute("productslink"), + searchIcons: { + icon: firmNode?.getAttribute("icon"), + }, + // projectorIcons: {}, + }, + category: { + id: + categoryNode?.getAttribute("id") !== null + ? +categoryNode?.getAttribute("id") + : undefined, + name: categoryNode?.getAttribute("name"), + link: categoryNode?.getAttribute("productslink"), + }, + group: { + id: + versionsNode?.getAttribute("id") !== null + ? +versionsNode?.getAttribute("id") + : undefined, + name: versionsNode?.getAttribute("name"), + displayAll: + versionsNode?.getAttribute("display_all") === "true" + ? true + : false, + link: versionsNode?.getAttribute("link"), + versions, + groupParameters: this.xmlGetTraitsFromNode( + versionsNode.querySelector(":scope > groupParameters") + ), + }, + opinion: { + rating: + commentsNode?.getAttribute("avg") !== null + ? +commentsNode?.getAttribute("avg") + : undefined, + count: + commentsNode?.getAttribute("count") !== null + ? +commentsNode?.getAttribute("count") + : undefined, + link: commentsNode?.getAttribute("link"), + }, + enclosuresImages, + // enclosuresAttachments: [], + series: { + id: + seriesNode?.getAttribute("id") !== null + ? +seriesNode?.getAttribute("id") + : undefined, + name: seriesNode?.getAttribute("name"), + link: seriesNode?.getAttribute("link"), + }, + awardedParameters: this.xmlGetTraitsFromNode( + prod.querySelector(":scope > traits") + ), + // parameteresWithContext: [], + sizes, + points: + priceNode?.getAttribute("points") !== null + ? +priceNode?.getAttribute("points") + : undefined, + pointsReceive: + priceNode?.getAttribute("points_recive") !== null + ? +priceNode?.getAttribute("points_recive") + : undefined, + // subscription: {}, + // bundled: [], + // responsibleEntity: {}, + }); + }); return data; - }catch(err){ - console.error(err); - return null; + } catch (err) { + console.error(err); + return null; } } - // ======================================================== // INICJALIZACJA // ======================================================== @@ -1857,17 +2298,25 @@ class IdmHotspot{ /** * Wykonywana po pełnej inicjalizacji hotspotu (Swiper, eventy, wysokości). */ - async afterInit(){ - try{ - if(!this.hotspotEl) throw new Error("Nie znaleziono elementu"); + async afterInit() { + try { + if (!this.hotspotEl) throw new Error("Nie znaleziono elementu"); - if(this.title && !this.hotspotEl.querySelector(".hotspot__name.headline__wrapper")){ - this.hotspotEl.querySelector(".hotspot.--initialized")?.insertAdjacentHTML("afterbegin", `

+ if ( + this.title && + !this.hotspotEl.querySelector(".hotspot__name.headline__wrapper") + ) { + this.hotspotEl + .querySelector(".hotspot.--initialized") + ?.insertAdjacentHTML( + "afterbegin", + `

${this.title} -

`); + ` + ); } - if(this.banner) this.placeBanners(); + if (this.banner) this.placeBanners(); await this.initSwiper(); @@ -1877,114 +2326,142 @@ class IdmHotspot{ console.log(`Initialized hotspot #${this.id}`); // funkcja wykonująca się po ramce rekomendacji - if(typeof this.options?.callbackFn === "function") this.options?.callbackFn(this); - }catch(err){ - console.error(idmHotspotTextObject["Wystąpił błąd z inicjalizacją. Proszę odśwież stronę"], err); + if (typeof this.options?.callbackFn === "function") + this.options?.callbackFn(this); + } catch (err) { + console.error( + idmHotspotTextObject[ + "Wystąpił błąd z inicjalizacją. Proszę odśwież stronę" + ], + err + ); } } - placeBanners(){ - if(!this.placeBanners) return; - - const productsWrapperEl = this.hotspotEl.querySelector(".products__wrapper"); - for(let [key, value] of Object.entries(this.banner)){ - const currBannerMarkup = this.markupBannerContainer({html: value?.html || "", position: key.split("-")[0] }); - if(key === "top"){ + placeBanners() { + if (!this.placeBanners) return; + + const productsWrapperEl = + this.hotspotEl.querySelector(".products__wrapper"); + for (let [key, value] of Object.entries(this.banner)) { + const currBannerMarkup = this.markupBannerContainer({ + html: value?.html || "", + position: key.split("-")[0], + }); + if (key === "top") { productsWrapperEl.insertAdjacentHTML("beforebegin", currBannerMarkup); - } - else if(key === "left"){ + } else if (key === "left") { productsWrapperEl.insertAdjacentHTML("beforebegin", currBannerMarkup); - } - else if(key === "right"){ + } else if (key === "right") { productsWrapperEl.insertAdjacentHTML("afterend", currBannerMarkup); - } - else if(key === "bottom"){ + } else if (key === "bottom") { productsWrapperEl.insertAdjacentHTML("afterend", currBannerMarkup); - } - else{ + } else { const slidePosition = Number(key.split("-")[1]) - 1; - if(!Number.isInteger(slidePosition)) return; + if (!Number.isInteger(slidePosition)) return; const allProducts = productsWrapperEl.querySelectorAll(".product"); let productIndex = slidePosition; - if(slidePosition > allProducts.length - 1) productIndex = allProducts.length - 1; - if(slidePosition < 0) productIndex = 0 + if (slidePosition > allProducts.length - 1) + productIndex = allProducts.length - 1; + if (slidePosition < 0) productIndex = 0; const bannerPosition = slidePosition < 0 ? "beforebegin" : "afterend"; - allProducts[productIndex]?.insertAdjacentHTML(bannerPosition, currBannerMarkup) + allProducts[productIndex]?.insertAdjacentHTML( + bannerPosition, + currBannerMarkup + ); } value?.callbackFn?.(this); } } - - afterInitOnce(){ - if(this.initialized) return; + afterInitOnce() { + if (this.initialized) return; // WCZYTANIE PONOWNIE DLA KOSZYKA - if(typeof app_shop.fn?.basket?.reloadForm === "function" && this.hotspotEl.closest("#content")){ - app_shop.run(()=>{ - this.init(); - console.log("test", this.hotspotEl) - }, "all", "#Basket", true) + if ( + typeof app_shop.fn?.basket?.reloadForm === "function" && + this.hotspotEl.closest("#content") + ) { + app_shop.run( + () => { + this.init(); + console.log("test", this.hotspotEl); + }, + "all", + "#Basket", + true + ); } this.initialized = true; } - initExternalFunctions(){ + initExternalFunctions() { this.addToFavFn = app_shop.fn?.shoppingList?.addProductToList; } - /** + /** * Pobiera dane, wypełnia markup i inicjuje Swipera. */ - async fillHotspot(){ + async fillHotspot() { // Zdefiniowanie funkcji do dodawania do ulubionych - try{ - if(!this.products){ - if((!this?.query?.graphFn || !this?.query?.string) && !this.source?.link) this.setQueryData(); - + try { + if (!this.products) { + if ( + (!this?.query?.graphFn || !this?.query?.string) && + !this.source?.link + ) + this.setQueryData(); + // pobranie danych o produktach await this.getHotspotData(); - if(!this.products) throw new Error(idmHotspotTextObject["Nie znaleziono produktów"]); + if (!this.products) + throw new Error(idmHotspotTextObject["Nie znaleziono produktów"]); } // Skeleton this.hotspotEl.querySelector(".idm_hotspot__skeleton")?.remove(); this.hotspotEl.classList.remove("--hotspot-loading"); - - + this.initExternalFunctions(); // Wstawienie markupa na strone - if(this.hotspotEl.querySelector(".products.hotspot__products")) this.hotspotEl.querySelector(".products.hotspot__products").insertAdjacentHTML("beforeend", this.markup()); - else if(this.hotspotEl.querySelector(".hotspot")){ - this.hotspotEl.querySelector(".hotspot")?.insertAdjacentHTML("beforeend", this.markupHotspotSwiperContainer(this.markup())); - } - else{ - throw new Error("Nie udało się wstawić produktów! Zła struktura HTML") + if (this.hotspotEl.querySelector(".products.hotspot__products")) + this.hotspotEl + .querySelector(".products.hotspot__products") + .insertAdjacentHTML("beforeend", this.markup()); + else if (this.hotspotEl.querySelector(".hotspot")) { + this.hotspotEl + .querySelector(".hotspot") + ?.insertAdjacentHTML( + "beforeend", + this.markupHotspotSwiperContainer(this.markup()) + ); + } else { + throw new Error("Nie udało się wstawić produktów! Zła struktura HTML"); } // init swiper + add to basket await this.afterInit(); this.afterInitOnce(); - }catch(err){ + } catch (err) { console.error(idmHotspotTextObject["Wystąpił błąd"], err); this.hotspotEl.remove(); } } - /** + /** * Inicjuje instancję Swipera dla hotspotu. */ - async initSwiper(isReinitialized){ - try{ + async initSwiper(isReinitialized) { + try { // swiper || slick - if(this.options?.swiper){ + if (this.options?.swiper) { // Wywołanie swipera this.swiperFn = new HotspotSlider({ selector: `#${this.id} .swiper`, @@ -2000,107 +2477,157 @@ class IdmHotspot{ // await idmSwiper.init(this.options.swiper); // if(!this.hotspotEl.querySelector(".swiper")) throw new Error("Brak elementu swipera") // this.swiperFn = await idmSwiper.setupSlider({ element: this.hotspotEl.querySelector(".swiper") }); - - if(this.options.swiperScrollbar && !isReinitialized) this.swiperFnProgress = new IdmSwiperProgress(this.swiperFn, `#${this.id} .swiper`); - else if(this.options.swiperScrollbar && isReinitialized) this.swiperFnProgress.reattachSwiperFn(this.swiperFn); + + if (this.options.swiperScrollbar && !isReinitialized) + this.swiperFnProgress = new IdmSwiperProgress( + this.swiperFn, + `#${this.id} .swiper` + ); + else if (this.options.swiperScrollbar && isReinitialized) + this.swiperFnProgress.reattachSwiperFn(this.swiperFn); } - }catch(err){ - console.error(idmHotspotTextObject["Wystąpił błąd z inicjalizacją. Proszę odśwież stronę"], err); + } catch (err) { + console.error( + idmHotspotTextObject[ + "Wystąpił błąd z inicjalizacją. Proszę odśwież stronę" + ], + err + ); } } - async reInitSwiper(differentOptions){ - try{ - if(differentOptions) this.options.swiper = differentOptions; + async reInitSwiper(differentOptions) { + try { + if (differentOptions) this.options.swiper = differentOptions; this.swiperFn?.slider?.slider?.destroy?.(); this.initSwiper(true); - }catch(err){ - console.error(idmHotspotTextObject["Wystąpił błąd z inicjalizacją. Proszę odśwież stronę"], err); + } catch (err) { + console.error( + idmHotspotTextObject[ + "Wystąpił błąd z inicjalizacją. Proszę odśwież stronę" + ], + err + ); } } /** * Inicjuje eventy dla produktów w hotspotcie. */ - initEvents(){ - this.hotspotEl.querySelectorAll(".product").forEach(prodEl=>{ + initEvents() { + this.hotspotEl.querySelectorAll(".product").forEach((prodEl) => { this.initSingleEvent(prodEl); - }) + }); } - initSingleEvent(prodEl){ + initSingleEvent(prodEl) { // DODAWANIE DO KOSZYKA - if(this.options?.addToBasket){ - + if (this.options?.addToBasket) { // Warunek this.isClosestForm w przypadku gdy hotspot znajduje się już w środku formularza - const addToBasketEl = prodEl.querySelector(`${this.isClosestForm ? "button.add_to_basket__button" : "form.add_to_basket"}`); - addToBasketEl?.addEventListener(`${this.isClosestForm ? "click" : "submit"}`, this.handleAddToBasket); + const addToBasketEl = prodEl.querySelector( + `${ + this.isClosestForm + ? "button.add_to_basket__button" + : "form.add_to_basket" + }` + ); + addToBasketEl?.addEventListener( + `${this.isClosestForm ? "click" : "submit"}`, + this.handleAddToBasket + ); // + - - if(this?.options?.addToBasket === "range"){ - addToBasketEl?.closest(".add_to_basket")?.querySelector(".idm-products-banner__qty")?.addEventListener("click",this.handleQuantityButtonClick); - addToBasketEl?.closest(".add_to_basket")?.querySelector(".idm-products-banner__qty-input")?.addEventListener("input",this.handleQuantityInputChange); + if (this?.options?.addToBasket === "range") { + addToBasketEl + ?.closest(".add_to_basket") + ?.querySelector(".idm-products-banner__qty") + ?.addEventListener("click", this.handleQuantityButtonClick); + addToBasketEl + ?.closest(".add_to_basket") + ?.querySelector(".idm-products-banner__qty-input") + ?.addEventListener("input", this.handleQuantityInputChange); } } // Dodaj do ulubionych - if(this.options?.addToFavorites && typeof this.addToFavFn === "function") prodEl.querySelector(".product__favorite")?.addEventListener("click", this.handleAddToFav); + if (this.options?.addToFavorites && typeof this.addToFavFn === "function") + prodEl + .querySelector(".product__favorite") + ?.addEventListener("click", this.handleAddToFav); // Porównanie - if(this.options?.addToCompare) prodEl.querySelector(".idm-products-banner__compare-btn")?.addEventListener("click", this.handleAddToCompare); + if (this.options?.addToCompare) + prodEl + .querySelector(".idm-products-banner__compare-btn") + ?.addEventListener("click", this.handleAddToCompare); // Hover drugie zdjęcie - if(this.options?.showSecondImage){ + if (this.options?.showSecondImage) { const prodIconEl = prodEl.querySelector(".product__icon"); - if(prodIconEl.querySelector(".product__image.--second")){ + if (prodIconEl.querySelector(".product__image.--second")) { prodIconEl?.addEventListener("mouseover", this.handleShowSecondImage); prodIconEl?.addEventListener("mouseleave", this.handleHideSecondImage); } } // Wybór wersji - if(this.options?.selectVersion) prodEl.querySelector(".product__versions")?.addEventListener("click", this.handleSelectVersion); + if (this.options?.selectVersion) + prodEl + .querySelector(".product__versions") + ?.addEventListener("click", this.handleSelectVersion); // Wybór rozmiaru - if(this.options?.selectSize) prodEl.querySelector(".product__select_sizes")?.addEventListener("click", this.handleSelectSize); + if (this.options?.selectSize) + prodEl + .querySelector(".product__select_sizes") + ?.addEventListener("click", this.handleSelectSize); } /** * Inicjuje kontener hotspotu w określonym miejscu DOM. */ - initHotspotContainer(){ + initHotspotContainer() { const selectedEl = document.querySelector(this?.placement.selector); - if(!selectedEl) throw new Error(idmHotspotTextObject["Nie znaleziono kontenera"]); + if (!selectedEl) + throw new Error(idmHotspotTextObject["Nie znaleziono kontenera"]); const markup = this.markupHotspotContainer(); selectedEl.insertAdjacentHTML(this.placement.insert || "afterend", markup); this.hotspotEl = document.getElementById(this.id); } - /** + /** * Główna metoda inicjalizująca hotspot (lazy lub natychmiast). */ - init(){ + init() { const queryString = window.location.search; const urlParams = new URLSearchParams(queryString); - const dev = urlParams.get('dev') + const dev = urlParams.get("dev"); - if(this.options?.devMode && dev !== "true") return console.error(`Brak włączonego devMode. Ramka ${this.id} nie mogła zostać utworzona!`); + if (this.options?.devMode && dev !== "true") + return console.error( + `Brak włączonego devMode. Ramka ${this.id} nie mogła zostać utworzona!` + ); // Opcje swipera - if(typeof this?.options?.swiper === "boolean") this.options.swiper = IdmHotspot.idmDefaultSwiperConfig; + if (typeof this?.options?.swiper === "boolean") + this.options.swiper = this.getDefaultSwiperOptions(); // Wstawienie kontenera - if(!this.hotspotEl || !document.contains(this.hotspotEl)) this.initHotspotContainer(); - else if(!this.hotspotEl.querySelector(".hotspot")) this.hotspotEl.innerHTML = this.markupHotspotInnerDiv(); - else if(!this.hotspotEl.querySelector(".products__wrapper")) this.hotspotEl.querySelector(".hotspot").insertAdjacentHTML("beforeend", this.markupHotspotSwiperContainer()) + if (!this.hotspotEl || !document.contains(this.hotspotEl)) + this.initHotspotContainer(); + else if (!this.hotspotEl.querySelector(".hotspot")) + this.hotspotEl.innerHTML = this.markupHotspotInnerDiv(); + else if (!this.hotspotEl.querySelector(".products__wrapper")) + this.hotspotEl + .querySelector(".hotspot") + .insertAdjacentHTML("beforeend", this.markupHotspotSwiperContainer()); - // Ustawienie wszystkich zmiennych CSS this.cssSetAll(); // Sprawdzenie czy hotspot znajduje się w formularzu(dla doawania do koszyka) this.isClosestForm = !!this.hotspotEl.closest("form"); - if(this.options?.lazy) this.handleObserveHotspotOnce(); + if (this.options?.lazy) this.handleObserveHotspotOnce(); else this.fillHotspot(); } } @@ -2138,11 +2665,14 @@ class IdmSwiperProgress { this.addDragTracking(); this.swiper.on("progress", () => this.updateProgress()); - this.swiper.on("breakpoint", () => {this.updateBarWidth()}); + this.swiper.on("breakpoint", () => { + this.updateBarWidth(); + }); } - reattachSwiperFn(newSwiperFn){ - this.swiper = newSwiperFn?.slider?.slider ?? newSwiperFn?.slider ?? newSwiperFn; + reattachSwiperFn(newSwiperFn) { + this.swiper = + newSwiperFn?.slider?.slider ?? newSwiperFn?.slider ?? newSwiperFn; this.progressEl.style.width = ""; this.progressEl.style.left = ""; this.updateBarWidth(); @@ -2152,10 +2682,12 @@ class IdmSwiperProgress { const { slidesPerGroup, slidesPerView } = this.swiper.params; const totalSlides = this.swiper.slides.length; - const progressWidth = 100 / (((totalSlides - slidesPerView) / slidesPerGroup) + 1); + const progressWidth = + 100 / ((totalSlides - slidesPerView) / slidesPerGroup + 1); this.progressEl.style.width = `${progressWidth}%`; - if (progressWidth >= 100 || progressWidth <= 0) this.scrollbarEl.style.display = "none"; + if (progressWidth >= 100 || progressWidth <= 0) + this.scrollbarEl.style.display = "none"; else this.scrollbarEl.style.display = ""; } @@ -2164,7 +2696,8 @@ class IdmSwiperProgress { const { slidesPerGroup, slidesPerView } = this.swiper.params; const totalSlides = this.swiper.slides.length; - const progressWidth = 100 / (((totalSlides - slidesPerView) / slidesPerGroup) + 1); + const progressWidth = + 100 / ((totalSlides - slidesPerView) / slidesPerGroup + 1); const newLeft = (100 - progressWidth) * progress; this.progressEl.style.left = `${Math.min( 100 - progressWidth, @@ -2225,15 +2758,15 @@ class IdmSwiperProgress { // ======================================================== // TOOLTIP // ======================================================== -function idmShowTooltip(tooltipEl){ +function idmShowTooltip(tooltipEl) { const tooltipContentEl = tooltipEl.querySelector(".idm_tooltip__content"); - if(!tooltipContentEl) return; - + if (!tooltipContentEl) return; + tooltipContentEl.classList.add("--visible"); - + // Logika pokazywania się i chowania tooltipa let timeoutVar; - + function onMouseLeave() { timeoutVar = idmHideTooltipTimer(tooltipEl); } @@ -2256,11 +2789,11 @@ function idmShowTooltip(tooltipEl){ document.addEventListener("scroll", onScroll); } -function idmHideTooltipTimer(tooltipEl){ +function idmHideTooltipTimer(tooltipEl) { return setTimeout(() => idmHideTooltip(tooltipEl), 1500); } -function idmHideTooltip(tooltipEl){ +function idmHideTooltip(tooltipEl) { const tooltipContentEl = tooltipEl.querySelector(".idm_tooltip__content"); if (!tooltipContentEl) return; @@ -2275,56 +2808,46 @@ function idmHideTooltip(tooltipEl){ delete tooltipEl._onScroll; } -document.addEventListener("DOMContentLoaded", ()=>{ - document.body.addEventListener("click", e=>{ +document.addEventListener("DOMContentLoaded", () => { + document.body.addEventListener("click", (e) => { const tooltipEl = e.target.closest(".idm_tooltip"); - if(!e.target.closest(".idm_tooltip__info_icon") || !tooltipEl) return; - + if (!e.target.closest(".idm_tooltip__info_icon") || !tooltipEl) return; + e.preventDefault(); idmShowTooltip(tooltipEl); }); }); -// new IdmHotspot({ -// id: "idmTestHotspot1", -// title: "tescik", -// products: [] // Tablica produktów -// placement: { -// selector: "#content", -// insert: "beforeend", -// }, -// source: { -// productsMenu: 1649, -// producersId: [], -// seriesId: [], -// parametersId: [], -// priceRange: { -// from: 0, -// to: 150, -// } -// } -// options: { -// lazy: true, -// addToBasket: "range", -// swiper: true, -// } -// }); -async function idmPrepareHotspotObject(selectedContainerEl){ +async function idmPrepareHotspotObject(selectedContainerEl) { selectedContainerEl.classList.add("--init"); const source = {}; - if(selectedContainerEl.dataset?.link) source.link = selectedContainerEl.dataset.link; - else if(selectedContainerEl.dataset?.hotspotsType) source.hotspotsType = selectedContainerEl.dataset.hotspotsType; + if (selectedContainerEl.dataset?.link) + source.link = selectedContainerEl.dataset.link; + else if (selectedContainerEl.dataset?.hotspotsType) + source.hotspotsType = selectedContainerEl.dataset.hotspotsType; else { - if(selectedContainerEl.dataset?.productsId) source.productsId = selectedContainerEl.dataset.productsId.split(","); - if(selectedContainerEl.dataset?.productsMenu) source.productsMenu = selectedContainerEl.dataset.productsMenu; - if(selectedContainerEl.dataset?.producersId) source.producersId = selectedContainerEl.dataset.producersId; - if(selectedContainerEl.dataset?.seriesId) source.seriesId = selectedContainerEl.dataset.seriesId; - if(selectedContainerEl.dataset?.parametersId) source.seriesId = selectedContainerEl.dataset.parametersId; - if(selectedContainerEl.dataset?.priceFrom && selectedContainerEl.dataset?.priceTo) source.priceRange = {from: +selectedContainerEl.dataset.priceFrom, to: +selectedContainerEl.dataset.priceTo}; + if (selectedContainerEl.dataset?.productsId) + source.productsId = selectedContainerEl.dataset.productsId.split(","); + if (selectedContainerEl.dataset?.productsMenu) + source.productsMenu = selectedContainerEl.dataset.productsMenu; + if (selectedContainerEl.dataset?.producersId) + source.producersId = selectedContainerEl.dataset.producersId; + if (selectedContainerEl.dataset?.seriesId) + source.seriesId = selectedContainerEl.dataset.seriesId; + if (selectedContainerEl.dataset?.parametersId) + source.seriesId = selectedContainerEl.dataset.parametersId; + if ( + selectedContainerEl.dataset?.priceFrom && + selectedContainerEl.dataset?.priceTo + ) + source.priceRange = { + from: +selectedContainerEl.dataset.priceFrom, + to: +selectedContainerEl.dataset.priceTo, + }; } - if(Object.keys(source).length === 0){ + if (Object.keys(source).length === 0) { console.error("Brak metody pobrania ramek rekomendacji"); selectedContainerEl?.remove(); return; @@ -2333,16 +2856,20 @@ async function idmPrepareHotspotObject(selectedContainerEl){ const idmHotspotObj = { id: selectedContainerEl?.id, source, - hotspotEl: selectedContainerEl + hotspotEl: selectedContainerEl, }; - if(selectedContainerEl?.dataset?.lazy) idmHotspotObj.options = {lazy: selectedContainerEl?.dataset?.lazy === "true" ? true : false}; + if (selectedContainerEl?.dataset?.lazy) + idmHotspotObj.options = { + lazy: selectedContainerEl?.dataset?.lazy === "true" ? true : false, + }; new IdmHotspot(idmHotspotObj); } - -document.addEventListener("DOMContentLoaded", ()=>{ - document.querySelectorAll(".hotspot__wrapper.idm__hotspot:not(.--init)").forEach(currentHotspot=>{ - idmPrepareHotspotObject(currentHotspot); - }); -}) \ No newline at end of file +document.addEventListener("DOMContentLoaded", () => { + document + .querySelectorAll(".hotspot__wrapper.idm__hotspot:not(.--init)") + .forEach((currentHotspot) => { + idmPrepareHotspotObject(currentHotspot); + }); +}); diff --git a/przyklady/extends.js b/przyklady/extends.js index 465f016..aab4186 100644 --- a/przyklady/extends.js +++ b/przyklady/extends.js @@ -1,4 +1,10 @@ IdmHotspot = class extends IdmHotspot { + getDefaultHotspotOptions() { + const defaultOptions = super.getDefaultHotspotOptions(); + defaultOptions.cssVariables.nameClamp = 2; + + return defaultOptions; + } markupLabel(prod) { // Standardowe labelki let labelMarkup = super.markupLabel(prod); @@ -6,11 +12,13 @@ IdmHotspot = class extends IdmHotspot { // Customowe labelki const awards = prod?.awardedParameters; if (awards?.length) { - const awardParam = awards.find(award => award.name === "Idm_custom_label"); - const values = awardParam?.values?.map(v => v.name) || []; + const awardParam = awards.find( + (award) => award.name === "Idm_custom_label" + ); + const values = awardParam?.values?.map((v) => v.name) || []; const html = values - .map(label => { + .map((label) => { const [text, bgColor, color] = label.split("||"); return `${text}`; }) @@ -21,4 +29,4 @@ IdmHotspot = class extends IdmHotspot { return labelMarkup; } -} \ No newline at end of file +}; diff --git a/ramka.txt b/ramka.txt index 9b474e4..3c85e73 100644 --- a/ramka.txt +++ b/ramka.txt @@ -1,7 +1,7 @@ bug - ramka nie działa dla banneru slider-1 itp problem z funkcją new HotspotSlider i tym że orzekuje tam hotspotów idosellowych!!!! - +- przeliczanie ceny - sprawdzenie zdjęcia producenta - Wykluczenie powtarzających się wersji - dodanie efektu 3d