Ghost/ghost/admin/app/templates/settings/membership.hbs
Kevin Ansfield 6339770a67 Fixed "connect to stripe" button in portal settings modal
no issue

- passed correct action for opening stripe connect modal through to portal settings modal
- updated `<GhTaskButton>` to accept a `@unlinkedTask=true/false` property
  - ember-concurrency will throw warnings about unsafe task cancellation if the initiator of a task is destroyed due to the actions of a task. Eg. the stripe connect button being replaced with the plan checkboxes because stripe connect details are added to settings
  - to avoid warnings ember-concurrency expects the task initiation to be marked as "unlinked" so that the task is allowed to continue even though the initiator is destroyed
- updated `<GhSiteIframe>` to force a refresh when the `@guid` property changes
  - we want the portal preview to fully reload so that it can fetch server data and see that stripe is connected
- updated portal settings modal to initiate a refresh when switching from "connect to stripe" to the plans checkboxes that happens automatically after a successful stripe connection
2021-05-19 20:24:18 +01:00

251 lines
14 KiB
Handlebars
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<section class="gh-canvas gh-setting-members-canvas" {{did-insert this.setup}}>
<GhCanvasHeader class="gh-canvas-header gh-setting-members-header">
<h2 class="gh-canvas-title" data-test-screen-title>
<LinkTo @route="settings">Settings</LinkTo>
<span>{{svg-jar "arrow-right"}}</span>
Membership
</h2>
<section class="view-actions">
<GhTaskButton
@buttonText="Save"
@task={{this.saveSettingsTask}}
@successText="Saved"
@runningText="Saving"
@class="gh-btn gh-btn-primary gh-btn-icon"
data-test-button="save-settings"
/>
</section>
</GhCanvasHeader>
<section class="view-container settings-debug">
<div class="gh-setting-members-basics">
<div class="gh-setting-members-basicsform">
<p class="intro">Fund your work with subscription revenue. Connect your Stripe account and offer premium content to your audience. Our creators are already making over $2 million per year, while Ghost takes 0% payment fees.</p>
<hr>
<div>
<section class="gh-expandable gh-setting-members-portalcta">
<div class="gh-expandable-block">
<div class="gh-expandable-header">
<div>
<h4 class="gh-expandable-title">Portal Settings</h4>
<p class="gh-expandable-description">
Customize members modal signup flow
</p>
</div>
<button type="button" class="gh-btn gh-btn-green" {{on "click" this.openPortalSettings}} data-test-toggle="portal-settings">
<span>Customise Portal &rarr;</span>
</button>
</div>
</div>
</section>
<div class="gh-setting-members-access">
<Settings::MembersSubscriptionAccess @onChange={{this.updatePortalPreview}} />
<Settings::MembersDefaultPostAccess />
</div>
</div>
</div>
<div class="gh-setting-members-portalpreview">
<div class="gh-setting-members-portal-mock">
{{#if (eq this.settings.membersSignupAccess 'none')}}
<div class="gh-setting-members-portal-disabled">
<span class="lightgrey">{{svg-jar "portal-logo-stroke"}}</span>
<h4>Portal disabled</h4>
<p>Change your Subscription Access setting to re-enable Portal</p>
</div>
{{else}}
<GhSiteIframe
@src={{this.portalPreviewUrl}}
@invisibleUntilLoaded={{true}}
@onLoad={{this.portalPreviewLoaded}}
@onDestroyed={{this.portalPreviewDestroyed}} />
{{/if}}
</div>
</div>
</div>
<div class="gh-setting-members-tierscontainer">
<div class="gh-settings-members-tiersheader">
<h4 class="gh-main-section-header small bn">Membership tiers</h4>
<button type="button" class="gh-btn gh-btn-outline gh-btn-stripe-status {{if this.isConnectDisallowed "disabled"}} {{if this.settings.stripeConnectAccountId "connected" ""}}" {{on "click" this.openStripeConnect}}>
<span>
{{if this.settings.stripeConnectAccountId "Connected to Stripe" "Stripe not connected"}}
</span>
</button>
</div>
<section class="gh-expandable">
<div class="gh-expandable-block">
<div class="gh-expandable-header">
<div>
<h4 class="gh-expandable-title">Free</h4>
<p class="gh-expandable-description">Free member sign up settings</p>
</div>
<button type="button" class="gh-btn" {{on "click" (toggle "freeOpen" this)}} data-test-toggle-pub-info><span>{{if this.freeOpen "Close" "Expand"}}</span></button>
</div>
<div class="gh-expandable-content">
{{#liquid-if this.freeOpen}}
<div class="gh-setting-content-extended">
<GhFormGroup @errors={{this.settings.errors}} @hasValidated={{this.settings.hasValidated}} @property="free-welcome-page">
<label for="freeWelcomePage">Welcome page</label>
<GhUrlInput
@id="freeWelcomePage"
@value={{readonly this.settings.membersFreeSignupRedirect}}
@baseUrl={{readonly this.siteUrl}}
@setResult={{action "setFreeSignupRedirect"}}
@validateUrl={{action "validateFreeSignupRedirect"}}
@placeholder={{readonly this.siteUrl}}
/>
<GhErrorMessage
@errors={{settings.errors}}
@property="membersFreeSignupRedirect"
/>
<p>Redirect to this URL after signup for a free membership</p>
</GhFormGroup>
</div>
{{/liquid-if}}
</div>
</div>
</section>
<section class="gh-expandable">
<div class="gh-expandable-block">
<div class="gh-expandable-header">
<div>
<h4 class="gh-expandable-title">Premium</h4>
<p class="gh-expandable-description">Set prices and paid member sign up settings</p>
</div>
{{#if this.settings.stripeConnectAccountId}}
<button type="button" class="gh-btn" {{action (toggle "paidOpen" this)}} data-test-toggle-pub-info><span>{{if this.paidOpen "Close" "Expand"}}</span></button>
{{else}}
<button type="button" class="stripe-connect {{if this.isConnectDisallowed "disabled"}}" {{action (toggle "showStripeConnect" this)}}>
<span>Connect with Stripe</span>
</button>
{{/if}}
</div>
{{#if this.isConnectDisallowed}}
<div class="gh-setting-nossl">
<div class="gh-setting-nossl-container">
<span class="red">{{svg-jar "shield-lock"}}</span>
<h4>Your site is not secured</h4>
<p>Paid memberships through Ghost can only be run on sites secured by SSL (HTTPS vs. HTTP). More information on adding a free SSL Certificate to your Ghost site can be <a href="https://ghost.org/integrations/lets-encrypt/" target="_blank" rel="noopener noreferrer">found here</a>.</p>
</div>
</div>
{{/if}}
<div class="gh-expandable-content">
{{#liquid-if this.paidOpen}}
<div class="gh-setting-content-extended">
{{#if this.fetchDefaultProduct.isRunning}}
Loading...
{{else}}
<GhFormGroup @errors={{this.settings.errors}} @hasValidated={{this.settings.hasValidated}} @property="prices">
<div class="gh-settings-members-pricelabelcont">
<label for="monthlyPrice">Prices</label>
<span></span>
<div>
<span class="gh-setting-members-currency gh-select">
<div class="gh-setting-members-currencylabel">
<span>{{this.currency}}</span>
{{svg-jar "arrow-down-small"}}
</div>
<OneWaySelect
@value={{this.selectedCurrency}}
id="currency"
name="currency"
@options={{readonly this.allCurrencies}}
@optionValuePath="value"
@optionLabelPath="label"
@update={{this.setStripePlansCurrency}}
/>
</span>
</div>
</div>
<div class="gh-setting-members-prices">
<div class="gh-input-group">
<GhTextInput
@id="monthlyPrice"
@value={{readonly this.stripeMonthlyAmount}}
@type="number"
@input={{action (mut this.stripeMonthlyAmount) value="target.value"}}
@focus-out={{action "validateStripePlans"}}
/>
<span class="gh-input-append"><span class="ttu">{{this.currency}}</span>/month</span>
</div>
<div class="gh-input-group">
<GhTextInput
@id="yearlyPrice"
@value={{readonly this.stripeYearlyAmount}}
@type="number"
@input={{action (mut this.stripeYearlyAmount) value="target.value"}}
@focus-out={{action "validateStripePlans"}}
@placeholder=''
data-test-title-input={{true}}
/>
<span class="gh-input-append"><span class="ttu">{{this.currency}}</span>/year</span>
</div>
</div>
{{#if this.stripePlanError}}
<p class="response w-100"><span class="red">{{this.stripePlanError}}</span></p>
{{/if}}
</GhFormGroup>
<GhFormGroup @errors={{this.settings.errors}} @hasValidated={{this.settings.hasValidated}} @property="paid-welcome-page">
<label for="paidWelcomePage">Welcome page</label>
<GhUrlInput
@value={{readonly this.settings.membersPaidSignupRedirect}}
@baseUrl={{readonly this.siteUrl}}
@setResult={{action "setPaidSignupRedirect"}}
@validateUrl={{action "validatePaidSignupRedirect"}}
@placeholder={{readonly this.siteUrl}}
/>
<GhErrorMessage
@errors={{settings.errors}}
@property="membersPaidSignupRedirect"
/>
<p>Redirect to this URL after signup for premium membership</p>
</GhFormGroup>
{{/if}}
</div>
{{/liquid-if}}
</div>
</div>
</section>
</div>
</section>
{{#if this.showLeaveRouteModal}}
<GhFullscreenModal
@modal="leave-settings"
@confirm={{this.confirmLeave}}
@close={{this.cancelLeave}}
@modifier="action wide"
/>
{{/if}}
{{#if this.showPortalSettings}}
<GhFullscreenModal @modal="portal-settings"
@model={{hash
preloadTask=this.saveSettingsTask
openStripeSettings=this.openStripeConnect
}}
@close={{this.closePortalSettings}}
@modifier="full-overlay portal-settings" />
{{/if}}
{{#if this.showLeavePortalModal}}
<GhFullscreenModal
@modal="leave-settings"
@confirm={{this.confirmClosePortalSettings}}
@close={{this.cancelClosePortalSettings}}
@modifier="action wide"
/>
{{/if}}
{{#if this.showStripeConnect}}
<GhFullscreenModal
@modal="stripe-connect"
@close={{action "closeStripeConnect"}}
@modifier="action wide stripe-connect {{if this.settings.stripeConnectAccountId "stripe-connected" ""}}" />
{{/if}}
</section>