new client 2017 09 19 various fixes: subscriptions, streaks, etc (#9047)

* remove excess brace on settings > subscription screen

* prevent User icon > Settings > Subscription page from crashing when subscription has termination date

* stop subscription modal from pitching subscription to a subscriber

* change placeholder text from Username to Login Name for consistency with other login/register forms

* fix test for POST-tasks_user -- streak and dateCompleted weren't being tested correctly

* prevent tag selector from appearing in edit screen for a challenge's own tasks

* restore Restore Streak when editing a user's Dailies (including their own copies of Challenge and Group Plan Dailies)

* remove failing streak test
This commit is contained in:
Alys
2017-09-19 16:39:39 +10:00
committed by GitHub
parent 32fa49191e
commit e784ae21ea
6 changed files with 101 additions and 81 deletions

View File

@@ -131,7 +131,7 @@ describe('POST /tasks/user', () => {
expect(task.updatedAt).not.to.equal('tomorrow'); expect(task.updatedAt).not.to.equal('tomorrow');
expect(task.challenge).not.to.equal('no'); expect(task.challenge).not.to.equal('no');
expect(task.completed).to.equal(false); expect(task.completed).to.equal(false);
expect(task.streak).not.to.equal('never'); expect(task.dateCompleted).not.to.equal('never');
expect(task.value).not.to.equal(324); expect(task.value).not.to.equal(324);
expect(task.yesterDaily).to.equal(true); expect(task.yesterDaily).to.equal(true);
}); });

View File

