Add a green box in stats for recently sent newsletters, add help KB link [MAILPOET-877]

This commit is contained in:
Alexey Stoletniy
2017-04-18 15:30:55 +03:00
parent e9070de9c4
commit 95ff83557f
7 changed files with 83 additions and 22 deletions

View File

@ -1,6 +1,7 @@
$excellent-badge-color = #2993ab
$good-badge-color = #f0b849
$bad-badge-color = #d54e21
$green-badge-color = #55bd56
$grey-stat-color = #707070
#newsletters_container
@ -39,6 +40,10 @@ $grey-stat-color = #707070
&_hidden
display: none
&_link_small
text-decoration: underline !important
font-size: 0.75rem
.mailpoet_badge
padding: 4px 6px 3px 6px
color: #FFFFFF
@ -57,3 +62,6 @@ $grey-stat-color = #707070
&_bad
background: $bad-badge-color
&_green
background: $green-badge-color

View File

@ -10,7 +10,7 @@ class Badge extends React.Component {
this.props.size ? `mailpoet_badge_size_${this.props.size}` : ''
);
const tooltip = this.props.tooltip.replace(/\n/g, '<br />') || false;
const tooltip = this.props.tooltip ? this.props.tooltip.replace(/\n/g, '<br />') : false;
// tooltip ID must be unique, defaults to tooltip text
const tooltipId = this.props.tooltipId || tooltip;

View File

@ -4,6 +4,7 @@ import ReactStringReplace from 'react-string-replace'
import { Link } from 'react-router'
import MailPoet from 'mailpoet'
import classNames from 'classnames'
import moment from 'moment'
import jQuery from 'jquery'
import Hooks from 'wp-js-hooks'
import StatsBadge from 'newsletters/badges/stats.jsx'
@ -143,14 +144,14 @@ const _QueueMixin = {
};
const _StatisticsMixin = {
renderStatistics: function(newsletter, sentCondition) {
if (sentCondition === undefined) {
renderStatistics: function(newsletter, sent_condition, current_time) {
if (sent_condition === undefined) {
// condition for standard and post notification listings
sentCondition = newsletter.statistics
sent_condition = newsletter.statistics
&& newsletter.queue
&& newsletter.queue.status !== 'scheduled'
}
if (!sentCondition) {
if (!sent_condition) {
return (
<span>{MailPoet.I18n.t('notSentYet')}</span>
);
@ -177,8 +178,19 @@ const _StatisticsMixin = {
const percentage_opened_display = MailPoet.Num.toLocaleFixed(percentage_opened, 1);
const percentage_unsubscribed_display = MailPoet.Num.toLocaleFixed(percentage_unsubscribed, 1);
// green box for newsletters that were just sent
const show_stats_timeout = 6; // in hours
const newsletter_date = newsletter.queue.scheduled_at || newsletter.queue.created_at;
const sent_hours_ago = moment(current_time).diff(moment(newsletter_date), 'hours');
const too_early_for_stats = sent_hours_ago < show_stats_timeout;
const improveStatsKBLink = 'http://beta.docs.mailpoet.com/article/190-whats-a-good-email-open-rate';
let content;
if (total_sent >= 20 && newsletter.statistics.opened >= 5) {
if (total_sent >= 20
&& newsletter.statistics.opened >= 5
&& !too_early_for_stats
) {
// display stats with badges
content = (
<div className="mailpoet_stats_text">
@ -206,27 +218,65 @@ const _StatisticsMixin = {
} else {
// display simple stats
content = (
<span className="mailpoet_stats_text">
{ percentage_opened_display }%,
{ " " }
{ percentage_clicked_display }%
<span className="mailpoet_stat_hidden">
, { percentage_unsubscribed_display }%
<div>
<span className="mailpoet_stats_text">
{ percentage_opened_display }%,
{ " " }
{ percentage_clicked_display }%
<span className="mailpoet_stat_hidden">
, { percentage_unsubscribed_display }%
</span>
</span>
</span>
{ too_early_for_stats && (
<div className="mailpoet_badge mailpoet_badge_green">
{MailPoet.I18n.t('checkBackInHours')
.replace('%$1d', show_stats_timeout - sent_hours_ago)}
</div>
) }
</div>
);
}
if (total_sent > 0 && params.link) {
let after_content;
if (percentage_opened < 5
&& sent_hours_ago >= 24
&& total_sent >= 10
) {
// help link for bad open rate
after_content = (
<div>
<a
href={improveStatsKBLink}
target="_blank"
className="mailpoet_stat_link_small"
>
{MailPoet.I18n.t('improveThisLinkText')}
</a>
</div>
)
}
if (total_sent > 0 && !too_early_for_stats && params.link) {
// wrap content in a link
return (
<Link
key={ `stats-${newsletter.id}` }
to={ params.link }
>{ content }</Link>
<div>
<Link
key={ `stats-${newsletter.id}` }
to={ params.link }
>
{content}
</Link>
{after_content}
</div>
);
}
return content;
return (
<div>
{content}
{after_content}
</div>
);
}
}

View File

@ -87,7 +87,7 @@ const NewsletterListNotificationHistory = React.createClass({
</td>
{ (mailpoet_tracking_enabled === true) ? (
<td className="column" data-colname={ MailPoet.I18n.t('statistics') }>
{ this.renderStatistics(newsletter) }
{ this.renderStatistics(newsletter, undefined, meta.current_time) }
</td>
) : null }
<td className="column-date" data-colname={ MailPoet.I18n.t('lastModifiedOn') }>

View File

@ -184,7 +184,7 @@ const NewsletterListStandard = React.createClass({
</td>
{ (mailpoet_tracking_enabled === true) ? (
<td className="column" data-colname={ MailPoet.I18n.t('statistics') }>
{ this.renderStatistics(newsletter) }
{ this.renderStatistics(newsletter, undefined, meta.current_time) }
</td>
) : null }
<td className="column-date" data-colname={ MailPoet.I18n.t('lastModifiedOn') }>

View File

@ -372,7 +372,8 @@ class Newsletters extends APIEndpoint {
'filters' => $listing_data['filters'],
'groups' => $listing_data['groups'],
'mta_log' => Setting::getValue('mta_log'),
'mta_method' => Setting::getValue('mta.method')
'mta_method' => Setting::getValue('mta.method'),
'current_time' => current_time('mysql')
));
}

View File

@ -99,6 +99,8 @@
'openedStatTooltip': __('Above 30% is excellent.\\nBetween 15 and 30% is good.\\nUnder 15% is bad.'),
'clickedStatTooltip': __('Above 3% is excellent.\\nBetween 1 and 3% is good.\\nUnder 1% is bad.'),
'unsubscribedStatTooltip': __('Under 1% is excellent.\\nBetween 1 and 3% is good.\\nOver 3% is bad.'),
'checkBackInHours': __('Nice job! Check back in %$1d hour(s) for more stats.'),
'improveThisLinkText': __('What can I do to improve this?'),
'templateFileMalformedError': __('This template file appears to be damaged. Please try another one.'),
'importTemplateTitle': __('Import a template'),