mirror of
https://github.com/codeninjasllc/codecombat.git
synced 2025-02-17 08:50:58 -05:00
Update admin subs dashboard
This commit is contained in:
parent
ce56312120
commit
b500e5334a
2 changed files with 47 additions and 10 deletions
|
@ -47,7 +47,10 @@ block content
|
|||
tr
|
||||
th User Start
|
||||
th Sub Start
|
||||
th
|
||||
if subscriberCancelled
|
||||
th Cancelled
|
||||
else
|
||||
th
|
||||
th
|
||||
//- th Name
|
||||
th Email
|
||||
|
|
|
@ -3,8 +3,6 @@ template = require 'templates/admin/analytics-subscriptions'
|
|||
ThangType = require 'models/ThangType'
|
||||
User = require 'models/User'
|
||||
|
||||
# TODO: Add last N subscribers table
|
||||
# TODO: Add revenue line
|
||||
# TODO: Graphing code copied/mangled from campaign editor level view. OMG, DRY.
|
||||
|
||||
require 'vendor/d3'
|
||||
|
@ -12,10 +10,11 @@ require 'vendor/d3'
|
|||
module.exports = class AnalyticsSubscriptionsView extends RootView
|
||||
id: 'admin-analytics-subscriptions-view'
|
||||
template: template
|
||||
targetSubCount: 2000
|
||||
|
||||
constructor: (options) ->
|
||||
super options
|
||||
@resetData()
|
||||
@resetSubscriptionsData()
|
||||
if me.isAdmin()
|
||||
@refreshData()
|
||||
_.delay (=> @refreshData()), 30 * 60 * 1000
|
||||
|
@ -25,6 +24,7 @@ module.exports = class AnalyticsSubscriptionsView extends RootView
|
|||
context.analytics = @analytics ? graphs: []
|
||||
context.subs = _.cloneDeep(@subs ? []).reverse()
|
||||
context.subscribers = @subscribers ? []
|
||||
context.subscriberCancelled = _.find context.subscribers, (subscriber) -> subscriber.cancel
|
||||
context.total = @total ? 0
|
||||
context.cancelled = @cancelled ? 0
|
||||
context.monthlyChurn = @monthlyChurn ? 0.0
|
||||
|
@ -35,16 +35,17 @@ module.exports = class AnalyticsSubscriptionsView extends RootView
|
|||
super()
|
||||
@updateAnalyticsGraphs()
|
||||
|
||||
resetData: ->
|
||||
resetSubscriptionsData: ->
|
||||
@analytics = graphs: []
|
||||
@subs = []
|
||||
@total = 0
|
||||
@cancelled = 0
|
||||
@monthlyChurn = 0.0
|
||||
@monthlyGrowth = 0.0
|
||||
|
||||
refreshData: ->
|
||||
return unless me.isAdmin()
|
||||
@resetData()
|
||||
@resetSubscriptionsData()
|
||||
@getSubscribers()
|
||||
@getSubscriptions()
|
||||
|
||||
|
@ -75,7 +76,7 @@ module.exports = class AnalyticsSubscriptionsView extends RootView
|
|||
console.error 'Failed to get subscriptions', response
|
||||
options.success = (subs, response, options) =>
|
||||
return if @destroyed
|
||||
@resetData()
|
||||
@resetSubscriptionsData()
|
||||
subDayMap = {}
|
||||
for sub in subs
|
||||
startDay = sub.start.substring(0, 10)
|
||||
|
@ -121,6 +122,7 @@ module.exports = class AnalyticsSubscriptionsView extends RootView
|
|||
# TODO: Where should this metadata live?
|
||||
# TODO: lineIDs assumed to be unique across graphs
|
||||
totalSubsID = 'total-subs'
|
||||
targetSubsID = 'target-subs'
|
||||
startedSubsID = 'started-subs'
|
||||
cancelledSubsID = 'cancelled-subs'
|
||||
netSubsID = 'net-subs'
|
||||
|
@ -129,6 +131,11 @@ module.exports = class AnalyticsSubscriptionsView extends RootView
|
|||
description: 'Total Active Subscriptions'
|
||||
color: 'green'
|
||||
strokeWidth: 1
|
||||
lineMetadata[targetSubsID] =
|
||||
description: 'Target Total Subscriptions'
|
||||
color: 'gold'
|
||||
strokeWidth: 4
|
||||
opacity: 1.0
|
||||
lineMetadata[startedSubsID] =
|
||||
description: 'New Subscriptions'
|
||||
color: 'blue'
|
||||
|
@ -185,8 +192,9 @@ module.exports = class AnalyticsSubscriptionsView extends RootView
|
|||
points: levelPoints
|
||||
description: lineMetadata[totalSubsID].description
|
||||
lineColor: lineMetadata[totalSubsID].color
|
||||
strokeWidth: lineMetadata[totalSubsID].strokeWidth
|
||||
min: 0
|
||||
max: d3.max(@subs, (d) -> d.total)
|
||||
max: Math.max(@targetSubCount, d3.max(@subs, (d) -> d.total))
|
||||
|
||||
## Started
|
||||
|
||||
|
@ -219,9 +227,34 @@ module.exports = class AnalyticsSubscriptionsView extends RootView
|
|||
points: levelPoints
|
||||
description: lineMetadata[startedSubsID].description
|
||||
lineColor: lineMetadata[startedSubsID].color
|
||||
strokeWidth: lineMetadata[startedSubsID].strokeWidth
|
||||
min: 0
|
||||
max: d3.max(@subs, (d) -> d.started)
|
||||
|
||||
## Total subs target
|
||||
|
||||
# Build line data
|
||||
levelPoints = []
|
||||
for sub, i in @subs
|
||||
levelPoints.push
|
||||
x: i
|
||||
y: @targetSubCount
|
||||
day: sub.day
|
||||
pointID: "#{targetSubsID}#{i}"
|
||||
values: []
|
||||
|
||||
levelPoints.splice(0, levelPoints.length - timeframeDays) if levelPoints.length > timeframeDays
|
||||
|
||||
@analytics.graphs[0].lines.push
|
||||
lineID: targetSubsID
|
||||
enabled: true
|
||||
points: levelPoints
|
||||
description: lineMetadata[targetSubsID].description
|
||||
lineColor: lineMetadata[targetSubsID].color
|
||||
strokeWidth: lineMetadata[targetSubsID].strokeWidth
|
||||
min: 0
|
||||
max: @targetSubCount
|
||||
|
||||
## Cancelled
|
||||
averageCancelled = 0
|
||||
|
||||
|
@ -258,6 +291,7 @@ module.exports = class AnalyticsSubscriptionsView extends RootView
|
|||
points: levelPoints
|
||||
description: lineMetadata[cancelledSubsID].description
|
||||
lineColor: lineMetadata[cancelledSubsID].color
|
||||
strokeWidth: lineMetadata[cancelledSubsID].strokeWidth
|
||||
min: 0
|
||||
max: d3.max(@subs, (d) -> d.started)
|
||||
|
||||
|
@ -333,7 +367,7 @@ module.exports = class AnalyticsSubscriptionsView extends RootView
|
|||
xRange = d3.scale.linear().range([0, width]).domain([d3.min(line.points, (d) -> d.x), d3.max(line.points, (d) -> d.x)])
|
||||
yRange = d3.scale.linear().range([height, 0]).domain([line.min, line.max])
|
||||
|
||||
# x-Axis and guideline once
|
||||
# x-Axis
|
||||
if currentLine is 0
|
||||
startDay = new Date(line.points[0].day)
|
||||
endDay = new Date(line.points[line.points.length - 1].day)
|
||||
|
@ -392,7 +426,7 @@ module.exports = class AnalyticsSubscriptionsView extends RootView
|
|||
svg.append("text")
|
||||
.attr("x", margin + 40 + 10)
|
||||
.attr("y", margin + height + xAxisHeight + keyHeight * currentLine + (keyHeight + 10) / 2)
|
||||
.attr("fill", line.lineColor)
|
||||
.attr("fill", if line.lineColor is 'gold' then 'orange' else line.lineColor)
|
||||
.attr("class", "key-text")
|
||||
.text(line.description)
|
||||
|
||||
|
|
Loading…
Reference in a new issue