Added "Get started" modal for first-load onboarding

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

- modal is triggered by the query param `?firstStart=true`, eg https://localhost:2368/ghost/#/?firstStart=true
- clears the query param after triggering the modal so it doesn't get re-triggered after leaving and re-entering the dashboard route
This commit is contained in:
Kevin Ansfield 2022-02-01 17:32:38 +00:00
parent 59f769a696
commit 9760e67b3d
4 changed files with 62 additions and 1 deletions

View File

@ -0,0 +1,25 @@
<div class="modal-content" data-test-modal="get-started">
<button type="button" class="close" role="button" title="Close" {{on "click" @close}}>{{svg-jar "close"}}<span class="hidden">Close</span></button>
<div class="tc f4">
<h1>You're all set!</h1>
<p>Your site is ready to start publishing content and sending newsletters.</p>
<p><LinkTo @route="editor.new" @model="post" @classNames="gh-btn gh-btn-black" {{on "click" @close}}><span>Start writing</span></LinkTo></p>
</div>
<div class="flex flex-row f8">
<div class="pa4 w-50 br">
<h3 class="tc">Paid memberships?</h3>
<p>
Allowing your audience to subscribe is fast and simple through Stripe. Not sure?
<a href="https://docs.ghost.org"><span>Learn more.</span></a>
</p>
<p class="tc"><LinkTo @route="settings.membership" @classNames="gh-btn" {{on "click" @close}}><span>Connect Stripe</span></LinkTo></p>
</div>
<div class="pa4 w-50">
<h3 class="tc">Migrating data?</h3>
<p>Our migration tools make it quick and painless to import your content and readers from other platforms.</p>
<p class="tc"><a href="https://docs.ghost.org" class="gh-btn" target="_blank" rel="noopener noreferer"><span>Learn more</span></a></p>
</div>
</div>
</div>

View File

@ -12,6 +12,10 @@ export default class DashboardController extends Controller {
@service settings;
@service whatsNew;
queryParams = ['firstStart'];
@tracked firstStart = false;
@tracked mrrStatsData = null;
@tracked mrrStatsError = null;
@tracked mrrStatsLoading = false;

View File

@ -3,13 +3,23 @@ import {inject as service} from '@ember/service';
export default class DashboardRoute extends AuthenticatedRoute {
@service feature;
@service modals;
beforeModel() {
beforeModel(transition) {
super.beforeModel(...arguments);
if (!this.session.user.isAdmin) {
return this.transitionTo('site');
}
if (this.feature.improvedOnboarding && transition.to?.queryParams?.firstStart === 'true') {
this.modals.open('modals/get-started');
// clear the query param so it doesn't stick around
transition.abort();
const queryParams = Object.assign({}, transition.to.queryParams, {firstStart: false});
this.transitionTo('dashboard', {queryParams});
}
}
buildRouteInfoMetadata() {

View File

@ -3,6 +3,7 @@ import {Response} from 'ember-cli-mirage';
import {authenticateSession, invalidateSession} from 'ember-simple-auth/test-support';
import {beforeEach, describe, it} from 'mocha';
import {blur, click, currentURL, fillIn, find, findAll} from '@ember/test-helpers';
import {enableLabsFlag} from '../helpers/labs-flag';
import {expect} from 'chai';
import {setupApplicationTest} from 'ember-mocha';
import {setupMirage} from 'ember-cli-mirage/test-support';
@ -345,4 +346,25 @@ describe('Acceptance: Setup', function () {
.to.equal(1);
});
});
describe('?firstStart=true', function () {
beforeEach(async function () {
enableLabsFlag(this.server, 'improvedOnboarding');
let role = this.server.create('role', {name: 'Owner'});
this.server.create('user', {roles: [role], slug: 'owner'});
await authenticateSession();
});
it('opens modal', async function () {
await visit('/?firstStart=true');
expect(find('[data-test-modal="get-started"]')).to.exist;
});
it('clears query param', async function () {
await visit('/?firstStart=true');
expect(currentURL()).to.equal('/dashboard');
});
});
});