@@ -81,80 +81,87 @@
.col-6.offset-3 {{ $t('buyGemsSupportsDevs') }} .col-6.offset-3 {{ $t('buyGemsSupportsDevs') }}
div(v-show='selectedPage === "subscribe"') div(v-show='selectedPage === "subscribe"')
.row.text-center div(v-if='hasSubscription')
h2.mx-auto.text-leadin {{ $t('subscriptionBenefitLeadin') }} .row.text-center
.row h2.mx-auto.text-leadin {{ $t('subscriptionAlreadySubscribedLeadIn') }}
.col .row.text-center
+featureBullet("{{ $t('subscriptionBenefit1') }}") .col
+featureBullet("{{ $t('subscriptionBenefit2') }}") p(v-html='$t("subscriptionAlreadySubscribed1")')
+featureBullet("{{ $t('subscriptionBenefit3') }}") div(v-if='!hasSubscription')
.col .row.text-center
+featureBullet("{{ $t('subscriptionBenefit4') }}") h2.mx-auto.text-leadin {{ $t('subscriptionBenefitLeadin') }}
+featureBullet("{{ $t('subscriptionBenefit5') }}") .row
+featureBullet("{{ $t('subscriptionBenefit6') }}") .col
.card-deck +featureBullet("{{ $t('subscriptionBenefit1') }}")
.card.text-center +featureBullet("{{ $t('subscriptionBenefit2') }}")
.card-body +featureBullet("{{ $t('subscriptionBenefit3') }}")
.subscription-price .col
span.superscript $ +featureBullet("{{ $t('subscriptionBenefit4') }}")
span 4 +featureBullet("{{ $t('subscriptionBenefit5') }}")
span.superscript.muted .99 +featureBullet("{{ $t('subscriptionBenefit6') }}")
.small {{ $t('everyMonth') }} .card-deck
.divider .card.text-center
p.benefits(v-markdown='$t("earnGemsMonthly", {cap:25})') .card-body
.spacer .subscription-price
button.btn.btn-primary {{ $t('select') }} span.superscript $
.card.text-center span 4
.card-body span.superscript.muted .99
.subscription-price .small {{ $t('everyMonth') }}
span.superscript $ .divider
span 14 p.benefits(v-markdown='$t("earnGemsMonthly", {cap:25})')
span.superscript.muted .99 .spacer
.small {{ $t('everyXMonths', {interval: 3}) }} button.btn.btn-primary {{ $t('select') }}
.divider .card.text-center
p.benefits(v-markdown='$t("earnGemsMonthly", {cap:30})') .card-body
p.benefits(v-markdown='$t("receiveMysticHourglass")') .subscription-price
button.btn.btn-primary {{ $t('select') }} span.superscript $
.card.text-center span 14
.card-body span.superscript.muted .99
.subscription-price .small {{ $t('everyXMonths', {interval: 3}) }}
span.superscript $ .divider
span 29 p.benefits(v-markdown='$t("earnGemsMonthly", {cap:30})')
span.superscript.muted .99 p.benefits(v-markdown='$t("receiveMysticHourglass")')
.small {{ $t('everyXMonths', {interval: 6}) }} button.btn.btn-primary {{ $t('select') }}
.divider .card.text-center
p.benefits(v-markdown='$t("earnGemsMonthly", {cap:35})') .card-body
p.benefits(v-markdown='$t("receiveMysticHourglasses", {amount:2})') .subscription-price
button.btn.btn-primary {{ $t('select') }} span.superscript $
.card.text-center span 29
.card-body span.superscript.muted .99
.subscription-price .small {{ $t('everyXMonths', {interval: 6}) }}
span.superscript $ .divider
span 47 p.benefits(v-markdown='$t("earnGemsMonthly", {cap:35})')
span.superscript.muted .99 p.benefits(v-markdown='$t("receiveMysticHourglasses", {amount:2})')
.small {{ $t('everyYear') }} button.btn.btn-primary {{ $t('select') }}
.divider .card.text-center
p.benefits(v-markdown='$t("earnGemsMonthly", {cap:45})') .card-body
p.benefits(v-markdown='$t("receiveMysticHourglasses", {amount:4})') .subscription-price
button.btn.btn-primary {{ $t('select') }} span.superscript $
.row.text-center span 47
h2.mx-auto.text-payment {{ $t('choosePaymentMethod') }} span.superscript.muted .99
.row.text-center .small {{ $t('everyYear') }}
a.mx-auto {{ $t('haveCouponCode') }} .divider
.card-deck p.benefits(v-markdown='$t("earnGemsMonthly", {cap:45})')
.card.text-center.payment-method p.benefits(v-markdown='$t("receiveMysticHourglasses", {amount:4})')
.card-body(@click='showStripe({})') button.btn.btn-primary {{ $t('select') }}
.mx-auto(v-html='icons.creditCard', style='"height: 56px; width: 159px; margin-top: 1em;"') .row.text-center
.card.text-center.payment-method h2.mx-auto.text-payment {{ $t('choosePaymentMethod') }}
a.card-body.paypal(:href='paypalCheckoutLink', target='_blank') .row.text-center
img(src='~assets/images/paypal.png') a.mx-auto {{ $t('haveCouponCode') }}
.card.text-center.payment-method .card-deck
.card-body.amazon(@click="amazonPaymentsInit({type: 'single'})") .card.text-center.payment-method
img(src='~assets/images/amazon-payments.png') .card-body(@click='showStripe({})')
.row.text-center .mx-auto(v-html='icons.creditCard', style='"height: 56px; width: 159px; margin-top: 1em;"')
.svg-icon.mx-auto(v-html='icons.heart', style='"height: 24px; width: 24px;"') .card.text-center.payment-method
.row.text-center.text-outtro a.card-body.paypal(:href='paypalCheckoutLink', target='_blank')
.col-6.offset-3 {{ $t('subscribeSupportsDevs') }} img(src='~assets/images/paypal.png')
.card.text-center.payment-method
.card-body.amazon(@click="amazonPaymentsInit({type: 'single'})")
img(src='~assets/images/amazon-payments.png')
.row.text-center
.svg-icon.mx-auto(v-html='icons.heart', style='"height: 24px; width: 24px;"')
.row.text-center.text-outtro
.col-6.offset-3 {{ $t('subscribeSupportsDevs') }}
</template> </template>
<style lang="scss"> <style lang="scss">
@@ -340,6 +347,9 @@
startingPageOption () { startingPageOption () {
return this.$store.state.gemModalOptions.startingPage; return this.$store.state.gemModalOptions.startingPage;
}, },
hasSubscription () {
return Boolean(this.user.purchased.plan.customerId);
},
userReachedGemCap () { userReachedGemCap () {
return this.user.purchased.plan.customerId && this.user.purchased.plan.gemsBought >= this.user.purchased.plan.consecutive.gemCapExtra + this.planGemLimits.convCap; return this.user.purchased.plan.customerId && this.user.purchased.plan.gemsBought >= this.user.purchased.plan.consecutive.gemCapExtra + this.planGemLimits.convCap;
}, },

View File

