parent
77a0a82118
commit
a1a4ac883d
|
@ -1,8 +1,9 @@
|
|||
import Rx from 'rx';
|
||||
import React from 'react';
|
||||
import Fetchr from 'fetchr';
|
||||
import debugFactory from 'debug';
|
||||
import { Router } from 'react-router';
|
||||
import { history } from 'react-router/lib/BrowserHistory';
|
||||
import debugFactory from 'debug';
|
||||
import { hydrate } from 'thundercats';
|
||||
import { Render } from 'thundercats-react';
|
||||
|
||||
|
@ -11,6 +12,9 @@ import { app$ } from '../common/app';
|
|||
const debug = debugFactory('fcc:client');
|
||||
const DOMContianer = document.getElementById('fcc');
|
||||
const catState = window.__fcc__.data || {};
|
||||
const services = new Fetchr({
|
||||
xhrPath: '/services'
|
||||
});
|
||||
|
||||
Rx.longStackSupport = !!debug.enabled;
|
||||
|
||||
|
@ -18,7 +22,7 @@ Rx.longStackSupport = !!debug.enabled;
|
|||
app$(history)
|
||||
.flatMap(
|
||||
({ AppCat }) => {
|
||||
const appCat = AppCat();
|
||||
const appCat = AppCat(null, services);
|
||||
return hydrate(appCat, catState)
|
||||
.map(() => appCat);
|
||||
},
|
||||
|
|
|
@ -1,28 +1,37 @@
|
|||
import React, { PropTypes } from 'react';
|
||||
import { contain } from 'thundercats-react';
|
||||
import { Row } from 'react-bootstrap';
|
||||
|
||||
import { Nav } from './components/Nav';
|
||||
import { Footer } from './components/Footer';
|
||||
|
||||
export default class extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
}
|
||||
export default contain(
|
||||
{
|
||||
store: 'appStore',
|
||||
fetchAction: 'appActions.getUser',
|
||||
getPayload(props) {
|
||||
return {
|
||||
isPrimed: !!props.username
|
||||
};
|
||||
}
|
||||
},
|
||||
React.createClass({
|
||||
displayName: 'FreeCodeCamp',
|
||||
|
||||
static displayName = 'FreeCodeCamp'
|
||||
static propTypes = {
|
||||
children: PropTypes.node
|
||||
}
|
||||
propTypes: {
|
||||
children: PropTypes.node
|
||||
},
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
<Nav />
|
||||
<Row>
|
||||
{ this.props.children }
|
||||
</Row>
|
||||
<Footer />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
<Nav />
|
||||
<Row>
|
||||
{ this.props.children }
|
||||
</Row>
|
||||
<Footer />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
})
|
||||
);
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
import { Cat } from 'thundercats';
|
||||
import { HikesActions, HikesStore } from './routes/Hikes/flux';
|
||||
|
||||
import { AppActions, AppStore } from './flux';
|
||||
|
||||
export default Cat()
|
||||
.init(({ instance }) => {
|
||||
instance.register(HikesActions);
|
||||
instance.register(HikesStore, null, instance);
|
||||
.init(({ instance: cat, args: [services] }) => {
|
||||
cat.register(AppActions, null, services);
|
||||
cat.register(AppStore, null, cat);
|
||||
cat.register(HikesActions, null, services);
|
||||
cat.register(HikesStore, null, cat);
|
||||
});
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
import { Actions } from 'thundercats';
|
||||
import debugFactory from 'debug';
|
||||
|
||||
const debug = debugFactory('freecc:app:actions');
|
||||
|
||||
export default Actions({
|
||||
setUser({ username, picture, progressTimestamps = [] }) {
|
||||
return {
|
||||
username,
|
||||
picture,
|
||||
points: progressTimestamps.length
|
||||
};
|
||||
},
|
||||
getUser: null
|
||||
})
|
||||
.refs({ displayName: 'AppActions' })
|
||||
.init(({ instance: appActions, args: [services] }) => {
|
||||
appActions.getUser.subscribe(({ isPrimed }) => {
|
||||
if (isPrimed) {
|
||||
debug('isPrimed');
|
||||
return;
|
||||
}
|
||||
services.read('user', null, null, (err, user) => {
|
||||
if (err) {
|
||||
return debug('user service error');
|
||||
}
|
||||
debug('user service returned successful');
|
||||
return appActions.setUser(user);
|
||||
});
|
||||
});
|
||||
});
|
|
@ -0,0 +1,18 @@
|
|||
import { Store } from 'thundercats';
|
||||
|
||||
const { createRegistrar, setter } = Store;
|
||||
const initValue = {
|
||||
username: null,
|
||||
picture: null,
|
||||
points: 0
|
||||
};
|
||||
|
||||
export default Store(initValue)
|
||||
.refs({ displayName: 'AppStore' })
|
||||
.init(({ instance: appStore, args: [cat] }) => {
|
||||
const { setUser } = cat.getActions('appActions');
|
||||
const register = createRegistrar(appStore);
|
||||
register(setter(setUser));
|
||||
|
||||
return appStore;
|
||||
});
|
|
@ -0,0 +1,2 @@
|
|||
export AppActions from './Actions';
|
||||
export AppStore from './Store';
|
|
@ -1,12 +1,8 @@
|
|||
import { Actions } from 'thundercats';
|
||||
import assign from 'object.assign';
|
||||
import debugFactory from 'debug';
|
||||
import Fetchr from 'fetchr';
|
||||
|
||||
const debug = debugFactory('freecc:hikes:actions');
|
||||
const service = new Fetchr({
|
||||
xhrPath: '/services'
|
||||
});
|
||||
|
||||
function getCurrentHike(hikes =[{}], dashedName, currentHike) {
|
||||
if (!dashedName) {
|
||||
|
@ -36,7 +32,7 @@ export default Actions({
|
|||
setHikes: null
|
||||
})
|
||||
.refs({ displayName: 'HikesActions' })
|
||||
.init(({ instance }) => {
|
||||
.init(({ instance, args: [services] }) => {
|
||||
// set up hikes fetching
|
||||
instance.fetchHikes.subscribe(
|
||||
({ isPrimed, dashedName }) => {
|
||||
|
@ -53,7 +49,7 @@ export default Actions({
|
|||
}
|
||||
});
|
||||
}
|
||||
service.read('hikes', null, null, (err, hikes) => {
|
||||
services.read('hikes', null, null, (err, hikes) => {
|
||||
if (err) {
|
||||
debug('an error occurred fetching hikes', err);
|
||||
}
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
import React from 'react';
|
||||
import Router from 'react-router';
|
||||
import Fetchr from 'fetchr';
|
||||
import Location from 'react-router/lib/Location';
|
||||
import debugFactory from 'debug';
|
||||
import { app$ } from '../../common/app';
|
||||
import { RenderToString } from 'thundercats-react';
|
||||
|
||||
const debug = debugFactory('freecc:servereact');
|
||||
const debug = debugFactory('freecc:react-server');
|
||||
|
||||
// add routes here as they slowly get reactified
|
||||
// remove their individual controllers
|
||||
|
@ -25,6 +26,7 @@ export default function reactSubRouter(app) {
|
|||
app.use(router);
|
||||
|
||||
function serveReactApp(req, res, next) {
|
||||
const services = new Fetchr({ req });
|
||||
const location = new Location(req.path, req.query);
|
||||
|
||||
// returns a router wrapped app
|
||||
|
@ -42,7 +44,7 @@ export default function reactSubRouter(app) {
|
|||
// prefetches data and sets up it up for current state
|
||||
debug('rendering to string');
|
||||
return RenderToString(
|
||||
AppCat(),
|
||||
AppCat(null, services),
|
||||
React.createElement(Router, initialState)
|
||||
);
|
||||
})
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
import Fetchr from 'fetchr';
|
||||
import getHikesService from '../services/hikes';
|
||||
import getUserServices from '../services/user';
|
||||
|
||||
export default function bootServices(app) {
|
||||
const hikesService = getHikesService(app);
|
||||
const userServices = getUserServices(app);
|
||||
Fetchr.registerFetcher(hikesService);
|
||||
Fetchr.registerFetcher(userServices);
|
||||
app.use('/services', Fetchr.middleware());
|
||||
}
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
import debugFactory from 'debug';
|
||||
import assign from 'object.assign';
|
||||
|
||||
const censor = '**********************:P********';
|
||||
const debug = debugFactory('freecc:services:user');
|
||||
const protectedUserFields = {
|
||||
id: censor,
|
||||
password: censor,
|
||||
profiles: censor
|
||||
};
|
||||
|
||||
export default function userServices(/* app */) {
|
||||
return {
|
||||
name: 'user',
|
||||
read: (req, resource, params, config, cb) => {
|
||||
let { user } = req;
|
||||
if (user) {
|
||||
debug('user is signed in');
|
||||
// Zalgo!!!
|
||||
return process.nextTick(() => {
|
||||
cb(null, assign({}, user.toJSON(), protectedUserFields));
|
||||
});
|
||||
}
|
||||
debug('user is not signed in');
|
||||
return process.nextTick(() => {
|
||||
cb(null, {});
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
Loading…
Reference in New Issue