Merge pull request #7921 from FreeCodeCamp/feature/add-stats
Feature add stats to about page
This commit is contained in:
@ -1,32 +1,59 @@
|
|||||||
|
import { Observable } from 'rx';
|
||||||
import dedent from 'dedent';
|
import dedent from 'dedent';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
|
|
||||||
import { observeMethod } from '../utils/rx';
|
import { timeCache, observeMethod } from '../utils/rx';
|
||||||
|
|
||||||
function numberWithCommas(x) {
|
function numberWithCommas(x) {
|
||||||
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
|
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// userCount(where: Object) => Observable[Number]
|
||||||
|
// getCertCount(userCount: userCount, cert: String) => Observable[Number]
|
||||||
|
function getCertCount(userCount, cert) {
|
||||||
|
return userCount({ [cert]: true })
|
||||||
|
// using This-Bind operator
|
||||||
|
::timeCache(2, 'hours');
|
||||||
|
}
|
||||||
|
|
||||||
export default function about(app) {
|
export default function about(app) {
|
||||||
const router = app.loopback.Router();
|
const router = app.loopback.Router();
|
||||||
const User = app.models.User;
|
const User = app.models.User;
|
||||||
const userCount$ = observeMethod(User, 'count');
|
const userCount = observeMethod(User, 'count');
|
||||||
|
const frontEndCount$ = getCertCount(userCount, 'isFrontEndCert');
|
||||||
|
const dataVisCount$ = getCertCount(userCount, 'isDataVisCert');
|
||||||
|
const backEndCount$ = getCertCount(userCount, 'isBackEndCert');
|
||||||
|
|
||||||
function showAbout(req, res, next) {
|
function showAbout(req, res, next) {
|
||||||
const daysRunning = moment().diff(new Date('10/15/2014'), 'days');
|
const daysRunning = moment().diff(new Date('10/15/2014'), 'days');
|
||||||
|
|
||||||
userCount$()
|
Observable.combineLatest(
|
||||||
.map(camperCount => numberWithCommas(camperCount))
|
frontEndCount$,
|
||||||
.doOnNext(camperCount => {
|
dataVisCount$,
|
||||||
|
backEndCount$,
|
||||||
|
(frontEndCount = 0, dataVisCount = 0, backEndCount = 0) => ({
|
||||||
|
frontEndCount,
|
||||||
|
dataVisCount,
|
||||||
|
backEndCount
|
||||||
|
})
|
||||||
|
)
|
||||||
|
.doOnNext(({ frontEndCount, dataVisCount, backEndCount }) => {
|
||||||
res.render('resources/about', {
|
res.render('resources/about', {
|
||||||
camperCount,
|
frontEndCount: numberWithCommas(frontEndCount),
|
||||||
|
dataVisCount: numberWithCommas(dataVisCount),
|
||||||
|
backEndCount: numberWithCommas(backEndCount),
|
||||||
daysRunning,
|
daysRunning,
|
||||||
title: dedent`
|
title: dedent`
|
||||||
About our Open Source Community, our social media presence,
|
About our Open Source Community, our social media presence,
|
||||||
and how to contact us`.split('\n').join(' '),
|
and how to contact us
|
||||||
|
`.split('\n').join(' '),
|
||||||
globalCompletedCount: numberWithCommas(
|
globalCompletedCount: numberWithCommas(
|
||||||
5612952 + (Math.floor((Date.now() - 1446268581061) / 1800))
|
5612952 + (Math.floor((Date.now() - 1446268581061) / 1800))
|
||||||
)
|
),
|
||||||
|
globalPledgedAmount: numberWithCommas(Math.floor(
|
||||||
|
28000 +
|
||||||
|
((Date.now() - 1456207176902) / (2629746000 / 2000) * 8.30)
|
||||||
|
))
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
.subscribe(() => {}, next);
|
.subscribe(() => {}, next);
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import Rx from 'rx';
|
import Rx, { AsyncSubject, Observable } from 'rx';
|
||||||
|
import moment from 'moment';
|
||||||
import debugFactory from 'debug';
|
import debugFactory from 'debug';
|
||||||
|
|
||||||
const debug = debugFactory('fcc:rxUtils');
|
const debug = debugFactory('fcc:rxUtils');
|
||||||
@ -31,3 +32,22 @@ export function observeQuery(Model, method, query) {
|
|||||||
export function observeMethod(context, methodName) {
|
export function observeMethod(context, methodName) {
|
||||||
return Rx.Observable.fromNodeCallback(context[methodName], context);
|
return Rx.Observable.fromNodeCallback(context[methodName], context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// timeChache(amount: Number, unit: String) => Observable
|
||||||
|
export function timeCache(time, unit) {
|
||||||
|
const source = this;
|
||||||
|
let cache;
|
||||||
|
let expireCacheAt;
|
||||||
|
return Observable.create(observable => {
|
||||||
|
// if there is no expire time set
|
||||||
|
// or if expireCacheAt is smaller than now,
|
||||||
|
// set new expire time in MS and create new subscription to source
|
||||||
|
if (!expireCacheAt || expireCacheAt < Date.now()) {
|
||||||
|
// set expire in ms;
|
||||||
|
expireCacheAt = moment().add(time, unit).valueOf();
|
||||||
|
cache = new AsyncSubject();
|
||||||
|
source.subscribe(cache);
|
||||||
|
}
|
||||||
|
return cache.subscribe(observable);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
@ -9,18 +9,31 @@ block content
|
|||||||
span.tag Established:	
|
span.tag Established:	
|
||||||
span.text-primary #{daysRunning}
|
span.text-primary #{daysRunning}
|
||||||
| days ago
|
| days ago
|
||||||
li
|
|
||||||
span.tag Population:	
|
|
||||||
span.text-primary #{camperCount}
|
|
||||||
| campers
|
|
||||||
li
|
|
||||||
span.tag Completed:	
|
|
||||||
span.text-primary #{globalCompletedCount}
|
|
||||||
| challenges
|
|
||||||
li.nowrap
|
li.nowrap
|
||||||
span.tag Donated:	
|
span.tag Donated:	
|
||||||
span.text-primary $850,000
|
span.text-primary $850,000
|
||||||
| in pro-bono code
|
| in pro-bono code
|
||||||
|
li.nowrap
|
||||||
|
span.tag Pledged:	
|
||||||
|
span.text-primary $#{globalPledgedAmount}
|
||||||
|
| to nonprofits
|
||||||
|
.row
|
||||||
|
.col-xs-12.col-sm-10.col-sm-offset-1.col-md-6.col-md-offset-3
|
||||||
|
h2.text-center Certifications
|
||||||
|
hr
|
||||||
|
ul.population-table
|
||||||
|
li.nowrap
|
||||||
|
span.tag Front End:	
|
||||||
|
span.text-primary #{frontEndCount}
|
||||||
|
| earned
|
||||||
|
li.nowrap
|
||||||
|
span.tag Data Viz:	
|
||||||
|
span.text-primary #{dataVisCount}
|
||||||
|
| earned
|
||||||
|
li.nowrap
|
||||||
|
span.tag Back End:	
|
||||||
|
span.text-primary #{backEndCount}
|
||||||
|
| earned
|
||||||
.spacer
|
.spacer
|
||||||
.row
|
.row
|
||||||
.col-xs-12.col-sm-10.col-sm-offset-1.col-md-6.col-md-offset-3
|
.col-xs-12.col-sm-10.col-sm-offset-1.col-md-6.col-md-offset-3
|
||||||
|
Reference in New Issue
Block a user