forked from MichaelYick/mailpoet
Remove old files
[MAILPOET-2791]
This commit is contained in:
parent
f9a3da175d
commit
3128b24070
@ -1,50 +0,0 @@
|
||||
import React from 'react';
|
||||
import classNames from 'classnames';
|
||||
import ReactTooltip from 'react-tooltip';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
function Badge(props) {
|
||||
const badgeClasses = classNames(
|
||||
'mailpoet_badge',
|
||||
props.type ? `mailpoet_badge_${props.type}` : ''
|
||||
);
|
||||
|
||||
const tooltip = props.tooltip ? props.tooltip.replace(/\n/g, '<br />') : false;
|
||||
// tooltip ID must be unique, defaults to tooltip text
|
||||
const tooltipId = props.tooltipId || tooltip;
|
||||
|
||||
return (
|
||||
<span>
|
||||
<span
|
||||
className={badgeClasses}
|
||||
data-tip={tooltip}
|
||||
data-for={tooltipId}
|
||||
>
|
||||
{props.name}
|
||||
</span>
|
||||
{ tooltip && (
|
||||
<ReactTooltip
|
||||
place="right"
|
||||
multiline
|
||||
id={tooltipId}
|
||||
/>
|
||||
) }
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
Badge.propTypes = {
|
||||
name: PropTypes.string.isRequired,
|
||||
tooltip: PropTypes.string,
|
||||
tooltipId: PropTypes.string,
|
||||
type: PropTypes.string,
|
||||
};
|
||||
|
||||
Badge.defaultProps = {
|
||||
type: undefined,
|
||||
tooltipId: undefined,
|
||||
tooltip: undefined,
|
||||
};
|
||||
|
||||
|
||||
export default Badge;
|
@ -1,121 +0,0 @@
|
||||
import MailPoet from 'mailpoet';
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import Badge from './badge.jsx';
|
||||
|
||||
const badges = {
|
||||
excellent: {
|
||||
name: MailPoet.I18n.t('excellentBadgeName'),
|
||||
tooltipTitle: MailPoet.I18n.t('excellentBadgeTooltip'),
|
||||
},
|
||||
good: {
|
||||
name: MailPoet.I18n.t('goodBadgeName'),
|
||||
tooltipTitle: MailPoet.I18n.t('goodBadgeTooltip'),
|
||||
},
|
||||
bad: {
|
||||
name: MailPoet.I18n.t('badBadgeName'),
|
||||
tooltipTitle: MailPoet.I18n.t('badBadgeTooltip'),
|
||||
},
|
||||
};
|
||||
|
||||
const stats = {
|
||||
opened: {
|
||||
badgeRanges: [30, 10, 0],
|
||||
badgeTypes: [
|
||||
'excellent',
|
||||
'good',
|
||||
'bad',
|
||||
],
|
||||
tooltipText: MailPoet.I18n.t('openedStatTooltip'),
|
||||
},
|
||||
clicked: {
|
||||
badgeRanges: [3, 1, 0],
|
||||
badgeTypes: [
|
||||
'excellent',
|
||||
'good',
|
||||
'bad',
|
||||
],
|
||||
tooltipText: MailPoet.I18n.t('clickedStatTooltip'),
|
||||
},
|
||||
unsubscribed: {
|
||||
badgeRanges: [3, 1, 0],
|
||||
badgeTypes: [
|
||||
'bad',
|
||||
'good',
|
||||
'excellent',
|
||||
],
|
||||
tooltipText: MailPoet.I18n.t('unsubscribedStatTooltip'),
|
||||
},
|
||||
};
|
||||
|
||||
class StatsBadge extends React.Component {
|
||||
static getBadgeType(stat, rate) {
|
||||
const len = stat.badgeRanges.length;
|
||||
for (let i = 0; i < len; i += 1) {
|
||||
if (rate > stat.badgeRanges[i]) {
|
||||
return stat.badgeTypes[i];
|
||||
}
|
||||
}
|
||||
// rate must be zero at this point
|
||||
return stat.badgeTypes[len - 1];
|
||||
}
|
||||
|
||||
render() {
|
||||
const stat = stats[this.props.stat] || null;
|
||||
if (!stat) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const rate = this.props.rate;
|
||||
if (rate < 0 || rate > 100) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const badgeType = StatsBadge.getBadgeType(stat, rate);
|
||||
const badge = badges[badgeType] || null;
|
||||
if (!badge) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const tooltipText = `${badge.tooltipTitle}\n\n${stat.tooltipText}`;
|
||||
const tooltipId = this.props.tooltipId || null;
|
||||
|
||||
const content = (
|
||||
<Badge
|
||||
type={badgeType}
|
||||
name={badge.name}
|
||||
tooltip={tooltipText}
|
||||
tooltipId={tooltipId}
|
||||
/>
|
||||
);
|
||||
|
||||
if (this.props.headline) {
|
||||
return (
|
||||
<div>
|
||||
<span className={`mailpoet_stat_${badgeType}`}>
|
||||
{this.props.headline}
|
||||
</span>
|
||||
{' '}
|
||||
{content}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return content;
|
||||
}
|
||||
}
|
||||
|
||||
StatsBadge.propTypes = {
|
||||
stat: PropTypes.string.isRequired,
|
||||
rate: PropTypes.number.isRequired,
|
||||
tooltipId: PropTypes.string,
|
||||
headline: PropTypes.string,
|
||||
};
|
||||
|
||||
StatsBadge.defaultProps = {
|
||||
headline: '',
|
||||
tooltipId: undefined,
|
||||
};
|
||||
|
||||
export default StatsBadge;
|
@ -1,95 +0,0 @@
|
||||
import MailPoet from 'mailpoet';
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import Tags from 'common/tag/tags';
|
||||
|
||||
function formatAddress(address, name) {
|
||||
let addressString = '';
|
||||
if (address) {
|
||||
addressString = (name) ? `${name} <${address}>` : address;
|
||||
}
|
||||
return addressString;
|
||||
}
|
||||
|
||||
function NewsletterStatsInfo(props) {
|
||||
const { newsletter } = props;
|
||||
|
||||
const newsletterDate = newsletter.queue.scheduled_at || newsletter.queue.created_at;
|
||||
|
||||
const senderAddress = formatAddress(
|
||||
newsletter.sender_address || '',
|
||||
newsletter.sender_name || ''
|
||||
);
|
||||
const replyToAddress = formatAddress(
|
||||
newsletter.reply_to_address || '',
|
||||
newsletter.reply_to_name || ''
|
||||
);
|
||||
|
||||
const segments = newsletter.segments || [];
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className="mailpoet_stat_spaced">
|
||||
<a
|
||||
href={newsletter.preview_url}
|
||||
className="button-secondary"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
{MailPoet.I18n.t('statsPreviewNewsletter')}
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
{MailPoet.I18n.t('statsDateSent')}
|
||||
:
|
||||
{' '}
|
||||
{MailPoet.Date.format(newsletterDate)}
|
||||
</div>
|
||||
|
||||
{ segments.length && (
|
||||
<>
|
||||
<div className="mailpoet-gap" />
|
||||
<div>
|
||||
{`${MailPoet.I18n.t('statsToSegments')}: `}
|
||||
<Tags segments={segments} dimension="large" />
|
||||
</div>
|
||||
</>
|
||||
) }
|
||||
|
||||
<div className="mailpoet-gap" />
|
||||
|
||||
<div>
|
||||
{`${MailPoet.I18n.t('statsFromAddress')}: `}
|
||||
{ senderAddress }
|
||||
</div>
|
||||
|
||||
{replyToAddress && (
|
||||
<>
|
||||
<div className="mailpoet-gap" />
|
||||
<div>
|
||||
{`${MailPoet.I18n.t('statsReplyToAddress')}: `}
|
||||
{ replyToAddress }
|
||||
</div>
|
||||
</>
|
||||
) }
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
NewsletterStatsInfo.propTypes = {
|
||||
newsletter: PropTypes.shape({
|
||||
queue: PropTypes.shape({
|
||||
scheduled_at: PropTypes.string,
|
||||
created_at: PropTypes.string,
|
||||
}).isRequired,
|
||||
sender_address: PropTypes.string,
|
||||
sender_name: PropTypes.string,
|
||||
reply_to_address: PropTypes.string,
|
||||
preview_url: PropTypes.string,
|
||||
reply_to_name: PropTypes.string,
|
||||
segments: PropTypes.array,
|
||||
}).isRequired,
|
||||
};
|
||||
|
||||
export default NewsletterStatsInfo;
|
@ -1,124 +0,0 @@
|
||||
import Hooks from 'wp-js-hooks';
|
||||
import MailPoet from 'mailpoet';
|
||||
import React from 'react';
|
||||
import StatsBadge from 'newsletters/badges/stats.jsx';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
const NewsletterGeneralStats = ({ newsletter }) => {
|
||||
const totalSent = newsletter.total_sent || 0;
|
||||
let percentageClicked = 0;
|
||||
let percentageOpened = 0;
|
||||
let percentageUnsubscribed = 0;
|
||||
if (totalSent > 0) {
|
||||
percentageClicked = (newsletter.statistics.clicked * 100) / totalSent;
|
||||
percentageOpened = (newsletter.statistics.opened * 100) / totalSent;
|
||||
percentageUnsubscribed = (newsletter.statistics.unsubscribed * 100) / totalSent;
|
||||
}
|
||||
// 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);
|
||||
const headlineOpened = `${percentageOpenedDisplay}% ${MailPoet.I18n.t('percentageOpened')}`;
|
||||
const headlineClicked = `${percentageClickedDisplay}% ${MailPoet.I18n.t('percentageClicked')}`;
|
||||
const headlineUnsubscribed = `${percentageUnsubscribedDisplay}% ${MailPoet.I18n.t('percentageUnsubscribed')}`;
|
||||
const statsKBLink = 'https://kb.mailpoet.com/article/190-whats-a-good-email-open-rate';
|
||||
// thresholds to display badges
|
||||
const minNewslettersSent = 20;
|
||||
const minNewslettersOpened = 5;
|
||||
let statsContent;
|
||||
if (totalSent >= minNewslettersSent
|
||||
&& newsletter.statistics.opened >= minNewslettersOpened
|
||||
) {
|
||||
// display stats with badges
|
||||
statsContent = (
|
||||
<div className="mailpoet_stat_grey">
|
||||
<div className="mailpoet_stat_big mailpoet_stat_spaced">
|
||||
<StatsBadge
|
||||
stat="opened"
|
||||
rate={percentageOpened}
|
||||
headline={headlineOpened}
|
||||
/>
|
||||
</div>
|
||||
<div className="mailpoet_stat_big mailpoet_stat_spaced">
|
||||
<StatsBadge
|
||||
stat="clicked"
|
||||
rate={percentageClicked}
|
||||
headline={headlineClicked}
|
||||
/>
|
||||
</div>
|
||||
{Hooks.applyFilters('mailpoet_newsletters_revenues_stats', null, newsletter.statistics.revenue)}
|
||||
<div>
|
||||
<StatsBadge
|
||||
stat="unsubscribed"
|
||||
rate={percentageUnsubscribed}
|
||||
headline={headlineUnsubscribed}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
// display stats without badges
|
||||
statsContent = (
|
||||
<div className="mailpoet_stat_grey">
|
||||
<div className="mailpoet_stat_big mailpoet_stat_spaced">
|
||||
{headlineOpened}
|
||||
</div>
|
||||
<div className="mailpoet_stat_big mailpoet_stat_spaced">
|
||||
{headlineClicked}
|
||||
</div>
|
||||
{Hooks.applyFilters('mailpoet_newsletters_revenues_stats', null, newsletter.statistics.revenue)}
|
||||
<div>
|
||||
{headlineUnsubscribed}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<p className="mailpoet_stat_grey mailpoet_stat_big">
|
||||
{MailPoet.I18n.t('statsTotalSent')}
|
||||
{' '}
|
||||
{parseInt(totalSent, 10).toLocaleString()}
|
||||
</p>
|
||||
{statsContent}
|
||||
{ newsletter.ga_campaign && (
|
||||
<p>
|
||||
{MailPoet.I18n.t('googleAnalytics')}
|
||||
{': '}
|
||||
{ newsletter.ga_campaign }
|
||||
</p>
|
||||
) }
|
||||
<p>
|
||||
<a
|
||||
href={statsKBLink}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
data-beacon-article="58f671152c7d3a057f8858e8"
|
||||
>
|
||||
{MailPoet.I18n.t('readMoreOnStats')}
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
NewsletterGeneralStats.propTypes = {
|
||||
newsletter: PropTypes.shape({
|
||||
ga_campaign: PropTypes.string,
|
||||
total_sent: PropTypes.number,
|
||||
statistics: PropTypes.shape({
|
||||
clicked: PropTypes.number,
|
||||
opened: PropTypes.number,
|
||||
unsubscribed: PropTypes.number,
|
||||
revenue: PropTypes.shape({
|
||||
currency: PropTypes.string.isRequired,
|
||||
value: PropTypes.number.isRequired,
|
||||
formatted: PropTypes.string.isRequired,
|
||||
count: PropTypes.number.isRequired,
|
||||
}),
|
||||
}).isRequired,
|
||||
}).isRequired,
|
||||
};
|
||||
|
||||
export default NewsletterGeneralStats;
|
@ -115,13 +115,6 @@ const baseConfig = {
|
||||
'babel-loader'
|
||||
],
|
||||
},
|
||||
{
|
||||
include: path.resolve(__dirname, 'assets/js/src/newsletters/badges/stats.jsx'),
|
||||
use: [
|
||||
'expose-loader?' + globalPrefix + '.StatsBadge',
|
||||
'babel-loader',
|
||||
]
|
||||
},
|
||||
{
|
||||
include: path.resolve(__dirname, 'assets/js/src/help-tooltip.jsx'),
|
||||
use: [
|
||||
@ -203,7 +196,6 @@ const adminConfig = {
|
||||
'help-tooltip.jsx',
|
||||
'listing/listing.jsx',
|
||||
'common/index.ts',
|
||||
'newsletters/badges/stats.jsx',
|
||||
],
|
||||
admin: 'webpack_admin_index.jsx',
|
||||
newsletter_editor: 'newsletter_editor/webpack_index.jsx',
|
||||
|
Loading…
x
Reference in New Issue
Block a user