2021-02-04 20:36:29 +03:00
|
|
|
import Controller from '@ember/controller';
|
2021-02-19 08:48:01 +03:00
|
|
|
import {getSymbol} from 'ghost-admin/utils/currency';
|
2021-02-04 20:36:29 +03:00
|
|
|
import {inject as service} from '@ember/service';
|
2021-02-18 17:17:10 +03:00
|
|
|
import {tracked} from '@glimmer/tracking';
|
2021-02-04 20:36:29 +03:00
|
|
|
|
|
|
|
export default class DashboardController extends Controller {
|
2021-02-04 21:35:19 +03:00
|
|
|
@service feature;
|
2021-02-04 20:36:29 +03:00
|
|
|
@service session;
|
2021-02-18 17:17:10 +03:00
|
|
|
@service membersStats;
|
2021-02-19 15:12:53 +03:00
|
|
|
@service store;
|
2021-02-19 16:55:35 +03:00
|
|
|
@service settings;
|
2021-02-18 17:17:10 +03:00
|
|
|
|
|
|
|
@tracked
|
|
|
|
events = {
|
|
|
|
data: null,
|
|
|
|
error: null,
|
|
|
|
loading: false
|
|
|
|
};
|
2021-02-18 20:13:51 +03:00
|
|
|
@tracked
|
|
|
|
mrrStats = {
|
|
|
|
data: null,
|
|
|
|
error: null,
|
|
|
|
loading: false
|
|
|
|
};
|
2021-02-19 08:48:01 +03:00
|
|
|
@tracked
|
|
|
|
memberCountStats = {
|
|
|
|
data: null,
|
|
|
|
error: null,
|
|
|
|
loading: false
|
|
|
|
};
|
2021-02-18 17:17:10 +03:00
|
|
|
|
2021-02-19 15:12:53 +03:00
|
|
|
@tracked
|
|
|
|
topMembers = {
|
|
|
|
data: null,
|
|
|
|
error: null,
|
|
|
|
loading: false
|
|
|
|
};
|
|
|
|
|
|
|
|
get showTopMembers() {
|
|
|
|
return this.feature.get('emailAnalytics') && this.settings.get('emailTrackOpens');
|
|
|
|
}
|
|
|
|
|
2021-02-18 17:17:10 +03:00
|
|
|
constructor(...args) {
|
|
|
|
super(...args);
|
|
|
|
this.loadEvents();
|
2021-02-19 15:12:53 +03:00
|
|
|
this.loadTopMembers();
|
2021-02-18 20:13:51 +03:00
|
|
|
this.loadCharts();
|
|
|
|
}
|
|
|
|
|
2021-02-19 08:48:01 +03:00
|
|
|
loadMRRStats() {
|
2021-02-18 20:13:51 +03:00
|
|
|
this.membersStats.fetchMRR().then((stats) => {
|
|
|
|
this.events.loading = false;
|
2021-02-19 08:48:01 +03:00
|
|
|
|
2021-02-19 15:50:41 +03:00
|
|
|
let currencyStats = stats[0] || {
|
|
|
|
data: [],
|
|
|
|
currency: 'usd'
|
|
|
|
};
|
2021-02-19 08:48:01 +03:00
|
|
|
if (currencyStats) {
|
|
|
|
currencyStats.data = this.membersStats.fillDates(currencyStats.data) || {};
|
|
|
|
const dateValues = Object.values(currencyStats.data).map(val => val / 100);
|
|
|
|
const currentMRR = dateValues.length ? dateValues[dateValues.length - 1] : 0;
|
2021-02-19 15:50:41 +03:00
|
|
|
const rangeStartMRR = dateValues.length ? dateValues[0] : 0;
|
|
|
|
const percentChange = rangeStartMRR !== 0 ? ((currentMRR - rangeStartMRR) / rangeStartMRR) * 100 : 0.0;
|
2021-02-19 08:48:01 +03:00
|
|
|
this.mrrStats.data = {
|
|
|
|
current: `${getSymbol(currencyStats.currency)}${currentMRR}`,
|
2021-02-19 15:50:41 +03:00
|
|
|
percentChange,
|
2021-02-19 08:48:01 +03:00
|
|
|
options: {
|
|
|
|
rangeInDays: 30
|
|
|
|
},
|
|
|
|
data: {
|
|
|
|
label: 'MRR',
|
|
|
|
dateLabels: Object.keys(currencyStats.data),
|
|
|
|
dateValues
|
|
|
|
},
|
|
|
|
title: 'MRR',
|
|
|
|
stats: currencyStats
|
|
|
|
};
|
|
|
|
}
|
2021-02-18 20:13:51 +03:00
|
|
|
}, (error) => {
|
|
|
|
this.mrrStats.error = error;
|
|
|
|
this.events.loading = false;
|
|
|
|
});
|
2021-02-18 17:17:10 +03:00
|
|
|
}
|
|
|
|
|
2021-02-19 08:48:01 +03:00
|
|
|
loadMemberCountStats() {
|
|
|
|
this.membersStats.fetchCounts().then((stats) => {
|
|
|
|
this.events.loading = false;
|
|
|
|
|
|
|
|
if (stats) {
|
|
|
|
stats.data = this.membersStats.fillCountDates(stats.data) || {};
|
|
|
|
const dateValues = Object.values(stats.data);
|
|
|
|
|
|
|
|
this.memberCountStats.data = {
|
|
|
|
all: {
|
|
|
|
total: dateValues.length ? dateValues[dateValues.length - 1].total : 0,
|
|
|
|
options: {
|
|
|
|
rangeInDays: 30
|
|
|
|
},
|
|
|
|
data: {
|
|
|
|
label: 'Members',
|
|
|
|
dateLabels: Object.keys(stats.data),
|
|
|
|
dateValues: dateValues.map(d => d.total)
|
|
|
|
},
|
|
|
|
title: 'Total Members',
|
|
|
|
stats: stats
|
|
|
|
},
|
|
|
|
paid: {
|
|
|
|
total: dateValues.length ? dateValues[dateValues.length - 1].paid : 0,
|
|
|
|
options: {
|
|
|
|
rangeInDays: 30
|
|
|
|
},
|
|
|
|
data: {
|
|
|
|
label: 'Members',
|
|
|
|
dateLabels: Object.keys(stats.data),
|
|
|
|
dateValues: dateValues.map(d => d.paid)
|
|
|
|
},
|
|
|
|
title: 'Paid Members',
|
|
|
|
stats: stats
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
}, (error) => {
|
|
|
|
this.mrrStats.error = error;
|
|
|
|
this.events.loading = false;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
loadCharts() {
|
|
|
|
this.loadMRRStats();
|
|
|
|
this.loadMemberCountStats();
|
|
|
|
}
|
|
|
|
|
2021-02-18 17:17:10 +03:00
|
|
|
loadEvents() {
|
|
|
|
this.events.loading = true;
|
|
|
|
this.membersStats.fetchTimeline().then(({events}) => {
|
|
|
|
this.events.data = events;
|
|
|
|
this.events.loading = false;
|
|
|
|
}, (error) => {
|
|
|
|
this.events.error = error;
|
|
|
|
this.events.loading = false;
|
|
|
|
});
|
|
|
|
}
|
2021-02-19 15:12:53 +03:00
|
|
|
|
|
|
|
loadTopMembers() {
|
|
|
|
this.topMembers.loading = true;
|
|
|
|
let query = {
|
|
|
|
filter: 'email_open_rate:-null',
|
|
|
|
order: 'email_open_rate desc',
|
|
|
|
limit: 10
|
|
|
|
};
|
|
|
|
this.store.query('member', query).then((result) => {
|
|
|
|
this.topMembers.data = result;
|
|
|
|
this.topMembers.loading = false;
|
|
|
|
}, (error) => {
|
|
|
|
this.topMembers.error = error;
|
|
|
|
this.topMembers.loading = false;
|
|
|
|
});
|
|
|
|
}
|
2021-02-18 17:17:10 +03:00
|
|
|
}
|