mirror of
https://github.com/codeninjasllc/codecombat.git
synced 2024-11-28 18:15:52 -05:00
609884eb51
Adding a second table, setting range to be 60 and 365 days. Updating teacher columns to prioritize student paid status over furthest student course.
365 lines
14 KiB
Text
365 lines
14 KiB
Text
extends /templates/base
|
|
|
|
block content
|
|
|
|
//- NOTE: do not localize / i18n
|
|
|
|
if me.isAdmin()
|
|
.container-fluid
|
|
.row
|
|
.col-md-5.big-stat.active-classes
|
|
div.description Monthly Active Classes
|
|
if activeClasses.length > 0
|
|
div.count= activeClasses[0].groups[activeClasses[0].groups.length - 1]
|
|
.col-md-5.big-stat.recurring-revenue
|
|
div.description Monthly Recurring Revenue
|
|
if revenue.length > 0
|
|
div.count $#{Math.round((revenue[0].groups[revenue[0].groups.length - 1]) / 100)}
|
|
.col-md-5.big-stat.classroom-active-users
|
|
div.description Classroom Monthly Active Users
|
|
if activeUsers.length > 0
|
|
- var classroomBigMAU = 0;
|
|
each count, event in activeUsers[0].events
|
|
if event.indexOf('MAU classroom') >= 0
|
|
- classroomBigMAU += count;
|
|
div.count= classroomBigMAU
|
|
.col-md-5.big-stat.campaign-active-users
|
|
div.description Campaign Monthly Active Users
|
|
if activeUsers.length > 0
|
|
- var campaignBigMAU = 0;
|
|
each count, event in activeUsers[0].events
|
|
if event.indexOf('MAU campaign') >= 0
|
|
- campaignBigMAU += count;
|
|
div.count= campaignBigMAU
|
|
|
|
ul.nav.nav-tabs
|
|
li.active
|
|
a(data-target="#tab_kpis", data-toggle="tab") KPIs
|
|
li
|
|
a(data-target="#tab_active_classes", data-toggle="tab") Active Classes
|
|
li
|
|
a(data-target="#tab_revenue", data-toggle="tab") Revenue
|
|
li
|
|
a(data-target="#tab_classroom", data-toggle="tab") Classroom
|
|
li
|
|
a(data-target="#tab_campaign", data-toggle="tab") Campaign
|
|
li
|
|
a(data-target="#tab_campaign_vs_classroom", data-toggle="tab") Campaign vs Classroom
|
|
|
|
.tab-content
|
|
.tab-pane.active#tab_kpis
|
|
h3 KPI 60 days
|
|
.kpi-recent-chart.line-chart-container
|
|
|
|
h3 KPI 365 days
|
|
.kpi-chart.line-chart-container
|
|
|
|
.tab-pane#tab_active_classes
|
|
h3 Active Classes 90 days
|
|
.small Active class: 12+ students in a classroom, with 6+ who played in last 30 days. Played == 'Started Level' analytics event.
|
|
.small Paid student: user.coursePrepaidID set and prepaid.properties.trialRequestID NOT set
|
|
.small Trial student: user.coursePrepaidID set and prepaid.properties.trialRequestID set
|
|
.small Paid class: at least one paid student in the classroom
|
|
.small Trial class: not paid, at least one trial student in classroom
|
|
.small Free class: not paid, not trial
|
|
.active-classes-chart-90.line-chart-container
|
|
|
|
h3 Active Classes 365 days
|
|
.active-classes-chart-365.line-chart-container
|
|
|
|
h1#active-classes-table Active Classes
|
|
table.table.table-striped.table-condensed
|
|
tr
|
|
th Day
|
|
for group in activeClassGroups
|
|
th= group.replace('Active classes', '')
|
|
each activeClass in activeClasses
|
|
tr
|
|
td= activeClass.day
|
|
each val in activeClass.groups
|
|
td= val
|
|
|
|
|
|
.tab-pane#tab_revenue
|
|
h3 Daily Recurring Revenue 90 days
|
|
.recurring-daily-revenue-chart-90.line-chart-container
|
|
|
|
h3 Monthly Recurring Revenue 90 days
|
|
.recurring-monthly-revenue-chart-90.line-chart-container
|
|
|
|
h3 Daily Recurring Revenue 365 days
|
|
.recurring-daily-revenue-chart-365.line-chart-container
|
|
|
|
h3 Monthly Recurring Revenue 365 days
|
|
.recurring-monthly-revenue-chart-365.line-chart-container
|
|
|
|
h1#recurring-revenue-table Recurring Revenue
|
|
table.table.table-striped.table-condensed
|
|
tr
|
|
th(style='min-width:85px;') Day
|
|
for group in revenueGroups
|
|
th= group.replace('DRR ', 'Daily ').replace('MRR ', 'Monthly ')
|
|
each entry in revenue
|
|
tr
|
|
td= entry.day
|
|
each val in entry.groups
|
|
td $#{(val / 100).toFixed(2)}
|
|
|
|
.tab-pane#tab_classroom
|
|
h3#classroom-daus-graph Classroom Daily Active Users 90 days
|
|
.small Paid student: user.coursePrepaidID set and prepaid.properties.trialRequestID NOT set
|
|
.small Trial student: user.coursePrepaidID set and prepaid.properties.trialRequestID set
|
|
.small Free student: not paid, not trial
|
|
.classroom-daily-active-users-chart-90.line-chart-container
|
|
|
|
h3#classroom-maus-graph Classroom Monthly Active Users 90 days
|
|
.classroom-monthly-active-users-chart-90.line-chart-container
|
|
|
|
h3#classroom-daus-graph Classroom Daily Active Users 365 days
|
|
.classroom-daily-active-users-chart-365.line-chart-container
|
|
|
|
h3#classroom-maus-graph Classroom Monthly Active Users 365 days
|
|
.classroom-monthly-active-users-chart-365.line-chart-container
|
|
|
|
h3#enrollments-graph Enrollments Issued and Redeemed 90 days
|
|
.paid-courses-chart.line-chart-container
|
|
|
|
#furthest-course
|
|
h3 Furthest Course in last #{view.furthestCourseDayRangeRecent} days
|
|
.small Restricted to courses instances from last #{view.furthestCourseDayRangeRecent} days
|
|
.small Teacher: owner of a course instance
|
|
.small Student: member of a course instance (assigned to course)
|
|
.small For course instances != Single Player, hourOfCode != true
|
|
.small Counts are not summed. I.e. a student or teacher only contributes to the count of one course
|
|
.small Paid student: user.coursePrepaidID set and prepaid.properties.trialRequestID NOT set
|
|
.small Trial student: user.coursePrepaidID set and prepaid.properties.trialRequestID set
|
|
.small Free student: not paid, not trial
|
|
.small Paid teacher: at least one paid student in course instance
|
|
.small Trial teacher: at least one trial student in course instance, and no paid students
|
|
.small Free teacher: no paid students, no trial students
|
|
.small Paid status takes precedent over furthest course, so teacher furthest course is furthest course of highest paid status student
|
|
if view.courseDistributionsRecent
|
|
table.table.table-striped.table-condensed
|
|
tr
|
|
th Course
|
|
th Paid Teachers
|
|
th Trial Teachers
|
|
th Free Teachers
|
|
th Total Teachers
|
|
th Paid Students
|
|
th Trial Students
|
|
th Free Students
|
|
th Total Students
|
|
each row in view.courseDistributionsRecent
|
|
tr
|
|
td= row.courseName
|
|
td= row.totals['Paid Teachers'] || 0
|
|
td= row.totals['Trial Teachers'] || 0
|
|
td= row.totals['Free Teachers'] || 0
|
|
td= row.totals['Total Teachers'] || 0
|
|
td= row.totals['Paid Students'] || 0
|
|
td= row.totals['Trial Students'] || 0
|
|
td= row.totals['Free Students'] || 0
|
|
td= row.totals['Total Students'] || 0
|
|
else
|
|
div Loading ...
|
|
|
|
h3 Furthest Course in last #{view.furthestCourseDayRange} days
|
|
if view.courseDistributions
|
|
table.table.table-striped.table-condensed
|
|
tr
|
|
th Course
|
|
th Paid Teachers
|
|
th Trial Teachers
|
|
th Free Teachers
|
|
th Total Teachers
|
|
th Paid Students
|
|
th Trial Students
|
|
th Free Students
|
|
th Total Students
|
|
each row in view.courseDistributions
|
|
tr
|
|
td= row.courseName
|
|
td= row.totals['Paid Teachers'] || 0
|
|
td= row.totals['Trial Teachers'] || 0
|
|
td= row.totals['Free Teachers'] || 0
|
|
td= row.totals['Total Teachers'] || 0
|
|
td= row.totals['Paid Students'] || 0
|
|
td= row.totals['Trial Students'] || 0
|
|
td= row.totals['Free Students'] || 0
|
|
td= row.totals['Total Students'] || 0
|
|
else
|
|
div Loading ...
|
|
|
|
#school-sales
|
|
h3 School Sales
|
|
if view.schoolSales
|
|
table.table.table-striped.table-condensed
|
|
tr
|
|
th Amount
|
|
th(style='min-width:85px;') Created
|
|
th PaymentID
|
|
th PrepaidID
|
|
th Description
|
|
th Email
|
|
th School
|
|
each val, i in view.schoolSales
|
|
tr
|
|
td $#{Math.round(val.amount / 100, 2)}
|
|
td= new Date(val.created).toISOString().substring(0, 10)
|
|
td= val._id
|
|
td= val.prepaidID
|
|
td= val.description
|
|
if val.user
|
|
td= val.user.emailLower
|
|
td= val.user.schoolName
|
|
else
|
|
td
|
|
td
|
|
else
|
|
div Loading ...
|
|
|
|
#school-counts
|
|
h3 School Counts
|
|
.small Only including schools with #{view.minSchoolCount}+ counts
|
|
if view.schoolCounts
|
|
table.table.table-striped.table-condensed
|
|
tr
|
|
th
|
|
th School Name
|
|
th User Count
|
|
each val, i in view.schoolCounts
|
|
tr
|
|
td= i + 1
|
|
td= val.schoolName
|
|
td= val.count
|
|
else
|
|
div Loading ...
|
|
|
|
h1#active-users-table Active Users
|
|
if activeUsers.length > 0
|
|
- var eventNames = [];
|
|
each count, event in activeUsers[0].events
|
|
if event.indexOf('classroom') >= 0
|
|
- eventNames.push(event)
|
|
- eventNames.sort(function (a, b) {return a.localeCompare(b);});
|
|
table.table.table-striped.table-condensed
|
|
tr
|
|
th(style='min-width:85px;') Day
|
|
each eventName in eventNames
|
|
th= eventName
|
|
th DAU Classroom Total
|
|
each activeUser in activeUsers
|
|
tr
|
|
td= activeUser.day
|
|
- var dauClassroomTotal = 0
|
|
each eventName in eventNames
|
|
if eventName.indexOf('DAU') >= 0
|
|
- dauClassroomTotal += (activeUser.events[eventName] || 0);
|
|
td= activeUser.events[eventName] || 0
|
|
td= dauClassroomTotal
|
|
|
|
h1#enrollments-table Enrollments
|
|
table.table.table-striped.table-condensed
|
|
tr
|
|
th Day
|
|
th Paid Enrollments Issued
|
|
th Paid Enrollments Redeemed
|
|
th Trial Enrollments Issued
|
|
th Trial Enrollments Redeemed
|
|
each day in enrollmentDays
|
|
tr
|
|
td= day
|
|
if dayEnrollmentsMap[day]
|
|
td= dayEnrollmentsMap[day].paidIssued || 0
|
|
td= dayEnrollmentsMap[day].paidRedeemed || 0
|
|
td= dayEnrollmentsMap[day].trialIssued || 0
|
|
td= dayEnrollmentsMap[day].trialRedeemed || 0
|
|
else
|
|
td 0
|
|
td 0
|
|
td 0
|
|
td 0
|
|
|
|
.tab-pane#tab_campaign
|
|
h3 Campaign Daily Active Users 90 days
|
|
.small Paid user: had monthly or yearly sub on given day
|
|
.small Free user: not paid
|
|
.campaign-daily-active-users-chart-90.line-chart-container
|
|
|
|
h3 Campaign Monthly Active Users 90 days
|
|
.campaign-monthly-active-users-chart-90.line-chart-container
|
|
|
|
h3 Campaign Daily Active Users 365 days
|
|
.campaign-daily-active-users-chart-365.line-chart-container
|
|
|
|
h3 Campaign Monthly Active Users 365 days
|
|
.campaign-monthly-active-users-chart-365.line-chart-container
|
|
|
|
h1#active-users-table Active Users
|
|
if activeUsers.length > 0
|
|
- var eventNames = [];
|
|
each count, event in activeUsers[0].events
|
|
if event.indexOf('campaign') >= 0
|
|
- eventNames.push(event)
|
|
- eventNames.sort(function (a, b) {return a.localeCompare(b);});
|
|
table.table.table-striped.table-condensed
|
|
tr
|
|
th(style='min-width:85px;') Day
|
|
each eventName in eventNames
|
|
th= eventName
|
|
th DAU Total
|
|
each activeUser in activeUsers
|
|
tr
|
|
td= activeUser.day
|
|
- var dauCampaignTotal = 0
|
|
each eventName in eventNames
|
|
if eventName.indexOf('DAU') >= 0
|
|
- dauCampaignTotal += (activeUser.events[eventName] || 0);
|
|
td= activeUser.events[eventName] || 0
|
|
td= dauCampaignTotal
|
|
|
|
|
|
.tab-pane#tab_campaign_vs_classroom
|
|
h3#campaign-vs-classroom-paid-maus-recent-graph Campaign vs Classroom Paid Monthly Active Users 90 days
|
|
.campaign-vs-classroom-monthly-active-users-recent-chart.line-chart-container
|
|
|
|
h3#campaign-vs-classroom-paid-maus-graph Campaign vs Classroom Paid Monthly Active Users 365 days
|
|
.campaign-vs-classroom-monthly-active-users-chart.line-chart-container
|
|
|
|
h1#active-users-table Active Users
|
|
if activeUsers.length > 0
|
|
- var eventNames = [];
|
|
each count, event in activeUsers[0].events
|
|
- eventNames.push(event)
|
|
- eventNames.sort(function (a, b) {
|
|
- if (a.indexOf('campaign') == b.indexOf('campaign') || a.indexOf('classroom') == b.indexOf('classroom')) {
|
|
- return a.localeCompare(b);
|
|
- }
|
|
- else if (a.indexOf('campaign') > b.indexOf('campaign')) {
|
|
- return 1;
|
|
- }
|
|
- else {
|
|
- return -1;
|
|
- }
|
|
- });
|
|
table.table.table-striped.table-condensed
|
|
tr
|
|
th(style='min-width:85px;') Day
|
|
each eventName in eventNames
|
|
th= eventName
|
|
th DAU Campaign Total
|
|
th DAU Classroom Total
|
|
each activeUser in activeUsers
|
|
tr
|
|
td= activeUser.day
|
|
- var dauCampaignTotal = 0
|
|
- var dauClassroomTotal = 0
|
|
each eventName in eventNames
|
|
td= activeUser.events[eventName] || 0
|
|
if eventName.indexOf('DAU campaign') >= 0
|
|
- dauCampaignTotal += (activeUser.events[eventName] || 0);
|
|
else if eventName.indexOf('DAU classroom') >= 0
|
|
- dauClassroomTotal += (activeUser.events[eventName] || 0);
|
|
td= dauCampaignTotal
|
|
td= dauClassroomTotal
|