diff --git a/website/client/app.vue b/website/client/app.vue index 9e7bccbb49..a53f71c705 100644 --- a/website/client/app.vue +++ b/website/client/app.vue @@ -443,7 +443,7 @@ export default { appState = JSON.parse(appState); if (appState.paymentCompleted) { removeLocalSetting(CONSTANTS.savedAppStateValues.SAVED_APP_STATE); - this.$root.$emit('bv::show::modal', 'payments-success-modal'); + this.$root.$emit('habitica:payment-success', appState); } } this.$nextTick(() => { diff --git a/website/client/components/achievements/questCompleted.vue b/website/client/components/achievements/questCompleted.vue index 495b1ca76f..208fa8b298 100644 --- a/website/client/components/achievements/questCompleted.vue +++ b/website/client/components/achievements/questCompleted.vue @@ -6,7 +6,7 @@ .quest(:class='`quest_${user.party.quest.completed}`') p(v-if='questData.completion && typeof questData.completion === "function"', v-html='questData.completion()') .quest-rewards.text-center - h3 {{ $t('youReceived') }} + h3(v-once) {{ $t('paymentYouReceived') }} questDialogDrops(:item="questData") .modal-footer button.btn.btn-primary(@click='setQuestCompleted()') {{ $t('ok') }} diff --git a/website/client/components/group-plans/createGroupModalPages.vue b/website/client/components/group-plans/createGroupModalPages.vue index 1dbeba34d1..e0971792a8 100644 --- a/website/client/components/group-plans/createGroupModalPages.vue +++ b/website/client/components/group-plans/createGroupModalPages.vue @@ -141,7 +141,7 @@ export default { this.changePage(this.PAGES.PAY); }, pay (paymentMethod) { - const subscriptionKey = 'group_monthly'; // @TODO: Get from content API? + const subscriptionKey = 'group_monthly'; let paymentData = { subscription: subscriptionKey, coupon: null, @@ -149,6 +149,7 @@ export default { if (this.upgradingGroup && this.upgradingGroup._id) { paymentData.groupId = this.upgradingGroup._id; + paymentData.group = this.upgradingGroup; } else { paymentData.groupToCreate = this.newGroup; } diff --git a/website/client/components/groups/groupPlan.vue b/website/client/components/groups/groupPlan.vue index 79a7f6d318..9e92d0aa58 100644 --- a/website/client/components/groups/groupPlan.vue +++ b/website/client/components/groups/groupPlan.vue @@ -395,14 +395,15 @@ export default { this.changePage(this.PAGES.PAY); }, pay (paymentMethod) { - let subscriptionKey = 'group_monthly'; // @TODO: Get from content API? - let paymentData = { + const subscriptionKey = 'group_monthly'; // @TODO: Get from content API? + const paymentData = { subscription: subscriptionKey, coupon: null, }; if (this.upgradingGroup && this.upgradingGroup._id) { paymentData.groupId = this.upgradingGroup._id; + paymentData.group = this.upgradingGroup; } else { paymentData.groupToCreate = this.newGroup; } diff --git a/website/client/components/payments/amazonModal.vue b/website/client/components/payments/amazonModal.vue index 513907788a..13380db0b5 100644 --- a/website/client/components/payments/amazonModal.vue +++ b/website/client/components/payments/amazonModal.vue @@ -34,6 +34,7 @@ import * as Analytics from 'client/libs/analytics'; import axios from 'axios'; import { mapState } from 'client/libs/store'; import { CONSTANTS, setLocalSetting } from 'client/libs/userlocalManager'; +import pick from 'lodash/pick'; const AMAZON_PAYMENTS = process.env.AMAZON_PAYMENTS; // eslint-disable-line const habiticaUrl = `${location.protocol}//${location.host}`; @@ -56,6 +57,8 @@ export default { OffAmazonPayments: {}, isAmazonSetup: false, amazonButtonEnabled: false, + groupToCreate: null, // creating new group + group: null, // upgrading existing group }; }, computed: { @@ -189,10 +192,37 @@ export default { new this.OffAmazonPayments.Widgets.Wallet(walletParams).bind('AmazonPayWallet'); }, storePaymentStatusAndReload (url) { + let paymentType; + + if (this.amazonPayments.type === 'single' && !this.amazonPayments.gift) paymentType = 'gems'; + if (this.amazonPayments.type === 'subscription') paymentType = 'subscription'; + if (this.amazonPayments.groupId || this.amazonPayments.groupToCreate) paymentType = 'groupPlan'; + if (this.amazonPayments.type === 'single' && this.amazonPayments.gift && this.amazonPayments.giftReceiver) { + paymentType = this.amazonPayments.gift.type === 'gems' ? 'gift-gems' : 'gift-subscription'; + } + const appState = { paymentMethod: 'amazon', paymentCompleted: true, + paymentType, }; + if (paymentType === 'subscription') { + appState.subscriptionKey = this.amazonPayments.subscription; + } else if (paymentType === 'groupPlan') { + appState.subscriptionKey = this.amazonPayments.subscription; + + if (this.amazonPayments.groupToCreate) { + appState.newGroup = true; + appState.group = pick(this.amazonPayments.groupToCreate, ['_id', 'memberCount', 'name']); + } else { + appState.newGroup = false; + appState.group = pick(this.amazonPayments.group, ['_id', 'memberCount', 'name']); + } + } else if (paymentType.indexOf('gift-') === 0) { + appState.gift = this.amazonPayments.gift; + appState.giftReceiver = this.amazonPayments.giftReceiver; + } + setLocalSetting(CONSTANTS.savedAppStateValues.SAVED_APP_STATE, JSON.stringify(appState)); if (url) { window.location.assign(url); @@ -215,11 +245,11 @@ export default { }); this.$set(this, 'amazonButtonEnabled', true); - this.reset(); this.storePaymentStatusAndReload(); } catch (e) { + console.error(e); // eslint-disable-line no-console this.$set(this, 'amazonButtonEnabled', true); - this.amazonPaymentsreset(); + this.reset(); } } else if (this.amazonPayments.type === 'subscription') { let url = '/amazon/subscribe'; @@ -265,7 +295,6 @@ export default { return; } - this.reset(); this.storePaymentStatusAndReload(); } catch (e) { this.$set(this, 'amazonButtonEnabled', true); @@ -286,13 +315,19 @@ export default { this.amazonPayments.modal = null; this.amazonPayments.type = null; this.amazonPayments.loggedIn = false; + + // Gift this.amazonPayments.gift = null; + this.amazonPayments.giftReceiver = null; + this.amazonPayments.billingAgreementId = null; this.amazonPayments.orderReferenceId = null; this.amazonPayments.paymentSelected = false; this.amazonPayments.recurringConsent = false; this.amazonPayments.subscription = null; this.amazonPayments.coupon = null; + this.amazonPayments.groupToCreate = null; + this.amazonPayments.group = null; }, }, }; diff --git a/website/client/components/payments/buyGemsModal.vue b/website/client/components/payments/buyGemsModal.vue index f0dd48b2b9..47d80dc5f1 100644 --- a/website/client/components/payments/buyGemsModal.vue +++ b/website/client/components/payments/buyGemsModal.vue @@ -111,7 +111,7 @@ span.superscript $ span 5 span.superscript.muted .00 - .small {{ $t('everyMonth') }} + .small(v-once) {{ $t('everyMonth') }} .divider p.benefits(v-markdown='$t("earnGemsMonthly", {cap:25})') .spacer @@ -122,7 +122,7 @@ span.superscript $ span 15 span.superscript.muted .00 - .small {{ $t('everyXMonths', {interval: 3}) }} + .small(v-once) {{ $t('everyXMonths', {interval: 3}) }} .divider p.benefits(v-markdown='$t("earnGemsMonthly", {cap:30})') p.benefits(v-markdown='$t("receiveMysticHourglass")') @@ -133,7 +133,7 @@ span.superscript $ span 30 span.superscript.muted .00 - .small {{ $t('everyXMonths', {interval: 6}) }} + .small(v-once) {{ $t('everyXMonths', {interval: 6}) }} .divider p.benefits(v-markdown='$t("earnGemsMonthly", {cap:35})') p.benefits(v-markdown='$t("receiveMysticHourglasses", {amount:2})') @@ -144,15 +144,15 @@ span.superscript $ span 48 span.superscript.muted .00 - .small {{ $t('everyYear') }} + .small(v-once) {{ $t('everyYear') }} .divider p.benefits(v-markdown='$t("earnGemsMonthly", {cap:45})') p.benefits(v-markdown='$t("receiveMysticHourglasses", {amount:4})') button.btn.btn-primary(@click='subscriptionPlan = "basic_12mo"') {{ subscriptionPlan === "basic_12mo" ? $t('selected') : $t('select') }} .row.text-center(v-if='subscriptionPlan') - h2.mx-auto.text-payment {{ $t('choosePaymentMethod') }} + h2.mx-auto.text-payment(v-once) {{ $t('choosePaymentMethod') }} .row.text-center - a.mx-auto {{ $t('haveCouponCode') }} + a.mx-auto(v-once) {{ $t('haveCouponCode') }} .card-deck(v-if='subscriptionPlan') .card.text-center.payment-method .card-body(@click='showStripe({subscription: subscriptionPlan})') diff --git a/website/client/components/payments/sendGemsModal.vue b/website/client/components/payments/sendGemsModal.vue index 47fde4a46b..717db43d1f 100644 --- a/website/client/components/payments/sendGemsModal.vue +++ b/website/client/components/payments/sendGemsModal.vue @@ -47,9 +47,9 @@ b-modal#send-gems(:title="title", :hide-footer="true", size='lg', @hide='onHide( :disabled="sendingInProgress" ) {{ $t("send") }} template(v-else) - button.btn.btn-primary(@click='showStripe({gift, uuid: userReceivingGems._id})') {{ $t('card') }} - button.btn.btn-warning(@click='openPaypalGift({gift: gift, giftedTo: userReceivingGems._id})') PayPal - button.btn.btn-success(@click="amazonPaymentsInit({type: 'single', gift, giftedTo: userReceivingGems._id})") Amazon Payments + button.btn.btn-primary(@click='showStripe({gift, uuid: userReceivingGems._id, receiverName})') {{ $t('card') }} + button.btn.btn-warning(@click='openPaypalGift({gift: gift, giftedTo: userReceivingGems._id, receiverName})') PayPal + button.btn.btn-success(@click="amazonPaymentsInit({type: 'single', gift, giftedTo: userReceivingGems._id, receiverName})") Amazon Payments button.btn.btn-secondary(@click='close()') {{$t('cancel')}} @@ -131,6 +131,13 @@ export default { if (!this.userReceivingGems) return ''; return this.$t('sendGiftHeading', {name: this.userReceivingGems.profile.name}); }, + receiverName () { + if (this.userReceivingGems.auth && this.userReceivingGems.auth.local && this.userReceivingGems.auth.local.username) { + return this.userReceivingGems.auth.local.username; + } else { + return this.userReceivingGems.profile.name; + } + }, }, methods: { // @TODO move to payments mixin or action (problem is that we need notifications) @@ -141,11 +148,21 @@ export default { toUserId: this.userReceivingGems._id, gemAmount: this.gift.gems.amount, }); - this.text(this.$t('sentGems')); this.close(); + this.$root.$emit('habitica:payment-success', { + paymentMethod: 'balance', + paymentCompleted: true, + paymentType: 'gift-gems-balance', + gift: { + gems: { + amount: this.gift.gems.amount, + }, + }, + giftReceiver: this.receiverName, + }); }, onHide () { - // TODO this breaks amazon purchases because when the amazon modal + // @TODO this breaks amazon purchases because when the amazon modal // is opened this one is closed and the amount reset // this.gift.gems.amount = 0; this.gift.message = ''; diff --git a/website/client/components/payments/successModal.vue b/website/client/components/payments/successModal.vue index 08fda4589b..f85d3e41a4 100644 --- a/website/client/components/payments/successModal.vue +++ b/website/client/components/payments/successModal.vue @@ -1,17 +1,39 @@