1class CartNotification extends HTMLElement{constructor(){super(),this.notification=document.getElementById("cart-notification"),this.header=document.querySelector("sticky-header"),this.onBodyClick=this.handleBodyClick.bind(this),this.algoliaService=new AlgoliaRecommendations,this.notification.addEventListener("keyup",evt=>evt.code==="Escape"&&this.close()),this.querySelectorAll('button[type="button"]').forEach(closeButton=>closeButton.addEventListener("click",this.close.bind(this)))}open(){this.notification.classList.add("animate","active"),this.notification.addEventListener("transitionend",()=>{this.notification.focus(),trapFocus(this.notification)},{once:!0}),document.body.addEventListener("click",this.onBodyClick)}close(){this.notification.classList.remove("active"),document.body.removeEventListener("click",this.onBodyClick),removeTrapFocus(this.activeElement)}async renderContents(parsedState){this.cartItemKey=parsedState.key,this.getSectionsToRender().forEach(section=>{document.getElementById(section.id).innerHTML=this.getSectionInnerHTML(parsedState.sections[section.id],section.selector)}),this.loadRecommendations(parsedState),this.header&&this.header.reveal(),this.open()}async loadRecommendations(parsedState){try{const cart=await(await fetch("/cart.js")).json(),addedItem=cart.items.find(item=>item.key===this.cartItemKey);if(!addedItem)return;const recommendations=await this.algoliaService.getBoughtTogether(addedItem.variant_id,30);if(!recommendations||recommendations.length===0){console.log("No recommendations found");return}const cartProductHandles=cart.items.map(item=>item.handle),filteredRecommendations=recommendations.filter(product=>!cartProductHandles.includes(product.handle));if(filteredRecommendations.length===0)return;const limitedProducts=filteredRecommendations.slice(0,2);await this.renderRecommendations(limitedProducts)}catch(error){console.error("Error loading recommendations:",error)}}async renderRecommendations(products){try{let recommendationsContainer=this.notification.querySelector("[data-recommendations]");if(!recommendationsContainer){const recommendationsHTML=` 2 <div class="cart-notification__recommendations" data-recommendations> 3 <h4 class="cart-notification__recommendations-title">You may also like</h4> 4 <div class="cart-notification__recommendations-grid" data-recommendations-grid> 5 </div> 6 </div> 7 `,linksSection=this.notification.querySelector(".cart-notification-product");linksSection&&(linksSection.insertAdjacentHTML("beforebegin",recommendationsHTML),recommendationsContainer=this.notification.querySelector("[data-recommendations]"))}const recommendationsGrid=recommendationsContainer.querySelector("[data-recommendations-grid]");if(!recommendationsGrid)return;recommendationsGrid.innerHTML="";const productPromises=products.map(product=>fetch(`/products/${product.handle}.js`).then(res=>res.json()));(await Promise.all(productPromises)).forEach(product=>{const productHTML=this.createRecommendationHTML(product);recommendationsGrid.insertAdjacentHTML("beforeend",productHTML)}),this.initializeRecommendationHandlers(recommendationsGrid)}catch(error){console.error("Error rendering recommendations:",error)}}createRecommendationHTML(product){const hasVariants=product.variants.length>1,isAvailable=product.available,buttonText=hasVariants?"Options":isAvailable?'<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M6.88327 1.52C6.88327 0.967712 6.43555 0.519997 5.88327 0.519997C5.33099 0.519997 4.88327 0.967712 4.88327 1.52V4.99998H1.4028C0.850517 4.99998 0.402802 5.44769 0.402802 5.99998C0.402802 6.55226 0.850517 6.99998 1.4028 6.99998H4.88327V10.48C4.88327 11.0323 5.33099 11.48 5.88327 11.48C6.43555 11.48 6.88327 11.0323 6.88327 10.48V6.99998H10.3628C10.9151 6.99998 11.3628 6.55226 11.3628 5.99998C11.3628 5.44769 10.9151 4.99998 10.3628 4.99998H6.88327V1.52Z" fill="white"></path></svg> Add':"Sold Out",buttonClass=`cart-notification__recommendation-button ${isAvailable?"":"disabled"}`;return` 8 <div class="cart-notification__recommendation" data-product-id="${product.id}"> 9 <div class="cart-notification_recommendation-image-button"> 10 <div class="cart-notification__recommendation-image"> 11 ${product.featured_image?` 12 <img src="${product.featured_image}" alt="${product.title}" loading="lazy"> 13 `:""} 14 </div> 15 <div class="quick-add no-js-hidden"> 16 ${hasVariants?` 17 <modal-opener data-modal="#QuickAdd-${product.id}"> 18 <button 19 id="quick-add-${product.id}-submit" 20 type="submit" 21 name="add" 22 class="${buttonClass} quick-add__submit button button--full-width button" 23 aria-haspopup="dialog" 24 aria-labelledby="quick-add-${product.id}-submit title-${product.id}" 25 data-product-url="/products/${product.handle}" 26 data-product-id="${product.id}" 27 > 28 ${buttonText} 29 <div class="loading__spinner hidden"> 30 <svg aria-hidden="true" focusable="false" class="spinner" viewBox="0 0 66 66"> 31 <circle class="path" fill="none" stroke-width="6" cx="33" cy="33" r="30"></circle> 32 </svg> 33 </div> 34 </button> 35 </modal-opener> 36 <quick-add-modal id="QuickAdd-${product.id}" class="quick-add-modal"> 37 <div 38 role="dialog" 39 aria-label="{{ 'products.product.choose_product_options' | t: product_name: product.title }}" 40 aria-modal="true" 41 class="quick-add-modal__content global-settings-popup" 42 tabindex="-1" 43 > 44 <button 45 id="ModalClose-${product.id}" 46 type="button" 47 class="quick-add-modal__toggle" 48 aria-label="{{ 'accessibility.close' | t }}" 49 > 50 <svg aria-hidden="true" focusable="false" role="presentation" xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 13 13">
51 <path fill="currentColor" fill-rule="evenodd" d="M5.306 6.5L0 1.194 1.194 0 6.5 5.306 11.806 0 13 1.194 7.694 6.5 13 11.806 11.806 13 6.5 7.694 1.194 13 0 11.806 5.306 6.5z"></path> 52 </svg> 53 </button> 54 <div id="QuickAddInfo-${product.id}" class="quick-add-modal__content-info"></div> 55 </div> 56 </quick-add-modal> 57 `:` 58 <algolia-product-form data-section-id="algolia-${product.id}"> 59 <form action="/cart/add" method="post" enctype="multipart/form-data" class="form" novalidate="novalidate" data-type="add-to-cart-form" id="product form-${product.id}"> 60 <input type="hidden" name="id" value="${product.variants?.[0]?.id||product.objectID}" class="product-variant-id" /> 61 <button 62 id="ProductSubmitButton-${product.id}" 63 type="submit" 64 name="add" 65 class="${buttonClass} quick-add__submit button button--full-width button" 66 aria-labelledby="ProductSubmitButton-${product.id} title-${product.id}" 67 aria-live="polite" 68 data-sold-out-message="true" 69 > 70 ${buttonText} 71 <span class="sold-out-message hidden">{{ 'products.product.sold_out' | t }}</span> 72 <div class="loading__spinner hidden"> 73 <svg aria-hidden="true" focusable="false" class="spinner" viewBox="0 0 66 66"> 74 <circle class="path" fill="none" stroke-width="6" cx="33" cy="33" r="30"></circle> 75 </svg> 76 </div> 77 </button> 78 </form> 79 </algolia-product-form> 80 `} 81 </div> 82 </div> 83 <div class="cart-notification__recommendation-info"> 84 <h5 class="cart-notification__recommendation-title"><a href="https://medicalrite.com/products/${product.handle}">${product.title}${this.getSoldByOption(product)?`, <span>${this.getSoldByOption(product)}</span>`:""}</a></h5> 85 <div class="cart-notification__recommendation-price"> 86 <div class="price-wrap-custom"> 87 ${hasVariants?` 88 <span class="from-span">From</span> 89 `:""} 90 <span class="productitem--price"> 91 <span class="productitem--price-main${product.compare_at_price>product.price?" price--reduced":""}"> 92 ${Shopify.formatMoney(product.price)} 93 </span> 94 ${product.compare_at_price>product.price?` 95 <span class="productitem--price-compare-at"> 96 ${Shopify.formatMoney(product.compare_at_price)} 97 </span> 98 `:""} 99 </span> 100 </div> 101 </div> 102 </div> 103 </div> 104 `}getSoldByOption(product){if(!product.options)return"";for(let option of product.options)if(option.name.toLowerCase().replace(/[^a-z0-9]+/g,"-")==="sold-by"){const selectedValue=option.values[0],selectedValueHandle=selectedValue.toLowerCase().replace(/[^a-z0-9]+/g,"-");return["each","ea"].includes(selectedValueHandle)?"":selectedValue}return""}initializeRecommendationHandlers(container){const buttons=container.querySelectorAll(".cart-notification__recommendation-button")}getSectionsToRender(){return[{id:"cart-notification-product",selector:`[id="cart-notification-product-${this.cartItemKey}"]`},{id:"cart-notification-shipping"},{id:"cart-icon-bubble"}]}getSectionInnerHTML(html,selector=".shopify-section"){return new DOMParser().parseFromString(html,"text/html").querySelector(selector).innerHTML}handleBodyClick(evt){const target=evt.target;if(target!==this.notification&&!target.closest("cart-notification")){const disclosure=target.closest("details-disclosure, header-menu");this.activeElement=disclosure?disclosure.querySelector("summary"):null,this.close()}}setActiveElement(element){this.activeElement=element}}customElements.define("cart-notification",CartNotification); 105//# sourceMappingURL=/cdn/shop/t/183/assets/cart-notification.js.map?v=130782802833411354181761229736
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.