catarse/catarse.js

View on GitHub
legacy/src/c/project-insights-sub.js

Summary

Maintainability
F
3 days
Test Coverage
import m from 'mithril';
import prop from 'mithril/stream';
import moment, { min } from 'moment';
import _ from 'underscore';
import { catarse, catarseMoments, commonAnalytics } from '../api';
import models from '../models';
import h from '../h';
import projectDashboardMenu from '../c/project-dashboard-menu';
import projectDataChart from '../c/project-data-chart';
import projectInviteCard from '../c/project-invite-card';
import subscriptionsPerMonthTable from '../c/subscriptions-per-month-table';
import projectGoalsBoxDashboard from './project-goals-box-dashboard';
import insightsInfoBox from './insights-info-box';
import projectGoalsVM from '../vms/project-goals-vm';
import subscriptionVM from '../vms/subscription-vm';
import userVM from '../vms/user-vm';

const I18nScope = _.partial(h.i18nScope, 'projects.insights');

const projectInsightsSub = {
    oninit: function(vnode) {
        const filtersVM = vnode.attrs.filtersVM,
            visitorsTotal = prop(0),
            visitorLoader = catarseMoments.loaderWithToken,
            loader = commonAnalytics.loaderWithToken,
            visitorsPerDay = prop([]);
        const insightResumeDataLastWeek = prop({
            mean_amount : 0, 
            subscriptions_count : 0, 
            total_amount : 0
        });
        const insightResumeDataLast2Week = prop({
            mean_amount : 0, 
            subscriptions_count : 0, 
            total_amount : 0
        });
        const subscriptionsPerDay = prop([]);
        const weekTransitions = prop([]);
        const lastWeekTransitions = prop([]);
        const subscriptionsPerMonth = prop([]);
        const isSubscriptionsPerMonthLoaded = prop(false);
        const balanceData = prop(null);
        const subVM = commonAnalytics.filtersVM({
            project_id: 'eq',
        });
        const processVisitors = data => {
            if (!_.isEmpty(data)) {
                visitorsPerDay(data);
                visitorsTotal(_.first(data).total);
            }
        };
        const requestRedraw = h.createRequestAutoRedraw(
            subscriptionsPerDay,
            weekTransitions,
            lastWeekTransitions,
            subscriptionsPerMonth,
            isSubscriptionsPerMonthLoaded,
            balanceData
        );

        subscriptionVM
            .getNewSubscriptionsInsightsFromLastWeek(vnode.attrs.project.common_id)
            .then(insights => {
                insightResumeDataLastWeek(insights);
                h.redraw();
            });

        subscriptionVM
            .getNewSubscriptionsInsightsFromLast2Week(vnode.attrs.project.common_id)
            .then(insightsLast2Weeks => {
                insightResumeDataLast2Week(insightsLast2Weeks);
                h.redraw();
            });

        subVM.project_id(vnode.attrs.project.common_id);
        const lVisitorsPerDay = visitorLoader(models.projectVisitorsPerDay.getRowOptions(filtersVM.parameters()));
        lVisitorsPerDay
            .load()
            .then(processVisitors)
            .then(requestRedraw);

        const lSubscriptionsPerDay = loader(models.projectSubscriptionsPerDay.getRowOptions(subVM.parameters()));
        lSubscriptionsPerDay
            .load()
            .then(subscriptionsPerDay)
            .then(requestRedraw);

        subscriptionVM
            .getSubscriptionTransitions(vnode.attrs.project.common_id, ['inactive', 'canceled'], 'active', moment().utc().subtract(1, 'weeks').format(), moment().utc().format())
            .then(weekTransitions)
            .then(requestRedraw);

        subscriptionVM
            .getSubscriptionTransitions(
                vnode.attrs.project.common_id,
                ['inactive', 'canceled'],
                'active',
                moment()
                    .utc()
                    .subtract(2, 'weeks')
                    .format(),
                moment()
                    .utc()
                    .subtract(1, 'weeks')
                    .format()
            )
            .then(lastWeekTransitions)
            .then(requestRedraw);

        subscriptionVM.getSubscriptionsPerMonth(vnode.attrs.project.common_id).then(subscriptions => {
            subscriptionsPerMonth(subscriptions);
            isSubscriptionsPerMonthLoaded(true);
            requestRedraw();
        });

        projectGoalsVM.fetchGoals(filtersVM.project_id());
        const balanceLoader = userVM.getUserBalance(vnode.attrs.project.user_id);
        balanceLoader.then(balanceData).then(requestRedraw);

        vnode.state = {
            subscriptionsPerMonth,
            weekTransitions,
            lastWeekTransitions,
            projectGoalsVM,
            lVisitorsPerDay,
            lSubscriptionsPerDay,
            subscriptionsPerDay,
            visitorsTotal,
            visitorsPerDay,
            balanceLoader,
            balanceData,
            isSubscriptionsPerMonthLoaded,
            insightResumeDataLastWeek,
            insightResumeDataLast2Week
        };
    },
    view: function({state, attrs}) {
        const project = attrs.project,
            subscribersDetails = attrs.subscribersDetails,
            balanceData = (state.balanceData() && !_.isNull(_.first(state.balanceData())) ? _.first(state.balanceData()) : null);
        
        const atLeastZero = num => (num === null || isNaN(num)) ? 0 : Math.max(0, num);
        const averageAmount = atLeastZero(state.insightResumeDataLastWeek().mean_amount) / 100.0;
        const totalAmountFromLastWeek = atLeastZero(state.insightResumeDataLastWeek().total_amount) / 100.0;
        const totalAmountFromLast2Week = atLeastZero(state.insightResumeDataLast2Week().total_amount) / 100.0;

        return m('.project-insights', !attrs.l() ? [
            m(`.w-section.section-product.${project.mode}`),
            (project.is_owner_or_admin ? m(projectDashboardMenu, {
                project: prop(project)
            }) : ''),
            m('.dashboard-header.section-one-column', [
                m('.u-marginbottom-30.u-text-center', [
                    m('.fontsize-larger.fontweight-semibold',
                        `Olá, ${project.user.public_name || project.user.name}!`
                    ),
                    m('.fontsize-smaller',
                        `Este é o retrato de sua campanha hoje, ${moment().format('DD [de] MMMM [de] YYYY')}`
                    )
                ]),
                m('.w-container', [
                    m('.flex-row.u-marginbottom-40.u-text-center-small-only', [
                        subscribersDetails && !_.isEmpty(state.projectGoalsVM.goalsData()) ?
                        m(projectGoalsBoxDashboard, {
                            goalDetails: state.projectGoalsVM.goalsData,
                            amount: subscribersDetails.amount_paid_for_valid_period
                        }) : '',
                        m('.card.card-terciary.flex-column.u-marginbottom-10.u-radius', [
                            m('.fontsize-small.u-marginbottom-10',
                                'Assinaturas ativas'
                            ),
                            m('.fontsize-largest.fontweight-semibold',
                                subscribersDetails.total_subscriptions
                            )
                        ]),
                        m('.card.card-terciary.flex-column.u-marginbottom-10.u-radius', [
                            m('.fontsize-small.u-marginbottom-10',
                                'Receita Mensal'
                            ),
                            m('.fontsize-largest.fontweight-semibold.u-marginbottom-10',
                                `R$${h.formatNumber(subscribersDetails.amount_paid_for_valid_period, 2, 3)}`
                            ),
                            m('.fontsize-mini.fontcolor-secondary.lineheight-tighter',
                                'Com base nas assinaturas ativas que você possui hoje (taxas já descontadas).'
                            )
                        ]),
                        m('.card.flex-column.u-marginbottom-10.u-radius', [
                            m('.fontsize-small.u-marginbottom-10', [
                                'Saldo',
                                m.trust(' '),
                                ' ',
                                m(`a.btn-inline.btn-terciary.fontsize-smallest.u-radius[href='/users/${project.user_id}/edit#balance'][target='_self']`,
                                    'Sacar'
                                )
                            ]),
                            m('.fontsize-largest.fontweight-semibold.text-success.u-marginbottom-10',
                                (balanceData && balanceData.amount ? `R$${h.formatNumber(balanceData.amount, 2, 3)}` : '')
                            ),
                            m('.fontsize-mini.fontcolor-secondary.lineheight-tighter',
                                'O saldo demora até 20 mins após o pagamento para ser atualizado.'
                            )
                        ])
                    ]),
                    (project.state === 'online' && !project.has_cancelation_request ? m('.w-container.u-marginbottom-60', m(projectInviteCard, {
                        project
                    })) : ''),

                    m('.u-marginbottom-30', [
                        m('.flex-row.u-marginbottom-40.u-text-center-small-only', [
                            m('.flex-column.card.u-radius.u-marginbottom-10', [
                                m('div',
                                    'Receita média por assinatura'
                                ),
                                m('.fontsize-smallest.fontcolor-secondary.lineheight-tighter',
                                    `em ${moment().format('DD/MM/YYYY')}`
                                ),
                                m('.fontsize-largest.fontweight-semibold',
                                    `R$${averageAmount ? `${h.formatNumber(averageAmount, 2, 3)}` : '--'}`
                                )

                            ]),
                            m(insightsInfoBox, {
                                label: 'Novos Assinantes',
                                info: state.insightResumeDataLastWeek().subscriptions_count,
                                newCount: state.insightResumeDataLastWeek().subscriptions_count,
                                oldCount: state.insightResumeDataLast2Week().subscriptions_count
                            }),
                            m(insightsInfoBox, {
                                label: 'Nova receita',
                                info: `R$${h.formatNumber(totalAmountFromLastWeek, 2, 3)}`,
                                newCount: totalAmountFromLastWeek,
                                oldCount: totalAmountFromLast2Week
                            })
                        ]),
                        m(".fontsize-large.fontweight-semibold.u-marginbottom-10.u-text-center[id='origem']", [
                            window.I18n.t('visitors_per_day_label', I18nScope())
                        ]),
                        m('.u-text-center.fontsize-smaller.fontcolor-secondary.lineheight-tighter.u-marginbottom-20', [
                            window.I18n.t('last_30_days_indication', I18nScope())
                        ])
                    ]), !state.lVisitorsPerDay() ? m(projectDataChart, {
                        collection: state.visitorsPerDay,
                        dataKey: 'visitors',
                        limitDataset: 30,
                        xAxis: item => h.momentify(item.day),
                        emptyState: window.I18n.t('visitors_per_day_empty', I18nScope())
                    }) : h.loader(),

                    m('.u-text-center', {
                        style: {
                            'min-height': '300px'
                        }
                    }, [!state.lSubscriptionsPerDay() ? m(projectDataChart, {
                        collection: state.subscriptionsPerDay,
                        label: window.I18n.t('amount_per_day_label_sub', I18nScope()),
                        subLabel: window.I18n.t('paid_date_indication', I18nScope()),
                        dataKey: 'total_amount',
                        xAxis: item => h.momentify(item.paid_at),
                        emptyState: m.trust(window.I18n.t('amount_per_day_empty_sub', I18nScope()))
                    }) : h.loader()]),
                    m('.u-text-center', {
                        style: {
                            'min-height': '300px'
                        }
                    }, [!state.lSubscriptionsPerDay() ? m(projectDataChart, {
                        collection: state.subscriptionsPerDay,
                        label: window.I18n.t('contributions_per_day_label_sub', I18nScope()),
                        subLabel: window.I18n.t('paid_date_indication', I18nScope()),
                        dataKey: 'total',
                        xAxis: item => h.momentify(item.paid_at),
                        emptyState: m.trust(window.I18n.t('contributions_per_day_empty_sub', I18nScope()))
                    }) : h.loader()]),
                    (state.isSubscriptionsPerMonthLoaded() ?
                        m(subscriptionsPerMonthTable, { data: state.subscriptionsPerMonth() }) : h.loader())
                          ]),
                      ]),
                  ]
                : h.loader()
        );
    },
};

export default projectInsightsSub;