diff --git a/assets/css/src/admin.styl b/assets/css/src/admin.styl
index ee8c726139..30550bca59 100644
--- a/assets/css/src/admin.styl
+++ b/assets/css/src/admin.styl
@@ -32,3 +32,4 @@
@require '../../../node_modules/react-confirm-alert/src/react-confirm-alert.css'
@require 'newsletter_templates'
+@require 'welcome_wizard'
diff --git a/assets/css/src/welcome_wizard.styl b/assets/css/src/welcome_wizard.styl
new file mode 100644
index 0000000000..cdeeef825c
--- /dev/null
+++ b/assets/css/src/welcome_wizard.styl
@@ -0,0 +1,118 @@
+.mailpoet_welcome_wizard_centered_column
+ display: flex
+ flex-direction: column
+ justify-content: center
+ align-items: center
+
+.mailpoet_welcome_wizard_header img
+ margin-bottom: 20px
+
+.mailpoet_welcome_wizard_steps
+ padding-top: 20px
+ width: 100%
+
+.mailpoet_welcome_wizard_step_content
+ margin-top: 40px
+ max-width: 620px
+ min-height: 35%vh;
+ h1
+ font-weight: 400
+ padding-bottom: 10px
+ text-align: center
+ p
+ font-weight: normal
+ font-size: 15px
+ line-height: 22px
+ color: #595c65
+ text-align: center
+ margin: 10px 0;
+
+#mailpoet_sender_form
+ margin-top: 30px
+ width: 330px
+ label
+ display: inline-block
+ font-size: 15px
+ margin-bottom: 20px
+ input[type="text"]
+ margin-top: 10px
+ font-size: 15px
+ width: 328px
+ height: 30px
+ input[type="submit"]
+ margin: 50px 0 25px 0
+ a
+ font-size: 12px
+ color: #595c65
+
+.mailpoet_sender_form_loading
+ opacity: .5
+
+.mailpoet_welcome_wizard_help_info_block
+ padding-left: 180px
+ position: relative
+ margin-bottom: 10px
+ p
+ text-align: left
+
+.mailpoet_welcome_wizard_support_button
+ background: #32a8d9 url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADwAAAA8CAMAAAANIilAAAAA3lBMVEUAAAD////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////ymXGKAAAASXRSTlMAAQIFBwoPEBIUFRscHR8jKCkqLC0/Q0RGSEpNUFFXYHFzeXp9gIKFjKCjpamwvL7Aw8bIy8zN0NLT1dja3ODk5ujq7PT19/3+6Nyy9QAAAklJREFUeAGl1/1W4jwQBvAHBapi0erLK7XsKmLxAyp+SBEVAUXluf8b2ibHnqUk0LT7+3+anJlpMoGe1Wh3B9MZOZsOuu2GBWN2q//NhO9+y4YJtzenxrznIs1xyJXCY6xTDfhj3Gl6jm1ZtuM1O2P+CKpY6eST0sh3kOD4I0qfJ9ArXVG6cwtQFNw7SlclaGzdU3ipY4X6C4X7LSh2n2VN/CJWKvqygs+7yroydlLDWrWJjF5auyT3PKwgRWUod17CIpmrhzJSlR9k1hI1kuuWYaAs116oWFXUd1KBkcpE1LuKWCDyXIOhmsh5gB/HjPgw5jMS93koeqMIY0XRLSEkl5E6Mqgz4kLoiX5G7PKLy74usUT0eQ8Rex5/RviPOodIcknObQAtkqNCtuDCiGQLQF+mOtu2ZcL7gCWq5uCvTWvZJhSO6AwLDZJjZDYm2UCbZAeZdUi20SXZRGZNkl0MSHrIzCM5wFTmKzOH5BQzkjbWlkpXMZvkDIxYgNIkKb1iMfJPwXm3vc2ImjC1w3SNdkDyPW+pXJJPeZvklGSQtz2vSV7k/THeSDaUX9LMPiM7usNALY7ijGSYdgwdQqvwSvJcPQCNgo8Y2VOPXqNt35C81R36m2pPaRf28l03eCQ53Mh30ZXkwrmu2Ph3VC9382BlrMgXrA405sHqKGUerA5x5sHq+GgebDy4/v/IBZlG5qMbJpgP6/tnr0z6MHkmbB+4p9dvXPbxO+sDZehZsYxPI956G/keZQzP95BGfQ7y/Sm4+LUDrT+vKBtiP2phEAAAAABJRU5ErkJggg==') center center no-repeat
+ background-size: 30px
+ display: inline-block
+ height: 54px
+ width: 54px
+ border-radius: 28px
+ position: absolute
+ top: 10px
+ left: 70px
+ box-shadow: 2px 2px 8px #666;
+ transform: scale(0.8)
+
+.mailpoet_welcome_wizard_video_badge
+ cursor: default
+ position: absolute
+ top: 20px
+ left: 30px
+ line-height: 1.5em
+ padding-bottom: 0
+ .dashicons
+ line-height: 1em
+ &:hover
+ background: $video-guide-badge-color
+
+.mailpoet_welcome_wizard_mail_icon
+ background: transparent url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAKAAAABrCAYAAADw4IlaAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAABT9JREFUeNrsnTFSGz0YhhWSgpJJkS4z9tBS4JbKOUHwDfAJYp8AcwLDCSBdOpwT4IoWCoo0jJ1JlybcIPmEvw0LwyTG1iftrp5nRjGh+PktHmv16t3YzgEA5Mqrp9/Y297pysMnGftMDwRmIuPk8vZm+qyAIt9AHsbMExjTFwnPHgko8vkV75y5gUj0RMLJRukbrHwQk/HfFVD3fRfMCUSmU6yALeYCErCFgJCUDaYAEBAQEAABAQEBYvImwc+8k3F0eXtzzPRXC61iD2VsNVlA/+TG8mQ/yuNQRLzmV59cvF15OJWxm9MluCvjSp78CAWSibclw1diVynkq8oe8FAmYaZ1IMSTr6viDXLbAz5HS8aFTMqZXpbvUMRu1dPLbSXu91x1BZz6IKGBIiQHMmZ6axjYhIyZgXzeg6F6EecSLKuU37t1VvmhS4SUc5ksvyK20CaIeC0/n25xC1TohOvvcu6seqqx1h5Qfuhcxgf5smewGhJSwsg30lUv9B577hY3lfoxTxpC/J2t8tCWcWawGvqQcqVHBfCCkOHDnVuc64XmWFe9SWVCiAaHvjzpz7rJDXn53NXV0D/xI0LKf0PGoVG6vdaQGGzbFfwYxv/PyWhrSAnNQEUkpDwv375ebkPLV7RXnZDymQgYIaS0NKSc66sd8R5CxrlByJjq5dZkL256EO1rNg0pQ4OQcv9q16OF3I9WrgxCxv2Wyv/+1gkZSQUsiXisIWUS+D9d9MoXuYUU/3x9ODM6WvFhsl38211LolVxPjj4yO4WRzahX1Fdl8mRjXF/638vfsXrxwp60btgje4djfKhaXSvbNzfHulebxrzOSXpgvXVNSwd2YR8JfuQ0qhe2bi/nbqEt8UlvRtGQ0rH0Sv/S74DZ9jfashIdk9mJW7Jp1f+59HKqatYf9s4AVXColfuu8x7ZcP+1s/r2v1tIwUsiXh/BOAy7JW1v/Uhw6q/bYfob2sfQpYMKdn0ynXrbxu9Aj4Rcap7Q8teuZtYPqv+1jmj/jYbAYvV0LhXvkjRK2vI8N2tVX/btupvsxKwJGJjeuVSf2txtGLe32YpYEnEY10NLXvllpF4lv3txEXqb7MWUCWcG/fKs5BHNtrfjpxtf9urY+tT6/eGqUOvXOpvLY5WkvS3IXnjak6pV/6qlzaLXvnFRzbG/e217vVq/7YmjXl3LP2nAFa98sC9oFeO0N92mvKeOo17e7aUvXIu/S0CLhdSrHvlwRP5Ri6T/hYBlxfRH0lY9cpj7ZUPcutvCSEvDymWvfKpUcgY1jndsgI+E1KcXa8cksr3twi4xmpoGFLWZepq0t8i4PoiWvbKq4SMWvW3CBhORKteeVlq2d8SQsJK6Fednh4yj12cz82b66o3zX3++ZyQBxEte+VHIcPVvL9lBTQMKc6uV25Mf8sKaC9iyF65cf0tAsYTceTWO7JpZH/LJTh+SPmgd7gseydzcbQyYQZZAUOJeOaW65Ub39+yAqYNKUWv/Mkt7nzZ0hXPX6ZPSLcIGCWkuOpVeVyCARAQEBAAAQEBARAQEBAAAQEBARAQEBAAAQEBARAQEBAQEAABAQEBEBAQEAABAQEBEBAQEAABAQEBEBAQEAABAQEBEBAQEAABoX6s+g6p3b3tnd9MH7ACAgICICAgIAACQi0FnDMVkFJAPsURUnD3qvhqb3tn5uJ8WjjA/VX38vamXd4DDpkTiEjf//G6+NuPXz+/vX/77rt8uc/cgLV8xaeJvi5/VyS8Fgn9x9Vv6uV4k7mCUPs9GV9k9PhEUagMfwQYAFppkb3J5HUdAAAAAElFTkSuQmCC') center center no-repeat
+ background-size: 40px 27px
+ display: inline-block
+ width: 40px
+ height: 27px
+ position: absolute
+ top: 50px
+ left: 75px
+
+@media screen and (max-width 520px)
+ .mailpoet_welcome_wizard_help_info_block
+ padding-left: 150px
+ .mailpoet_welcome_wizard_support_button
+ left: 40px
+ .mailpoet_welcome_wizard_video_badge
+ left: 10px
+ .mailpoet_welcome_wizard_mail_icon
+ left: 50px
+
+.mailpoet_welcome_wizard_step_controls
+ margin-top: 50px
+ .button
+ margin:0 10px
+
+.mailpoet_welcome_wizard_woo_screenshot
+ margin-top: 30px
+ width: 400px
+
+@media screen and (max-width 520px)
+ .mailpoet_welcome_wizard_woo_screenshot
+ width: 340px
+
+.welcome_wizard_video
+ position: absolute
+ top: -1000px
diff --git a/assets/js/src/welcome_wizard/header.jsx b/assets/js/src/welcome_wizard/header.jsx
new file mode 100644
index 0000000000..45cfa0a48d
--- /dev/null
+++ b/assets/js/src/welcome_wizard/header.jsx
@@ -0,0 +1,21 @@
+import React from 'react';
+import SteppedProgressBar from '../common/stepped_progess_bar.jsx';
+
+const WelcomeWizardHeader = props => (
+
+

+ {
+ props.current_step <= props.steps_count ?
+ (
)
+ : null
+ }
+
+);
+
+WelcomeWizardHeader.propTypes = {
+ current_step: React.PropTypes.number.isRequired,
+ steps_count: React.PropTypes.number.isRequired,
+ logo_src: React.PropTypes.string.isRequired,
+};
+
+module.exports = WelcomeWizardHeader;
diff --git a/assets/js/src/welcome_wizard/steps/help_info_step.jsx b/assets/js/src/welcome_wizard/steps/help_info_step.jsx
new file mode 100644
index 0000000000..9ba0a6e121
--- /dev/null
+++ b/assets/js/src/welcome_wizard/steps/help_info_step.jsx
@@ -0,0 +1,69 @@
+import React from 'react';
+import MailPoet from 'mailpoet';
+import ReactStringReplace from 'react-string-replace';
+
+const WelcomeWizardHelpInfoStep = props => (
+
+
+
+
+ {
+ ReactStringReplace(
+ MailPoet.I18n.t('welcomeWizardYouCanContactText'),
+ /\[strong\](.*?)\[\/strong\]/g,
+ match => ({ match })
+ )
+ }
+
+
+
+
+
+ {MailPoet.I18n.t('seeVideoGuide')}
+
+
+ {
+ ReactStringReplace(
+ MailPoet.I18n.t('welcomeWizardAboutVideosText'),
+ /\[strong\](.*?)\[\/strong\]/g,
+ match => ({ match })
+ )
+ }
+
+
+
+
+
+ {
+ ReactStringReplace(
+ MailPoet.I18n.t('welcomeWizardAboutCourseText'),
+ /\[strong\](.*?)\[\/strong\]/g,
+ match => ({ match })
+ )
+ }
+
+
+
+
+
+);
+
+module.exports = WelcomeWizardHelpInfoStep;
+
+WelcomeWizardHelpInfoStep.propTypes = {
+ next: React.PropTypes.func.isRequired,
+};
+
+module.exports = WelcomeWizardHelpInfoStep;
diff --git a/assets/js/src/welcome_wizard/steps/migrated_user_step.jsx b/assets/js/src/welcome_wizard/steps/migrated_user_step.jsx
new file mode 100644
index 0000000000..75709108de
--- /dev/null
+++ b/assets/js/src/welcome_wizard/steps/migrated_user_step.jsx
@@ -0,0 +1,18 @@
+import React from 'react';
+import MailPoet from 'mailpoet';
+
+const WelcomeWizardMigratedUserStep = props => (
+
+
{MailPoet.I18n.t('welcomeWizardLetsStartTitle')}
+
{MailPoet.I18n.t('welcomeWizardSenderMigratedUserText')}
+
+
+
+
+);
+
+WelcomeWizardMigratedUserStep.propTypes = {
+ next: React.PropTypes.func.isRequired,
+};
+
+module.exports = WelcomeWizardMigratedUserStep;
diff --git a/assets/js/src/welcome_wizard/steps/sender_step.jsx b/assets/js/src/welcome_wizard/steps/sender_step.jsx
new file mode 100644
index 0000000000..8db527b2b5
--- /dev/null
+++ b/assets/js/src/welcome_wizard/steps/sender_step.jsx
@@ -0,0 +1,64 @@
+import React from 'react';
+import MailPoet from 'mailpoet';
+import jQuery from 'jquery';
+
+const WelcomeWizardSenderStep = props => (
+
+
{MailPoet.I18n.t('welcomeWizardLetsStartTitle')}
+
{MailPoet.I18n.t('welcomeWizardSenderText')}
+
+
+);
+
+WelcomeWizardSenderStep.propTypes = {
+ finish: React.PropTypes.func.isRequired,
+ loading: React.PropTypes.bool.isRequired,
+ update_sender: React.PropTypes.func.isRequired,
+ submit_sender: React.PropTypes.func.isRequired,
+ sender: React.PropTypes.shape({
+ name: React.PropTypes.string,
+ address: React.PropTypes.string,
+ }),
+};
+
+WelcomeWizardSenderStep.defaultProps = {
+ sender: null,
+};
+
+module.exports = WelcomeWizardSenderStep;
diff --git a/assets/js/src/welcome_wizard/steps/usage_tracking_step.jsx b/assets/js/src/welcome_wizard/steps/usage_tracking_step.jsx
new file mode 100644
index 0000000000..c823ed646d
--- /dev/null
+++ b/assets/js/src/welcome_wizard/steps/usage_tracking_step.jsx
@@ -0,0 +1,55 @@
+import React from 'react';
+import MailPoet from 'mailpoet';
+import ReactStringReplace from 'react-string-replace';
+
+const WelcomeWizardUsageTrackingStep = props => (
+
+
{MailPoet.I18n.t('welcomeWizardUsageTrackingStepTitle')}
+
+ {
+ ReactStringReplace(
+ MailPoet.I18n.t('welcomeWizardTrackingText'),
+ /\[link\](.*?)\[\/link\]/g,
+ match => (
+ { match }
+ )
+ )
+ }
+
+
+
+
+
+
+);
+
+module.exports = WelcomeWizardUsageTrackingStep;
+
+WelcomeWizardUsageTrackingStep.propTypes = {
+ allow_action: React.PropTypes.func.isRequired,
+ allow_text: React.PropTypes.string.isRequired,
+ skip_action: React.PropTypes.func.isRequired,
+ loading: React.PropTypes.bool.isRequired,
+};
diff --git a/assets/js/src/welcome_wizard/steps/woo_commerce_step.jsx b/assets/js/src/welcome_wizard/steps/woo_commerce_step.jsx
new file mode 100644
index 0000000000..d16e45ffd1
--- /dev/null
+++ b/assets/js/src/welcome_wizard/steps/woo_commerce_step.jsx
@@ -0,0 +1,41 @@
+import React from 'react';
+import MailPoet from 'mailpoet';
+
+const WelcomeWizardWooCommerceStep = props => (
+
+
{MailPoet.I18n.t('welcomeWizardWooCommerceStepTitle')}
+
+ {MailPoet.I18n.t('welcomeWizardHelpingShopOwnersText')}
+
+
+ {MailPoet.I18n.t('welcomeWizardWooCommerceEmailsText')}
+
+

+
+
+
+
+);
+
+module.exports = WelcomeWizardWooCommerceStep;
+
+WelcomeWizardWooCommerceStep.propTypes = {
+ next: React.PropTypes.func.isRequired,
+ screenshot_src: React.PropTypes.string.isRequired,
+ loading: React.PropTypes.bool.isRequired,
+};
diff --git a/assets/js/src/welcome_wizard/steps_controller.jsx b/assets/js/src/welcome_wizard/steps_controller.jsx
new file mode 100644
index 0000000000..9a9418ffad
--- /dev/null
+++ b/assets/js/src/welcome_wizard/steps_controller.jsx
@@ -0,0 +1,147 @@
+import React from 'react';
+import MailPoet from 'mailpoet';
+import WelcomeWizardHeader from './header.jsx';
+import WelcomeWizardSenderStep from './steps/sender_step.jsx';
+import WelcomeWizardMigratedUserStep from './steps/migrated_user_step.jsx';
+import WelcomeWizardHelpInfoStep from './steps/help_info_step.jsx';
+import WelcomeWizardUsageTrackingStep from './steps/usage_tracking_step.jsx';
+import WelcomeWizardWooCommerceStep from './steps/woo_commerce_step.jsx';
+
+class WelcomeWizardStepsController extends React.Component {
+ constructor(props) {
+ super(props);
+
+ this.state = {
+ stepsCount: window.is_woocommerce_active ? 4 : 3,
+ shouldSetSender: !window.is_mp2_migration_complete,
+ loading: false,
+ sender: window.sender_data,
+ };
+
+ this.finishWizard = this.finishWizard.bind(this);
+ this.updateSettings = this.updateSettings.bind(this);
+ this.activateTracking = this.activateTracking.bind(this);
+ this.updateSender = this.updateSender.bind(this);
+ this.submitSender = this.submitSender.bind(this);
+ this.showWooCommerceStepOrFinish = this.showWooCommerceStepOrFinish.bind(this);
+ this.componentDidUpdate();
+ }
+
+ componentDidUpdate() {
+ const step = parseInt(this.props.params.step, 10);
+ if (step > this.state.stepsCount || step < 1) {
+ this.props.router.push('steps/1');
+ }
+ }
+
+ finishWizard() {
+ this.setState({ loading: true });
+ window.location = window.finish_wizard_url;
+ }
+
+ showWooCommerceStepOrFinish() {
+ if (this.state.stepsCount === 4) {
+ this.props.router.push('steps/4');
+ } else {
+ this.finishWizard();
+ }
+ }
+
+ updateSettings(data) {
+ this.setState({ loading: true });
+ return MailPoet.Ajax.post({
+ api_version: window.mailpoet_api_version,
+ endpoint: 'settings',
+ action: 'set',
+ data,
+ }).then(() => this.setState({ loading: false })
+ ).fail((response) => {
+ this.setState({ loading: false });
+ if (response.errors.length > 0) {
+ MailPoet.Notice.error(
+ response.errors.map(error => error.message),
+ { scroll: true }
+ );
+ }
+ });
+ }
+
+ activateTracking() {
+ this.updateSettings({ analytics: { enabled: true } }).then(() => (
+ this.showWooCommerceStepOrFinish())
+ );
+ }
+
+ updateSender(data) {
+ this.setState({
+ sender: Object.assign({}, this.state.sender, data),
+ });
+ }
+
+ submitSender() {
+ this.updateSettings({ sender: this.state.sender }).then(() => (this.props.router.push('steps/2')));
+ }
+
+ render() {
+ const step = parseInt(this.props.params.step, 10);
+ return (
+
+
+ { step === 1 && this.state.shouldSetSender ?
+ : null
+ }
+
+ { step === 1 && !this.state.shouldSetSender ?
+ this.props.router.push('steps/2')}
+ /> : null
+ }
+
+ { step === 2 ?
+ this.props.router.push('steps/3')}
+ /> : null
+ }
+
+ { step === 3 ?
+ : null
+ }
+
+ { step === 4 ?
+ : null
+ }
+
+ );
+ }
+}
+
+WelcomeWizardStepsController.propTypes = {
+ params: React.PropTypes.shape({
+ step: React.PropTypes.string.isRequired,
+ }).isRequired,
+ router: React.PropTypes.shape({
+ push: React.PropTypes.func.isRequired,
+ }).isRequired,
+};
+
+module.exports = WelcomeWizardStepsController;
diff --git a/assets/js/src/welcome_wizard/wizard.jsx b/assets/js/src/welcome_wizard/wizard.jsx
new file mode 100644
index 0000000000..346f09e321
--- /dev/null
+++ b/assets/js/src/welcome_wizard/wizard.jsx
@@ -0,0 +1,23 @@
+import React from 'react';
+import ReactDOM from 'react-dom';
+import { Router, Route, IndexRedirect, useRouterHistory } from 'react-router';
+import { createHashHistory } from 'history';
+import WelcomeWizardStepsController from './steps_controller.jsx';
+
+const container = document.getElementById('welcome_wizard_container');
+
+if (container) {
+ const history = useRouterHistory(createHashHistory)({ queryKey: false });
+
+ ReactDOM.render((
+
+
+
+
+
+
+ ), container);
+}
diff --git a/webpack.config.js b/webpack.config.js
index 014d550ceb..4a1795077c 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -277,6 +277,7 @@ var adminConfig = {
'settings/reinstall_from_scratch.js',
'subscribers/importExport/import.js',
'subscribers/importExport/export.js',
+ 'welcome_wizard/wizard.jsx'
],
form_editor: [
'form_editor/form_editor.js',