diff --git a/assets/js/src/newsletters/listings/mixins.jsx b/assets/js/src/newsletters/listings/mixins.jsx
index 8930f3f92a..9e7bd7bb64 100644
--- a/assets/js/src/newsletters/listings/mixins.jsx
+++ b/assets/js/src/newsletters/listings/mixins.jsx
@@ -1,247 +1,14 @@
import React from 'react';
import ReactDOM from 'react-dom';
import ReactStringReplace from 'react-string-replace';
-import { Link } from 'react-router-dom';
import MailPoet from 'mailpoet';
-import moment from 'moment';
import jQuery from 'jquery';
-import Hooks from 'wp-js-hooks';
-import StatsBadge from 'newsletters/badges/stats.jsx';
-import HelpTooltip from 'help-tooltip.jsx';
-function trackStatsCTAClicked() {
+export const trackStatsCTAClicked = () => {
MailPoet.trackEvent(
'User has clicked a CTA to view detailed stats',
{ 'MailPoet Free version': window.mailpoet_version }
);
-}
-
-function wrapInLink(content, params, id, totalSent) {
- if (totalSent <= 0 || !params.link) {
- return content;
- }
-
- if (params.externalLink) {
- return (
-
- {content}
-
- );
- }
- return (
-
- {content}
-
- );
-}
-
-const addStatsCTALink = (params) => {
- if (window.mailpoet_premium_active) {
- return params;
- }
- const newParams = params;
- newParams.link = 'admin.php?page=mailpoet-premium';
- newParams.externalLink = true;
- newParams.onClick = trackStatsCTAClicked;
- return newParams;
-};
-
-export const renderStatistics = (newsletter, isSent, currentTime) => {
- let sent = isSent;
- if (sent === undefined) {
- // condition for standard and post notification listings
- sent = newsletter.statistics
- && newsletter.queue
- && newsletter.queue.status !== 'scheduled';
- }
- if (!sent) {
- return (
- {MailPoet.I18n.t('notSentYet')}
- );
- }
-
- let params = {};
- Hooks.addFilter('mailpoet_newsletters_listing_stats_before', 'mailpoet', addStatsCTALink);
- params = Hooks.applyFilters('mailpoet_newsletters_listing_stats_before', params, newsletter);
-
- // welcome emails provide explicit total_sent value
- const totalSent = Number((newsletter.total_sent || newsletter.queue.count_processed));
-
- let percentageClicked = 0;
- let percentageOpened = 0;
- let percentageUnsubscribed = 0;
- let revenue = null;
-
- if (totalSent > 0) {
- percentageClicked = (newsletter.statistics.clicked * 100) / totalSent;
- percentageOpened = (newsletter.statistics.opened * 100) / totalSent;
- percentageUnsubscribed = (newsletter.statistics.unsubscribed * 100) / totalSent;
- revenue = newsletter.statistics.revenue;
- }
-
- // format to 1 decimal place
- const percentageClickedDisplay = MailPoet.Num.toLocaleFixed(percentageClicked, 1);
- const percentageOpenedDisplay = MailPoet.Num.toLocaleFixed(percentageOpened, 1);
- const percentageUnsubscribedDisplay = MailPoet.Num.toLocaleFixed(percentageUnsubscribed, 1);
-
- let showStatsTimeout;
- let newsletterDate;
- let sentHoursAgo;
- let tooEarlyForStats;
- let showKbLink;
- if (currentTime !== undefined) {
- // standard emails and post notifications:
- // display green box for newsletters that were just sent
- showStatsTimeout = 6; // in hours
- newsletterDate = newsletter.queue.scheduled_at || newsletter.queue.created_at;
- sentHoursAgo = moment(currentTime).diff(moment(newsletterDate), 'hours');
- tooEarlyForStats = sentHoursAgo < showStatsTimeout;
- showKbLink = true;
- } else {
- // welcome emails: no green box and KB link
- tooEarlyForStats = false;
- showKbLink = false;
- }
-
- const improveStatsKBLink = 'http://beta.docs.mailpoet.com/article/191-how-to-improve-my-open-and-click-rates';
-
- // thresholds to display badges
- const minNewslettersSent = 20;
- const minNewsletterOpens = 5;
-
- let openedAndClickedStats;
- if (totalSent >= minNewslettersSent
- && newsletter.statistics.opened >= minNewsletterOpens
- && !tooEarlyForStats
- ) {
- // display stats with badges
- openedAndClickedStats = (
-
-
-
- { percentageOpenedDisplay }
- %
- {' '}
-
-
-
-
-
- { percentageClickedDisplay }
- %
- {' '}
-
-
-
-
-
- { percentageUnsubscribedDisplay }
- %
-
-
-
- );
- } else {
- // display simple stats
- openedAndClickedStats = (
-
-
- { percentageOpenedDisplay }
- %,
- { ' ' }
- { percentageClickedDisplay }
- %
-
- ,
- {' '}
- { percentageUnsubscribedDisplay }
- %
-
-
-
- );
- }
-
- const wrapContentInLink = (content, idPrefix) => wrapInLink(
- content,
- params,
- `${idPrefix}-${newsletter.id}`,
- totalSent
- );
-
- const content = (
- <>
- { wrapContentInLink(openedAndClickedStats, 'opened-and-clicked') }
- { revenue !== null && revenue.value > 0 && (
-
- { wrapContentInLink(revenue.formatted, 'revenue') }
- {' '}
-
-
- ) }
- { tooEarlyForStats && wrapContentInLink(
- (
-
- {MailPoet.I18n.t('checkBackInHours').replace('%$1d', showStatsTimeout - sentHoursAgo)}
-
- ),
- 'check-back'
- ) }
- >
- );
-
- // thresholds to display bad open rate help
- const maxPercentageOpened = 5;
- const minSentHoursAgo = 24;
- const minTotalSent = 10;
-
- let afterContent;
- if (showKbLink
- && percentageOpened < maxPercentageOpened
- && sentHoursAgo >= minSentHoursAgo
- && totalSent >= minTotalSent
- ) {
- // help link for bad open rate
- afterContent = (
-
- );
- }
-
- return (
-
- {content}
- {afterContent}
-
- );
};
export const addStatsCTAAction = (actions) => {
diff --git a/assets/js/src/newsletters/listings/notification_history.jsx b/assets/js/src/newsletters/listings/notification_history.jsx
index c1c1982ce9..ccc53f623c 100644
--- a/assets/js/src/newsletters/listings/notification_history.jsx
+++ b/assets/js/src/newsletters/listings/notification_history.jsx
@@ -12,8 +12,8 @@ import ListingHeading from 'newsletters/listings/heading.jsx';
import FeatureAnnouncement from 'announcements/feature_announcement.jsx';
import QueueStatus from 'newsletters/listings/queue_status.jsx';
+import Statistics from 'newsletters/listings/statistics.jsx';
import {
- renderStatistics,
addStatsCTAAction,
checkCronStatus,
checkMailerStatus,
@@ -102,7 +102,7 @@ const NewsletterListNotificationHistory = createReactClass({ // eslint-disable-l
{ (mailpoetTrackingEnabled === true) ? (
- { renderStatistics(newsletter, undefined, meta.current_time) }
+
|
) : null }
diff --git a/assets/js/src/newsletters/listings/standard.jsx b/assets/js/src/newsletters/listings/standard.jsx
index f1f14a3c21..e73a55abbf 100644
--- a/assets/js/src/newsletters/listings/standard.jsx
+++ b/assets/js/src/newsletters/listings/standard.jsx
@@ -11,8 +11,8 @@ import ListingTabs from 'newsletters/listings/tabs.jsx';
import ListingHeading from 'newsletters/listings/heading.jsx';
import FeatureAnnouncement from 'announcements/feature_announcement.jsx';
import QueueStatus from 'newsletters/listings/queue_status.jsx';
+import Statistics from 'newsletters/listings/statistics.jsx';
import {
- renderStatistics,
addStatsCTAAction,
checkCronStatus,
checkMailerStatus,
@@ -213,7 +213,7 @@ const NewsletterListStandard = createReactClass({ // eslint-disable-line react/p
|
{ (mailpoetTrackingEnabled === true) ? (
- { renderStatistics(newsletter, undefined, meta.current_time) }
+
|
) : null }
diff --git a/assets/js/src/newsletters/listings/statistics.jsx b/assets/js/src/newsletters/listings/statistics.jsx
new file mode 100644
index 0000000000..55af075982
--- /dev/null
+++ b/assets/js/src/newsletters/listings/statistics.jsx
@@ -0,0 +1,264 @@
+import React from 'react';
+import moment from 'moment';
+import MailPoet from 'mailpoet';
+import Hooks from 'wp-js-hooks';
+import PropTypes from 'prop-types';
+import { Link } from 'react-router-dom';
+import HelpTooltip from 'help-tooltip.jsx';
+import StatsBadge from 'newsletters/badges/stats.jsx';
+import { trackStatsCTAClicked } from 'newsletters/listings/mixins.jsx';
+
+const wrapInLink = (content, params, id, totalSent) => {
+ if (totalSent <= 0 || !params.link) {
+ return content;
+ }
+
+ if (params.externalLink) {
+ return (
+
+ {content}
+
+ );
+ }
+ return (
+
+ {content}
+
+ );
+};
+
+const addStatsCTALink = (params) => {
+ if (window.mailpoet_premium_active) {
+ return params;
+ }
+ const newParams = params;
+ newParams.link = 'admin.php?page=mailpoet-premium';
+ newParams.externalLink = true;
+ newParams.onClick = trackStatsCTAClicked;
+ return newParams;
+};
+
+const Statistics = ({ newsletter, isSent, currentTime }) => {
+ let sent = isSent;
+ if (sent === undefined) {
+ // condition for standard and post notification listings
+ sent = newsletter.statistics
+ && newsletter.queue
+ && newsletter.queue.status !== 'scheduled';
+ }
+ if (!sent) {
+ return (
+ {MailPoet.I18n.t('notSentYet')}
+ );
+ }
+
+ let params = {};
+ Hooks.addFilter('mailpoet_newsletters_listing_stats_before', 'mailpoet', addStatsCTALink);
+ params = Hooks.applyFilters('mailpoet_newsletters_listing_stats_before', params, newsletter);
+
+ // welcome emails provide explicit total_sent value
+ const totalSent = Number((newsletter.total_sent || newsletter.queue.count_processed));
+
+ let percentageClicked = 0;
+ let percentageOpened = 0;
+ let percentageUnsubscribed = 0;
+ let revenue = null;
+
+ if (totalSent > 0) {
+ percentageClicked = (newsletter.statistics.clicked * 100) / totalSent;
+ percentageOpened = (newsletter.statistics.opened * 100) / totalSent;
+ percentageUnsubscribed = (newsletter.statistics.unsubscribed * 100) / totalSent;
+ revenue = newsletter.statistics.revenue;
+ }
+
+ // format to 1 decimal place
+ const percentageClickedDisplay = MailPoet.Num.toLocaleFixed(percentageClicked, 1);
+ const percentageOpenedDisplay = MailPoet.Num.toLocaleFixed(percentageOpened, 1);
+ const percentageUnsubscribedDisplay = MailPoet.Num.toLocaleFixed(percentageUnsubscribed, 1);
+
+ let showStatsTimeout;
+ let newsletterDate;
+ let sentHoursAgo;
+ let tooEarlyForStats;
+ let showKbLink;
+ if (currentTime !== undefined) {
+ // standard emails and post notifications:
+ // display green box for newsletters that were just sent
+ showStatsTimeout = 6; // in hours
+ newsletterDate = newsletter.queue.scheduled_at || newsletter.queue.created_at;
+ sentHoursAgo = moment(currentTime).diff(moment(newsletterDate), 'hours');
+ tooEarlyForStats = sentHoursAgo < showStatsTimeout;
+ showKbLink = true;
+ } else {
+ // welcome emails: no green box and KB link
+ tooEarlyForStats = false;
+ showKbLink = false;
+ }
+
+ const improveStatsKBLink = 'http://beta.docs.mailpoet.com/article/191-how-to-improve-my-open-and-click-rates';
+
+ // thresholds to display badges
+ const minNewslettersSent = 20;
+ const minNewsletterOpens = 5;
+
+ let openedAndClickedStats;
+ if (totalSent >= minNewslettersSent
+ && newsletter.statistics.opened >= minNewsletterOpens
+ && !tooEarlyForStats
+ ) {
+ // display stats with badges
+ openedAndClickedStats = (
+
+
+
+ {percentageOpenedDisplay}
+ %
+ {' '}
+
+
+
+
+
+ {percentageClickedDisplay}
+ %
+ {' '}
+
+
+
+
+
+ {percentageUnsubscribedDisplay}
+ %
+
+
+
+ );
+ } else {
+ // display simple stats
+ openedAndClickedStats = (
+
+
+ {percentageOpenedDisplay}
+ %,
+ {' '}
+ {percentageClickedDisplay}
+ %
+
+ ,
+ {' '}
+ {percentageUnsubscribedDisplay}
+ %
+
+
+
+ );
+ }
+
+ const wrapContentInLink = (content, idPrefix) => wrapInLink(
+ content,
+ params,
+ `${idPrefix}-${newsletter.id}`,
+ totalSent
+ );
+
+ const content = (
+ <>
+ {wrapContentInLink(openedAndClickedStats, 'opened-and-clicked')}
+ {revenue !== null && revenue.value > 0 && (
+
+ {wrapContentInLink(revenue.formatted, 'revenue')}
+ {' '}
+
+
+ )}
+ {tooEarlyForStats && wrapContentInLink(
+ (
+
+ {MailPoet.I18n.t('checkBackInHours').replace('%$1d', showStatsTimeout - sentHoursAgo)}
+
+ ),
+ 'check-back'
+ )}
+ >
+ );
+
+ // thresholds to display bad open rate help
+ const maxPercentageOpened = 5;
+ const minSentHoursAgo = 24;
+ const minTotalSent = 10;
+
+ let afterContent;
+ if (showKbLink
+ && percentageOpened < maxPercentageOpened
+ && sentHoursAgo >= minSentHoursAgo
+ && totalSent >= minTotalSent
+ ) {
+ // help link for bad open rate
+ afterContent = (
+
+ );
+ }
+
+ return (
+
+ {content}
+ {afterContent}
+
+ );
+};
+Statistics.propTypes = {
+ newsletter: PropTypes.shape({
+ id: PropTypes.number.isRequired,
+ queue: PropTypes.shape({
+ status: PropTypes.string,
+ count_processed: PropTypes.number.isRequired,
+ count_total: PropTypes.number.isRequired,
+ created_at: PropTypes.instanceOf(Date),
+ scheduled_at: PropTypes.instanceOf(Date),
+ }),
+ total_sent: PropTypes.number,
+ statistics: PropTypes.shape({
+ clicked: PropTypes.number,
+ opened: PropTypes.number,
+ unsubscribed: PropTypes.number,
+ revenue: PropTypes.number,
+ }),
+ }).isRequired,
+ isSent: PropTypes.bool,
+ currentTime: PropTypes.instanceOf(Date),
+};
+Statistics.defaultProps = {
+ isSent: undefined,
+ currentTime: undefined,
+};
+
+export default Statistics;
diff --git a/assets/js/src/newsletters/listings/welcome.jsx b/assets/js/src/newsletters/listings/welcome.jsx
index 5aea970eac..f3274eb95e 100644
--- a/assets/js/src/newsletters/listings/welcome.jsx
+++ b/assets/js/src/newsletters/listings/welcome.jsx
@@ -8,8 +8,8 @@ import ListingTabs from 'newsletters/listings/tabs.jsx';
import ListingHeading from 'newsletters/listings/heading.jsx';
import FeatureAnnouncement from 'announcements/feature_announcement.jsx';
+import Statistics from 'newsletters/listings/statistics.jsx';
import {
- renderStatistics,
addStatsCTAAction,
checkCronStatus,
checkMailerStatus,
@@ -332,10 +332,10 @@ const NewsletterListWelcome = createReactClass({ // eslint-disable-line react/pr
|
{ (mailpoetTrackingEnabled === true) ? (
- { renderStatistics(
- newsletter,
- newsletter.total_sent > 0 && newsletter.statistics
- ) }
+ 0 && newsletter.statistics}
+ />
|
) : null }
|