{"version":3,"file":"Src_Scripts_components_variant-product_js.1b9b48555e7956f950e5.js","sources":["webpack://haveselskabet/./Src/Scripts/components/variant-product.js","webpack://haveselskabet/./Src/Scripts/functionality-classes/tracking.js"],"sourcesContent":["import { pushDataLayerCartEvent } from '../functionality-classes/tracking';\nexport default class VariantProduct {\n constructor(elm, args) {\n let container = elm.querySelector('[data-variant-product-container]');\n\n if (!container) { return; }\n\n elm.querySelectorAll('.product__video').forEach(x => x.addEventListener('click', () => {\n const mediaContainer = x.querySelector('.media-container__video:not(.media-container__video--playing)');\n if (mediaContainer) {\n mediaContainer.setAttribute('controls', '');\n mediaContainer.classList.add('media-container__video--playing');\n window.requestAnimationFrame(() => {\n mediaContainer.play();\n });\n }\n }));\n\n const productSku = container.dataset.productSku;\n const isMembership = container.dataset.isMembership == 'True';\n const quantity = container.dataset.productQuantity;\n const addToBasket = container.querySelector('[data-add-to-basket]');\n let variations = container.querySelectorAll('.variation');\n let currentColor = '';\n\n const sizeGuideHeadline = elm.querySelector('.variant-product__size-guide-headline');\n sizeGuideHeadline?.addEventListener('click', () => {\n if (window.innerWidth > 992) {\n const selectedProductHeadline = elm.querySelector('.product__info-headline--selected');\n const selectedProductInfo = elm.querySelector('.product__info-text--selected');\n selectedProductHeadline.classList.remove('product__info-headline--selected');\n selectedProductInfo.classList.remove('product__info-text--selected');\n const sizeGuideHeadline = elm.querySelector('.product__info-headline--size-guide');\n const sizeGuideProductInfo = elm.querySelector('.product__info-text--size-guide');\n sizeGuideHeadline.classList.add('product__info-headline--selected');\n sizeGuideProductInfo.classList.add('product__info-text--selected');\n window.scrollTo(0, sizeGuideHeadline.getBoundingClientRect().top - 400);\n } else {\n const activeAccordionItem = elm.querySelector('.accordion__item--active');\n if (activeAccordionItem) {\n activeAccordionItem.classList.remove('accordion__item--active');\n const activeAccordionBody = activeAccordionItem.querySelector('.accordion__item-body');\n activeAccordionBody.style.height = 0;\n const chevron = activeAccordionItem.querySelector('.accordion__chevron');\n chevron.classList.remove('.accordion__chevron--up');\n }\n const sizeGuideAccordionItem = elm.querySelector('.accordion__item--size-guide');\n sizeGuideAccordionItem.classList.add('accordion__item--active');\n const sizeGuideAccordionBody = sizeGuideAccordionItem.querySelector('.accordion__item-body');\n sizeGuideAccordionBody.style.height = 'auto';\n const sizeGuideChevron = sizeGuideAccordionItem.querySelector('.accordion__chevron');\n sizeGuideChevron.classList.add('accordion__chevron--up');\n window.scrollTo(0, sizeGuideAccordionItem.getBoundingClientRect().top);\n }\n });\n\n if (!addToBasket) { return; }\n\n event();\n wireupVariations();\n function event() {\n variations.forEach(item => {\n item.addEventListener('change', e => {\n applyVariations(e);\n });\n });\n\n addToBasket.addEventListener('click', e => {\n const productVariantSku = container.dataset.productVariantSku;\n const productName = container.dataset.productName;\n const productPrice = container.dataset.productPrice;\n const productBrand = container.dataset.productBrand;\n const productCategory = container.dataset.productCategory;\n\n addToBasket.classList.add('btn--loader-shown');\n addProductToBasket(isMembership, productSku, productVariantSku, quantity, productName, productPrice, productBrand, productCategory);\n });\n }\n\n function addProductToBasket(isMembership, productSku, variantSku, quantity, productName, productPrice, productBrand, productCategory) {\n const url = isMembership ? `/Umbraco/surface/basketsurface/AddMembershipFlowProductToBasket?sku=${productSku}&quantity=${quantity}` :\n `/Umbraco/surface/basketsurface/AddtoBasket?sku=${productSku}&variantSku=${variantSku}&quantity=${quantity}`;\n\n fetch(url, {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/json',\n },\n }).then(response => response.json())\n .then(json => {\n const response = json.basketRespons;\n addToBasket.classList.remove('btn--loader-shown');\n if (response.Status) {\n pushDataLayerCartEvent('addToCart', productName, productSku, productPrice, productBrand, productCategory, variantSku, 1);\n\n document.querySelectorAll('.header__items-in-cart__number').forEach(b => {\n b.innerHTML = response.TotalItems;\n });\n const modal = document.querySelector('.modal[id=\"addedToBasket\"]');\n modal.classList.add('modal--active');\n document.body.classList.add('modal-active');\n } else {\n const modalContent = response.Errors?.membership ?? 'There was an error';\n const modal = document.querySelector('.modal[id=\"error\"]');\n modal.querySelector('.modal__contentText').innerHTML = modalContent;\n modal.classList.add('modal--active');\n document.body.classList.add('modal-active');\n }\n\n });\n }\n function applyVariations(e) {\n wireupVariations();\n }\n\n function wireupVariations() {\n const colorHexCodeVariation = [...variations].find(v => v.id === 'variation-ColorHexCode') !== undefined ? [...variations].find(v => v.id === 'variation-ColorHexCode') : null;\n const colorHexCodeVariations = elm.querySelectorAll('input[name=\"color\"]');\n const sizeVariation = [...variations].find(v => v.id === 'variation-Size') !== undefined ? [...variations].find(v => v.id === 'variation-Size') : null;\n // var genderVariation = [...variations].find(v => v.id === 'variation-Gender') !== undefined ? [...variations].find(v => v.id === 'variation-Gender') : null;\n // var variantVariation = [...variations].find(v => v.id === 'variation-Variant') !== undefined ? [...variations].find(v => v.id === 'variation-Variant') : null;\n\n /* var selectedColorHexCodeVariation = colorHexCodeVariation !== null ? colorHexCodeVariation.value : ''; */\n const checkedColorInput = elm.querySelector('input[name=\"color\"]:checked');\n let checkedColorInputValue;\n if (checkedColorInput) {\n checkedColorInputValue = checkedColorInput.value;\n }\n let selectedColorHexCodeVariation;\n if (colorHexCodeVariations && checkedColorInput) {\n selectedColorHexCodeVariation = checkedColorInputValue;\n } else {\n selectedColorHexCodeVariation = '';\n }\n /* const selectedColorHexCodeVariation = colorHexCodeVariation !== null ? checkedColorInputValue : ''; */\n // var selectedSizeVariation = sizeVariation !== null ? sizeVariation.value : '';\n // var selectedGenderVariation = genderVariation !== null ? genderVariation.value : '';\n // var selectedVariantVariation = variantVariation !== null ? variantVariation.value : '';\n // wireup Color and size\n fetch('/Umbraco/api/shopproduct/GetProductVariations', {\n method: 'POST',\n body: JSON.stringify({ productSku: productSku }),\n headers: {\n 'Content-Type': 'application/json',\n },\n })\n .then(response => response.json())\n .then(json => {\n const variationsResponse = JSON.parse(json);\n if (variationsResponse.Variations && variationsResponse.Variations.length > 0) {\n if (colorHexCodeVariation && sizeVariation) { // for color and size variation\n\n const sizeVariationInputs = sizeVariation.querySelectorAll('.variant-product__size-variation-input');\n sizeVariationInputs.forEach(i => {\n\n i.disabled = 'disabled';\n const label = i.parentNode.querySelector('label');\n label.classList.add('variant-product__size-label--disabled');\n });\n // Lilla outcommented this - this belong to the old setup with select and options\n /* [...sizeVariation.options].forEach(i => { i.disabled = 'disabled'; }) */\n\n variationsResponse.Variations.forEach(v => {\n const variationSize = getObjectsByKey(v.Properties, 'Name', 'Size')[0];\n const variationColor = getObjectsByKey(v.Properties, 'Name', 'Color')[0];\n const variationColorHexCode = getObjectsByKey(v.Properties, 'Name', 'ColorHexCode')[0];\n // If the size matches the selected size, this color is available so enable it\n if (variationColorHexCode && variationColorHexCode.Value == selectedColorHexCodeVariation) {\n // Next line is working with the select element, but not meant to work with the radios\n /* [...sizeVariation].find(c => c.value == variationSize.Value).disabled = ''; */\n const sizeToDisable = [...sizeVariationInputs].find(c => {\n if (c.value == variationSize.Value) {\n return c;\n }\n });\n sizeToDisable.disabled = '';\n const sizeToDisableLabel = sizeToDisable.parentNode.querySelector('.variant-product__size-label');\n sizeToDisableLabel.classList.remove('variant-product__size-label--disabled');\n\n currentColor = variationColor.Value;\n if (container.querySelector('[data-product-color]') != null) {\n container.querySelector('[data-product-color]').innerHTML = currentColor;\n }\n }\n });\n\n // set the size attribute if it was already selected\n let selectedSize;\n if (sizeVariation.querySelector('input[name=\"size\"]:checked')) {\n selectedSize = sizeVariation.querySelector('input[name = \"size\"]:checked');\n }\n\n elm.querySelectorAll('input:disabled').forEach(x => x.checked = false);\n\n // Pick the first non disabled input\n if (![...sizeVariationInputs].find(x => { if (x.checked) return x; })) {\n const firstAvailable = [...sizeVariationInputs].find(x => { if (!x.disabled) return x; });\n if (firstAvailable) {\n firstAvailable.checked = 'checked';\n }\n }\n } else if (colorHexCodeVariation) { // for only color variation\n variationsResponse.Variations.forEach(v => {\n const variationColor = getObjectsByKey(v.Properties, 'Name', 'Color')[0];\n const variationColorHexCode = getObjectsByKey(v.Properties, 'Name', 'ColorHexCode')[0];\n if (variationColorHexCode && variationColorHexCode.Value == selectedColorHexCodeVariation) {\n currentColor = variationColor.Value;\n if (container.querySelector('[data-product-color]') != null) {\n container.querySelector('[data-product-color]').innerHTML = currentColor;\n }\n }\n });\n }\n getVariantSkuFromSelection();\n }\n });\n\n\n }\n\n // Have been working on this\n function getVariantSkuFromSelection() {\n container = elm.querySelector('[data-variant-product-container]');\n const memberPriceContainer = container.querySelector('[data-member-price-container]');\n const memberPrice = container.querySelector('[data-member-price]');\n const productPrice = container.querySelector('[data-product-price]');\n const productName = container.querySelector('[data-product-name]');\n const productDescription = container.querySelector('[data-product-description]');\n const arrivingDateContainer = container.querySelector('[data-arriving-date-container]');\n const arrivingDate = container.querySelector('[data-arriving-date]');\n // hide add to cart button and prices\n // addToBasket.classList.add('d-none');\n // memberPriceContainer.classList.add('d-none');\n // memberPrice.classList.add('d-none');\n arrivingDateContainer.classList.add('d-none');\n // get variant sku and other properties based on selections\n variations = container.querySelectorAll('.variation');\n const selectedVariations = {};\n variations.forEach(v => {\n\n if (v.id == 'variation-ColorHexCode') {\n selectedVariations[v.id.replace('variation-', '')] = v.querySelector('input:checked')?.id;\n } else if (v.id == 'variation-Size') {\n\n selectedVariations[v.id.replace('variation-', '')] = v.querySelector('input:checked')?.value;\n } else {\n selectedVariations[v.id.replace('variation-', '')] = v.value;\n }\n });\n fetch('/Umbraco/api/shopproduct/GetVariantSkuFromSelection', {\n method: 'POST',\n body: JSON.stringify({ productSku: productSku, variantProperties: selectedVariations }),\n headers: {\n 'Content-Type': 'application/json',\n },\n }).then(response => response.json())\n .then(json => {\n const variant = JSON.parse(json).Variant;\n if (variant.ProductHasValidPrices) {\n container.dataset.productVariantSku = variant.VariantSku;\n // set variant image\n const allVariantMedias = container.querySelectorAll('[data-media-variant-sku]');\n allVariantMedias.forEach(m => {\n m.classList.remove('selected');\n });\n const selectedVariantMedia = container.querySelector(`[data-media-variant-sku=\"${variant.VariantSku}\"]`);\n if (selectedVariantMedia) {\n const index = Array.from(selectedVariantMedia.parentNode.children).indexOf(selectedVariantMedia);\n selectedVariantMedia.closest('.product__images-container').querySelectorAll('.swiper-container').forEach(x => x.swiper.slideTo(index));\n }\n\n productName.innerHTML = variant.Name;\n productDescription.innerHTML = variant.Description;\n if (variant.HasMemberDiscount) {\n memberPriceContainer.classList.remove('d-none');\n memberPrice.innerHTML = variant.MemberPriceFormatted;\n memberPrice.classList.remove('d-none');\n } else {\n memberPriceContainer.classList.add('d-none');\n memberPrice.classList.add('d-none');\n }\n productPrice.innerHTML = variant.PriceFormatted;\n if (variant.InStock) {\n addToBasket.classList.remove('d-none');\n arrivingDateContainer.classList.add('d-none');\n } else {\n addToBasket.classList.add('d-none');\n if (variant.ArrivingDate) {\n arrivingDate.innerHTML = variant.ArrivingDate;\n arrivingDateContainer.classList.remove('d-none');\n } else {\n arrivingDateContainer.classList.add('d-none');\n }\n }\n } else {\n addToBasket.classList.add('d-none');\n arrivingDateContainer.classList.add('d-none');\n }\n });\n }\n function getObjectsByKey(obj, key, val) {\n let objects = [];\n for (const i in obj) {\n if (!obj.hasOwnProperty(i)) continue;\n if (typeof obj[i] === 'object') {\n objects = objects.concat(getObjectsByKey(obj[i], key, val));\n } else if (i == key && obj[key] == val) {\n objects.push(obj);\n }\n }\n return objects;\n }\n }\n}\n\n","// eslint-disable-next-line max-params\nexport function pushDataLayerCartEvent(eventType, name, sku, price, brand, category, variantSku, quantity) {\n window.dataLayer.push({ ecommerce: null });\n if (eventType === 'addToCart') {\n window.dataLayer.push({\n event: 'addToCart',\n ecommerce: {\n currencyCode: 'DKK',\n add: {\n products: [{\n id: sku,\n variant: variantSku,\n name,\n price: parseFloat(price.replace(',', '.')),\n brand,\n category,\n quantity: parseInt(quantity, 10),\n }],\n },\n },\n });\n } else {\n window.dataLayer.push({\n event: 'removeFromCart',\n ecommerce: {\n remove: {\n products: [{\n id: sku,\n variant: variantSku,\n name,\n price: parseFloat(price.replace(',', '.')),\n brand,\n category,\n quantity: parseInt(quantity, 10),\n }],\n },\n },\n });\n }\n}\n// todo prod price\n// eslint-disable-next-line max-params\nexport function pushDataLayerCheckoutEvent(products, step, option) {\n window.dataLayer.push({ ecommerce: null });\n window.dataLayer.push({\n event: 'checkout',\n ecommerce: {\n currencyCode: 'DKK',\n checkout: {\n actionField: { step, option },\n products: products.map(product => ({\n ...product,\n price: parseFloat(product.price.replace(',', '.')),\n quantity: parseInt(product.quantity, 10),\n })),\n },\n },\n });\n}\n\nexport function pushDataLayerPurchaseEvent(products, actionField) {\n window.dataLayer.push({ ecommerce: null });\n window.dataLayer.push({\n event: 'purchase',\n ecommerce: {\n currencyCode: 'DKK',\n purchase: {\n actionField: {\n ...actionField,\n revenue: parseFloat(actionField.revenue.replace(',', '.')),\n shipping: parseFloat(actionField.shipping.replace(',', '.')),\n },\n products: products.map(product => ({\n ...product,\n price: parseFloat(product.price.replace(',', '.')),\n quantity: parseInt(product.quantity, 10) })),\n },\n },\n });\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AACA;AACA;AACA;AAEA;AAAA;AAAA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAAA;AAAA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAAA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AAAA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;;A;;;;;;;;;;;;;;;;;;;;;;;;ACzTA;AACA;AACA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;;A;;A","sourceRoot":""}