(()=>{class t{constructor(t={}){this.checkout=document.querySelector("aside#cart"),this.checkout&&(this.config=Object.assign({application_id:squareConfig.application_id,location_id:squareConfig.location_id,api_url:squareConfig.api_url,nonce:squareConfig.nonce,currency:squareConfig.currency||"CAD"},t),this.stepMultiplier=1,this.cache=new window.jvbCache("cart",{TTL:864e5}),this.a11y=window.jvbA11y,this.initCart(),this.payments=null,this.card=null,this.isInitialized=!1,this.clickHandler=this.handleClick.bind(this),this.keyHandler=this.handleEscape.bind(this),this.changeHandler=this.handleChange.bind(this),this.initElements(),this.bindEvents(),this.init(),this.toggle.hidden=!1)}async initCart(){this.cartItems=await this.cache.get("cart")??new Map,console.log("cart",this.cartItems),this.cartItems.size>0&&this.notifyRestoredCart()}handleClick(t){if(window.targetCheck(t,".toggle-cart")){window.targetCheck(t,".toggle-cart");console.log("Toggle found. Toggling cart"),this.toggleCart()}else if(window.targetCheck(t,"button")&&window.targetCheck(t,"div.quantity")){let e=window.targetCheck(t,"div.quantity");this.handleNumberClick(t,e)}else if(window.targetCheck(t,"[data-add-to-cart]")){let e=window.targetCheck(t,"[data-add-to-cart]");this.handleAddToCart(e)}else if(window.targetCheck(t,"[data-remove-from-cart]")){let e=window.targetCheck(t,"[data-remove-from-cart]");this.handleRemoveFromCart(e)}else window.targetCheck(t,"[data-clear-cart]")?this.clearCart():this.checkout.classList.contains("expanded")&&!this.checkout.contains(t.target)&&t.target!==this.toggle&&this.closeCart()}handleChange(t,e){console.log("Checkout change");let a=window.targetCheck(t,".quantity-input");if(a){let e=t.target.closest(".quantity"),i=a.value;if(window.targetCheck(t,".cart-items")){let t=document.querySelector(`.menu-section [data-id="${e.dataset.id}"] input`);t&&(t.value=a.value)}i>0?this.handleAddToCart(e):this.handleRemoveFromCart(e)}}handleNumberClick(t,e){console.log(e),t.preventDefault();let a=0;if(t.target.closest(".increase")?a+=1:t.target.closest(".decrease")&&(a-=1),0!==a){let[t,i]=[parseInt(e.dataset.step),e.querySelector("input")],r=""===i.value?0:parseInt(i.value);i.value=r+t*a*this.stepMultiplier,i.dispatchEvent(new Event("change",{bubbles:!0})),this.handleNumberLimits(e)}}handleNumberLimits(t){let[e,a,i,r,s]=[t.dataset.min,t.dataset.max,t.querySelector("input"),t.querySelector(".increase"),t.querySelector(".decrease")],o=parseInt(i.value);o<e?(i.value=e,s.disabled=!0):o>a?(i.value=a,r.disabled=!1):r.disabled?r.disabled=!1:s.disabled&&(s.disabled=!1)}toggleCart(){this.checkout.classList.contains("expanded")?this.closeCart():this.openCart()}openCart(t="Opened Cart"){this.checkout.classList.add("expanded"),this.toggle.title="Hide cart",this.toggle.ariaExpanded=!0,this.toggle.querySelector("span").textContent="Close Cart",this.a11y.announce(t),this.maybeAddEmptyState(),document.addEventListener("keydown",this.keyHandler)}maybeAddEmptyState(){let t=this.itemsList.querySelector(".empty");if(t&&t.remove(),0===this.cartItems.size){this.checkoutPanel.disabled=!0,this.checkoutPanel.title="Add some things to your cart first!";let t=window.getTemplate("emptyCart");this.itemsList.append(t),this.table.closest("table").hidden=!0,this.total.hidden=!0,this.a11y.announce("Nothing in Cart")}else this.checkoutPanel.disabled=!1,this.table.closest("table").hidden=!1,this.total.hidden=!1,this.checkoutPanel.title="Checkout"}closeCart(t="Closed Cart"){this.checkout.classList.remove("expanded"),this.toggle.title="Show Cart",this.toggle.ariaExpanded=!1,this.toggle.querySelector("span").textContent="",this.a11y.announce(t),document.removeEventListener("keydown",this.keyHandler)}handleEscape(t){"Escape"===t.key?(this.closeCart("Closed Cart with escape key"),this.stepMultiplier=1):t.ctrlKey&&t.shiftKey?this.stepMultiplier=Math.max(100*parseInt(this.stepMultiplier),1e3):t.shiftKey&&(this.stepMultiplier=Math.max(10*parseInt(this.stepMultiplier),1e3))}handleAddToCart(t){let e=t.dataset.id;this.createItemElement(t);let a=parseFloat(t.dataset.price),i=parseInt(t.querySelector(".quantity-input")?.value)??1,r=parseFloat(a*i);this.cartItems.set(e,{post_id:e,name:t.dataset.name,price:a,quantity:i,total:r,square_catalog_id:t.dataset.squareCatalogId}),this.saveCart()}notifyRestoredCart(){let t=window.getTemplate("restoredCart");this.checkout.querySelector(".tab-content[data-tab=cartItems]").insertBefore(t,this.itemsList),this.cartItems.forEach((t=>{console.log(t);let e=window.getTemplate("cartItem"),a=e.querySelector(".quantity"),i=t.price,r=t.quantity;[a.dataset.id,e.querySelector("label").textContent,e.querySelector(".price").textContent,a.dataset.price,a.dataset.squareCatalogId,e.querySelector('[name="quantity"]').value,e.querySelector(".total").textContent]=[t.post_id,t.name,window.formatPrice(i),i,t.square_catalog_id,r,window.formatPrice(r*i)],this.table.append(e)})),this.updateTotal()}handleRemoveFromCart(t){if(confirm("This will remove this item from the cart. Continue?")){t.querySelector("[data-id]")||(t=t.closest(".item")?.querySelector(".quantity.field"));let e=t.dataset.id;this.cartItems.delete(e),this.table.querySelector(`[data-id="${e}"]`)?.closest("tr").remove();let a=document.querySelector(`[data-id="${e}"] input`);a&&(a.value=0),this.maybeAddEmptyState(),this.saveCart()}}clearCart(){this.cartItems.clear(),window.removeChildren(this.table),this.saveCart()}saveCart(){this.updateTotal(),this.cache.set("cart",this.cartItems)}updateTotal(){let t=0;this.cartItems.forEach((e=>{console.log(e),t+=e.total}));let e=.05*t;t=window.formatPrice(t+e),e=window.formatPrice(e),window.eraseText(this.totalTax),window.eraseText(this.grandTotal),window.typeText(this.totalTax,e),window.typeText(this.grandTotal,t),this.totalTax.classList.remove("typeText")}createItemElement(t){let e=this.itemsList.querySelector(`[data-id="${t.dataset.id}"]`),a=!1,i=t.dataset.price,r=t.querySelector('[name="quantity"]')?.value??1;if(e)e=e.closest("tr");else{a=!0,e=window.getTemplate("cartItem");let r=e.querySelector(".quantity");[r.dataset.id,e.querySelector("label").textContent,e.querySelector(".price").textContent,r.dataset.price,r.dataset.squareCatalogId]=[t.dataset.id,t.dataset.name,window.formatPrice(i),i,t.dataset.squareCatalogId]}[e.querySelector('[name="quantity"]').value,e.querySelector(".total").textContent]=[r,window.formatPrice(r*i)],a&&(e.classList.add("adding"),this.table.append(e),setTimeout((()=>{e.classList.remove("adding")}),500))}async init(){if(window.Square)try{this.payments=window.Square.payments(this.config.application_id,this.config.location_id),await this.initializePaymentMethods(),this.isInitialized=!0,document.dispatchEvent(new CustomEvent("squareCheckoutReady",{detail:{checkout:this}}))}catch(t){console.error("Failed to initialize Square payments:",t),this.handleError(t)}else console.error("Square Web Payments SDK not loaded")}initElements(){this.toggle=document.querySelector(".toggle-cart"),"1"!==squareConfig.isOpen&&(this.toggle.disabled=!0,this.toggle.title="Currently closed for online ordering"),this.checkoutPanel=this.checkout.querySelector('button[data-tab="checkout"]'),this.itemsList=this.checkout.querySelector(".cart-items"),this.table=this.checkout.querySelector(".cart-items tbody"),this.total=this.checkout.querySelector(".cart-total"),this.totalTax=this.total.querySelector(".tax span"),this.grandTotal=this.total.querySelector(".total span"),this.checkoutForm=this.checkout.querySelector("form"),this.tabs=new window.jvbTabs(this.checkoutForm,{updateURL:!1}),console.log("Initialized Checkout")}bindEvents(){this.checkoutForm.addEventListener("submit",(t=>this.handleFormSubmit(t))),document.addEventListener("click",this.clickHandler),document.addEventListener("change",this.changeHandler)}async initializePaymentMethods(){if(document.getElementById("square-card-container"))try{this.card=await this.payments.card({style:this.getCardStyle()}),await this.card.attach("#square-card-container")}catch(t){throw console.error("Failed to initialize card:",t),t}}getCardStyle(){return{input:{fontSize:"16px",fontFamily:"inherit",color:"#333",backgroundColor:"#fff"},".input-container":{borderColor:"#ccc",borderRadius:"4px"},".input-container.is-focus":{borderColor:"#007cba"},".input-container.is-error":{borderColor:"#d63638"}}}async handleFormSubmit(t){if("1"!==squareConfig.isOpen)return;if(t.preventDefault(),!this.isInitialized)return void this.handleError("Checkout not initialized");const e=t.target,a=this.extractOrderData(e);try{window.jvbLoading.showLoading("Processing payment...");const t=await this.processPayment(a);this.handleSuccess(t,e)}catch(t){this.handleError(t)}finally{window.jvbLoading.hideLoading()}}extractOrderData(t){const e=Array.from(this.cartItems.values()).map((t=>({post_id:t.post_id,quantity:t.quantity,price:t.price,name:t.name})));return{total:100*e.reduce(((t,e)=>t+e.price*e.quantity),0),items:e,customer:{email:t.querySelector('[name="email"]')?.value||"",name:t.querySelector('[name="name"]')?.value||"",phone:t.querySelector('[name="phone"]')?.value||""},note:t.querySelector('[name="special_instructions"]')?.value||"",pickup_time:t.querySelector('[name="pickup_time"]')?.value||""}}async processPayment(t){try{const e=await this.card.tokenize();if("OK"===e.status)return await this.submitToServer(e.token,t);throw new Error("Card tokenization failed: "+(e.errors?.join(", ")||"Unknown error"))}catch(t){throw console.error("Payment processing failed:",t),t}}async submitToServer(t,e){if("1"!==squareConfig.isOpen)return;const a=await fetch(this.config.api_url+"save-order",{method:"POST",headers:{"Content-Type":"application/json","X-WP-Nonce":this.config.nonce},body:JSON.stringify({order_id:t.orderId,payment_id:t.paymentId,customer:e.customer,items:e.items,action:"jvb_integration_action",service:"square",integration_action:"save_order"})}),i=await a.json();if(!a.ok)throw new Error(i.message||"Failed to save order");return i}trackOrder(t){this.orderId=t,this.scheduleOrderCheck(),this.checkout.querySelector("button[data-tab=order]").hidden=!1}scheduleOrderCheck(){window.debouncer.schedule("order",(()=>{this.checkOrderStatus()}),3e4)}async checkOrderStatus(){const t=await fetch(`/wp-json/jvb/v1/square/order-status/${this.orderId}`),e=await t.json();"ready"!==e.status&&this.scheduleOrderCheck(),this.updateOrderStatus(e)}updateOrderStatus(t){this.checkout.querySelectorAll(".status-item").forEach((e=>{e.dataset.status===t.status&&e.classList.add("active")})),this.checkout.querySelector("#eta").textContent=t.eta||"In progress"}async loadCustomerProfile(t){const e=await fetch("/wp-json/jvb/v1/square/customer",{method:"POST",headers:{"Content-Type":"application/json","X-WP-Nonce":this.config.nonce},body:JSON.stringify({email:t})}),a=await e.json();a&&(this.displaySavedCards(a.cards),this.fillCustomerInfo(a.customer))}displaySavedCards(t){const e=document.getElementById("saved-cards");t.length&&(e.innerHTML=`\n <h3>Saved Payment Methods</h3>\n ${t.map((t=>`\n <label>\n <input type="radio" name="payment_method" value="${t.id}">\n •••• ${t.last_4} (${t.card_brand})\n </label>\n `)).join("")}\n <label>\n <input type="radio" name="payment_method" value="new" checked>\n Use new card\n </label>\n `)}handleSuccess(t,e){document.dispatchEvent(new CustomEvent("squareCheckoutSuccess",{detail:{result:t,form:e}}));const a=e.dataset.successUrl||`/order-confirmation/?order=${t.wp_order_id}`;window.location.href=a}handleError(t){console.error("Square checkout error:",t),document.dispatchEvent(new CustomEvent("squareCheckoutError",{detail:{error:t}})),window.jvbNotifications?.show?.(t.message||"Payment failed","error")}}document.addEventListener("DOMContentLoaded",(()=>{window.squareCheckout=new t}))})();
|