' +
'
' +
'
' +
'
' +
diff --git a/assets/js/src/newsletters/newsletters.jsx b/assets/js/src/newsletters/newsletters.jsx
index 32fad98194..0463cceb51 100644
--- a/assets/js/src/newsletters/newsletters.jsx
+++ b/assets/js/src/newsletters/newsletters.jsx
@@ -1,6 +1,6 @@
import React from 'react';
import ReactDOM from 'react-dom';
-import { Router, Route, IndexRedirect, useRouterHistory } from 'react-router';
+import { IndexRedirect, Route, Router, useRouterHistory } from 'react-router';
import { createHashHistory } from 'history';
import Hooks from 'wp-js-hooks';
import _ from 'underscore';
@@ -9,6 +9,7 @@ import PropTypes from 'prop-types';
import NewsletterTypes from 'newsletters/types.jsx';
import NewsletterTemplates from 'newsletters/templates.jsx';
import NewsletterSend from 'newsletters/send.jsx';
+import NewsletterCongratulate from 'newsletters/send/congratulate/congratulate.jsx';
import NewsletterTypeStandard from 'newsletters/types/standard.jsx';
import NewsletterTypeNotification from 'newsletters/types/notification/notification.jsx';
import NewsletterTypeWelcome from 'newsletters/types/welcome/welcome.jsx';
@@ -89,6 +90,11 @@ if (container) {
path: 'template/:id',
component: NewsletterTemplates,
},
+ /* congratulate */
+ {
+ path: 'send/congratulate/:id',
+ component: NewsletterCongratulate,
+ },
/* Sending options */
{
path: 'send/:id',
@@ -98,7 +104,7 @@ if (container) {
routes = Hooks.applyFilters('mailpoet_newsletters_before_router', [...routes, ...getAutomaticEmailsRoutes()]);
- const mailpoetListing = ReactDOM.render(( // eslint-disable-line react/no-render-return-value
+ window.mailpoet_listing = ReactDOM.render(( // eslint-disable-line react/no-render-return-value
@@ -115,6 +121,4 @@ if (container) {
), container);
-
- window.mailpoet_listing = mailpoetListing;
}
diff --git a/assets/js/src/newsletters/send.jsx b/assets/js/src/newsletters/send.jsx
index 81f873fc53..d0e242d21b 100644
--- a/assets/js/src/newsletters/send.jsx
+++ b/assets/js/src/newsletters/send.jsx
@@ -162,6 +162,11 @@ const NewsletterSend = createReactClass({ // eslint-disable-line react/prefer-es
).done((response) => {
// save template in recently sent category
this.saveTemplate(newsletter, () => {
+ if (window.mailpoet_show_congratulate_after_first_newsletter) {
+ MailPoet.Modal.loading(false);
+ this.context.router.push(`/send/congratulate/${this.state.item.id}`);
+ return;
+ }
// redirect to listing based on newsletter type
this.context.router.push(Hooks.applyFilters('mailpoet_newsletters_send_server_request_response_redirect', `/${this.state.item.type || ''}`, this.state.item));
const customResponse = Hooks.applyFilters('mailpoet_newsletters_send_server_request_response', this.state.item, response);
@@ -205,6 +210,11 @@ const NewsletterSend = createReactClass({ // eslint-disable-line react/prefer-es
}).done((response) => {
// save template in recently sent category
this.saveTemplate(newsletter, () => {
+ if (window.mailpoet_show_congratulate_after_first_newsletter) {
+ MailPoet.Modal.loading(false);
+ this.context.router.push(`/send/congratulate/${this.state.item.id}`);
+ return;
+ }
// redirect to listing based on newsletter type
this.context.router.push(`/${this.state.item.type || ''}`);
const opts = this.state.item.options;
diff --git a/assets/js/src/newsletters/send/congratulate/congratulate.jsx b/assets/js/src/newsletters/send/congratulate/congratulate.jsx
new file mode 100644
index 0000000000..7dca4aaa0d
--- /dev/null
+++ b/assets/js/src/newsletters/send/congratulate/congratulate.jsx
@@ -0,0 +1,136 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import MailPoet from 'mailpoet';
+import moment from 'moment';
+
+import Success from './success.jsx';
+import Fail from './fail.jsx';
+import Loading from './loading.jsx';
+
+const SECONDS_WAITING_FOR_SUCCESS = 20;
+const SECONDS_MINIMUIM_LOADING_SCREEN_DISPLAYED = 6;
+
+function successPageClosed() {
+ return MailPoet.Ajax.post({
+ api_version: window.mailpoet_api_version,
+ endpoint: 'settings',
+ action: 'set',
+ data: { show_congratulate_after_first_newsletter: false },
+ }).always(() => {
+ window.location = window.mailpoet_main_page;
+ });
+}
+
+function renderSuccess(newsletter, testingPassed) {
+ if (testingPassed) {
+ MailPoet.trackEvent('Cron testing done', {
+ 'Cron is working': 'true',
+ });
+ }
+ return (
);
+}
+
+function renderFail() {
+ MailPoet.trackEvent('Cron testing done', {
+ 'Cron is working': 'false',
+ });
+ return (
{
+ window.location = window.mailpoet_main_page;
+ }}
+ />);
+}
+
+function renderLoading(showRichLoadingScreen) {
+ return ();
+}
+
+class Congratulate extends React.Component {
+ constructor(props) {
+ super(props);
+ this.state = {
+ loading: true,
+ fail: false,
+ newsletter: null,
+ testingPassed: false,
+ timeStart: moment(),
+ minimumLoadingTimePassed: false,
+ };
+ this.tick = this.tick.bind(this);
+ }
+
+ componentDidMount() {
+ this.loadNewsletter(this.props.params.id);
+ this.tick();
+ }
+
+ componentWillReceiveProps(props) {
+ this.loadNewsletter(props.params.id);
+ }
+
+ tick() {
+ if (moment().subtract(SECONDS_WAITING_FOR_SUCCESS, 'second').isAfter(this.state.timeStart)) {
+ this.setState({ error: true, loading: false });
+ }
+ if (this.state.loading) {
+ this.loadNewsletter(this.props.params.id);
+ }
+ if (moment().subtract(SECONDS_MINIMUIM_LOADING_SCREEN_DISPLAYED, 'seconds').isAfter(this.state.timeStart)) {
+ this.setState({ minimumLoadingTimePassed: true });
+ }
+ if (this.state.loading || !this.state.minimumLoadingTimePassed) {
+ setTimeout(this.tick, 2000);
+ }
+ }
+
+ loadNewsletter(id) {
+ MailPoet.Ajax.post({
+ api_version: window.mailpoet_api_version,
+ endpoint: 'newsletters',
+ action: 'get',
+ data: {
+ id,
+ },
+ })
+ .done(response => this.newsletterLoaded(response.data));
+ }
+
+ newsletterLoaded(newsletter) {
+ if ((newsletter.type !== 'standard') || (newsletter.status === 'scheduled')) {
+ this.setState({ newsletter, loading: false, minimumLoadingTimePassed: true });
+ } else if ((newsletter.status === 'sent') || (newsletter.status === 'sending')) {
+ this.setState({ newsletter, loading: false, testingPassed: true });
+ } else {
+ this.setState({ newsletter });
+ }
+ }
+
+ renderContent() {
+ if (this.state.loading || !this.state.minimumLoadingTimePassed) {
+ return renderLoading(!!this.state.newsletter);
+ } else if (this.state.error) {
+ return renderFail();
+ }
+ return renderSuccess(this.state.newsletter, this.state.testingPassed);
+ }
+
+ render() {
+ return ({this.renderContent()}
);
+ }
+}
+
+Congratulate.propTypes = {
+ params: PropTypes.shape({
+ id: PropTypes.string.isRequired,
+ }).isRequired,
+};
+
+module.exports = Congratulate;
diff --git a/assets/js/src/newsletters/send/congratulate/fail.jsx b/assets/js/src/newsletters/send/congratulate/fail.jsx
new file mode 100644
index 0000000000..f919caa957
--- /dev/null
+++ b/assets/js/src/newsletters/send/congratulate/fail.jsx
@@ -0,0 +1,34 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import ReactStringReplace from 'react-string-replace';
+import MailPoet from '../../../mailpoet';
+
+function Fail(props) {
+ return (
+
+
{MailPoet.I18n.t('congratulationsSendFailHeader')}
+
+ { ReactStringReplace(
+ MailPoet.I18n.t('congratulationsSendFailExplain'),
+ /\[link\](.*?)\[\/link\]/g,
+ (match, i) => (
+ { match }
+ )
+ )
+ }
+
+
+
+ );
+}
+
+Fail.propTypes = {
+ failClicked: PropTypes.func.isRequired,
+};
+
+module.exports = Fail;
diff --git a/assets/js/src/newsletters/send/congratulate/loading.jsx b/assets/js/src/newsletters/send/congratulate/loading.jsx
new file mode 100644
index 0000000000..908f3a4d9c
--- /dev/null
+++ b/assets/js/src/newsletters/send/congratulate/loading.jsx
@@ -0,0 +1,32 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import MailPoet from '../../../mailpoet';
+import LoadingDots from '../../../loading.jsx';
+
+function renderRichData(showRichData, illustrationImageUrl) {
+ if (showRichData) {
+ return (
+
+
{MailPoet.I18n.t('congratulationsLoadingHeader')}
+

+
+ );
+ }
+ return ();
+}
+
+function Loading(props) {
+ return (
+
+
+ {renderRichData(props.showRichLoadingScreen, props.illustrationImageUrl)}
+
+ );
+}
+
+Loading.propTypes = {
+ illustrationImageUrl: PropTypes.string.isRequired,
+ showRichLoadingScreen: PropTypes.bool.isRequired,
+};
+
+module.exports = Loading;
diff --git a/assets/js/src/newsletters/send/congratulate/success.jsx b/assets/js/src/newsletters/send/congratulate/success.jsx
new file mode 100644
index 0000000000..aa560c4251
--- /dev/null
+++ b/assets/js/src/newsletters/send/congratulate/success.jsx
@@ -0,0 +1,38 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import MailPoet from '../../../mailpoet';
+
+function renderHeader(newsletter) {
+ if (newsletter.type === 'welcome') {
+ return MailPoet.I18n.t('congratulationsWelcomeEmailSuccessHeader');
+ } else if (newsletter.type === 'notification') {
+ return MailPoet.I18n.t('congratulationsPostNotificationSuccessHeader');
+ } else if (newsletter.type === 'automatic') {
+ return MailPoet.I18n.t('congratulationsWooSuccessHeader');
+ } else if (newsletter.status === 'scheduled') {
+ return MailPoet.I18n.t('congratulationsScheduleSuccessHeader');
+ }
+ return MailPoet.I18n.t('congratulationsSendSuccessHeader');
+}
+
+function Success(props) {
+ return (
+
+
{renderHeader(props.newsletter)}
+

+
+
+ );
+}
+
+Success.propTypes = {
+ successClicked: PropTypes.func.isRequired,
+ illustrationImageUrl: PropTypes.string.isRequired,
+ newsletter: PropTypes.shape({
+ status: PropTypes.string.isRequired,
+ type: PropTypes.string.isRequired,
+ }).isRequired,
+};
+
+
+module.exports = Success;
diff --git a/lib/Config/Changelog.php b/lib/Config/Changelog.php
index 4c3da9d25e..4fab1d432c 100644
--- a/lib/Config/Changelog.php
+++ b/lib/Config/Changelog.php
@@ -53,6 +53,7 @@ class Changelog {
Setting::setValue('show_intro', true);
}
}
+ Setting::setValue('show_congratulate_after_first_newsletter', true);
}
}
diff --git a/lib/Config/Menu.php b/lib/Config/Menu.php
index ac6934a01f..0c7bd45492 100644
--- a/lib/Config/Menu.php
+++ b/lib/Config/Menu.php
@@ -575,6 +575,8 @@ class Menu {
'+1 hour',
24
);
+ $data['mailpoet_main_page'] = admin_url('admin.php?page=' . self::MAIN_PAGE_SLUG);
+ $data['show_congratulate_after_first_newsletter'] = isset($data['settings']['show_congratulate_after_first_newsletter'])?$data['settings']['show_congratulate_after_first_newsletter']:'false';
$data['tracking_enabled'] = Setting::getValue('tracking.enabled');
$data['premium_plugin_active'] = License::getLicense();
diff --git a/views/newsletters.html b/views/newsletters.html
index 130df81fb2..e25c2258e8 100644
--- a/views/newsletters.html
+++ b/views/newsletters.html
@@ -9,6 +9,7 @@
var mailpoet_listing_per_page = <%= items_per_page %>;
var mailpoet_segments = <%= json_encode(segments) %>;
var mailpoet_settings = <%= json_encode(settings) %>;
+ var mailpoet_show_congratulate_after_first_newsletter = <%= show_congratulate_after_first_newsletter %>;
var mailpoet_installed_at_isoFormat = "<%= settings['installed_at'] | date('c') %>";
var mailpoet_current_wp_user = <%= json_encode(current_wp_user) %>;
var mailpoet_lists = <%= json_encode(lists) %>;
@@ -24,6 +25,9 @@
var mailpoet_automatic_emails = <%= json_encode(automatic_emails) %>;
var mailpoet_in_app_announcements = mailpoet_settings.in_app_announcements;
var mailpoet_free_welcome_emails_image = '<%= image_url('in_app_announcements/hello-illustration-for-welcome-emails.png') %>';
+ var mailpoet_congratulations_success_image = '<%= image_url('newsletter/congrat-illu-success.png') %>';
+ var mailpoet_congratulations_loading_image = '<%= image_url('newsletter/congratulation-page-illustration-transparent-LQ.png') %>';
+ var mailpoet_main_page = '<%= mailpoet_main_page %>';
<% set newUser = (is_new_user == true) ? 'true' : 'false' %>
var mailpoet_is_new_user = <%= newUser %>;
@@ -308,6 +312,15 @@
'freeWelcomeEmailsHeading': __('Welcome Emails are now free for everyone'),
'freeWelcomeEmailsParagraph': __('Say “Hello!” automatically to all your new subscribers. They’ll appreciate the extra touch.'),
+
+ 'congratulationsSendSuccessHeader': __('Congratulations, your newsletter is being sent!'),
+ 'congratulationsScheduleSuccessHeader': __('Congratulations, your newsletter is scheduled to be sent.'),
+ 'congratulationsWooSuccessHeader': __('Congratulations, your WooCommerce email has been activated.'),
+ 'congratulationsPostNotificationSuccessHeader': __('Congratulations, your Post Notification is now active.'),
+ 'congratulationsWelcomeEmailSuccessHeader': __('Congratulations, your Welcome Email is now active.'),
+ 'congratulationsSendFailHeader': __('Oops! We can’t send your newsletter 😕'),
+ 'congratulationsSendFailExplain': __('Rest assured, this is fairly common and is usually fixed quickly. [link]See our quick guide[/link] to help you solve this and get your website sending.'),
+ 'congratulationsLoadingHeader': __('Congrats, you’re sending your first newsletter! We’re doing a quick verification to make sure everything works fine.'),
}) %>
<% endblock %>