diff --git a/ghost/admin/app/components/modal-portal-settings.hbs b/ghost/admin/app/components/modal-portal-settings.hbs index 51ff0a157e..9c2df0b264 100644 --- a/ghost/admin/app/components/modal-portal-settings.hbs +++ b/ghost/admin/app/components/modal-portal-settings.hbs @@ -34,6 +34,34 @@ {{#if this.membersUtils.isStripeEnabled}}
+ {{#if (feature "multipleProducts")}} +
+

Products available at signup

+
+ {{#each this.products as |product|}} +
+ +
+ {{/each}} + {{/if}}

Prices available at signup

@@ -275,4 +303,4 @@
{{/if}} - \ No newline at end of file + diff --git a/ghost/admin/app/components/modal-portal-settings.js b/ghost/admin/app/components/modal-portal-settings.js index e16bb6925e..b070860228 100644 --- a/ghost/admin/app/components/modal-portal-settings.js +++ b/ghost/admin/app/components/modal-portal-settings.js @@ -36,7 +36,7 @@ export default ModalComponent.extend({ return `data-portal`; }), - portalPreviewUrl: computed('page', 'membersUtils.{isFreeChecked,isMonthlyChecked,isYearlyChecked}', 'settings.{portalName,portalButton,portalButtonIcon,portalButtonSignupText,portalButtonStyle,accentColor,portalPlans.[]}', function () { + portalPreviewUrl: computed('page', 'membersUtils.{isFreeChecked,isMonthlyChecked,isYearlyChecked}', 'settings.{portalName,portalButton,portalButtonIcon,portalButtonSignupText,portalButtonStyle,accentColor,portalPlans.[],portalProducts.[]}', function () { const options = this.getProperties(['page']); return this.membersUtils.getPortalPreviewUrl(options); }), @@ -69,6 +69,20 @@ export default ModalComponent.extend({ const allowedPlans = this.settings.get('portalPlans') || []; return (this.membersUtils.isStripeEnabled && allowedPlans.includes('yearly')); }), + products: computed('model.products.[]', 'settings.portalProducts.[]', 'isPreloading', function () { + if (this.isPreloading || !this.model.products) { + return []; + } + const portalProducts = this.settings.get('portalProducts') || []; + const products = this.model.products.map((product) => { + return { + id: product.id, + name: product.name, + checked: portalProducts.includes(product.id) + }; + }); + return products; + }), init() { this._super(...arguments); @@ -92,6 +106,9 @@ export default ModalComponent.extend({ togglePlan(plan, event) { this.updateAllowedPlan(plan, event.target.checked); }, + toggleProduct(productId, event) { + this.updateAllowedProduct(productId, event.target.checked); + }, togglePortalButton(showButton) { this.settings.set('portalButton', showButton); }, @@ -202,6 +219,18 @@ export default ModalComponent.extend({ } }, + updateAllowedProduct(productId, isChecked) { + const portalProducts = this.settings.get('portalProducts') || []; + const allowedProducts = [...portalProducts]; + + if (!isChecked) { + this.settings.set('portalProducts', allowedProducts.filter(p => p !== productId)); + } else { + allowedProducts.push(productId); + this.settings.set('portalProducts', allowedProducts); + } + }, + _validateSignupRedirect(url, type) { let errMessage = `Please enter a valid URL`; this.settings.get('errors').remove(type); diff --git a/ghost/admin/app/models/setting.js b/ghost/admin/app/models/setting.js index 1418aa9818..f0a7d53214 100644 --- a/ghost/admin/app/models/setting.js +++ b/ghost/admin/app/models/setting.js @@ -45,6 +45,7 @@ export default Model.extend(ValidationEngine, { portalButton: attr('boolean'), portalName: attr('boolean'), portalPlans: attr('json-string'), + portalProducts: attr('json-string'), portalButtonStyle: attr('string'), portalButtonIcon: attr('string'), portalButtonSignupText: attr('string'), diff --git a/ghost/admin/app/services/members-utils.js b/ghost/admin/app/services/members-utils.js index f86d0270e3..caad697269 100644 --- a/ghost/admin/app/services/members-utils.js +++ b/ghost/admin/app/services/members-utils.js @@ -87,6 +87,7 @@ export default class MembersUtilsService extends Service { monthlyPrice, yearlyPrice, portalPlans = this.settings.get('portalPlans'), + portalProducts = this.settings.get('portalProducts'), currency, membersSignupAccess = this.settings.get('membersSignupAccess') } = overrides; @@ -112,6 +113,10 @@ export default class MembersUtilsService extends Service { settingsParam.append('portalPrices', encodeURIComponent(portalPlans)); } + if (portalProducts) { + settingsParam.append('portalProducts', encodeURIComponent(portalProducts)); + } + if (this.settings.get('accentColor') === '' || this.settings.get('accentColor')) { settingsParam.append('accentColor', encodeURIComponent(`${this.settings.get('accentColor')}`)); } diff --git a/ghost/admin/app/templates/settings/membership.hbs b/ghost/admin/app/templates/settings/membership.hbs index aee6364b2c..1ba8bde6f1 100644 --- a/ghost/admin/app/templates/settings/membership.hbs +++ b/ghost/admin/app/templates/settings/membership.hbs @@ -236,6 +236,7 @@ @model={{hash preloadTask=this.saveSettingsTask openStripeSettings=this.openStripeConnect + products=this.products }} @close={{this.closePortalSettings}} @modifier="full-overlay portal-settings" /> @@ -256,4 +257,4 @@ @close={{this.closeStripeConnect}} @modifier="action wide stripe-connect" /> {{/if}} - \ No newline at end of file +