2021-01-21 12:20:06 +03:00
|
|
|
import Component from '@glimmer/component';
|
2021-05-19 17:26:45 +03:00
|
|
|
import envConfig from 'ghost-admin/config/environment';
|
2021-01-21 12:20:06 +03:00
|
|
|
import {action} from '@ember/object';
|
2021-05-20 14:30:52 +03:00
|
|
|
import {currencies, getCurrencyOptions, getSymbol} from 'ghost-admin/utils/currency';
|
2021-01-21 12:20:06 +03:00
|
|
|
import {inject as service} from '@ember/service';
|
2022-02-09 13:49:38 +03:00
|
|
|
import {task} from 'ember-concurrency';
|
2021-01-21 12:20:06 +03:00
|
|
|
import {tracked} from '@glimmer/tracking';
|
|
|
|
|
2021-02-25 16:07:57 +03:00
|
|
|
const CURRENCIES = currencies.map((currency) => {
|
|
|
|
return {
|
|
|
|
value: currency.isoCode.toLowerCase(),
|
|
|
|
label: `${currency.isoCode} - ${currency.name}`,
|
|
|
|
isoCode: currency.isoCode
|
|
|
|
};
|
|
|
|
});
|
|
|
|
|
2021-01-21 12:20:06 +03:00
|
|
|
export default class GhLaunchWizardSetPricingComponent extends Component {
|
2021-01-28 21:41:03 +03:00
|
|
|
@service config;
|
|
|
|
@service membersUtils;
|
2021-01-21 12:20:06 +03:00
|
|
|
@service settings;
|
2021-05-04 18:47:50 +03:00
|
|
|
@service store;
|
2021-01-21 12:20:06 +03:00
|
|
|
|
|
|
|
currencies = CURRENCIES;
|
|
|
|
|
2021-05-04 18:47:50 +03:00
|
|
|
@tracked stripeMonthlyAmount = 5;
|
|
|
|
@tracked stripeYearlyAmount = 50;
|
|
|
|
@tracked currency = 'usd';
|
|
|
|
@tracked isFreeChecked = true;
|
|
|
|
@tracked isMonthlyChecked = true;
|
|
|
|
@tracked isYearlyChecked = true;
|
|
|
|
@tracked stripePlanError = '';
|
|
|
|
@tracked product;
|
2021-05-11 11:42:40 +03:00
|
|
|
@tracked loadingProduct = false;
|
2021-01-21 12:20:06 +03:00
|
|
|
|
|
|
|
get selectedCurrency() {
|
2021-05-04 18:47:50 +03:00
|
|
|
return this.currencies.findBy('value', this.currency);
|
2021-01-21 12:20:06 +03:00
|
|
|
}
|
|
|
|
|
2021-05-20 14:30:52 +03:00
|
|
|
get allCurrencies() {
|
|
|
|
return getCurrencyOptions();
|
|
|
|
}
|
|
|
|
|
2021-05-19 17:26:45 +03:00
|
|
|
get isConnectDisallowed() {
|
|
|
|
const siteUrl = this.config.get('blogUrl');
|
|
|
|
|
|
|
|
return envConfig.environment !== 'development' && !/^https:/.test(siteUrl);
|
|
|
|
}
|
|
|
|
|
2021-05-04 18:47:50 +03:00
|
|
|
get isPaidPriceDisabled() {
|
2021-06-04 10:52:20 +03:00
|
|
|
return !this.membersUtils.isStripeEnabled;
|
2021-01-28 21:41:03 +03:00
|
|
|
}
|
|
|
|
|
2021-05-04 18:47:50 +03:00
|
|
|
get isFreeDisabled() {
|
2021-06-04 10:52:20 +03:00
|
|
|
return this.settings.get('membersSignupAccess') !== 'all';
|
2021-05-20 14:30:52 +03:00
|
|
|
}
|
|
|
|
|
2021-07-15 17:27:29 +03:00
|
|
|
willDestroy() {
|
|
|
|
super.willDestroy?.(...arguments);
|
|
|
|
// clear any unsaved settings changes when going back/forward/closing
|
|
|
|
this.args.updatePreview('');
|
|
|
|
}
|
|
|
|
|
2021-05-20 14:30:52 +03:00
|
|
|
@action
|
|
|
|
setup() {
|
|
|
|
this.fetchDefaultProduct.perform();
|
|
|
|
this.updatePreviewUrl();
|
2021-01-28 21:41:03 +03:00
|
|
|
}
|
|
|
|
|
2021-05-12 14:50:13 +03:00
|
|
|
@action
|
|
|
|
backStep() {
|
2021-05-20 14:30:52 +03:00
|
|
|
const product = this.product;
|
2021-05-12 14:50:13 +03:00
|
|
|
const data = this.args.getData() || {};
|
|
|
|
this.args.storeData({
|
|
|
|
...data,
|
|
|
|
product,
|
|
|
|
isFreeChecked: this.isFreeChecked,
|
|
|
|
isMonthlyChecked: this.isMonthlyChecked,
|
|
|
|
isYearlyChecked: this.isYearlyChecked,
|
|
|
|
monthlyAmount: this.stripeMonthlyAmount,
|
2021-05-20 14:30:52 +03:00
|
|
|
yearlyAmount: this.stripeYearlyAmount,
|
|
|
|
currency: this.currency
|
2021-05-12 14:50:13 +03:00
|
|
|
});
|
|
|
|
this.args.backStep();
|
|
|
|
}
|
|
|
|
|
2021-01-21 12:20:06 +03:00
|
|
|
@action
|
|
|
|
setStripePlansCurrency(event) {
|
|
|
|
const newCurrency = event.value;
|
2021-05-04 18:47:50 +03:00
|
|
|
this.currency = newCurrency;
|
2021-01-28 21:41:03 +03:00
|
|
|
this.updatePreviewUrl();
|
|
|
|
}
|
|
|
|
|
|
|
|
@action
|
|
|
|
toggleFreePlan(event) {
|
2021-05-04 18:47:50 +03:00
|
|
|
this.isFreeChecked = event.target.checked;
|
|
|
|
this.updatePreviewUrl();
|
2021-01-21 12:20:06 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
@action
|
2021-01-28 21:41:03 +03:00
|
|
|
toggleMonthlyPlan(event) {
|
2021-05-04 18:47:50 +03:00
|
|
|
this.isMonthlyChecked = event.target.checked;
|
|
|
|
this.updatePreviewUrl();
|
2021-01-28 21:41:03 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
@action
|
|
|
|
toggleYearlyPlan(event) {
|
2021-05-04 18:47:50 +03:00
|
|
|
this.isYearlyChecked = event.target.checked;
|
|
|
|
this.updatePreviewUrl();
|
2021-01-21 12:20:06 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
@action
|
|
|
|
validateStripePlans() {
|
2021-05-04 18:47:50 +03:00
|
|
|
this.stripePlanError = undefined;
|
2021-01-21 12:20:06 +03:00
|
|
|
|
|
|
|
try {
|
2021-05-04 18:47:50 +03:00
|
|
|
const yearlyAmount = this.stripeYearlyAmount;
|
|
|
|
const monthlyAmount = this.stripeMonthlyAmount;
|
|
|
|
const symbol = getSymbol(this.currency);
|
2021-01-21 12:20:06 +03:00
|
|
|
if (!yearlyAmount || yearlyAmount < 1 || !monthlyAmount || monthlyAmount < 1) {
|
2021-05-04 18:47:50 +03:00
|
|
|
throw new TypeError(`Subscription amount must be at least ${symbol}1.00`);
|
2021-01-21 12:20:06 +03:00
|
|
|
}
|
|
|
|
|
2021-01-28 21:41:03 +03:00
|
|
|
this.updatePreviewUrl();
|
2021-01-21 12:20:06 +03:00
|
|
|
} catch (err) {
|
2021-05-04 18:47:50 +03:00
|
|
|
this.stripePlanError = err.message;
|
2021-01-21 12:20:06 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@task
|
|
|
|
*saveAndContinue() {
|
2021-05-20 14:30:52 +03:00
|
|
|
if (this.isConnectDisallowed) {
|
2021-05-19 17:26:45 +03:00
|
|
|
this.args.nextStep();
|
|
|
|
} else {
|
|
|
|
yield this.validateStripePlans();
|
2021-01-21 12:20:06 +03:00
|
|
|
|
2021-05-19 17:26:45 +03:00
|
|
|
if (this.stripePlanError) {
|
|
|
|
return false;
|
|
|
|
}
|
2021-05-20 14:30:52 +03:00
|
|
|
const product = this.product;
|
2021-05-19 17:26:45 +03:00
|
|
|
const data = this.args.getData() || {};
|
|
|
|
this.args.storeData({
|
|
|
|
...data,
|
|
|
|
product,
|
|
|
|
isFreeChecked: this.isFreeChecked,
|
|
|
|
isMonthlyChecked: this.isMonthlyChecked,
|
|
|
|
isYearlyChecked: this.isYearlyChecked,
|
|
|
|
monthlyAmount: this.stripeMonthlyAmount,
|
2021-05-20 14:30:52 +03:00
|
|
|
yearlyAmount: this.stripeYearlyAmount,
|
|
|
|
currency: this.currency
|
2021-05-19 17:26:45 +03:00
|
|
|
});
|
|
|
|
this.args.nextStep();
|
2021-01-21 12:20:06 +03:00
|
|
|
}
|
|
|
|
}
|
2021-01-28 21:41:03 +03:00
|
|
|
|
2021-05-20 14:30:52 +03:00
|
|
|
@task({drop: true})
|
|
|
|
*fetchDefaultProduct() {
|
|
|
|
const storedData = this.args.getData();
|
|
|
|
if (storedData?.product) {
|
|
|
|
this.product = storedData.product;
|
2021-05-09 15:06:45 +03:00
|
|
|
|
2021-05-20 14:30:52 +03:00
|
|
|
if (storedData.isMonthlyChecked !== undefined) {
|
|
|
|
this.isMonthlyChecked = storedData.isMonthlyChecked;
|
|
|
|
}
|
|
|
|
if (storedData.isYearlyChecked !== undefined) {
|
|
|
|
this.isYearlyChecked = storedData.isYearlyChecked;
|
|
|
|
}
|
|
|
|
if (storedData.isFreeChecked !== undefined) {
|
|
|
|
this.isFreeChecked = storedData.isFreeChecked;
|
|
|
|
}
|
|
|
|
if (storedData.currency !== undefined) {
|
|
|
|
this.currency = storedData.currency;
|
|
|
|
}
|
|
|
|
this.stripeMonthlyAmount = storedData.monthlyAmount;
|
|
|
|
this.stripeYearlyAmount = storedData.yearlyAmount;
|
|
|
|
} else {
|
2022-01-17 21:53:43 +03:00
|
|
|
const products = yield this.store.query('product', {filter: 'type:paid', include: 'monthly_price,yearly_price'});
|
2021-05-20 14:30:52 +03:00
|
|
|
this.product = products.firstObject;
|
2022-01-17 21:53:43 +03:00
|
|
|
|
2021-05-20 14:30:52 +03:00
|
|
|
let portalPlans = this.settings.get('portalPlans') || [];
|
2021-06-04 10:52:20 +03:00
|
|
|
|
|
|
|
this.isMonthlyChecked = portalPlans.includes('monthly');
|
|
|
|
this.isYearlyChecked = portalPlans.includes('yearly');
|
|
|
|
this.isFreeChecked = portalPlans.includes('free');
|
|
|
|
|
|
|
|
const monthlyPrice = this.product.get('monthlyPrice');
|
|
|
|
const yearlyPrice = this.product.get('yearlyPrice');
|
2021-05-20 14:30:52 +03:00
|
|
|
if (monthlyPrice && monthlyPrice.amount) {
|
|
|
|
this.stripeMonthlyAmount = (monthlyPrice.amount / 100);
|
|
|
|
this.currency = monthlyPrice.currency;
|
|
|
|
}
|
|
|
|
if (yearlyPrice && yearlyPrice.amount) {
|
|
|
|
this.stripeYearlyAmount = (yearlyPrice.amount / 100);
|
2021-05-04 18:47:50 +03:00
|
|
|
}
|
2021-01-28 21:41:03 +03:00
|
|
|
}
|
2021-05-20 14:30:52 +03:00
|
|
|
this.updatePreviewUrl();
|
2021-01-28 21:41:03 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
updatePreviewUrl() {
|
|
|
|
const options = {
|
|
|
|
disableBackground: true,
|
|
|
|
currency: this.selectedCurrency.value,
|
2022-03-04 12:18:45 +03:00
|
|
|
monthlyPrice: Math.round(this.stripeMonthlyAmount * 100),
|
|
|
|
yearlyPrice: Math.round(this.stripeYearlyAmount * 100),
|
2021-02-11 21:37:23 +03:00
|
|
|
isMonthlyChecked: this.isMonthlyChecked,
|
|
|
|
isYearlyChecked: this.isYearlyChecked,
|
2021-05-20 14:30:52 +03:00
|
|
|
isFreeChecked: this.isFreeChecked,
|
|
|
|
portalPlans: null
|
2021-01-28 21:41:03 +03:00
|
|
|
};
|
2021-02-11 21:37:23 +03:00
|
|
|
|
2021-01-28 21:41:03 +03:00
|
|
|
const url = this.membersUtils.getPortalPreviewUrl(options);
|
|
|
|
this.args.updatePreview(url);
|
|
|
|
}
|
2021-01-21 12:20:06 +03:00
|
|
|
}
|