Oct 4 fixes (#9159)

* Added gem purchase note

* Added notification count

* Added party reload

* Added description when user can no longer purchase gems this month

* Prevent modal from showing when pruchasing recently purchased items

* Added progress bar

* Prevented non leader from loading approvals

* Added group billing
This commit is contained in:
Keith Holliday
2017-10-04 16:47:19 -05:00
committed by GitHub
parent 1a0d39e566
commit 7325d2020e
21 changed files with 335 additions and 136 deletions
+54 -41
View File
@@ -68,6 +68,15 @@
"@types/mime": "1.3.1"
}
},
"JSONStream": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.1.tgz",
"integrity": "sha1-cH92HgHa6eFvG8+TcDt4xwlmV5o=",
"requires": {
"jsonparse": "1.3.1",
"through": "2.3.8"
}
},
"abbrev": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.0.tgz",
@@ -782,6 +791,14 @@
"is-buffer": "1.1.5"
}
},
"axios-progress-bar": {
"version": "0.1.7",
"resolved": "https://registry.npmjs.org/axios-progress-bar/-/axios-progress-bar-0.1.7.tgz",
"integrity": "sha512-xStxJUtcQUH0ulLni5qc8YwvNMTUjO7rmUTsvnxS1bD2GJKEemozP6sJ5OeoC6jjd6MS5FZyx5BlkU/lD8JLUw==",
"requires": {
"nprogress": "0.2.0"
}
},
"babel-code-frame": {
"version": "6.26.0",
"resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz",
@@ -2325,9 +2342,9 @@
"resolved": "https://registry.npmjs.org/browser-pack/-/browser-pack-6.0.2.tgz",
"integrity": "sha1-+GzWzvT1MAyOY+B6TVEvZfv/RTE=",
"requires": {
"JSONStream": "1.3.1",
"combine-source-map": "0.7.2",
"defined": "1.0.0",
"JSONStream": "1.3.1",
"through2": "2.0.3",
"umd": "3.0.1"
}
@@ -2357,6 +2374,7 @@
"resolved": "https://registry.npmjs.org/browserify/-/browserify-12.0.2.tgz",
"integrity": "sha1-V/IeXm4wj/WYfE2v1EhAsrmPehk=",
"requires": {
"JSONStream": "1.3.1",
"assert": "1.3.0",
"browser-pack": "6.0.2",
"browser-resolve": "1.11.2",
@@ -2378,7 +2396,6 @@
"inherits": "2.0.3",
"insert-module-globals": "7.0.1",
"isarray": "0.0.1",
"JSONStream": "1.3.1",
"labeled-stream-splicer": "2.0.0",
"module-deps": "4.1.1",
"os-browserify": "0.1.2",
@@ -7389,13 +7406,6 @@
}
}
},
"string_decoder": {
"version": "1.0.1",
"bundled": true,
"requires": {
"safe-buffer": "5.0.1"
}
},
"string-width": {
"version": "1.0.2",
"bundled": true,
@@ -7405,6 +7415,13 @@
"strip-ansi": "3.0.1"
}
},
"string_decoder": {
"version": "1.0.1",
"bundled": true,
"requires": {
"safe-buffer": "5.0.1"
}
},
"stringstream": {
"version": "0.0.5",
"bundled": true,
@@ -10353,10 +10370,10 @@
"resolved": "https://registry.npmjs.org/insert-module-globals/-/insert-module-globals-7.0.1.tgz",
"integrity": "sha1-wDv04BywhtW15azorQr+eInWOMM=",
"requires": {
"JSONStream": "1.3.1",
"combine-source-map": "0.7.2",
"concat-stream": "1.5.2",
"is-buffer": "1.1.5",
"JSONStream": "1.3.1",
"lexical-scope": "1.2.0",
"process": "0.11.10",
"through2": "2.0.3",
@@ -11349,15 +11366,6 @@
"resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.1.tgz",
"integrity": "sha1-T9kss04OnbPInIYi7PUfm5eMbLk="
},
"JSONStream": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.1.tgz",
"integrity": "sha1-cH92HgHa6eFvG8+TcDt4xwlmV5o=",
"requires": {
"jsonparse": "1.3.1",
"through": "2.3.8"
}
},
"jsprim": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
@@ -13257,6 +13265,7 @@
"resolved": "https://registry.npmjs.org/module-deps/-/module-deps-4.1.1.tgz",
"integrity": "sha1-IyFYM/HaE/1gbMuAh7RIUty4If0=",
"requires": {
"JSONStream": "1.3.1",
"browser-resolve": "1.11.2",
"cached-path-relative": "1.0.1",
"concat-stream": "1.5.2",
@@ -13264,7 +13273,6 @@
"detective": "4.5.0",
"duplexer2": "0.1.4",
"inherits": "2.0.3",
"JSONStream": "1.3.1",
"parents": "1.0.1",
"readable-stream": "2.0.6",
"resolve": "1.4.0",
@@ -14640,6 +14648,11 @@
"set-blocking": "2.0.0"
}
},
"nprogress": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/nprogress/-/nprogress-0.2.0.tgz",
"integrity": "sha1-y480xTIT2JVyP8urkH6UIq28r7E="
},
"nth-check": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.1.tgz",
@@ -17234,22 +17247,6 @@
}
}
},
"require_optional": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/require_optional/-/require_optional-1.0.1.tgz",
"integrity": "sha512-qhM/y57enGWHAe3v/NcwML6a3/vfESLe/sGM2dII+gEO0BpKRUkWZow/tyloNqJyN6kXSl3RyyM8Ll5D/sJP8g==",
"requires": {
"resolve-from": "2.0.0",
"semver": "5.4.1"
},
"dependencies": {
"semver": {
"version": "5.4.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz",
"integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg=="
}
}
},
"require-again": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/require-again/-/require-again-2.0.0.tgz",
@@ -17289,6 +17286,22 @@
}
}
},
"require_optional": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/require_optional/-/require_optional-1.0.1.tgz",
"integrity": "sha512-qhM/y57enGWHAe3v/NcwML6a3/vfESLe/sGM2dII+gEO0BpKRUkWZow/tyloNqJyN6kXSl3RyyM8Ll5D/sJP8g==",
"requires": {
"resolve-from": "2.0.0",
"semver": "5.4.1"
},
"dependencies": {
"semver": {
"version": "5.4.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz",
"integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg=="
}
}
},
"requires-port": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
@@ -18655,11 +18668,6 @@
"resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz",
"integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM="
},
"string_decoder": {
"version": "0.10.31",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
"integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ="
},
"string-length": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/string-length/-/string-length-0.1.2.tgz",
@@ -18693,6 +18701,11 @@
"strip-ansi": "3.0.1"
}
},
"string_decoder": {
"version": "0.10.31",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
"integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ="
},
"stringify-object": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-1.0.1.tgz",
+1
View File
@@ -14,6 +14,7 @@
"autoprefixer": "^6.4.0",
"aws-sdk": "^2.0.25",
"axios": "^0.16.0",
"axios-progress-bar": "^0.1.7",
"babel-core": "^6.0.0",
"babel-eslint": "^7.2.3",
"babel-loader": "^6.0.0",
+9 -1
View File
@@ -68,6 +68,8 @@
<script>
import axios from 'axios';
import { loadProgressBar } from 'axios-progress-bar';
import AppMenu from './components/appMenu';
import AppHeader from './components/appHeader';
import AppFooter from './components/appFooter';
@@ -129,6 +131,7 @@ export default {
this.$refs.sound.load();
});
// @TODO: I'm not sure these should be at the app level. Can we move these back into shop/inventory or maybe they need a lateral move?
this.$root.$on('buyModal::showItem', (item) => {
this.selectedItemToBuy = item;
this.$root.$emit('show::modal', 'buy-modal');
@@ -140,6 +143,9 @@ export default {
});
// @TODO split up this file, it's too big
loadProgressBar();
// Set up Error interceptors
axios.interceptors.response.use((response) => {
if (this.user && response.data && response.data.notifications) {
@@ -320,10 +326,12 @@ export default {
}
}
},
memberSelected (member) {
async memberSelected (member) {
this.$store.dispatch('user:castSpell', {key: this.selectedSpellToBuy.key, targetId: member.id});
this.selectedSpellToBuy = null;
this.$store.dispatch('party:getMembers', {forceLoad: true});
this.$root.$emit('hide::modal', 'select-member-modal');
},
hideLoadingScreen () {
+2 -2
View File
@@ -331,7 +331,6 @@ export default {
hourglasses: svgHourglasses,
logo,
}),
groupPlans: [],
};
},
computed: {
@@ -341,6 +340,7 @@ export default {
...mapState({
user: 'user.data',
userHourglasses: 'user.data.purchased.plan.consecutive.trinkets',
groupPlans: 'groupPlans',
}),
},
mounted () {
@@ -367,7 +367,7 @@ export default {
this.$root.$emit('show::modal', 'profile');
},
async getUserGroupPlans () {
this.groupPlans = await this.$store.dispatch('guilds:getGroupPlans');
this.$store.state.groupPlans = await this.$store.dispatch('guilds:getGroupPlans');
},
openPartyModal () {
this.$root.$emit('show::modal', 'create-party-modal');
@@ -0,0 +1,74 @@
<template lang="pug">
.row.standard-page(v-if='groupIsSubscribed && isLeader')
.col-12.col-md-6.offset-md-3
table.table.alert.alert-info
tr(v-if='group.purchased.plan.dateTerminated')
td.alert.alert-warning
span.noninteractive-button.btn-danger {{ $t('canceledGroupPlan') }}
i.glyphicon.glyphicon-time {{ $t('groupPlanCanceled') }}
strong {{dateTerminated}}
tr(v-if='!group.purchased.plan.dateTerminated')
td
h3 {{ $t('paymentDetails') }}
p(v-if='group.purchased.plan.planId') {{ $t('groupSubscriptionPrice') }}
tr(v-if='group.purchased.plan.extraMonths')
td
span.glyphicon.glyphicon-credit-card
| {{ $t('purchasedGroupPlanPlanExtraMonths', purchasedGroupPlanPlanExtraMonths) }}
tr(v-if='group.purchased.plan.consecutive.count || group.purchased.plan.consecutive.offset')
td
span.glyphicon.glyphicon-forward
| {{ $t('consecutiveSubscription') }}
ul.list-unstyled
li {{ $t('consecutiveMonths') }} {{group.purchased.plan.consecutive.count + group.purchased.plan.consecutive.offset}}
li {{ $t('gemCapExtra') }} {{group.purchased.plan.consecutive.gemCapExtra}}
li {{ $t('mysticHourglasses') }} {{group.purchased.plan.consecutive.trinkets}}
.col-12.col-md-6.offset-md-3
.btn.btn-primary(v-if='!group.purchased.plan.dateTerminated && group.purchased.plan.paymentMethod === "Stripe"',
@click='showStripeEdit({groupId: group.id})') {{ $t('subUpdateCard') }}
.btn.btn-sm.btn-danger(v-if='!group.purchased.plan.dateTerminated',
@click='cancelSubscription({group: group})') {{ $t('cancelGroupSub') }}
</template>
<script>
import moment from 'moment';
import { mapState } from 'client/libs/store';
import paymentsMixin from 'client/mixins/payments';
export default {
mixins: [paymentsMixin],
props: ['groupId'],
data () {
return {
group: {},
};
},
mounted () {
this.loadGroup();
},
computed: {
...mapState({user: 'user.data'}),
isLeader () {
return this.user._id === this.group.leader._id;
},
groupIsSubscribed () {
return this.group.purchased && this.group.purchased.plan && this.group.purchased.plan.customerId;
},
dateTerminated () {
if (!this.user.preferences || !this.user.preferences.dateFormat) return moment(this.group.purchased.plan.dateTerminated);
return moment(this.group.purchased.plan.dateTerminated).format(this.user.preferences.dateFormat.toUpperCase());
},
purchasedGroupPlanPlanExtraMonths () {
return {
months: parseFloat(this.group.purchased.plan.extraMonths).toFixed(2),
};
},
},
methods: {
async loadGroup () {
let group = await this.$store.dispatch('guilds:getGroup', {groupId: this.groupId});
this.group = Object.assign({}, group);
},
},
};
</script>
@@ -2,9 +2,14 @@
.row
secondary-menu.col-12
router-link.nav-link(:to="{name: 'groupPlanDetailTaskInformation', params: {groupId}}",
exact, :class="{'active': $route.name === 'groupPlanDetailTaskInformation'}") Task Board
exact, :class="{'active': $route.name === 'groupPlanDetailTaskInformation'}") {{ $t('groupTaskBoard') }}
router-link.nav-link(:to="{name: 'groupPlanDetailInformation', params: {groupId}}",
exact, :class="{'active': $route.name === 'groupPlanDetailInformation'}") Group Information
exact, :class="{'active': $route.name === 'groupPlanDetailInformation'}") {{ $t('groupInformation') }}
router-link.nav-link(
v-if='isLeader',
:to="{name: 'groupPlanBilling', params: {groupId}}",
exact,
:class="{'active': $route.name === 'groupPlanBilling'}") {{ $t('groupBilling') }}
.col-12
router-view
@@ -12,11 +17,26 @@
<script>
import SecondaryMenu from 'client/components/secondaryMenu';
import { mapState } from 'client/libs/store';
export default {
props: ['groupId'],
components: {
SecondaryMenu,
},
computed: {
...mapState({
user: 'user.data',
groupPlans: 'groupPlans',
}),
isLeader () {
let groupFound = this.groupPlans.find(group => {
return group._id === this.groupId;
});
if (!groupFound) return false;
return groupFound.leader === this.user._id;
},
},
};
</script>
@@ -349,15 +349,21 @@ export default {
groupId: this.searchId,
});
let groupedApprovals = this.loadApprovals();
tasks.forEach((task) => {
if (groupedApprovals.length > 0) task.approvals = groupedApprovals[task._id];
this.tasksByType[task.type].push(task);
});
},
async loadApprovals () {
if (this.group.leader._id !== this.user._id) return [];
let approvalRequests = await this.$store.dispatch('tasks:getGroupApprovals', {
groupId: this.searchId,
});
let groupedApprovals = groupBy(approvalRequests, 'group.taskId');
tasks.forEach((task) => {
task.approvals = groupedApprovals[task._id];
this.tasksByType[task.type].push(task);
});
return groupBy(approvalRequests, 'group.taskId');
},
editTask (task) {
this.taskFormPurpose = 'edit';
+45 -27
View File
@@ -1,8 +1,7 @@
<template lang="pug">
div.item-with-icon.item-notifications.dropdown
span.message-count.top-count(v-if='notificationsCount > 0') {{ notificationsCount }}
.svg-icon.notifications(v-html="icons.notifications")
// span.glyphicon(:class='iconClasses()')
// span.notification-counter(v-if='getNotificationsCount()') {{getNotificationsCount()}}
.dropdown-menu.dropdown-menu-right.user-dropdown
h4.dropdown-item.dropdown-separated(v-if='!hasNoNotifications()') {{ $t('notifications') }}
h4.dropdown-item.toolbar-notifs-no-messages(v-if='hasNoNotifications()') {{ $t('noNotifications') }}
@@ -58,6 +57,25 @@ div.item-with-icon.item-notifications.dropdown
<style lang='scss' scoped>
@import '~client/assets/scss/colors.scss';
.message-count {
background-color: #46a7d9;
border-radius: 50%;
height: 20px;
width: 20px;
float: right;
color: #fff;
text-align: center;
font-weight: bold;
font-size: 12px;
}
.message-count.top-count {
position: absolute;
right: -.5em;
top: .5em;
padding: .2em;
}
.clear-button {
margin-left: .5em;
}
@@ -168,6 +186,31 @@ export default {
}
return userNewMessages;
},
notificationsCount () {
let count = 0;
if (this.user.invitations.parties) {
count += this.user.invitations.parties.length;
}
if (this.user.purchased.plan && this.user.purchased.plan.mysteryItems.length) {
count++;
}
if (this.user.invitations.guilds) {
count += this.user.invitations.guilds.length;
}
if (this.user.flags.classSelected && !this.user.preferences.disableClasses && this.user.stats.points) {
count += this.user.stats.points > 0 ? 1 : 0;
}
if (this.userNewMessages) {
count += Object.keys(this.userNewMessages).length;
}
return count;
},
},
methods: {
// @TODO: I hate this function, we can do better with a hashmap
@@ -237,31 +280,6 @@ export default {
clearCards () {
this.$store.dispatch('chat:clearCards');
},
getNotificationsCount () {
let count = 0;
if (this.user.invitations.parties) {
count += this.user.invitations.parties.length;
}
if (this.user.purchased.plan && this.user.purchased.plan.mysteryItems.length) {
count++;
}
if (this.user.invitations.guilds) {
count += this.user.invitations.guilds.length;
}
if (this.user.flags.classSelected && !this.user.preferences.disableClasses && this.user.stats.points) {
count += this.user.stats.points > 0 ? 1 : 0;
}
if (this.userNewMessages) {
count += Object.keys(this.userNewMessages).length;
}
return count;
},
iconClasses () {
return this.selectNotificationValue(
'glyphicon-gift',
@@ -21,6 +21,12 @@
.nav-item(@click='selectedPage = "subscribe"', :class="{active: selectedPage === 'subscribe'}") {{ $t('subscribe') }}
.nav-item(@click='selectedPage = "gems"', :class="{active: selectedPage === 'gems'}") {{ $t('buyGems') }}
div(v-show='selectedPage === "gems"')
div(v-if='hasSubscription')
.row.text-center
h2.mx-auto.text-leadin {{ $t('subscriptionAlreadySubscribedLeadIn') }}
.row.text-center
.col-6.offset-3
p {{ $t("gemsPurchaseNote") }}
.row.text-center
h2.mx-auto.text-leadin {{ $t('gemBenefitLeadin') }}
.row
@@ -112,7 +112,6 @@ import filter from 'lodash/filter';
import sortBy from 'lodash/sortBy';
import min from 'lodash/min';
import { mapState } from 'client/libs/store';
import encodeParams from 'client/libs/encodeParams';
import subscriptionBlocks from '../../../common/script/content/subscriptionBlocks';
import planGemLimits from '../../../common/script/libs/planGemLimits';
@@ -261,42 +260,6 @@ export default {
subs.basic_6mo.discount = true;
subs.google_6mo.discount = false;
},
async cancelSubscription (config) {
if (config && config.group && !confirm(this.$t('confirmCancelGroupPlan'))) return;
if (!confirm(this.$t('sureCancelSub'))) return;
let group;
if (config && config.group) {
group = config.group;
}
let paymentMethod = this.user.purchased.plan.paymentMethod;
if (group) {
paymentMethod = group.purchased.plan.paymentMethod;
}
if (paymentMethod === 'Amazon Payments') {
paymentMethod = 'amazon';
} else {
paymentMethod = paymentMethod.toLowerCase();
}
let queryParams = {
_id: this.user._id,
apiToken: this.credentials.API_TOKEN,
noRedirect: true,
};
if (group) {
queryParams.groupId = group._id;
}
let cancelUrl = `/${paymentMethod}/subscribe/cancel?${encodeParams(queryParams)}`;
await axios.get(cancelUrl);
// Success
alert(this.$t('paypalCanceled'));
this.$router.push('/');
},
getCancelSubInfo () {
// @TODO: String 'cancelSubInfoGroup Plan' not found. ?
return this.$t(`cancelSubInfo${this.user.purchased.plan.paymentMethod}`);
+15 -1
View File
@@ -14,7 +14,6 @@
span.svg-icon.inline.icon-10(aria-hidden="true", v-html="icons.close", @click="hideDialog()")
div.content(v-if="item != null")
div.inner-content
slot(name="item", :item="item")
div(v-if="showAvatar")
@@ -46,6 +45,11 @@
span.svg-icon.inline.icon-32(aria-hidden="true", v-html="icons[getPriceClass()]")
span.value(:class="getPriceClass()") {{ item.value }}
.gems-left(v-if='item.key === "gem"')
strong(v-if='gemsLeft > 0') {{ gemsLeft }} {{ $t('gemsRemaining') }}
strong(v-if='gemsLeft === 0') {{ $t('maxBuyGems') }}
button.btn.btn-primary(
@click="purchaseGems()",
v-if="getPriceClass() === 'gems' && !this.enoughCurrency(getPriceClass(), item.value)"
@@ -54,6 +58,7 @@
button.btn.btn-primary(
@click="buyItem()",
v-else,
:disabled='item.key === "gem" && gemsLeft === 0',
:class="{'notEnough': !preventHealthPotion || !this.enoughCurrency(getPriceClass(), item.value)}"
) {{ $t('buyNow') }}
@@ -203,6 +208,10 @@
.bordered {
margin-top: 8px;
}
.gems-left {
margin-top: .5em;
}
}
</style>
@@ -210,6 +219,7 @@
import bModal from 'bootstrap-vue/lib/components/modal';
import * as Analytics from 'client/libs/analytics';
import spellsMixin from 'client/mixins/spells';
import planGemLimits from 'common/script/libs/planGemLimits';
import svgClose from 'assets/svg/close.svg';
import svgGold from 'assets/svg/gold.svg';
@@ -292,6 +302,10 @@
limitedString () {
return this.$t('limitedOffer', {date: moment(seasonalShopConfig.dateRange.end).format('LL')});
},
gemsLeft () {
if (!this.user.purchased.plan) return 0;
return planGemLimits.convCap + this.user.purchased.plan.consecutive.gemCapExtra - this.user.purchased.plan.gemsBought;
},
},
watch: {
item: function itemChanged () {
@@ -383,6 +383,8 @@
const sortGearTypes = ['sortByType', 'sortByPrice', 'sortByCon', 'sortByPer', 'sortByStr', 'sortByInt'];
import notifications from 'client/mixins/notifications';
import buyMixin from 'client/mixins/buy';
import currencyMixin from '../_currencyMixin';
const sortGearTypeMap = {
sortByType: 'type',
@@ -393,7 +395,7 @@
};
export default {
mixins: [notifications],
mixins: [notifications, buyMixin, currencyMixin],
components: {
ShopItem,
Item,
@@ -694,6 +696,11 @@ export default {
}
},
itemSelected (item) {
if (item.purchaseType !== 'gear' && this.$store.state.recentlyPurchased[item.key]) {
this.makeGenericPurchase(item);
return;
}
this.$root.$emit('buyModal::showItem', item);
},
featuredItemSelected (item) {
@@ -43,11 +43,9 @@
:currencyNeeded="priceType",
:amountNeeded="item.value"
).float-right
</template>
<style lang="scss">
<style lang="scss">
@import '~client/assets/scss/colors.scss';
@import '~client/assets/scss/modal.scss';
@@ -173,7 +171,6 @@
</style>
<script>
import {mapState} from 'client/libs/store';
import bModal from 'bootstrap-vue/lib/components/modal';
@@ -188,12 +185,13 @@
import currencyMixin from '../_currencyMixin';
import QuestInfo from './questInfo.vue';
import notifications from 'client/mixins/notifications';
import buyMixin from 'client/mixins/buy';
import questDialogDrops from './questDialogDrops';
import questDialogContent from './questDialogContent';
export default {
mixins: [currencyMixin, notifications],
mixins: [currencyMixin, notifications, buyMixin],
components: {
bModal,
BalanceInfo,
@@ -243,15 +241,8 @@
this.$emit('change', $event);
},
buyItem () {
this.$store.dispatch('shops:genericPurchase', {
pinType: this.item.pinType,
type: this.item.purchaseType,
key: this.item.key,
currency: this.item.currency,
});
this.makeGenericPurchase(this.item, 'buyQuestModal');
this.purchased(this.item.text);
this.$root.$emit('playSound', 'Reward');
this.$emit('buyPressed', this.item);
this.hideDialog();
},
togglePinned () {
@@ -328,6 +328,8 @@
import ItemRows from 'client/components/ui/itemRows';
import toggleSwitch from 'client/components/ui/toggleSwitch';
import Avatar from 'client/components/avatar';
import buyMixin from 'client/mixins/buy';
import currencyMixin from '../_currencyMixin';
import BuyModal from './buyQuestModal.vue';
import QuestInfo from './questInfo.vue';
@@ -348,6 +350,7 @@
import _map from 'lodash/map';
export default {
mixins: [buyMixin, currencyMixin],
components: {
ShopItem,
Item,
@@ -470,6 +473,11 @@ export default {
selectItem (item) {
this.selectedItemToBuy = item;
if (this.$store.state.recentlyPurchased[item.key]) {
this.makeGenericPurchase(item);
return;
}
this.$root.$emit('show::modal', 'buy-quest-modal');
},
},
@@ -274,6 +274,8 @@
import ItemRows from 'client/components/ui/itemRows';
import toggleSwitch from 'client/components/ui/toggleSwitch';
import Avatar from 'client/components/avatar';
import buyMixin from 'client/mixins/buy';
import currencyMixin from '../_currencyMixin';
import bPopover from 'bootstrap-vue/lib/components/popover';
import bDropdown from 'bootstrap-vue/lib/components/dropdown';
@@ -302,6 +304,7 @@
import shops from 'common/script/libs/shops';
export default {
mixins: [buyMixin, currencyMixin],
components: {
ShopItem,
Item,
@@ -485,9 +488,14 @@
}
},
itemSelected (item) {
if (!item.locked) {
this.$root.$emit('buyModal::showItem', item);
if (item.locked) return;
if (this.$store.state.recentlyPurchased[item.key]) {
this.makeGenericPurchase(item);
return;
}
this.$root.$emit('buyModal::showItem', item);
},
},
};
+13 -2
View File
@@ -1,14 +1,25 @@
export default {
methods: {
makeGenericPurchase (item) {
makeGenericPurchase (item, type = 'buyModal') {
this.$store.dispatch('shops:genericPurchase', {
pinType: item.pinType,
type: item.purchaseType,
key: item.key,
currency: item.currency,
});
this.$root.$emit('buyModal::boughtItem', item);
if (item.purchaseType !== 'gear') {
this.$store.state.recentlyPurchased[item.key] = true;
}
this.$root.$emit('playSound', 'Reward');
if (type !== 'buyModal') {
this.$emit('buyPressed', this.item);
return;
}
this.$root.$emit('buyModal::boughtItem', item);
},
},
};
+37
View File
@@ -3,6 +3,7 @@ import axios from 'axios';
const STRIPE_PUB_KEY = process.env.STRIPE_PUB_KEY; // eslint-disable-line
import subscriptionBlocks from '../../common/script/content/subscriptionBlocks';
import { mapState } from 'client/libs/store';
import encodeParams from 'client/libs/encodeParams';
import notificationsMixin from 'client/mixins/notifications';
export default {
@@ -170,5 +171,41 @@ export default {
this.$root.$emit('show::modal', 'amazon-payment');
},
async cancelSubscription (config) {
if (config && config.group && !confirm(this.$t('confirmCancelGroupPlan'))) return;
if (!confirm(this.$t('sureCancelSub'))) return;
let group;
if (config && config.group) {
group = config.group;
}
let paymentMethod = this.user.purchased.plan.paymentMethod;
if (group) {
paymentMethod = group.purchased.plan.paymentMethod;
}
if (paymentMethod === 'Amazon Payments') {
paymentMethod = 'amazon';
} else {
paymentMethod = paymentMethod.toLowerCase();
}
let queryParams = {
_id: this.user._id,
apiToken: this.credentials.API_TOKEN,
noRedirect: true,
};
if (group) {
queryParams.groupId = group._id;
}
let cancelUrl = `/${paymentMethod}/subscribe/cancel?${encodeParams(queryParams)}`;
await axios.get(cancelUrl);
// Success
alert(this.$t('paypalCanceled'));
this.$router.push('/');
},
},
};
+7
View File
@@ -73,6 +73,7 @@ const GroupPlansAppPage = () => import(/* webpackChunkName: "guilds" */ './compo
// Group Plans
const GroupPlanIndex = () => import(/* webpackChunkName: "group-plans" */ './components/group-plans/index');
const GroupPlanTaskInformation = () => import(/* webpackChunkName: "group-plans" */ './components/group-plans/taskInformation');
const GroupPlanBilling = () => import(/* webpackChunkName: "group-plans" */ './components/group-plans/billing');
// Challenges
const ChallengeIndex = () => import(/* webpackChunkName: "challenges" */ './components/challenges/index');
@@ -145,6 +146,12 @@ const router = new VueRouter({
component: GroupPage,
props: true,
},
{
name: 'groupPlanBilling',
path: '/group-plans/:groupId/billing',
component: GroupPlanBilling,
props: true,
},
],
},
{
+2
View File
@@ -135,6 +135,8 @@ export default function () {
userIdToMessage: '',
brokenChallengeTask: {},
equipmentDrawerOpen: true,
recentlyPurchased: {},
groupPlans: [],
},
});
+4 -1
View File
@@ -393,5 +393,8 @@
"details": "Details",
"participantDesc": "Once all members have either accepted or declined, the Quest begins. Only those who clicked 'accept' will be able to participate in the Quest and receive the rewards.",
"groupGems": "Group Gems",
"groupGemsDesc": "Guild Gems can be spent to make Challenges! In the future, you will be able to add more Guild Gems."
"groupGemsDesc": "Guild Gems can be spent to make Challenges! In the future, you will be able to add more Guild Gems.",
"groupTaskBoard": "Task Board",
"groupInformation": "Group Information",
"groupBilling": "Group Billing"
}
+3 -1
View File
@@ -202,5 +202,7 @@
"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",
"gemsPurchaseNote": "Subscribers can buy gems for gold in the Market! For easy access, you can also pin the gem to your Rewards column.",
"gemsRemaining": "gems remaining"
}