diff --git a/website/client/app.vue b/website/client/app.vue
index 6583241956..9e7bccbb49 100644
--- a/website/client/app.vue
+++ b/website/client/app.vue
@@ -11,6 +11,7 @@ div
#app(:class='{"casting-spell": castingSpell}')
banned-account-modal
amazon-payments-modal(v-if='!isStaticPage')
+ payments-success-modal
snackbars
router-view(v-if="!isUserLoggedIn || isStaticPage")
template(v-else)
@@ -185,7 +186,10 @@ import SelectMembersModal from 'client/components/selectMembersModal.vue';
import notifications from 'client/mixins/notifications';
import { setup as setupPayments } from 'client/libs/payments';
import amazonPaymentsModal from 'client/components/payments/amazonModal';
+import paymentsSuccessModal from 'client/components/payments/successModal';
+
import spellsMixin from 'client/mixins/spells';
+import { CONSTANTS, getLocalSetting, removeLocalSetting } from 'client/libs/userlocalManager';
import svgClose from 'assets/svg/close.svg';
import bannedAccountModal from 'client/components/bannedAccountModal';
@@ -205,6 +209,7 @@ export default {
SelectMembersModal,
amazonPaymentsModal,
bannedAccountModal,
+ paymentsSuccessModal,
},
data () {
return {
@@ -433,6 +438,14 @@ export default {
});
}
+ let appState = getLocalSetting(CONSTANTS.savedAppStateValues.SAVED_APP_STATE);
+ if (appState) {
+ appState = JSON.parse(appState);
+ if (appState.paymentCompleted) {
+ removeLocalSetting(CONSTANTS.savedAppStateValues.SAVED_APP_STATE);
+ this.$root.$emit('bv::show::modal', 'payments-success-modal');
+ }
+ }
this.$nextTick(() => {
// Load external scripts after the app has been rendered
setupPayments();
diff --git a/website/client/components/page.vue b/website/client/components/page.vue
deleted file mode 100644
index c39bc57819..0000000000
--- a/website/client/components/page.vue
+++ /dev/null
@@ -1,6 +0,0 @@
-
-.row
- .col
- h1.page-header Page
- p {{ $route.path }}
-
\ No newline at end of file
diff --git a/website/client/components/payments/amazonModal.vue b/website/client/components/payments/amazonModal.vue
index 347c768fcd..513907788a 100644
--- a/website/client/components/payments/amazonModal.vue
+++ b/website/client/components/payments/amazonModal.vue
@@ -33,8 +33,10 @@
import * as Analytics from 'client/libs/analytics';
import axios from 'axios';
import { mapState } from 'client/libs/store';
+import { CONSTANTS, setLocalSetting } from 'client/libs/userlocalManager';
const AMAZON_PAYMENTS = process.env.AMAZON_PAYMENTS; // eslint-disable-line
+const habiticaUrl = `${location.protocol}//${location.host}`;
export default {
data () {
@@ -186,6 +188,18 @@ export default {
new this.OffAmazonPayments.Widgets.Wallet(walletParams).bind('AmazonPayWallet');
},
+ storePaymentStatusAndReload (url) {
+ const appState = {
+ paymentMethod: 'amazon',
+ paymentCompleted: true,
+ };
+ setLocalSetting(CONSTANTS.savedAppStateValues.SAVED_APP_STATE, JSON.stringify(appState));
+ if (url) {
+ window.location.assign(url);
+ } else {
+ window.location.reload(true);
+ }
+ },
async amazonCheckOut () {
this.amazonButtonEnabled = false;
@@ -202,8 +216,7 @@ export default {
this.$set(this, 'amazonButtonEnabled', true);
this.reset();
- // @TODO: What are we syncing?
- window.location.reload(true);
+ this.storePaymentStatusAndReload();
} catch (e) {
this.$set(this, 'amazonButtonEnabled', true);
this.amazonPaymentsreset();
@@ -231,8 +244,6 @@ export default {
if (newGroup && newGroup._id) {
// Handle new user signup
if (!this.$store.state.isUserLoggedIn) {
- const habiticaUrl = `${location.protocol}//${location.host}`;
-
Analytics.track({
hitType: 'event',
eventCategory: 'group-plans-static',
@@ -240,23 +251,22 @@ export default {
eventLabel: 'paid-with-amazon',
});
- location.href = `${habiticaUrl}/group-plans/${newGroup._id}/task-information?showGroupOverview=true`;
+ this.storePaymentStatusAndReload(`${habiticaUrl}/group-plans/${newGroup._id}/task-information?showGroupOverview=true`);
return;
}
- // @TODO: Just append? or $emit?
- this.$router.push(`/group-plans/${newGroup._id}/task-information`);
this.user.guilds.push(newGroup._id);
+ this.storePaymentStatusAndReload(`${habiticaUrl}/group-plans/${newGroup._id}/task-information`);
return;
}
if (this.amazonPayments.groupId) {
- this.$router.push(`/group-plans/${this.amazonPayments.groupId}/task-information`);
+ this.storePaymentStatusAndReload(`${habiticaUrl}/group-plans/${this.amazonPayments.groupId}/task-information`);
return;
}
- window.location.reload(true);
this.reset();
+ this.storePaymentStatusAndReload();
} catch (e) {
this.$set(this, 'amazonButtonEnabled', true);
// @TODO: do we need this? this.amazonPaymentsreset();
diff --git a/website/client/components/payments/buyGemsModal.vue b/website/client/components/payments/buyGemsModal.vue
index 8c32e26d02..f0dd48b2b9 100644
--- a/website/client/components/payments/buyGemsModal.vue
+++ b/website/client/components/payments/buyGemsModal.vue
@@ -75,7 +75,7 @@
.card-body
.mx-auto(v-html='icons.creditCard', style='"height: 56px; width: 159px; margin-top: 1em;"')
.card.text-center.payment-method
- a.card-body.paypal(:href='paypalCheckoutLink', target='_blank')
+ a.card-body.paypal(@click="openPaypal(paypalCheckoutLink, 'gems')")
img(src='~assets/images/paypal.png')
.card.text-center.payment-method(@click="amazonPaymentsInit({type: 'single'})")
.card-body.amazon
@@ -158,7 +158,7 @@
.card-body(@click='showStripe({subscription: subscriptionPlan})')
.mx-auto(v-html='icons.creditCard', style='"height: 56px; width: 159px; margin-top: 1em;"')
.card.text-center.payment-method
- a.card-body.paypal(:href='paypalSubscriptionLink', target='_blank')
+ a.card-body.paypal(@click="openPaypal(paypalSubscriptionLink, 'subscription')")
img(src='~assets/images/paypal.png')
.card.text-center.payment-method
.card-body.amazon(@click="amazonPaymentsInit({type: 'subscription', subscription: subscriptionPlan})")
diff --git a/website/client/components/payments/successModal.vue b/website/client/components/payments/successModal.vue
new file mode 100644
index 0000000000..08fda4589b
--- /dev/null
+++ b/website/client/components/payments/successModal.vue
@@ -0,0 +1,86 @@
+
+ b-modal#payments-success-modal(
+ :title="$t('accountSuspendedTitle')",
+ size='sm',
+ )
+ div(slot="modal-header")
+ .check-container.d-flex.align-items-center.justify-content-center
+ .svg-icon.check(v-html="icons.check")
+ h2(v-ocne) {{ $t('paymentSuccessful') }}
+ div(slot="modal-footer")
+ .small-text(v-once) {{ $t('giftSubscriptionText4') }}
+ .row
+ .col-12.text-center
+ button.btn.btn-primary(@click='close()') {{$t('onwards')}}
+
+
+
+
+
\ No newline at end of file
diff --git a/website/client/components/settings/subscription.vue b/website/client/components/settings/subscription.vue
index c71ef673d8..da71ec2c86 100644
--- a/website/client/components/settings/subscription.vue
+++ b/website/client/components/settings/subscription.vue
@@ -77,7 +77,7 @@
.col-md-4
button.purchase.btn.btn-primary(@click='showStripe({subscription:subscription.key, coupon:subscription.coupon})', :disabled='!subscription.key') {{ $t('card') }}
.col-md-4
- a.purchase(:href='paypalPurchaseLink', :disabled='!subscription.key', target='_blank')
+ a.purchase(@click="openPaypal(paypalPurchaseLink, 'subscription')", :disabled='!subscription.key')
img(src='https://www.paypalobjects.com/webstatic/en_US/i/buttons/pp-acceptance-small.png', :alt="$t('paypal')")
.col-md-4
a.btn.btn-secondary.purchase(@click="payWithAmazon()")
diff --git a/website/client/libs/userlocalManager.js b/website/client/libs/userlocalManager.js
index 1c2f00343a..da3e30489a 100644
--- a/website/client/libs/userlocalManager.js
+++ b/website/client/libs/userlocalManager.js
@@ -14,6 +14,9 @@ const CONSTANTS = {
COSTUME_TAB: 'costume-tab',
EQUIPMENT_TAB: 'equipment-tab',
},
+ savedAppStateValues: {
+ SAVED_APP_STATE: 'saved-app-state',
+ },
};
function setLocalSetting (key, value) {
@@ -24,8 +27,14 @@ function getLocalSetting (key) {
return localStorage.getItem(key);
}
+function removeLocalSetting (key) {
+ return localStorage.removeItem(key);
+}
+
+
export {
CONSTANTS,
getLocalSetting,
setLocalSetting,
+ removeLocalSetting,
};
diff --git a/website/client/main.js b/website/client/main.js
index 928d48bd98..f6b0701dd8 100644
--- a/website/client/main.js
+++ b/website/client/main.js
@@ -4,7 +4,7 @@ import {
setup as setupAnalytics,
} from 'client/libs/analytics';
import { setUpLogging } from 'client/libs/logging';
-import router from './router';
+import router from './router/index';
import getStore from './store';
import StoreModule from './libs/store';
import './filters/registerGlobals';
diff --git a/website/client/mixins/payments.js b/website/client/mixins/payments.js
index 71078350fc..dee1aa4db4 100644
--- a/website/client/mixins/payments.js
+++ b/website/client/mixins/payments.js
@@ -6,12 +6,14 @@ import { mapState } from 'client/libs/store';
import encodeParams from 'client/libs/encodeParams';
import notificationsMixin from 'client/mixins/notifications';
import * as Analytics from 'client/libs/analytics';
+import { CONSTANTS, setLocalSetting } from 'client/libs/userlocalManager';
+
+const habiticaUrl = `${location.protocol}//${location.host}`;
export default {
mixins: [notificationsMixin],
computed: {
...mapState(['credentials']),
- // @TODO refactor into one single computed property
paypalCheckoutLink () {
return '/paypal/checkout';
},
@@ -41,7 +43,26 @@ export default {
let gift = this.encodeGift(data.giftedTo, data.gift);
const url = `/paypal/checkout?gift=${gift}`;
+ this.openPaypal(url, 'gift');
+ },
+ openPaypal (url/* , type*/) {
+ const appState = {
+ paymentMethod: 'paypal',
+ paymentCompleted: false,
+ };
+ setLocalSetting(CONSTANTS.savedAppStateValues.SAVED_APP_STATE, JSON.stringify(appState));
window.open(url, '_blank');
+
+ function localStorageChangeHandled (e) {
+ if (e.key === 'saved-app-state') {
+ window.removeEventListener('storage', localStorageChangeHandled);
+ const newState = e.newValue ? JSON.parse(e.newValue) : {};
+ if (newState.paymentCompleted) window.location.reload(true);
+ }
+ }
+
+ // Listen for changes to local storage, indicating that the payment completed
+ window.addEventListener('storage', localStorageChangeHandled);
},
showStripe (data) {
if (!this.checkGemAmount(data)) return;
@@ -92,6 +113,12 @@ export default {
return;
}
+ const appState = {
+ paymentMethod: 'stripe',
+ paymentCompleted: true,
+ };
+ setLocalSetting(CONSTANTS.savedAppStateValues.SAVED_APP_STATE, JSON.stringify(appState));
+
let newGroup = response.data.data;
if (newGroup && newGroup._id) {
// @TODO this does not do anything as we reload just below
@@ -99,8 +126,6 @@ export default {
// Handle new user signup
if (!this.$store.state.isUserLoggedIn) {
- const habiticaUrl = `${location.protocol}//${location.host}`;
-
Analytics.track({
hitType: 'event',
eventCategory: 'group-plans-static',
@@ -108,18 +133,17 @@ export default {
eventLabel: 'paid-with-stripe',
});
- location.href = `${habiticaUrl}/group-plans/${newGroup._id}/task-information?showGroupOverview=true`;
+ window.location.assign(`${habiticaUrl}/group-plans/${newGroup._id}/task-information?showGroupOverview=true`);
return;
}
- this.$router.push(`/group-plans/${newGroup._id}/task-information`);
- // @TODO action
this.user.guilds.push(newGroup._id);
+ window.location.assign(`${habiticaUrl}/group-plans/${newGroup._id}/task-information`);
return;
}
if (data.groupId) {
- this.$router.push(`/group-plans/${data.groupId}/task-information`);
+ window.location.assign(`${habiticaUrl}/group-plans/${data.groupId}/task-information`);
return;
}
@@ -144,7 +168,7 @@ export default {
let url = '/stripe/subscribe/edit';
let response = await axios.post(url, data);
- // Succss
+ // Success
window.location.reload(true);
// error
alert(response.message);
diff --git a/website/client/router/handleRedirect.js b/website/client/router/handleRedirect.js
new file mode 100644
index 0000000000..0aba06afec
--- /dev/null
+++ b/website/client/router/handleRedirect.js
@@ -0,0 +1,21 @@
+import { CONSTANTS, getLocalSetting, setLocalSetting } from 'client/libs/userlocalManager';
+
+export default function (to, from, next) {
+ const redirect = to.params.redirect;
+
+ switch (redirect) {
+ case 'paypal-success-checkout':
+ case 'paypal-success-subscribe': {
+ const appState = getLocalSetting(CONSTANTS.savedAppStateValues.SAVED_APP_STATE);
+ if (appState) {
+ const newAppState = JSON.parse(appState);
+ newAppState.paymentCompleted = true;
+ setLocalSetting(CONSTANTS.savedAppStateValues.SAVED_APP_STATE, JSON.stringify(newAppState));
+ }
+ window.close();
+ break;
+ }
+ default:
+ next({name: 'notFound'});
+ }
+}
\ No newline at end of file
diff --git a/website/client/router.js b/website/client/router/index.js
similarity index 79%
rename from website/client/router.js
rename to website/client/router/index.js
index a7c53c18ff..2052ded759 100644
--- a/website/client/router.js
+++ b/website/client/router/index.js
@@ -2,51 +2,49 @@ import Vue from 'vue';
import VueRouter from 'vue-router';
import getStore from 'client/store';
import * as Analytics from 'client/libs/analytics';
+import handleRedirect from './handleRedirect';
-// import EmptyView from './components/emptyView';
-
-// TODO Dummy elements used as placeholder until real components are implemented
-import ParentPage from './components/parentPage';
+import ParentPage from 'client/components/parentPage';
// Static Pages
-const StaticWrapper = () => import(/* webpackChunkName: "entry" */'./components/static/staticWrapper');
-const HomePage = () => import(/* webpackChunkName: "entry" */'./components/static/home');
+const StaticWrapper = () => import(/* webpackChunkName: "entry" */'client/components/static/staticWrapper');
+const HomePage = () => import(/* webpackChunkName: "entry" */'client/components/static/home');
-const AppPage = () => import(/* webpackChunkName: "static" */'./components/static/app');
-const ClearBrowserDataPage = () => import(/* webpackChunkName: "static" */'./components/static/clearBrowserData');
-const CommunityGuidelinesPage = () => import(/* webpackChunkName: "static" */'./components/static/communityGuidelines');
-const ContactPage = () => import(/* webpackChunkName: "static" */'./components/static/contact');
-const FAQPage = () => import(/* webpackChunkName: "static" */'./components/static/faq');
-const FeaturesPage = () => import(/* webpackChunkName: "static" */'./components/static/features');
-const GroupPlansPage = () => import(/* webpackChunkName: "static" */'./components/static/groupPlans');
-const MerchPage = () => import(/* webpackChunkName: "static" */'./components/static/merch');
-const NewsPage = () => import(/* webpackChunkName: "static" */'./components/static/newStuff');
-const OverviewPage = () => import(/* webpackChunkName: "static" */'./components/static/overview');
-const PressKitPage = () => import(/* webpackChunkName: "static" */'./components/static/pressKit');
-const PrivacyPage = () => import(/* webpackChunkName: "static" */'./components/static/privacy');
-const TermsPage = () => import(/* webpackChunkName: "static" */'./components/static/terms');
+const AppPage = () => import(/* webpackChunkName: "static" */'client/components/static/app');
+const ClearBrowserDataPage = () => import(/* webpackChunkName: "static" */'client/components/static/clearBrowserData');
+const CommunityGuidelinesPage = () => import(/* webpackChunkName: "static" */'client/components/static/communityGuidelines');
+const ContactPage = () => import(/* webpackChunkName: "static" */'client/components/static/contact');
+const FAQPage = () => import(/* webpackChunkName: "static" */'client/components/static/faq');
+const FeaturesPage = () => import(/* webpackChunkName: "static" */'client/components/static/features');
+const GroupPlansPage = () => import(/* webpackChunkName: "static" */'client/components/static/groupPlans');
+const MerchPage = () => import(/* webpackChunkName: "static" */'client/components/static/merch');
+const NewsPage = () => import(/* webpackChunkName: "static" */'client/components/static/newStuff');
+const OverviewPage = () => import(/* webpackChunkName: "static" */'client/components/static/overview');
+const PressKitPage = () => import(/* webpackChunkName: "static" */'client/components/static/pressKit');
+const PrivacyPage = () => import(/* webpackChunkName: "static" */'client/components/static/privacy');
+const TermsPage = () => import(/* webpackChunkName: "static" */'client/components/static/terms');
-const RegisterLoginReset = () => import(/* webpackChunkName: "auth" */'./components/auth/registerLoginReset');
-const Logout = () => import(/* webpackChunkName: "auth" */'./components/auth/logout');
+const RegisterLoginReset = () => import(/* webpackChunkName: "auth" */'client/components/auth/registerLoginReset');
+const Logout = () => import(/* webpackChunkName: "auth" */'client/components/auth/logout');
// User Pages
// const StatsPage = () => import(/* webpackChunkName: "user" */'./components/userMenu/stats');
// const AchievementsPage = () => import(/* webpackChunkName: "user" */'./components/userMenu/achievements');
-const ProfilePage = () => import(/* webpackChunkName: "user" */'./components/userMenu/profilePage');
+const ProfilePage = () => import(/* webpackChunkName: "user" */'client/components/userMenu/profilePage');
// Settings
-const Settings = () => import(/* webpackChunkName: "settings" */'./components/settings/index');
-const API = () => import(/* webpackChunkName: "settings" */'./components/settings/api');
-const DataExport = () => import(/* webpackChunkName: "settings" */'./components/settings/dataExport');
-const Notifications = () => import(/* webpackChunkName: "settings" */'./components/settings/notifications');
-const PromoCode = () => import(/* webpackChunkName: "settings" */'./components/settings/promoCode');
-const Site = () => import(/* webpackChunkName: "settings" */'./components/settings/site');
-const Subscription = () => import(/* webpackChunkName: "settings" */'./components/settings/subscription');
+const Settings = () => import(/* webpackChunkName: "settings" */'client/components/settings/index');
+const API = () => import(/* webpackChunkName: "settings" */'client/components/settings/api');
+const DataExport = () => import(/* webpackChunkName: "settings" */'client/components/settings/dataExport');
+const Notifications = () => import(/* webpackChunkName: "settings" */'client/components/settings/notifications');
+const PromoCode = () => import(/* webpackChunkName: "settings" */'client/components/settings/promoCode');
+const Site = () => import(/* webpackChunkName: "settings" */'client/components/settings/site');
+const Subscription = () => import(/* webpackChunkName: "settings" */'client/components/settings/subscription');
// Hall
-const HallPage = () => import(/* webpackChunkName: "hall" */'./components/hall/index');
-const PatronsPage = () => import(/* webpackChunkName: "hall" */'./components/hall/patrons');
-const HeroesPage = () => import(/* webpackChunkName: "hall" */'./components/hall/heroes');
+const HallPage = () => import(/* webpackChunkName: "hall" */'client/components/hall/index');
+const PatronsPage = () => import(/* webpackChunkName: "hall" */'client/components/hall/patrons');
+const HeroesPage = () => import(/* webpackChunkName: "hall" */'client/components/hall/heroes');
// Except for tasks that are always loaded all the other main level
// All the main level
@@ -55,41 +53,41 @@ const HeroesPage = () => import(/* webpackChunkName: "hall" */'./components/hall
// for docs
// Tasks
-const UserTasks = () => import(/* webpackChunkName: "userTasks" */'./components/tasks/user');
+const UserTasks = () => import(/* webpackChunkName: "userTasks" */'client/components/tasks/user');
// Inventory
-const InventoryContainer = () => import(/* webpackChunkName: "inventory" */'./components/inventory/index');
-const ItemsPage = () => import(/* webpackChunkName: "inventory" */'./components/inventory/items/index');
-const EquipmentPage = () => import(/* webpackChunkName: "inventory" */'./components/inventory/equipment/index');
-const StablePage = () => import(/* webpackChunkName: "inventory" */'./components/inventory/stable/index');
+const InventoryContainer = () => import(/* webpackChunkName: "inventory" */'client/components/inventory/index');
+const ItemsPage = () => import(/* webpackChunkName: "inventory" */'client/components/inventory/items/index');
+const EquipmentPage = () => import(/* webpackChunkName: "inventory" */'client/components/inventory/equipment/index');
+const StablePage = () => import(/* webpackChunkName: "inventory" */'client/components/inventory/stable/index');
// Guilds
-const GuildIndex = () => import(/* webpackChunkName: "guilds" */ './components/groups/index');
-const TavernPage = () => import(/* webpackChunkName: "guilds" */ './components/groups/tavern');
-const MyGuilds = () => import(/* webpackChunkName: "guilds" */ './components/groups/myGuilds');
-const GuildsDiscoveryPage = () => import(/* webpackChunkName: "guilds" */ './components/groups/discovery');
-const GroupPage = () => import(/* webpackChunkName: "guilds" */ './components/groups/group');
-const GroupPlansAppPage = () => import(/* webpackChunkName: "guilds" */ './components/groups/groupPlan');
+const GuildIndex = () => import(/* webpackChunkName: "guilds" */ 'client/components/groups/index');
+const TavernPage = () => import(/* webpackChunkName: "guilds" */ 'client/components/groups/tavern');
+const MyGuilds = () => import(/* webpackChunkName: "guilds" */ 'client/components/groups/myGuilds');
+const GuildsDiscoveryPage = () => import(/* webpackChunkName: "guilds" */ 'client/components/groups/discovery');
+const GroupPage = () => import(/* webpackChunkName: "guilds" */ 'client/components/groups/group');
+const GroupPlansAppPage = () => import(/* webpackChunkName: "guilds" */ 'client/components/groups/groupPlan');
// 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');
+const GroupPlanIndex = () => import(/* webpackChunkName: "group-plans" */ 'client/components/group-plans/index');
+const GroupPlanTaskInformation = () => import(/* webpackChunkName: "group-plans" */ 'client/components/group-plans/taskInformation');
+const GroupPlanBilling = () => import(/* webpackChunkName: "group-plans" */ 'client/components/group-plans/billing');
// Challenges
-const ChallengeIndex = () => import(/* webpackChunkName: "challenges" */ './components/challenges/index');
-const MyChallenges = () => import(/* webpackChunkName: "challenges" */ './components/challenges/myChallenges');
-const FindChallenges = () => import(/* webpackChunkName: "challenges" */ './components/challenges/findChallenges');
-const ChallengeDetail = () => import(/* webpackChunkName: "challenges" */ './components/challenges/challengeDetail');
+const ChallengeIndex = () => import(/* webpackChunkName: "challenges" */ 'client/components/challenges/index');
+const MyChallenges = () => import(/* webpackChunkName: "challenges" */ 'client/components/challenges/myChallenges');
+const FindChallenges = () => import(/* webpackChunkName: "challenges" */ 'client/components/challenges/findChallenges');
+const ChallengeDetail = () => import(/* webpackChunkName: "challenges" */ 'client/components/challenges/challengeDetail');
// Shops
-const ShopsContainer = () => import(/* webpackChunkName: "shops" */'./components/shops/index');
-const MarketPage = () => import(/* webpackChunkName: "shops-market" */'./components/shops/market/index');
-const QuestsPage = () => import(/* webpackChunkName: "shops-quest" */'./components/shops/quests/index');
-const SeasonalPage = () => import(/* webpackChunkName: "shops-seasonal" */'./components/shops/seasonal/index');
-const TimeTravelersPage = () => import(/* webpackChunkName: "shops-timetravelers" */'./components/shops/timeTravelers/index');
+const ShopsContainer = () => import(/* webpackChunkName: "shops" */'client/components/shops/index');
+const MarketPage = () => import(/* webpackChunkName: "shops-market" */'client/components/shops/market/index');
+const QuestsPage = () => import(/* webpackChunkName: "shops-quest" */'client/components/shops/quests/index');
+const SeasonalPage = () => import(/* webpackChunkName: "shops-seasonal" */'client/components/shops/seasonal/index');
+const TimeTravelersPage = () => import(/* webpackChunkName: "shops-timetravelers" */'client/components/shops/timeTravelers/index');
-import NotFoundPage from './components/404';
+import NotFoundPage from 'client/components/404';
Vue.use(VueRouter);
@@ -279,6 +277,9 @@ const router = new VueRouter({
{ name: 'contributors', path: 'contributors', component: HeroesPage },
],
},
+ // Only used to handle some redirects
+ // See router.beforeEach
+ { path: '/redirect/:redirect', name: 'redirect' },
{ path: '*', redirect: { name: 'notFound' } },
],
});
@@ -289,6 +290,8 @@ router.beforeEach(function routerGuard (to, from, next) {
const isUserLoggedIn = store.state.isUserLoggedIn;
const routeRequiresLogin = to.meta.requiresLogin !== false;
+ if (to.name === 'redirect') return handleRedirect(to, from, next);
+
if (!isUserLoggedIn && routeRequiresLogin) {
// Redirect to the login page unless the user is trying to reach the
// root of the website, in which case show the home page.
diff --git a/website/common/locales/en/npc.json b/website/common/locales/en/npc.json
index f9e862ccd3..da725f429f 100644
--- a/website/common/locales/en/npc.json
+++ b/website/common/locales/en/npc.json
@@ -115,6 +115,7 @@
"card": "Credit Card (using Stripe)",
"amazonInstructions": "Click the button to pay using Amazon Payments",
"paymentMethods": "Purchase using",
+ "paymentSuccessful": "Your payment was successful!",
"classGear": "Class Gear",
"classGearText": "Congratulations on choosing a class! I've added your new basic weapon to your inventory. Take a look below to equip it!",
diff --git a/website/server/controllers/top-level/payments/paypal.js b/website/server/controllers/top-level/payments/paypal.js
index 6461bccc79..100c5d7361 100644
--- a/website/server/controllers/top-level/payments/paypal.js
+++ b/website/server/controllers/top-level/payments/paypal.js
@@ -61,7 +61,7 @@ api.checkoutSuccess = {
if (req.query.noRedirect) {
res.respond(200);
} else {
- res.redirect('/');
+ res.redirect('/redirect/paypal-success-checkout');
}
},
};
@@ -122,7 +122,7 @@ api.subscribeSuccess = {
if (req.query.noRedirect) {
res.respond(200);
} else {
- res.redirect('/user/settings/subscription');
+ res.redirect('/redirect/paypal-success-subscribe');
}
},
};