class SubscriptionForm { TWELVE_OZ = '12' SIXTEEN_OZ = '16' FIVE_LBS = '75' TWELVE_SHIPPING = 7 SIXTEEN_SHIPPING = 5 FIVE_SHIPPING = 1 max_quantity = 20 form = null products = null output = null price = null productsAndQuantities = null constructor(form, output) { this.form = form this.productsAndQuantities = this.form.querySelector('[name=products_quantities]') this.output = this.form.querySelector('.output') this.shippingDiscount = 10 this.price = this.form.querySelector('select[name=size]') this.products = this.form.querySelectorAll('input[name^=product_]') this.form.addEventListener('change', this.render.bind(this)) this.render() } get total_qty() { return Array.from(this.products).reduce((total, current) => { return total + Number(current.value) }, 0) } get hasFreeShipping() { switch(this.price.value) { case this.TWELVE_OZ: if (parseInt(this.total_qty) >= this.TWELVE_SHIPPING) { return true } else { return false } break case this.SIXTEEN_OZ: if (parseInt(this.total_qty) >= this.SIXTEEN_SHIPPING) { return true } else { return false } break case this.FIVE_LBS: if (parseInt(this.total_qty) >= this.FIVE_SHIPPING) { return true } else { return false } break default: throw 'Something is wrong with the price' } } get countToFreeShipping() { switch(this.price.value) { case this.TWELVE_OZ: return this.TWELVE_SHIPPING - this.total_qty break case this.SIXTEEN_OZ: return this.SIXTEEN_SHIPPING - this.total_qty break case this.FIVE_LBS: return this.FIVE_SHIPPING break default: throw 'Something is wrong with the price' break } } get shippingStatus() { let items = 0 if (this.hasFreeShipping) { return 'You have free shipping!' } else { return `Add ${this.countToFreeShipping} more item(s) for free shipping!` } } get totalRetailPrice() { let totalPrice = Array.from(this.products).reduce((total, current) => { return total + (Number(this.price.value) * current.value); }, 0); return new Intl.NumberFormat('en-US', { currency: 'USD', style: 'currency', }).format(totalPrice) } get totalPrice() { let totalPrice = Array.from(this.products).reduce((total, current) => { return total + (Number(this.price.value) * current.value); }, 0); let percentage = (this.shippingDiscount / 100) * totalPrice return new Intl.NumberFormat('en-US', { currency: 'USD', style: 'currency', }).format(totalPrice - percentage) } render(event) { this.output.querySelector('.retail-price').innerText = this.totalRetailPrice this.output.querySelector('.price').innerText = this.totalPrice this.output.querySelector('.shipping').innerText = this.shippingStatus this.updateSelected() if (this.total_qty < this.max_quantity) { Array.from(this.products).map(input => input.max = this.max_quantity) } else { Array.from(this.products).map(input => { if (input.value == '') { input.max = 0 } else { input.max = input.value } }) } } updateSelected() { const selected = Array.from(this.products).filter(item => item.value > 0) this.productsAndQuantities.value = selected.map(item => `${item.name.slice(8)}:${item.value}`).join(',') console.log(this.productsAndQuantities.value) } createSubscription() { fetch('/create-subscription', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ priceId: priceId, customerId: customerId, }), }) } } document.addEventListener('DOMContentLoaded', () => { new SubscriptionForm(document.querySelector('.subscription-create-form')) })