2020-11-21 22:14:37 +00:00
context = window
rest = context . JK . Rest ( )
logger = context . JK . logger
LocationActions = context . LocationActions
SubscriptionActions = context . SubscriptionActions
UserStore = context . UserStore
AppStore = context . AppStore
@CurrentSubscription = React . createClass ( {
mixins: [ Reflux . listenTo ( AppStore , " onAppInit " ) ]
getInitialState: () ->
{
selectedPlan: null
2020-11-30 00:24:28 +00:00
updating: false
2020-11-21 22:14:37 +00:00
}
getDisplayNameTier: (plan_code) ->
2020-11-30 00:24:28 +00:00
if plan_code == ' '
plan_code = null
2020-11-21 22:14:37 +00:00
for subscriptionCode in gon . global . subscription_codes
if plan_code == subscriptionCode . id
return subscriptionCode . name
return " Unknown plan code= #{ plan_code } "
getDisplayNamePrice: (plan_code) ->
2020-11-30 00:24:28 +00:00
if plan_code == ' '
plan_code = null
2020-11-21 22:14:37 +00:00
for subscriptionCode in gon . global . subscription_codes
if plan_code == subscriptionCode . id
return subscriptionCode . price
return " Unknown plan code= #{ plan_code } "
2021-01-11 05:44:49 +00:00
getDisplayCycle : (plan_code) ->
if plan_code == ' '
plan_code = null
for subscriptionCode in gon . global . subscription_codes
if plan_code == subscriptionCode . id
if subscriptionCode . cycle == " year "
return " annual "
else
return subscriptionCode . cycle + " ly "
return " Unknown plan code= #{ plan_code } "
2020-11-21 22:14:37 +00:00
onPlanChanged: (e) ->
2020-11-30 00:24:28 +00:00
val = e . target . value
2021-01-11 05:44:49 +00:00
@originalPlan = this . currentPlan ( )
2020-11-21 22:14:37 +00:00
@ setState ( { selectedPlan: val } )
currentPlan: () ->
2020-11-30 00:24:28 +00:00
if this . state . selectedPlan ?
this . state . selectedPlan
else
this . props . subscription . desired_plan_code || ' '
2020-11-21 22:14:37 +00:00
2020-12-08 15:59:29 +00:00
checkIfPending : () ->
return this . state . selectedPlan ?
2020-11-30 00:24:28 +00:00
onSubmit: (event) ->
if event
event . preventDefault ( )
2021-01-11 05:44:49 +00:00
@ prePerformSubmit ( )
2020-11-30 00:24:28 +00:00
onChangeSubmit: (form) ->
if @ state . updating
return
2021-01-11 05:44:49 +00:00
@ prePerformSubmit ( )
2020-11-21 22:14:37 +00:00
2021-01-11 05:44:49 +00:00
cancelChangePlan : () ->
console . log ( " cancel change plan " , @ originalPlan )
@ setState ( { selectedPlan: @ originalPlan } )
2020-12-02 15:30:58 +00:00
# user selects button on main page
onUpdatePaymentMethod: () ->
if gon . isNativeClient
context . JK . popExternalLink ( " /client # /account/paymentHistory " , true )
else
window . location.href = " /client # /account/paymentHistory "
openBrowserToPayment: () ->
if gon . isNativeClient
context . JK . popExternalLink ( " /client # /account/paymentHistory " , true )
else
window . location.href = " /client # /account/paymentHistory "
2021-01-11 05:44:49 +00:00
prePerformSubmit : () ->
2020-11-30 00:24:28 +00:00
if ! @ state . selectedPlan ?
2020-11-21 22:14:37 +00:00
return
2020-11-30 00:24:28 +00:00
2021-01-11 05:44:49 +00:00
message = null
if this . props . subscription . subscription
if this . state . selectedPlan == null || this . state . selectedPlan == ' '
message = " <p>You have chosen to go back down to the FREE PLAN. Your subscription will be canceled, and you will keep your plan until the end of the current billing cycle.</p> "
else
message = " <p>You have selected the #{ this . getDisplayNameTier ( this . state . selectedPlan ) . toUpperCase ( ) } #{ this . getDisplayCycle ( this . state . selectedPlan ) . toUpperCase ( ) } PLAN and will be charged US$ #{ this . getDisplayNamePrice ( this . state . selectedPlan ) } on the start of next billing cycle.</p> "
else
if this . state . selectedPlan == null || this . state . selectedPlan == ' '
@ performSubmit ( )
return
else
message = " <p>You have selected the #{ this . getDisplayNameTier ( this . state . selectedPlan ) . toUpperCase ( ) } #{ this . getDisplayCycle ( this . state . selectedPlan ) . toUpperCase ( ) } PLAN and will be charged US$ #{ this . getDisplayNamePrice ( this . state . selectedPlan ) } .</p> "
buttons = [ ]
buttons . push ( {
name: ' CANCEL ' ,
buttonStyle: ' button-grey ' ,
click: ( () => ( @ cancelChangePlan ( ) ) )
} )
buttons . push ( {
name: ' CONFIRM ' ,
buttonStyle: ' button-orange ' ,
click: ( () => ( @ performSubmit ( ) ) )
} )
context . JK . Banner . show ( {
title: " Confirm Plan Change " ,
html: message ,
buttons: buttons } )
performSubmit: () ->
2020-11-30 00:24:28 +00:00
@ setState ( { updating: true } )
#SubscriptionActions.changeSubscription(this.state.selectedPlan)
rest . changeSubscription ( this . state . selectedPlan ) . done ( (subscription) =>
SubscriptionActions . forceUpdate ( subscription )
has_billing_info = subscription . has_billing_info
console . log ( " subscription change update " , subscription )
2020-12-08 15:59:29 +00:00
@ setState ( { updating: false , selectedPlan: null } )
2020-11-30 00:24:28 +00:00
if has_billing_info
@ props . app . layout . notify ( {
title: " Subscription updated! " ,
text: " Thank you for supporting JamKazam! "
} )
else
2020-12-02 15:30:58 +00:00
if subscription . desired_plan_code
if gon . isNativeClient
html = context . _ . template ( $ ( ' # template-payment-still-needed-native ' ) . html ( ) , { } , { variable: ' data ' } )
else
html = context . _ . template ( $ ( ' # template-payment-still-needed ' ) . html ( ) , { } , { variable: ' data ' } )
buttons = [ ]
buttons . push ( { name: ' CLOSE ' , buttonStyle: ' button-grey ' } )
buttons . push ( {
name: ' UPDATE PAYMENT METHOD ' ,
buttonStyle: ' button-orange ' ,
click: ( () => ( @ openBrowserToPayment ( ) ) )
} )
context . JK . Banner . show ( {
title: " Payment Method Needed " ,
html: html ,
buttons: buttons } )
else
@ props . app . layout . notify ( {
title: " Subscription updated! " ,
text: " Thank you for supporting JamKazam! "
} )
#@props.app.layout.notify({
# title: "Payment method still needed",
# text: "Please click UPDATE PAYMENT METHOD in the bottom-right of the screen."
#})
2020-12-08 15:59:29 +00:00
2020-11-30 00:24:28 +00:00
)
. fail ( (jqXHR) =>
@ setState ( { updating: false } )
if jqXHR . status == 422
@ props . app . layout . notify ( {
title: " you already have this subscription " ,
text: " No changes were made to your account. "
} )
else
@ props . app . layout . notify ( {
title: " unable to update subscription status " ,
text: " Please contact support@jamkazam.com. Error: \n #{ jqXHR . responseText } "
} )
)
2020-11-21 22:14:37 +00:00
onCancelPlan: (event) ->
if confirm ( " Are you sure you want to cancel your plan? " )
SubscriptionActions . cancelSubscription ( )
componentDidMount: () ->
@root = $ ( @ getDOMNode ( ) )
document . querySelector ( ' # change-subscription-form ' ) . addEventListener ( ' submit ' , @ onChangeSubmit . bind ( this ) )
2021-01-11 05:44:49 +00:00
getTimeRemaining: (t) ->
if t < 0
t = - t
seconds = Math . floor ( ( t / 1000 ) % 60 ) ;
minutes = Math . floor ( ( t / 1000 / 60 ) % 60 ) ;
hours = Math . floor ( ( t / ( 1000 * 60 * 60 ) ) % 24 ) ;
days = Math . floor ( t / ( 1000 * 60 * 60 * 24 ) ) ;
return {
' total ' : t ,
' days ' : days ,
' hours ' : hours ,
' minutes ' : minutes ,
' seconds ' : seconds
} ;
displayTime: (until_time) ->
2021-01-17 01:37:34 +00:00
if until_time < 0
return ' no time '
2021-01-11 05:44:49 +00:00
untilTime = @ getTimeRemaining ( until_time * 1000 )
timeString = ' '
if untilTime . days != 0
timeString += " #{ untilTime . days } days, "
if untilTime . hours != 0 || timeString . length > 0
timeString += " #{ untilTime . hours } hours, "
if untilTime . minutes != 0 || timeString . length > 0
2021-01-17 01:37:34 +00:00
timeString += " #{ untilTime . minutes } minutes "
#if untilTime.seconds != 0 || timeString.length > 0
# timeString += "#{untilTime.seconds} seconds"
2021-01-11 05:44:49 +00:00
if timeString == ' '
' now! '
timeString
2020-11-30 00:24:28 +00:00
comparePlans: (e) ->
if context . JK . clientType ( ) == ' client '
context . JK . popExternalLink ( " https://jamkazam.freshdesk.com/support/solutions/articles/66000122535-what-are-jamkazam-s-free-vs-premium-features- " )
e . preventDefault ( )
2020-11-21 22:14:37 +00:00
render: () ->
plan_codes = [ ]
2020-11-30 00:24:28 +00:00
monthlies = [ ]
yearlies = [ ]
2020-11-21 22:14:37 +00:00
for plan in gon . global . subscription_codes
2020-11-30 00:24:28 +00:00
if plan . cycle == ' month '
monthlies . push ( plan )
else
yearlies . push ( plan )
plan_codes . push ( ` < option key = " monthly " value = " monthly " disabled = " disabled " > - - - - - - - - MONTHLY PLANS - - - - - - - - < / option > ` )
for plan in monthlies
plan_codes . push ( ` < option key = { plan . id || ' ' } value = { plan . id || ' ' } > { plan . name } ( $ { plan . price . toFixed ( 2 ) } / { plan . cycle } ) < / option > ` )
plan_codes . push ( ` < option key = " yearly " value = " yearly " disabled = " disabled " > - - - - - - - - YEARLY PLANS - - - - - - - - < / option > ` )
for plan in yearlies
plan_codes . push ( ` < option key = { plan . id || ' ' } value = { plan . id || ' ' } > { plan . name } ( $ { plan . price . toFixed ( 2 ) } / { plan . cycle } ) < / option > ` )
2021-01-11 05:44:49 +00:00
plansJsx = ` < select name = " plan_code " onChange = { this . onPlanChanged } defaultValue = { this . currentPlan ( ) } value = { this . currentPlan ( ) } > { plan_codes } < / select > `
2020-11-30 00:24:28 +00:00
changeClass = ' button-orange update-plan '
if ! @ state . selectedPlan ? || @ state . updating
2020-11-21 22:14:37 +00:00
changeClass = changeClass + ' disabled '
2020-12-08 15:59:29 +00:00
if @ state . updating
update_plan_text = ' UPDATING PLAN ... PLEASE WAIT '
else
update_plan_text = ' UPDATE PLAN '
2020-11-21 22:14:37 +00:00
2020-11-30 00:24:28 +00:00
recurly_subscription = @ props . subscription . subscription
effective_plan_name = ` < span className = " plan-name " > { this . getDisplayNameTier ( this . props . subscription . plan_code ) } < / span > `
desired_plan_name = ` < span className = " plan-name " > { this . getDisplayNameTier ( this . props . subscription . desired_plan_code ) } < / span > `
admin_override_plan_name = ` < span className = " plan-name " > { this . getDisplayNameTier ( this . props . subscription . admin_override_plan_code ) } < / span > `
in_trial = @ props . subscription . in_trial
2020-12-05 19:53:04 +00:00
admin_override = @ props . subscription . admin_override_plan_code ?
2020-11-30 00:24:28 +00:00
effective_is_free = ! ! this . props . subscription . plan_code
has_pending_subscription = @ props . subscription . subscription ? . pending_subscription ?
cancelled_subscription = @ props . subscription . subscription ? . remaining_billing_cycles == 0
show_payment_info = null
has_billing_info = @ props . subscription . has_billing_info
2020-12-08 15:59:29 +00:00
2020-12-05 19:53:04 +00:00
if admin_override
explanation = ` < span > You have a { effective_plan_name } account until your gifted plan ends { context . JK . formatDateShort ( this . props . subscription . admin_override_ends_at ) } . < / span > `
else if in_trial
2020-11-30 00:24:28 +00:00
if @ props . subscription . desired_plan_code
if has_billing_info
note = ` < span > Billing starts for the { desired_plan_name } plan after the trial ends . < / span > `
else
warning = ` < p className = " uncollectable-msg " > You will drop to the < span className = " plan-name " > Free < / span > free plan after the trial ends because you have not yet entered payment info . < / p > `
show_payment_info = true
else
if has_billing_info
warning = ` < p className = " uncollectable-msg " > You will drop to the < span className = " plan-name " > Free < / span > free plan after the trial ends because you have not selected a plan . < / p > `
else
warning = ` < p className = " uncollectable-msg " > You will drop to the < span className = " plan-name " > Free < / span > free plan after the trial ends because you have not yet entered payment info or selected a plan . < / p > `
show_payment_info = true
2020-12-03 22:53:39 +00:00
explanation = ` < span > You have a { effective_plan_name } account until your trial ends { context . JK . formatDateShort ( this . props . subscription . trial_ends_at ) } . { note } < / span > `
2020-11-30 00:24:28 +00:00
else
if @ props . subscription . desired_plan_code && ! @ props . subscription . plan_code && ! has_billing_info
explanation = ` < span > You have successfully upgraded your plan to the { desired_plan_name } level , thank you ! < / span > `
warning = ` < p className = " uncollectable-msg " > For this plan to take effect , you must provide a payment method ( e . g . a credit card ) , for the monthly subscription charge . Please click the Update Payment Method button to do this now . < / p > `
show_payment_info = true
else
if @ props . subscription . desired_plan_code
if ! has_billing_info
show_payment_info = true
explanation = ` < span > You have successfully upgraded your plan to the { desired_plan_name } level , thank you < / span > `
warning = ` < p className = " uncollectable-msg " > However , you must provide a payment method ( e . g . a credit card ) , for the monthly subscription charge . Please click the Update Payment Method button to do this now . < / p > `
else
2021-01-17 01:37:34 +00:00
explanation = ` < span > You are currently on the { effective_plan_name } level , thank you ! < / span > `
2020-11-30 00:24:28 +00:00
else
# free plan situation - not much to go on about
2021-01-17 01:37:34 +00:00
explanation = ` < span > You are currently on the { effective_plan_name } plan . < / span > `
2020-11-30 00:24:28 +00:00
if show_payment_info
2020-12-02 15:30:58 +00:00
update_payment_btn = ` < a className = " button-orange update-payment-method " href = " /client # /account/paymentHistory " onClick = { this . onUpdatePaymentMethod } > UPDATE PAYMENT METHOD < / a > `
2020-11-30 00:24:28 +00:00
if has_pending_subscription
2021-01-17 01:37:34 +00:00
if this . props . subscription . subscription . plan . plan_code != this . props . subscription . plan_code
billingAddendum = ` < span > You have paid only for the < span className = " plan-name " > { this . getDisplayNameTier ( this . props . subscription . subscription . plan . plan_code ) } < / span > level for the current billing cycle , so there will be a change to the < span className = " plan-name " > { this . getDisplayNameTier ( this . props . subscription . subscription . pending_subscription . plan . plan_code ) } < / span > level on the next billing cycle . < / span > `
else
billingAddendum = ` < span > And your plan and billing will switch to the < span className = " plan-name " > { this . getDisplayNameTier ( this . props . subscription . subscription . pending_subscription . plan . plan_code ) } < / span > level on the next billing cycle . < / span > `
2020-11-30 00:24:28 +00:00
else if cancelled_subscription && this . props . subscription . desired_plan_code == null && this . props . subscription . plan_code != null
billingAddendum = ` < span > However , your cancelled { effective_plan_name } plan is still active until the end of the billing cycle . < /span>`# `<span><br/ > < br / > < span > You will be billed a final time at the < span className = " plan-name " > { this . getDisplayNameTier ( this . props . subscription . subscription . plan . plan_code ) } < / span > at end of this billing cycle . < / span > < / span > `
2020-11-21 22:14:37 +00:00
else
billingAddendum = null
2021-01-11 05:44:49 +00:00
if @ props . subscription . subscription_rules . remaining_month_play_time
remaining_month_play_time = @ props . subscription . subscription_rules . remaining_month_play_time
until_time = new Date ( )
until_time = new Date ( until_time . getTime ( ) + remaining_month_play_time * 1000 )
#until_time.setSeconds(until_time.getSeconds() + @subscriptionRules.remaining_month_play_time)
playtime = ` < div className = " play-time " >
< label > monthly play time remaining : < / label >
2021-01-17 01:37:34 +00:00
< p > You have < span className = " playtime " > { this . displayTime ( remaining_month_play_time ) } < / span > remaining this month . Only the time you spend in a session with 2 or more people uses your session play time . < / p >
2021-01-11 05:44:49 +00:00
< / div > `
else
playtime = ` < div className = " play-time " >
< label > monthly play time remaining : < / label >
< p > You have unlimited play time . < / p >
< / div > `
2020-11-30 00:24:28 +00:00
` < div className = " current-subscription " >
2020-11-21 22:14:37 +00:00
< div >
2020-11-30 00:24:28 +00:00
< h2 > Subscription : < / h2 >
< p className = " explainer " > Your JamKazam subscription is currently set to the plan displayed below . To compare the features available for different subscription plans , click the Compare Plans button below . To change your plan , click the " subscription plan " list box below , select a new plan , and then click the Update Plan button below . < / p >
< div className = " subscription-plan-and-status " >
< div className = " subscription-plan " >
< form id = " change-subscription-form " onSubmit = { this . onChangeSubmit } >
< label for = " plan_code " > subscription plan : < / label >
< div className = " subscription-actions " >
{ plansJsx }
< a className = " button-grey " onClick = { this . comparePlans } target = " _blank " href = " https://jamkazam.freshdesk.com/support/solutions/articles/66000122535-what-are-jamkazam-s-free-vs-premium-features- " > COMPARE PLANS < / a >
2020-12-08 15:59:29 +00:00
< button className = { changeClass } onClick = { this . onSubmit } type = " submit " > { update_plan_text } < / button >
2020-11-30 00:24:28 +00:00
< / div >
< / form >
< / div >
< / div >
< div className = " effective-subscription " >
< div className = " explanation " >
< p > { explanation } { billingAddendum } < / p >
{ warning }
< / div >
2021-01-11 05:44:49 +00:00
{ playtime }
2020-11-30 00:24:28 +00:00
< a className = " button-grey " onClick = { this . onCancel } > BACK < / a > { update_payment_btn }
2020-11-21 22:14:37 +00:00
< / div >
< / div >
< / div > `
} )