Add a component for stats

[MAILPOET-2791]
This commit is contained in:
Pavel Dohnal
2020-10-14 08:57:37 +02:00
committed by Veljko V
parent 113192c9dd
commit 52596ce012
3 changed files with 134 additions and 16 deletions

View File

@@ -0,0 +1,109 @@
import React from 'react';
import MailPoet from 'mailpoet';
import Hooks from 'wp-js-hooks';
import Grid from 'common/grid';
import StatsBadge from 'common/listings/newsletter_stats/stats';
import { NewsletterType } from './newsletter_type';
type Props = {
newsletter: NewsletterType
}
const minNewslettersSent = 20;
const minNewslettersOpened = 5;
export const NewsletterGeneralStats = ({
newsletter,
}: Props) => {
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 headlineClicked = `${percentageClickedDisplay}% ${MailPoet.I18n.t('percentageClicked')}`;
const displayBadges = ((totalSent >= minNewslettersSent)
&& (newsletter.statistics.opened >= minNewslettersOpened)
);
const opened = (
<>
<div>{`${percentageOpenedDisplay}% ${MailPoet.I18n.t('percentageOpened')}`}</div>
{displayBadges && (
<StatsBadge
stat="opened"
rate={percentageOpened}
tooltipId={`opened-${newsletter.id || '0'}`}
/>
)}
</>
);
const unsubscribed = (
<>
<div>{`${percentageUnsubscribedDisplay}% ${MailPoet.I18n.t('percentageUnsubscribed')}`}</div>
{displayBadges && (
<StatsBadge
stat="unsubscribed"
rate={percentageUnsubscribed}
tooltipId={`unsubscribed-${newsletter.id || '0'}`}
/>
)}
</>
);
const clicked = (
<>
<div>{`${percentageClickedDisplay}% ${MailPoet.I18n.t('percentageClicked')}`}</div>
{displayBadges && (
<StatsBadge
stat="clicked"
rate={percentageClicked}
tooltipId={`clicked-${newsletter.id || '0'}`}
/>
)}
</>
);
return (
<>
<Grid.ThreeColumns>
<div>
{MailPoet.I18n.t('statsTotalSent')}
{': '}
{totalSent.toLocaleString()}
{opened}
</div>
<div>
{unsubscribed}
{clicked}
</div>
<div>
{Hooks.applyFilters('mailpoet_newsletters_revenues_stats', null, newsletter.statistics.revenue)}
</div>
</Grid.ThreeColumns>
<p>
<a
href="https://kb.mailpoet.com/article/190-whats-a-good-email-open-rate"
target="_blank"
rel="noopener noreferrer"
data-beacon-article="58f671152c7d3a057f8858e8"
>
{MailPoet.I18n.t('readMoreOnStats')}
</a>
</p>
</>
);
};

View File

@@ -0,0 +1,17 @@
export type NewsletterType = {
id: string
total_sent: number
subject: string
queue: object
clicked_links: {cnt: string, url: string}[]
statistics: {
clicked: number
opened: number
unsubscribed: number
revenue: {
value: number
formatted: string
count: number
}
}
}

View File

@@ -1,11 +1,12 @@
import React, { useState, useEffect, useCallback } from 'react';
import Hooks from 'wp-js-hooks';
import MailPoet from 'mailpoet';
import { Link, withRouter } from 'react-router-dom';
import { withRouter } from 'react-router-dom';
import InvalidMssKeyNotice from 'notices/invalid_mss_key_notice';
import { TopBarWithBeamer } from 'common/top_bar/top_bar';
import NewsletterGeneralStats from './newsletter_stats.jsx';
import { NewsletterGeneralStats } from './newsletter_general_stats';
import { NewsletterType } from './newsletter_type';
import NewsletterStatsInfo from './newsletter_info.jsx';
import PremiumBanner from './premium_banner.jsx';
import Heading from '../../common/typography/heading/heading';
@@ -37,12 +38,7 @@ type Props = {
};
type State = {
item?: {
id: string,
queue: object
subject: string
clicked_links: object[]
}
item?: NewsletterType
loading: boolean
}
@@ -93,7 +89,7 @@ const CampaignStatsPage = ({ match, history, location }: Props) => {
return () => {
showWPScreenOptions();
};
}, [match.params.id, loadItem]);
}, [match.params.id, loadItem, state.item]);
const { item, loading } = state;
const newsletter = item;
@@ -122,13 +118,9 @@ const CampaignStatsPage = ({ match, history, location }: Props) => {
/>
<div className="mailpoet_stat_triple-spaced">
<div className="mailpoet_stat_info">
<NewsletterStatsInfo newsletter={newsletter} />
</div>
<div className="mailpoet_stat_general">
<NewsletterGeneralStats newsletter={newsletter} />
</div>
<div style={{ clear: 'both' }} />
<NewsletterStatsInfo newsletter={newsletter} />
<NewsletterGeneralStats newsletter={newsletter} />
</div>
<h2>{MailPoet.I18n.t('clickedLinks')}</h2>