catarse/catarse.js

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

Summary

Maintainability
F
5 days
Test Coverage
import m from 'mithril';
import prop from 'mithril/stream';
import { catarse } from '../api';
import _ from 'underscore';
import h from '../h';
import models from '../models';
import tooltip from '../c/tooltip';
import projectDashboardMenu from '../c/project-dashboard-menu';
import modalBox from '../c/modal-box';
import adminProjectDetailsCard from '../c/admin-project-details-card';
import onlineSuccessModalContent from '../c/online-success-modal-content';
import projectDataStats from '../c/project-data-stats';
import projectDeleteButton from '../c/project-delete-button';
import projectCancelButton from '../c/project-cancel-button';
import projectDataChart from '../c/project-data-chart';
import projectDataTable from '../c/project-data-table';
import projectReminderCount from '../c/project-reminder-count';
import projectSuccessfulOnboard from '../c/project-successful-onboard';
import projectInviteCard from '../c/project-invite-card';
import projectSuccessfullNextSteps from '../c/project-successful-next-steps';
import {
    catarseMoments
} from '../api';
import { SolidarityProjectInsightsWelcomeDraft } from './solidarity-project-insights-welcome-draft';

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

const projectInsights = {
    oninit: function(vnode) {
        const filtersVM = vnode.attrs.filtersVM,
            displayModal = h.toggleProp(false, true),
            contributionsPerDay = prop([]),
            visitorsTotal = prop(0),
            visitorsPerDay = prop([]),
            loader = catarse.loaderWithToken,
            countDownToRedraw = prop(4),
            requestRedraw = () => {
                countDownToRedraw(Math.max(0, countDownToRedraw() - 1));
                if (countDownToRedraw() <= 0) {
                    m.redraw();
                }
            };

        if (h.paramByName('online_success') === 'true') {
            displayModal.toggle();
        }

        const processVisitors = (data) => {
            if (!_.isEmpty(data)) {
                visitorsPerDay(data);
                visitorsTotal(_.first(data).total);
            }
        };

        const lVisitorsPerDay = catarseMoments.loaderWithToken(models.projectVisitorsPerDay.getRowOptions(filtersVM.parameters()));
        lVisitorsPerDay
            .load()
            .then(processVisitors)
            .then(requestRedraw);

        const lContributionsPerDay = loader(models.projectContributionsPerDay.getRowOptions(filtersVM.parameters()));
        lContributionsPerDay
            .load()
            .then(contributionsPerDay)
            .then(requestRedraw);

        const contributionsPerLocationTable = [['Estado', 'Apoios', 'R$ apoiados (% do total)']];
        const buildPerLocationTable = contributions => (!_.isEmpty(contributions)) ? _.map(_.first(contributions).source, (contribution) => {
            const column = [];

            column.push(contribution.state_acronym || 'Outro/other');
            column.push(contribution.total_contributions);
            column.push([contribution.total_contributed, [// Adding row with custom comparator => read project-data-table description
                m(`input[type="hidden"][value="${contribution.total_contributed}"`),
                'R$ ',
                h.formatNumber(contribution.total_contributed, 2, 3),
                m('span.w-hidden-small.w-hidden-tiny', ` (${contribution.total_on_percentage.toFixed(2)}%)`)
            ]]);
            return contributionsPerLocationTable.push(column);
        }) : [];

        const lContributionsPerLocation = loader(models.projectContributionsPerLocation.getRowOptions(filtersVM.parameters()));
        lContributionsPerLocation
            .load()
            .then(buildPerLocationTable)
            .then(requestRedraw);

        const contributionsPerRefTable = [[
            window.I18n.t('ref_table.header.origin', I18nScope()),
            window.I18n.t('ref_table.header.contributions', I18nScope()),
            window.I18n.t('ref_table.header.amount', I18nScope())
        ]];
        const buildPerRefTable = contributions => (!_.isEmpty(contributions)) ? _.map(_.first(contributions).source, (contribution) => {
                // Test if the string matches a word starting with ctrse_ and followed by any non-digit group of characters
                // This allows to remove any versioned referral (i.e.: ctrse_newsletter_123) while still getting ctrse_test_ref
            const re = /(ctrse_[\D]*)/,
                test = re.exec(contribution.referral_link);

            const column = [];

            if (test) {
                    // Removes last underscore if it exists
                contribution.referral_link = test[0].substr(-1) === '_' ? test[0].substr(0, test[0].length - 1) : test[0];
            }

            column.push(contribution.referral_link ? window.I18n.t(`referral.${contribution.referral_link}`, I18nScope({ defaultValue: contribution.referral_link })) : window.I18n.t('referral.others', I18nScope()));
            column.push(contribution.total);
            column.push([contribution.total_amount, [
                m(`input[type="hidden"][value="${contribution.total_contributed}"`),
                'R$ ',
                h.formatNumber(contribution.total_amount, 2, 3),
                m('span.w-hidden-small.w-hidden-tiny', ` (${contribution.total_on_percentage.toFixed(2)}%)`)
            ]]);
            return contributionsPerRefTable.push(column);
        }) : [];

        const lContributionsPerRef = loader(models.projectContributionsPerRef.getRowOptions(filtersVM.parameters()));
        lContributionsPerRef
            .load()
            .then(buildPerRefTable)
            .then(requestRedraw);

        function isSolidarityProject() {
            const project = vnode.attrs.project;
            if (project) {
                const solidarityIntegration = (project.integrations || []).find(integration => integration.name === 'SOLIDARITY_SERVICE_FEE');
                return !!solidarityIntegration;
            } else {
                return false;
            }
        }

        vnode.state = {
            lContributionsPerRef,
            lContributionsPerLocation,
            lContributionsPerDay,
            lVisitorsPerDay,
            displayModal,
            filtersVM,
            contributionsPerDay,
            contributionsPerLocationTable,
            contributionsPerRefTable,
            visitorsPerDay,
            visitorsTotal,
            isSolidarityProject
        };
    },
    view: function({state, attrs}) {
        const project = attrs.project,
            isSolidarityProject = state.isSolidarityProject,
            buildTooltip = el => m(tooltip, {
                el,
                text: [
                    'Informa de onde vieram os apoios de seu projeto. Saiba como usar essa tabela e planejar melhor suas ações de comunicação ',
                    m(`a[href="${window.I18n.t('ref_table.help_url', I18nScope())}"][target='_blank']`, 'aqui.')
                ],
                width: 380
            });

        if (!attrs.l()) {
            project.user.name = project.user.name || 'Realizador';
        }

        return m('.project-insights', !attrs.l() ? [
            m(`.w-section.section-product.${project.mode}`),
            (project.is_owner_or_admin ? m(projectDashboardMenu, {
                project: prop(project)
            }) : ''),
            (state.displayModal() ? m(modalBox, {
                displayModal: state.displayModal,
                content: [onlineSuccessModalContent]
            }) : ''),

            m('.w-container', 
                ((project.state === 'successful' || project.state === 'waiting_funds' ) && !project.has_cancelation_request) ? 
                    m(projectSuccessfullNextSteps, { project: prop(project) }) : [
                        m('.w-row.u-marginbottom-40', [
                            m('.w-col.w-col-8.w-col-push-2', [
                                m('.fontweight-semibold.fontsize-larger.lineheight-looser.u-marginbottom-10.u-text-center.dashboard-header', window.I18n.t('campaign_title', I18nScope())),

                                (
                                    (project.state === 'draft' && !project.has_cancelation_request && isSolidarityProject()) ?
                                        [
                                            m(SolidarityProjectInsightsWelcomeDraft),
                                        ] 
                                    :
                                        [
                                            (project.state === 'online' && !project.has_cancelation_request ? m(projectInviteCard, { project }) : ''),
                                            (project.state === 'draft' && !project.has_cancelation_request ? m(adminProjectDetailsCard, { resource: project }) : ''),
                                            m(`p.${project.state}-project-text.u-text-center.fontsize-small.lineheight-loose`,
                                                project.has_cancelation_request ? 
                                                    m.trust(window.I18n.t('has_cancelation_request_explanation', I18nScope())) : [
                                                        project.mode === 'flex' && _.isNull(project.expires_at) && project.state !== 'draft' ? 
                                                            m('span', [
                                                                m.trust(window.I18n.t('finish_explanation', I18nScope())),
                                                                m('a.alt-link[href="http://suporte.catarse.me/hc/pt-br/articles/213783503-tudo-sobre-Prazo-da-campanha"][target="_blank"]', window.I18n.t('know_more', I18nScope()))
                                                            ]) : 
                                                            m.trust(
                                                                window.I18n.t(`campaign.${project.mode}.${project.state}`, 
                                                                I18nScope({ username: project.user.name, expires_at: h.momentify(project.zone_expires_at), sent_to_analysis_at: h.momentify(project.sent_to_analysis_at) })))
                                                    ]
                                            )
                                        ]
                                )
                            ])
                        ])
                    ]),
            (project.state === 'draft' ?
               m(projectDeleteButton, { project })
            : ''),
            (project.is_published) ? [
                m('.divider'),
                m('.w-section.section-one-column.section.bg-gray.before-footer', [
                    m('.w-container', [
                        m(
                            projectDataStats,
                            { project: prop(project), visitorsTotal: state.visitorsTotal }
                        ),
                        m('.w-row', [
                            m('.w-col.w-col-12.u-text-center', {
                                style: {
                                    'min-height': '300px'
                                }
                            }, [
                                m('.fontweight-semibold.u-marginbottom-10.fontsize-large.u-text-center', [
                                    window.I18n.t('visitors_per_day_label', I18nScope())
                                ]),
                                !state.lVisitorsPerDay() ? m(projectDataChart, {
                                    collection: state.visitorsPerDay,
                                    dataKey: 'visitors',
                                    xAxis: item => h.momentify(item.day),
                                    emptyState: window.I18n.t('visitors_per_day_empty', I18nScope())
                                }) : h.loader()
                            ]),
                        ]),
                        m('.w-row', [
                            m('.w-col.w-col-12.u-text-center', {
                                style: {
                                    'min-height': '300px'
                                }
                            }, [
                                !state.lContributionsPerDay() ? m(projectDataChart, {
                                    collection: state.contributionsPerDay,
                                    label: window.I18n.t('amount_per_day_label', I18nScope()),
                                    dataKey: 'total_amount',
                                    xAxis: item => h.momentify(item.paid_at),
                                    emptyState: window.I18n.t('amount_per_day_empty', I18nScope())
                                }) : h.loader()
                            ]),
                        ]),
                        m('.w-row', [
                            m('.w-col.w-col-12.u-text-center', {
                                style: {
                                    'min-height': '300px'
                                }
                            }, [
                                !state.lContributionsPerDay() ? m(projectDataChart, {
                                    collection: state.contributionsPerDay,
                                    label: window.I18n.t('contributions_per_day_label', I18nScope()),
                                    dataKey: 'total',
                                    xAxis: item => h.momentify(item.paid_at),
                                    emptyState: window.I18n.t('contributions_per_day_empty', I18nScope())
                                }) : h.loader()
                            ]),
                        ]),
                        m('.w-row', [
                            m('.w-col.w-col-12.u-text-center', [
                                m('.project-contributions-per-ref', [
                                    m('.fontweight-semibold.u-marginbottom-10.fontsize-large.u-text-center', [
                                        window.I18n.t('ref_origin_title', I18nScope()),
                                        ' ',
                                        buildTooltip('span.fontsize-smallest.tooltip-wrapper.fa.fa-question-circle.fontcolor-secondary')
                                    ]),
                                    !state.lContributionsPerRef() ? !_.isEmpty(_.rest(state.contributionsPerRefTable)) ? m(projectDataTable, {
                                        table: state.contributionsPerRefTable,
                                        defaultSortIndex: -2
                                    }) : m('.card.u-radius.medium.u-marginbottom-60',
                                            m('.w-row.u-text-center.u-margintop-40.u-marginbottom-40',
                                                m('.w-col.w-col-8.w-col-push-2',
                                                    m('p.fontsize-base', window.I18n.t('contributions_per_ref_empty', I18nScope()))
                                                )
                                            )
                                        ) : h.loader()
                                ])
                            ]),
                        ]),
                        m('.w-row', [
                            m('.w-col.w-col-12.u-text-center', [
                                m('.project-contributions-per-ref', [
                                    m('.fontweight-semibold.u-marginbottom-10.fontsize-large.u-text-center', window.I18n.t('location_origin_title', I18nScope())),
                                    !state.lContributionsPerLocation() ? !_.isEmpty(_.rest(state.contributionsPerLocationTable)) ? m(projectDataTable, {
                                        table: state.contributionsPerLocationTable,
                                        defaultSortIndex: -2
                                    }) : m('.card.u-radius.medium.u-marginbottom-60',
                                            m('.w-row.u-text-center.u-margintop-40.u-marginbottom-40',
                                                m('.w-col.w-col-8.w-col-push-2',
                                                    m('p.fontsize-base', window.I18n.t('contributions_per_location_empty', I18nScope()))
                                                )
                                            )
                                        ) : h.loader()
                                ])
                            ]),
                        ]),
                        m('.w-row', [
                            m('.w-col.w-col-12.u-text-center', [
                                m(projectReminderCount, {
                                    resource: project
                                })
                            ]),
                        ]),
                    ])
                ]),
            (project.can_cancel ?
                m(projectCancelButton, { project })
            : '')

            ] : ''
        ] : h.loader());
    }
};

export default projectInsights;