@@ -32,7 +32,7 @@
tr(v-if='hasCanceledSubscription'): td.alert.alert-warning tr(v-if='hasCanceledSubscription'): td.alert.alert-warning
span.noninteractive-button.btn-danger {{ $t('canceledSubscription') }} span.noninteractive-button.btn-danger {{ $t('canceledSubscription') }}
i.glyphicon.glyphicon-time i.glyphicon.glyphicon-time
| {{ $t('subCanceled') }} | {{ $t('subCanceled') }} &nbsp;
strong {{user.purchased.plan.dateTerminated | date}} strong {{user.purchased.plan.dateTerminated | date}}
tr(v-if='!hasCanceledSubscription'): td tr(v-if='!hasCanceledSubscription'): td
h4 {{ $t('subscribed') }} h4 {{ $t('subscribed') }}
@@ -46,7 +46,7 @@
| &nbsp; {{ $t('consecutiveSubscription') }} | &nbsp; {{ $t('consecutiveSubscription') }}
ul.list-unstyled ul.list-unstyled
li {{ $t('consecutiveMonths') }} {{user.purchased.plan.consecutive.count + user.purchased.plan.consecutive.offset}} li {{ $t('consecutiveMonths') }} {{user.purchased.plan.consecutive.count + user.purchased.plan.consecutive.offset}}
li {{ $t('gemCapExtra') }}} {{user.purchased.plan.consecutive.gemCapExtra}} li {{ $t('gemCapExtra') }} {{user.purchased.plan.consecutive.gemCapExtra}}
li {{ $t('mysticHourglasses') }} {{user.purchased.plan.consecutive.trinkets}} li {{ $t('mysticHourglasses') }} {{user.purchased.plan.consecutive.trinkets}}
div(v-if='!hasSubscription || hasCanceledSubscription') div(v-if='!hasSubscription || hasCanceledSubscription')
@@ -147,7 +147,8 @@ export default {
filters: { filters: {
date (value) { date (value) {
if (!value) return ''; if (!value) return '';
return moment(value).formate(this.user.preferences.dateFormat); return moment(value);
// return moment(value).format(this.user.preferences.dateFormat); // @TODO make that work (`TypeError: this is undefined`)
}, },
}, },
computed: { computed: {
@@ -156,6 +157,7 @@ export default {
let couponString = ''; let couponString = '';
if (this.subscription.coupon) couponString = `&coupon=${this.subscription.coupon}`; if (this.subscription.coupon) couponString = `&coupon=${this.subscription.coupon}`;
return `/paypal/subscribe?_id=${this.user._id}&apiToken=${this.user.apiToken}&sub=${this.subscription.key}${couponString}`; return `/paypal/subscribe?_id=${this.user._id}&apiToken=${this.user.apiToken}&sub=${this.subscription.key}${couponString}`;
// @TODO don't put API Token in URL parameters
}, },
subscriptionBlocksOrdered () { subscriptionBlocksOrdered () {
let subscriptions = filter(subscriptionBlocks, (o) => { let subscriptions = filter(subscriptionBlocks, (o) => {

View File

@@ -23,7 +23,7 @@
.strike .strike
span OR span OR
.form .form
input.form-control(type='text', placeholder='Username', v-model='username', :class='{"input-valid": username.length > 0}') input.form-control(type='text', placeholder='Login Name', v-model='username', :class='{"input-valid": username.length > 0}')
input.form-control(type='email', placeholder='Email', v-model='email', :class='{"input-invalid": emailInvalid, "input-valid": emailValid}') input.form-control(type='email', placeholder='Email', v-model='email', :class='{"input-invalid": emailInvalid, "input-valid": emailValid}')
input.form-control(type='password', placeholder='Password', v-model='password', :class='{"input-valid": password.length > 0}') input.form-control(type='password', placeholder='Password', v-model='password', :class='{"input-valid": password.length > 0}')
input.form-control(type='password', placeholder='Confirm Password', v-model='passwordConfirm', :class='{"input-invalid": passwordConfirmInvalid, "input-valid": passwordConfirmValid}') input.form-control(type='password', placeholder='Confirm Password', v-model='passwordConfirm', :class='{"input-invalid": passwordConfirmInvalid, "input-valid": passwordConfirmValid}')

View File

@@ -117,7 +117,7 @@
span.custom-control-indicator span.custom-control-indicator
span.custom-control-description {{ $t('dayOfWeek') }} span.custom-control-description {{ $t('dayOfWeek') }}
.option .option(v-if="task.userId")
label(v-once) {{ $t('tags') }} label(v-once) {{ $t('tags') }}
.category-wrap(@click="showTagsSelect = !showTagsSelect") .category-wrap(@click="showTagsSelect = !showTagsSelect")
span.category-select(v-if='task.tags && task.tags.length === 0') {{$t('none')}} span.category-select(v-if='task.tags && task.tags.length === 0') {{$t('none')}}
@@ -135,12 +135,18 @@
span.custom-control-description(v-once) {{ tag.name }} span.custom-control-description(v-once) {{ tag.name }}
.row .row
button.btn.btn-primary(@click="showTagsSelect = !showTagsSelect") {{$t('close')}} button.btn.btn-primary(@click="showTagsSelect = !showTagsSelect") {{$t('close')}}
.option(v-if="task.type === 'habit'") .option(v-if="task.type === 'habit'")
label(v-once) {{ $t('resetStreak') }} label(v-once) {{ $t('resetStreak') }}
b-dropdown(:text="$t(task.frequency)") b-dropdown(:text="$t(task.frequency)")
b-dropdown-item(v-for="frequency in ['daily', 'weekly', 'monthly']", :key="frequency", @click="task.frequency = frequency", :class="{active: task.frequency === frequency}") b-dropdown-item(v-for="frequency in ['daily', 'weekly', 'monthly']", :key="frequency", @click="task.frequency = frequency", :class="{active: task.frequency === frequency}")
| {{ $t(frequency) }} | {{ $t(frequency) }}
.option(v-if="task.type === 'daily' && task.userId")
.form-group
label(v-once) {{ $t('restoreStreak') }}
input(type="number", v-model="task.streak", min="0", required)
.option.group-options(v-if='groupId') .option.group-options(v-if='groupId')
label(v-once) Assigned To label(v-once) Assigned To
.category-wrap(@click="showAssignedSelect = !showAssignedSelect") .category-wrap(@click="showAssignedSelect = !showAssignedSelect")

View File

@@ -39,7 +39,7 @@
"manageSub": "Click to manage subscription", "manageSub": "Click to manage subscription",
"cancelSub": "Cancel Subscription", "cancelSub": "Cancel Subscription",
"cancelSubInfoGoogle": "Please go to the \"Account\" > \"Subscriptions\" section of the Google Play Store app to cancel your subscription or to see your subscription's termination date if you have already cancelled it. This screen is not able to show you whether your subscription has been cancelled.", "cancelSubInfoGoogle": "Please go to the \"Account\" > \"Subscriptions\" section of the Google Play Store app to cancel your subscription or to see your subscription's termination date if you have already cancelled it. This screen is not able to show you whether your subscription has been cancelled.",
"cancelSubInfoApple": "Please follow <a href=\"https://support.apple.com/en-us/HT202039\">Apples official instructions</a> to cancel your subscription or to see your subscription's termination date if you have already cancelled it. This screen is not able to show you whether your subscription has been cancelled.", "cancelSubInfoApple": "Please follow <a href=\"https://support.apple.com/en-us/HT202039\">Apple's official instructions</a> to cancel your subscription or to see your subscription's termination date if you have already cancelled it. This screen is not able to show you whether your subscription has been cancelled.",
"canceledSubscription": "Canceled Subscription", "canceledSubscription": "Canceled Subscription",
"cancelingSubscription": "Canceling the subscription", "cancelingSubscription": "Canceling the subscription",
"adminSub": "Administrator Subscriptions", "adminSub": "Administrator Subscriptions",
@@ -199,5 +199,7 @@
"subscriptionBenefit5": "Receive the exclusive Royal Purple Jackalope pet!", "subscriptionBenefit5": "Receive the exclusive Royal Purple Jackalope pet!",
"subscriptionBenefit6": "Earn Mystic Hourglasses for use in the Time Travelers' Shop!", "subscriptionBenefit6": "Earn Mystic Hourglasses for use in the Time Travelers' Shop!",
"haveCouponCode": "Do you have a coupon code?", "haveCouponCode": "Do you have a coupon code?",
"subscriptionAlreadySubscribedLeadIn": "Thanks for subscribing!",
"subscriptionAlreadySubscribed1": "To see your subscription details and cancel, renew, or change your subscription, please go to <a href='/user/settings/subscription'>User icon &gt; Settings &gt; Subscription</a>.",
"purchaseAll": "Purchase All" "purchaseAll": "Purchase All"
} }