Added stripe connection to launch site wizard

refs https://github.com/TryGhost/Team/issues/450

- duplicated and refactored/updated direct and connect settings UI from labs to the "connect stripe" step of the launch site wizard
- updated wizard buttons to be right-aligned
This commit is contained in:
Kevin Ansfield 2021-01-19 22:31:59 +00:00
parent 7828aea09c
commit 63c1f2060c
6 changed files with 165 additions and 7 deletions

View File

@ -1,2 +1,94 @@
<h2>Connect Stripe</h2>
<button type="button" class="gh-btn gh-btn-blue" {{on "click" @afterComplete}} data-test-button="wizard-next"><span>Next</span></button>
<div class="flex mb4 br3 bg-white">
<div class="pa4">
{{#if this.config.stripeDirect}}
<div class="flex flex-column flex-row-l items-start justify-between mb4 mt6">
<div class="w-100 w-50-l">
<div class="mb4">
<label for="stripe-publishable-key" class="fw6 f8">Stripe Publishable key</label>
<GhTextInput
@id="stripe-publishable-key"
@type="password"
@value={{readonly this.settings.stripeDirectPublicKey}}
class="mt1 password"
{{on "input" this.setStripeDirectPublicKey}}
/>
</div>
<div class="nudge-top--3">
<label for="stripe-secret-key" class="fw6 f8 mt4">Stripe Secret key</label>
<GhTextInput
@id="stripe-secret-key"
@type="password"
@value={{readonly this.settings.stripeDirectSecretKey}}
class="mt1 password"
{{on "input" this.setStripeDirectSecretKey}}
/>
<a href="https://dashboard.stripe.com/account/apikeys" target="_blank" rel="noopener noreferrer" class="mt1 fw4 f8">
Find your Stripe API keys here &raquo;
</a>
</div>
</div>
<div class="ml0 ml5-l mt6">
<div class="gh-members-stripe-info">
<div class="gh-members-stripe-info-header">
<h4>How you get paid</h4>
{{svg-jar "stripe-verified-partner-badge" class="gh-members-stripe-badge"}}
</div>
<p class="f8 mt2 mb0">
Stripe is our exclusive direct payments partner.<br />
Ghost collects <strong>no fees</strong> on any payments! If you dont have a Stripe account yet, you can <a href="https://stripe.com" target="_blank" rel="noopener noreferrer" class="gh-members-stripe-link">sign up here</a>.
</p>
</div>
</div>
</div>
{{else}}
<div class="flex flex-column flex-row-l items-start justify-between">
<div class="w-100 w-50-l">
<label class="fw6 f8">Generate secure key</label>
<div class="flex items-center mb4 justify-between gh-members-connectbutton-container mt2">
<a href="{{this.stripeConnectAuthUrl}}" class="stripe-connect light-blue" target="_blank" rel="noopener noreferrer"><span>Connect with Stripe</span></a>
<div class="ml2 flex items-center flex-nowrap">
<span class="mr2 f8 midgrey nowrap {{if this.stripeConnectTestMode "gh-members-connect-testmodeon"}}">{{if this.stripeConnectTestMode "Using" "Use"}} test mode</span>
<div class="for-switch small">
<label class="switch" for="stripe-connect-test-mode" {{on "click" this.toggleStripeConnectTestMode}}>
<input type="checkbox" class="gh-input" checked={{this.stripeConnectTestMode}} {{on "click" this.toggleStripeConnectTestMode}} data-test-checkbox="stripe-connect-test-mode">
<span class="input-toggle-component mt1"></span>
</label>
</div>
</div>
</div>
<div class="nudge-top--3">
<GhTextarea
class="gh-members-stripe-connect-token"
placeholder="Paste your secure key here"
{{on "input" this.setStripeConnectIntegrationToken}}
/>
{{#if this.stripeConnectError}}<p class="mb0 mt2 f8 red">{{this.stripeConnectError}}</p>{{/if}}
</div>
</div>
<div class="mt5 mt5-m mt8-l ml0 ml5-l">
<div class="gh-members-stripe-info">
<div class="gh-members-stripe-info-header">
<h4>How you get paid</h4>
{{svg-jar "stripe-verified-partner-badge" class="gh-members-stripe-badge"}}
</div>
<p class="f8 mt2 mb0">
Stripe is our exclusive direct payments partner.<br />
Ghost collects <strong>no fees</strong> on any payments! If you dont have a Stripe account yet, you can <a href="https://stripe.com" target="_blank" rel="noopener noreferrer" class="gh-members-stripe-link">sign up here</a>.
</p>
</div>
</div>
</div>
{{/if}}
</div>
</div>
{{!-- TODO: reset "failed" state automatically --}}
<GhTaskButton
@buttonText={{if this.settings.stripeConnectIntegrationToken "Save & continue" "Skip"}}
@task={{this.saveAndContinue}}
@runningText="Saving"
@class="right gh-btn gh-btn-blue gh-btn-icon"
data-test-button="wizard-next"
/>

View File

@ -1,4 +1,67 @@
import Component from '@glimmer/component';
import {action} from '@ember/object';
import {inject as service} from '@ember/service';
import {task} from 'ember-concurrency-decorators';
import {tracked} from '@glimmer/tracking';
export default class GhLaunchWizardConnectStripeComponent extends Component {
@service config;
@service ghostPaths;
@service settings;
@tracked stripeConnectTestMode = false;
@tracked stripeConnectError = null;
get stripeConnectAuthUrl() {
const mode = this.stripeConnectTestMode ? 'test' : 'live';
return `${this.ghostPaths.url.api('members/stripe_connect')}?mode=${mode}`;
}
willDestroy() {
// clear any unsaved settings changes when going back/forward/closing
this.settings.rollbackAttributes();
}
@action
setStripeDirectPublicKey(event) {
this.settings.set('stripeProductName', this.settings.get('title'));
this.settings.set('stripePublishableKey', event.target.value);
}
@action
setStripeDirectSecretKey(event) {
this.settings.set('stripeProductName', this.settings.get('title'));
this.settings.set('stripePublishableKey', event.target.value);
}
@action
toggleStripeConnectTestMode() {
this.stripeConnectTestMode = !this.stripeConnectTestMode;
}
@action
setStripeConnectIntegrationToken(event) {
this.settings.set('stripeProductName', this.settings.get('title'));
this.settings.set('stripeConnectIntegrationToken', event.target.value);
this.stripeConnectError = null;
}
@task
*saveAndContinue() {
if (this.settings.get('stripeConnectIntegrationToken')) {
try {
yield this.settings.save();
} catch (error) {
if (error.payload?.errors) {
this.stripeConnectError = 'Invalid secure key';
return false;
}
throw error;
}
}
// skip when no token supplied
this.args.afterComplete();
}
}

View File

@ -109,4 +109,4 @@
</div>
</div>
<button type="button" class="gh-btn gh-btn-blue" {{on "click" @afterComplete}} data-test-button="wizard-next"><span>Next</span></button>
<button type="button" class="right gh-btn gh-btn-blue" {{on "click" @afterComplete}} data-test-button="wizard-next"><span>Next</span></button>

View File

@ -1,2 +1,2 @@
<h2>Set pricing</h2>
<button type="button" class="gh-btn gh-btn-green" {{on "click" @afterComplete}} data-test-button="wizard-next"><span>Finish & launch my site</span></button>
<h2>Set subscription pricing</h2>
<button type="button" class="right gh-btn gh-btn-green" {{on "click" @afterComplete}} data-test-button="wizard-next"><span>Finish & launch my site</span></button>

View File

@ -66,10 +66,10 @@ export default Service.extend(_ProxyMixin, ValidationEngine, {
},
rollbackAttributes() {
return this.content.rollbackAttributes();
return this.content?.rollbackAttributes();
},
changedAttributes() {
return this.content.changedAttributes();
return this.content?.changedAttributes();
}
});

View File

@ -5,5 +5,8 @@
<section class="ma19">
<h2>Congrats</h2>
<button type="button" class="gh-btn gh-btn-blue" {{on "click" this.finish}} data-test-button="wizard-next"><span>Start publishing</span></button>
<div class="flex mb4 br3 bg-white">
<div class="pa4">You're all set up!</div>
</div>
<button type="button" class="right gh-btn gh-btn-blue" {{on "click" this.finish}} data-test-button="wizard-next"><span>Start publishing</span></button>
</section>