var EditSubscriptionModal = ModalView.extend({ el: ".mediaDrawer.editSubscription", action: "/api/subscription", syncAction: "/api/subscription/sync", updateAction: "/api/subscription", destroyAction: "/api/subscription/destroy", fixedClose: true, editing: false, subscriber: null, tempSubscriber: null, events: { "click [data-role='addLayouts']": 'addLayouts', "click [data-role='changePlan']": 'changePlan', "click [data-role='cancelSubscription']": 'destroy', "click .gear": 'sync', "click .planList button": 'followLink', "click [data-role=showEditMenu]": "editMode", "click [data-role=closeMenu]": "resetMode", "input [data-role=basicLayoutInput]": "updateQuantity", "input [data-role=proLayoutInput]": "updateQuantity", "click [data-role=saveChanges]": "saveChanges", "change [name=planRadio]": "updatePlan", "click [data-role=savePlan]": "savePlan", "submit form": "preventDefault", }, initialize: function(){ // this.parent = opt.parent this.__super__.initialize.call(this) // two sections this.$freePlan = this.$(".freePlan") this.$paidPlan = this.$(".paidPlan") // subscription table this.$planInfo = this.$(".planInfo") this.$planRow = this.$(".planRow") this.$basicLayoutRow = this.$(".basicLayoutRow") this.$proLayoutRow = this.$(".proLayoutRow") this.$totalRow = this.$(".totalRow") this.$planList = this.$(".planList") this.$billingInterval = this.$("[data-role=billingInterval]") // plan stuff this.$planName = this.$("[data-role=planName]") this.$planCost = this.$("[data-role=planCost]") this.$planTotal = this.$("[data-role=planTotal]") this.$basicPlanName = this.$("[data-role=basicPlanName]") this.$basicPlanCost = this.$("[data-role=basicPlanCost]") this.$proPlanName = this.$("[data-role=proPlanName]") this.$proPlanCost = this.$("[data-role=proPlanCost]") // basic + pro layout stuff this.$basicLayoutCost = this.$("[data-role=basicLayoutCost]") this.$basicLayoutQuantity = this.$("[data-role=basicLayoutQuantity]") this.$basicLayoutTotal = this.$("[data-role=basicLayoutTotal]") this.$proLayoutCost = this.$("[data-role=proLayoutCost]") this.$proLayoutQuantity = this.$("[data-role=proLayoutQuantity]") this.$proLayoutTotal = this.$("[data-role=proLayoutTotal]") // menus.. main menu this.$showEditMenu = this.$("[data-role=showEditMenu]") this.$cancelSubscription = this.$("[data-role=cancelSubscription]") // three submenus this.$editMenu = this.$("[data-role=editMenu]") this.$planMenu = this.$("[data-role=planMenu]") this.$buyLayouts = this.$("[data-role=buyLayouts]") this.$closeMenu = this.$("[data-role=closeMenu]") this.$changePlan = this.$("[data-role=changePlan]") // input fields this.$basicLayoutInput = this.$("[data-role=basicLayoutInput]") this.$proLayoutInput = this.$("[data-role=proLayoutInput]") this.$planRadio = this.$("[name=planRadio]") this.$basicPlanInput = this.$("[data-role=basicPlanInput]") this.$proPlanInput = this.$("[data-role=proPlanInput]") this.$gear = this.$(".gear") }, plan_levels: { free: 0, basic: 1, pro: 2, custom: 3, artist: 4, }, loaded: false, load: function(){ if (this.loaded) { return this.show() } $.get(this.action, this.didLoad.bind(this)) }, didLoad: function(data){ this.loaded = true this.plans = data.plans if (data.subscription) { this.subscriber = data.subscription } else if (data.error) { // ...no subscription found this.subscriber = null } return this.show() }, followLink: function(e){ e.preventDefault(); window.location.href = $(e.target).closest("a").attr("href") }, show: function(){ this.$gear.removeClass("turning") if (! this.subscriber) { this.$freePlan.show() this.$paidPlan.hide() this.$planList.load("/partials/plans", function(){ this.$(".free_plan_info").remove() this.__super__.show.call(this) }.bind(this)) return } this.$freePlan.hide() this.$paidPlan.show() this.resetMode() this.__super__.show.call(this) }, reset: function(){ var subscriber = this.subscriber var plan = this.getPlan(subscriber.plan_type) this.displayTotals(subscriber, plan) }, getPlan: function(plan_type){ return this.plans[ this.plan_levels[ plan_type ] ] }, calculateTotals: function(subscriber, plan){ var t = {} t.is_pro = subscriber.plan_type == "pro" t.is_monthly = subscriber.plan_period == "monthly" t.plan_price = t.is_monthly ? plan.monthly_price : plan.yearly_price t.basic_layout_price = t.is_monthly ? plan.basic_layout_monthly_price : plan.basic_layout_yearly_price t.basic_layout_total = subscriber.basic_layouts * t.basic_layout_price t.pro_layout_price = t.is_monthly ? plan.pro_layout_monthly_price : plan.pro_layout_yearly_price t.pro_layout_total = t.is_pro ? subscriber.pro_layouts * t.pro_layout_price : 0 t.plan_total = t.plan_price + t.basic_layout_total + t.pro_layout_total return t }, displayTotals: function(subscriber, plan){ var totals = this.calculateTotals(subscriber, plan) this.$basicPlanName.html ( this.plans[1].name ) this.$proPlanName.html ( this.plans[2].name ) this.$basicPlanCost.toDollars ( totals.is_monthly ? this.plans[1].monthly_price : this.plans[2].yearly_price) this.$proPlanCost.toDollars ( totals.is_monthly ? this.plans[2].monthly_price : this.plans[2].yearly_price) this.$planName.html ( plan.name ) this.$planCost.toDollars ( totals.plan_price ) this.$billingInterval.html ( totals.is_monthly ? "mo." : "yr." ) this.$basicLayoutRow.toggle ( subscriber.basic_layouts > 0 ) this.$proLayoutRow.toggle ( totals.is_pro && subscriber.pro_layouts > 0) this.$basicLayoutCost.toDollars ( totals.basic_layout_price ) this.$basicLayoutQuantity.html ( subscriber.basic_layouts ) this.$basicLayoutTotal.toDollars ( totals.basic_layout_total ) this.$proLayoutCost.toDollars ( totals.pro_layout_price ) this.$proLayoutQuantity.html ( subscriber.pro_layouts ) this.$proLayoutTotal.toDollars ( totals.pro_layout_total ) this.$planTotal.toDollars ( totals.plan_total ) }, editMode: function(e){ e && e.preventDefault() this.editing = true this.$el.addClass("editing") this.tempSubscriber = defaults({}, this.subscriber) this.$basicLayoutInput.val( this.subscriber.basic_layouts ) this.$proLayoutInput.val( this.subscriber.pro_layouts ) this.$basicLayoutRow.show() this.$proLayoutRow.toggle(this.subscriber.plan_type == "pro") switch (this.subscriber.plan_type) { case 'basic': this.$basicPlanInput.prop('checked', true); break; case 'pro': this.$proPlanInput.prop('checked', true); break; } }, resetMode: function(e){ e && e.preventDefault() this.editing = false this.$el.removeClass("editing") this.reset() }, updateQuantity: function(e){ e && e.preventDefault() var plan = this.getPlan( this.tempSubscriber.plan_type ) this.tempSubscriber.basic_layouts = clamp( this.$basicLayoutInput.int() || 0, 0, 100) this.tempSubscriber.pro_layouts = clamp( this.$proLayoutInput.int() || 0, 0, 100) this.$basicLayoutInput.val(this.tempSubscriber.basic_layouts) this.$proLayoutInput.val(this.tempSubscriber.pro_layouts) this.displayTotals(this.tempSubscriber, plan) this.$basicLayoutRow.show() this.$proLayoutRow.toggle(this.tempSubscriber.plan_type == "pro") }, saveChanges: function(e){ e && e.preventDefault() var is_changed = false var diff = {} "plan_type basic_layouts pro_layouts".split(" ").forEach(function(field){ diff[field] = this.tempSubscriber[field] if (this.tempSubscriber[field] != this.subscriber[field]) { is_changed = true } }.bind(this)) if (is_changed) { this.update(diff) } this.subscriber = this.tempSubscriber this.resetMode() }, updatePlan: function(e){ e && e.preventDefault() this.tempSubscriber.plan_type = this.$("[name=planRadio]:checked").val() this.updateQuantity() }, sync: function(){ this.$gear.addClass("turning") $.ajax({ url: this.syncAction, type: "put", data: { _csrf: $("[name=_csrf]").val() }, success: this.didLoad.bind(this) }) }, update: function(data){ data['_csrf'] = $("[name=_csrf]").val() this.$gear.addClass("turning") $.ajax({ url: this.updateAction, type: "put", data: data, success: function(data){ this.$gear.removeClass("turning") }.bind(this) }) }, destroy: function(e){ e.preventDefault() var msg = "Are you sure you want to cancel your subscription?" ConfirmModal.confirm(msg, function(){ $.ajax({ url: this.destroyAction, type: "delete", data: { _csrf: $("[name=_csrf]").val() }, success: function(data){ this.subscriber = null this.didLoad(data) }.bind(this) }) }.bind(this), function(){ this.show() }.bind(this)) }, })