Skip to content

Commit

Permalink
Signup: Add Site Title step (#7386)
Browse files Browse the repository at this point in the history
This PR adds a Site Title step to the signup flows. It will allow the user to set their site title early in signup and it will give us the option to automatically fire domain suggestions based on what the user entered as a site title.
  • Loading branch information
bisko authored Sep 27, 2016
1 parent cf9df46 commit aca2949
Show file tree
Hide file tree
Showing 22 changed files with 416 additions and 5 deletions.
2 changes: 2 additions & 0 deletions assets/stylesheets/_components.scss
Original file line number Diff line number Diff line change
Expand Up @@ -118,9 +118,11 @@
@import 'blocks/upgrade-nudge-expanded/style';
@import 'components/seo/preview-upgrade-nudge/style';
@import 'components/signup-form/style';
@import 'components/signup-site-title/style';
@import 'components/site-icon/style';
@import 'components/site-selector/style';
@import 'components/site-selector-modal/style';
@import 'components/site-title-example/style';
@import 'components/sites-dropdown/style';
@import 'components/sites-popover/style';
@import 'components/social-logo/style';
Expand Down
91 changes: 91 additions & 0 deletions client/components/signup-site-title/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/**
* External dependencies
*/
import React, { PropTypes } from 'react';
import { connect } from 'react-redux';
import { noop } from 'lodash';

/**
* Internal dependencies
*/
import LoggedOutForm from 'components/logged-out-form';
import formState from 'lib/form-state';
import FormFieldset from 'components/forms/form-fieldset';
import FormButton from 'components/forms/form-button';
import FormTextInput from 'components/forms/form-text-input';
import { getSiteTitle } from 'state/signup/steps/site-title/selectors';

import { translate } from 'i18n-calypso';

const SignupSiteTitle = React.createClass( {
propTypes: {
onSubmit: PropTypes.func.isRequired,
siteTitle: PropTypes.string.isRequired,
},

componentWillMount() {
this.formStateController = new formState.Controller( {
fieldNames: [ 'siteTitle' ],
validatorFunction: noop,
onNewState: this.setFormState,
hideFieldErrorsOnChange: true,
initialState: {
siteTitle: {
value: this.props.siteTitle
}
}
} );

this.setFormState( this.formStateController.getInitialState() );
},

setFormState( state ) {
this.setState( { form: state } );
},

handleChangeEvent( event ) {
this.formStateController.handleFieldChange( {
name: event.target.name,
value: event.target.value
} );
},

formFields() {
return (
<FormFieldset>
<FormTextInput
autoFocus={ true }
autoCapitalize="off"
className="signup-site-title__input"
type="text"
name="siteTitle"
placeholder={ translate( 'Give your site a title' ) }
value={ this.state.form.siteTitle.value }
onChange={ this.handleChangeEvent }
/>
<FormButton className="signup-site-title__button">{ translate( 'Continue' ) }</FormButton>
</FormFieldset>
);
},

handleSubmit( event ) {
event.preventDefault();

const siteTitle = formState.getFieldValue( this.state.form, 'siteTitle' );
this.props.onSubmit( siteTitle );
},

render() {
return (
<LoggedOutForm className="signup-site-title" onSubmit={ this.handleSubmit } noValidate>
{ this.formFields() }
</LoggedOutForm>
);
}
} );

export default connect(
state => ( {
siteTitle: getSiteTitle( state ),
} )
)( SignupSiteTitle );
18 changes: 18 additions & 0 deletions client/components/signup-site-title/style.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
.signup-site-title {
padding: 0;
position: relative;
border: none;
background: none;
box-shadow: none;
max-width: 600px;
}

.signup-site-title__input[type="text"] {
padding: 14px 16px;
}

.signup-site-title__button {
position: absolute;
top: 7px;
right: 8px;
}
27 changes: 27 additions & 0 deletions client/components/site-title-example/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/**
* External dependencies
*/
import React from 'react';
import { translate } from 'i18n-calypso';

export default () => {
return (
<div className="site-title-example">
<p className="site-title-example__description">
{ translate( 'Your Site Title is the name of your Blog or Website. It\'s often displayed at the top of your site.' ) }
</p>
<div className="site-title-example__image">
<svg width="269" height="135" viewBox="0 0 269 135" xmlns="http://www.w3.org/2000/svg">
<title>Group</title>
<g fill="none" fillRule="evenodd">
<path fill="#E9EFF3" d="M0 24h269v111H0z" />
<path d="M0 24h269V3.99c0-2.204-.947-3.99-2.107-3.99H2.107C.943 0 0 1.784 0 3.99V24M28 75h182v12H28zM28 93h139v12H28z" fill="#C8D7E1" />
<text fontSize="15" fontWeight="400" fill="#556875" transform="translate(-345 -213)">
<tspan x="373.256" y="272">Your Site Title</tspan>
</text>
</g>
</svg>
</div>
</div>
);
};
58 changes: 58 additions & 0 deletions client/components/site-title-example/style.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
.site-title-example {
box-sizing: border-box;
position: relative;
padding-top: 42px;
max-width: 600px;
min-height: 120px;
margin: 30px auto 60px auto;

display: flex;
flex-direction: row;
flex-wrap: nowrap;
align-items: center;
justify-content: space-around;

@include breakpoint( "<660px" ) {
max-width: 100%;
padding: 32px 32px 0;
margin: 0 auto;
flex-wrap: wrap;
.site-title-example__description {
text-align: center;
margin-bottom: 16px;
}
}
}

.site-title-example__description {
color: darken( $gray, 20% );
text-align: right;
margin-bottom: 8px;
display: inline-block;
flex: 1 1 100%;
width: 270px;
}

.site-title-example__image {
pointer-events: none;
display: inline-block;
width: 270px;
flex: 1 1 100%;
text-align: right;

&:before {
content: '';
position: absolute;
right: 0;
bottom: 0;
left: 0;
height: 30px;
background: linear-gradient( to bottom, rgba( $gray-light, 0 ) 0%, rgba( $gray-light, 1 ) 100% );
}

@include breakpoint( "<660px" ) {
position: relative;
margin: 0 auto;
text-align: center;
}
}
8 changes: 6 additions & 2 deletions client/lib/signup/flow-controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ function SignupFlowController( options ) {

this._assertFlowHasValidDependencies();

this._reduxStore = options.reduxStore;

SignupProgressStore.on( 'change', this._boundProcess );

if ( options.flowName === store.get( STORAGE_KEY ) ) {
Expand Down Expand Up @@ -167,10 +169,12 @@ assign( SignupFlowController.prototype, {

SignupActions.processSignupStep( step );

steps[ step.stepName ].apiRequestFunction( function( errors, providedDependencies ) {
const apiFunction = steps[ step.stepName ].apiRequestFunction.bind( this );

apiFunction( ( errors, providedDependencies ) => {
this._processingSteps[ step.stepName ] = false;
SignupActions.processedSignupStep( step, errors, providedDependencies );
}.bind( this ), dependenciesFound, step );
}, dependenciesFound, step );
}
},

Expand Down
11 changes: 10 additions & 1 deletion client/lib/signup/step-actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,19 @@ import SignupCart from 'lib/signup/cart';
import { startFreeTrial } from 'lib/upgrades/actions';
import { PLAN_PREMIUM } from 'lib/plans/constants';

import { getSiteTitle } from 'state/signup/steps/site-title/selectors';

function addDomainItemsToCart( callback, dependencies, { domainItem, googleAppsCartItem, isPurchasingItem, siteUrl, themeSlug, themeSlugWithRepo, themeItem } ) {

let siteTitle = getSiteTitle( this._reduxStore.getState() ).trim();

if ( '' === siteTitle ) {
siteTitle = siteUrl;
}

wpcom.undocumented().sitesNew( {
blog_name: siteUrl,
blog_title: '',
blog_title: siteTitle,
options: {
theme: dependencies.theme || themeSlugWithRepo,
vertical: dependencies.surveyQuestion || undefined
Expand Down
7 changes: 7 additions & 0 deletions client/signup/config/flows.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,13 @@ const flows = {
lastModified: '2016-05-23'
},

'sitetitle': {
steps: [ 'survey', 'site-title', 'design-type', 'themes', 'domains', 'plans', 'survey-user' ],
destination: getSiteDestination,
description: 'The current best performing flow in AB tests',
lastModified: '2016-05-23'
},

website: {
steps: [ 'survey', 'design-type', 'themes', 'domains', 'plans', 'survey-user' ],
destination: getSiteDestination,
Expand Down
2 changes: 2 additions & 0 deletions client/signup/config/step-components.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ var config = require( 'config' ),
DomainsStepComponent = require( 'signup/steps/domains' ),
PlansStepComponent = require( 'signup/steps/plans' ),
SiteComponent = require( 'signup/steps/site' ),
SiteTitleComponent = require( 'signup/steps/site-title' ),
SurveyStepComponent = require( 'signup/steps/survey' ),
ThemeSelectionComponent = require( 'signup/steps/theme-selection' ),
UserSignupComponent = require( 'signup/steps/user' );
Expand All @@ -20,6 +21,7 @@ module.exports = {
'jetpack-user': UserSignupComponent,
plans: PlansStepComponent,
site: SiteComponent,
'site-title': SiteTitleComponent,
survey: SurveyStepComponent,
'survey-user': UserSignupComponent,
test: config( 'env' ) === 'development' ? require( 'signup/steps/test-step' ) : undefined,
Expand Down
5 changes: 5 additions & 0 deletions client/signup/config/steps.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,11 @@ module.exports = {
providesDependencies: [ 'bearer_token', 'username' ]
},

'site-title': {
stepName: 'site-title',
providesDependencies: [ 'siteTitle' ]
},

test: {
stepName: 'test'
},
Expand Down
1 change: 1 addition & 0 deletions client/signup/main.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ const Signup = React.createClass( {

this.signupFlowController = new SignupFlowController( {
flowName: this.props.flowName,
reduxStore: this.context.store,
onComplete: function( dependencies, destination ) {
const timeSinceLoading = this.state.loadingScreenStartTime
? Date.now() - this.state.loadingScreenStartTime
Expand Down
82 changes: 82 additions & 0 deletions client/signup/steps/site-title/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
/**
* External dependencies
*/
import React, { PropTypes } from 'react';
import { connect } from 'react-redux';

/**
* Internal dependencies
*/
import StepWrapper from 'signup/step-wrapper';
import SignupActions from 'lib/signup/actions';

import SignupSiteTitle from 'components/signup-site-title';
import SiteTitleExample from 'components/site-title-example';

import { setSiteTitle } from 'state/signup/steps/site-title/actions';

import { translate } from 'i18n-calypso';

const SiteTitleStep = React.createClass( {
propTypes: {
flowName: PropTypes.string,
goToNextStep: PropTypes.func.isRequired,
positionInFlow: PropTypes.number,
setSiteTitle: PropTypes.func.isRequired,
signupProgressStore: PropTypes.array,
stepName: PropTypes.string,
},

submitSiteTitleStep( siteTitle ) {
this.props.setSiteTitle( siteTitle );

SignupActions.submitSignupStep( {
processingMessage: translate( 'Setting up your site' ),
stepName: this.props.stepName,
siteTitle
}, [], { siteTitle } );

this.props.goToNextStep();
},

skipStep() {
this.submitSiteTitleStep( '' );
},

renderSiteTitleStep() {
return (
<div>
<SignupSiteTitle
onSubmit={ this.submitSiteTitleStep }
/>
<SiteTitleExample />
</div>
);
},
render() {
const headerText = translate( 'Give your new site a name.' );
const subHeaderText = translate( 'Enter a Site Title that will be displayed for visitors. You can always change this later.' );

return (
<div>
<StepWrapper
flowName={ this.props.flowName }
stepName={ this.props.stepName }
positionInFlow={ this.props.positionInFlow }
headerText={ headerText }
fallbackHeaderText={ headerText }
subHeaderText={ subHeaderText }
fallbackSubHeaderText={ subHeaderText }
signupProgressStore={ this.props.signupProgressStore }
stepContent={ this.renderSiteTitleStep() }
goToNextStep={ this.skipStep }
/>
</div>
);
}
} );

export default connect(
null,
{ setSiteTitle }
)( SiteTitleStep );
1 change: 1 addition & 0 deletions client/state/action-types.js
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,7 @@ export const SERVER_DESERIALIZE = 'SERVER_DESERIALIZE';
export const SEO_TITLE_SET = 'SEO_TITLE_SET';
export const SIGNUP_DEPENDENCY_STORE_RESET = 'SIGNUP_DEPENDENCY_STORE_RESET';
export const SIGNUP_DEPENDENCY_STORE_UPDATE = 'SIGNUP_DEPENDENCY_STORE_UPDATE';
export const SIGNUP_STEPS_SITE_TITLE = 'SIGNUP_STEPS_SITE_TITLE';
export const SITE_DOMAINS_RECEIVE = 'SITE_DOMAINS_RECEIVE';
export const SITE_DOMAINS_REQUEST = 'SITE_DOMAINS_REQUEST';
export const SITE_DOMAINS_REQUEST_FAILURE = 'SITE_DOMAINS_REQUEST_FAILURE';
Expand Down
Loading

0 comments on commit aca2949

Please sign in to comment.