//////////////////////////////////////////////////////////////////////////\\\\\\\\\\\\ // IDOSELL omnibus details // omnibusDetailsTxt - nadpisać na własny obiekt app_shop.fn.idmGetOmnibusDetails = (options) => { const { productData, sizeId, priceType = app_shop.vars.priceType, } = options || {}; if (!productData) return false; 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'], }; const activeLabel = {}; 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'); 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 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'); } // Aktywny kod rabatowy if (app_shop.vars.omnibus?.rebateCodeActivate && sizeData.price?.rebateCodeActive) { classes.add.push('--omnibus-code'); activeLabel.rebateCodeActive = `${idmHotspotTextObject["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'); } // Nadchodząca cena 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'); } // Cena omnibusa wyższa niż cena sprzedaży const higher = sizeData.price.omnibusPriceDetails?.omnibusPriceIsHigherThanSellingPrice; if (higher) { classes.add.push('--omnibus-higher'); classes.remove = classes.remove.filter((item) => item !== '--omnibus-higher'); } // label okazja if ((!higher || newDate) && !activeLabel?.rebateCodeActive) { activeLabel.bargain = `${idmHotspotTextObject["Okazja"]}`; } // label promocja if (Object.keys(activeLabel)?.length === 0) { activeLabel.bargain = `${idmHotspotTextObject["Promocja"]}`; } // labele zones if(productData.zones.find(zone => zone ==="bestseller")) activeLabel.bestseller = `${idmHotspotTextObject["Bestseller"]}`; if(productData.zones.find(zone => zone ==="news")) activeLabel.news = `${idmHotspotTextObject["Nowość"]}`; let omnibusPercentSign = ''; if (higher) { omnibusPercentSign = '-'; } else if (sizeData.price.omnibusPriceDetails?.youSavePercent !== 0) { omnibusPercentSign = '+'; } const omnibusPercent = `${omnibusPercentSign}${sizeData.price.omnibusPriceDetails?.youSavePercent}%`; const omnibus = { price: omnibusPrice, visible: true, percent: omnibusPercent, html: `${idmHotspotTextObject['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: `${idmHotspotTextObject['Cena regularna']}: ${maxPrice}-${sizeData.price.youSavePercent}%`, }, } : {}; const beforeRebate = (beforeRebatePrice) ? { beforeRebate: { price: beforeRebatePrice, visible: !!classes.add.includes('--omnibus-code'), percent: `-${sizeData.price.beforeRebateDetails?.youSavePercent}%`, html: `${idmHotspotTextObject['Cena bez kodu']}: ${beforeRebatePrice} -${sizeData.price.beforeRebateDetails?.youSavePercent}%`, }, } : {}; const newPriceEffectiveUntil = (newDate) ? { newPriceEffectiveUntil: { date: newDate, price: maxPrice, visible: !!classes.add.includes('--omnibus-new-price'), html: `${idmHotspotTextObject['Cena nadchodząca od']} ${newDate}: ${maxPrice}`, }, } : {}; return { classes, omnibus, ...max, ...beforeRebate, ...newPriceEffectiveUntil, activeLabel, }; }; ////////////////////////////////////////////////////////////////////////// // EVENTY // dodawanie do koszyka async function idmHandleAddToBasket(e){ const formEl = e.target.closest("form.add_to_basket"); if(!formEl) return; try{ // pobieranie danych i elementów formEl.classList.add("--loading") const buttonEl = formEl.querySelector(".add_to_basket__button"); e.preventDefault(); const id = formEl.querySelector("input[name='product']")?.value; const size = formEl.querySelector("input[type='hidden'][name='size']")?.value; const number = formEl.querySelector("input[name='number']")?.value; // dodanie do koszyka const res = await fetch(`/graphql/v1/`, { method: "POST", headers: { "Content-Type": "application/json", }, 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{ // Obsługiwanie sukcesu app_shop.graphql.trackingEvents(res); buttonEl.classList.add("--success"); // Dodawanie do koszyka na stronie basketedit.php będzie wymagał innego indywidualnego kodu!!!!! buttonEl.innerHTML = `${buttonEl.dataset.success}`; setTimeout(()=>{ buttonEl.innerHTML = `${buttonEl.dataset.text}`; app_shop.fn?.menu_basket_cache?.(); 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") } } ///qty const idmRangeMaxAlert = (max)=> Alertek.Error(`${idmHotspotTextObject["Maksymalna liczba sztuk tego towaru które możesz dodać do koszyka to:"]} ${max}`) const idmRangeMinAlert = (min)=> Alertek.Error(`${idmHotspotTextObject["Minimalna liczba sztuk tego towaru które możesz dodać do koszyka to:"]} ${min}`) function idmQuantityButtonClick(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"); const max = parseFloat(wrapper.dataset.max || "999999"); let current = parseFloat(input.value) || 0; if (e.target.classList.contains("idm-products-banner__qty-increase")) { current += step; if (current > max){ current = max; idmRangeMaxAlert(max) } } else if (e.target.classList.contains("idm-products-banner__qty-decrease")) { current -= step; if (current < step){ current = step; idmRangeMinAlert(step) } } input.value = current.toFixed(precision); } function idmQuantityInputChange(e){ if(e.target.value > +e.target.max){ idmRangeMaxAlert(e.target.max) e.target.value = +e.target.max } if(e.target.value < +e.target.min){ idmRangeMinAlert(e.target.min) e.target.value = +e.target.min; } } ////////////////////////////////////////////// // DANE // dwie funkcje zamiast jednej async function idmGetHotspotData(query, graphFn){ try{ const res = await fetch(`/graphql/v1/`, { method: "POST", headers: { "Content-Type": "application/json", }, body: graphFn ? graphFn(query) : IDM_PRODUCTS_GQL(query) }); const data = await res.json(); const products = graphFn === IDM_HOTSPOTS_GQL ? data?.data?.hotspots?.products : data?.data?.products?.products; if(!products || !products.length) throw new Error(idmHotspotTextObject["Nie znaleziono produktów"]); console.log(data); return products; }catch(err){ console.error(idmHotspotTextObject["Błąd przy pobieraniu danych"], err); return null; } } function idmGetQueryData({ productsID, productsMenu, hotspotsType }){ let graphFn, query; if(productsID){ graphFn = IDM_PRODUCTS_GQL; query = `searchInput: {productsId: [${productsID}]}`; }else if(productsMenu){ graphFn = IDM_PRODUCTS_GQL; query = `searchInput: {navigation: ${productsMenu}}`; }else if(hotspotsType){ graphFn = IDM_HOTSPOTS_GQL; query = `searchInput: {hotspot: ${hotspotsType}, limit: 16}`; } return {graphFn, query} } ////////////////////////////////////////////// // LAZY LOADING function idmObserveOnce(element, callback, options = { root: null, rootMargin: "0px", threshold: 0.1 }) { if (!element) return; const observer = new IntersectionObserver((entries, obs) => { entries.forEach(entry => { if (entry.isIntersecting) { callback(entry); // run your callback obs.disconnect(); // stop observing after first trigger } }); }, options); observer.observe(element); } //////////////////////////////////////////////// // IDM SET HEIGHT app_shop.fn.idmSetHeight = options => { const { selector, selectors, container } = options || {} if ((!selector && !selectors) || !container) return const containerElement = document.querySelector(container) if (!containerElement) return const adjustAllHeights = itemSelector => { const targets = containerElement.querySelectorAll(itemSelector) if (!targets.length) return targets.forEach(el => (el.style.minHeight = '')) const max = Math.max(...[...targets].map(el => el.offsetHeight || 0)) targets.forEach(el => (el.style.minHeight = `${max}px`)) } if (selector) adjustAllHeights(selector) if (selectors?.length) selectors.forEach(adjustAllHeights) }