Skip to content

Commit

Permalink
initial react app(WIP)
Browse files Browse the repository at this point in the history
  • Loading branch information
Berkeley Martinez authored and Berkeley Martinez committed Jul 23, 2015
1 parent 05c6dcd commit a5e7009
Show file tree
Hide file tree
Showing 19 changed files with 46,917 additions and 68 deletions.
3 changes: 3 additions & 0 deletions .babelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"stage": 0
}
7 changes: 5 additions & 2 deletions client/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,17 @@ import BrowserHistory from 'react-router/lib/BrowserHistory';
import debugFactory from 'debug';
import { Cat } from 'thundercats';

import AppFactory from '../common/app/appFactory';
import app$ from '../common/app/app$.jsx';

const debug = debugFactory('fcc:client');
const DOMContianer = document.getElemenetById('#fCC');
const fcc = new Cat();

// returns an observable
fcc.render(AppFactory(BrowserHistory), DOMContianer)
app$(BrowserHistory)
.flatMap(app => {
return fcc.render(app, DOMContianer);
})
.subscribe(
function() {
debug('react rendered');
Expand Down
25 changes: 25 additions & 0 deletions common/app/app-stream.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import Rx from 'rx';
import React from 'react';
import { Route, Router } from 'react-router';

// components
import App from './App.jsx';
import Jobs from './routes/Jobs';
import NotFound from './components/NotFound';

const router$ = Rx.Observable.fromNodeCallback(Router.run, Router);

export const routes = (
<Route handler={ App }>
<Route
component={ Jobs }
path='/jobs' />
<Route
component={ NotFound }
path='*' />
</Route>
);

export default function app$(location) {
return router$(routes, location);
}
18 changes: 0 additions & 18 deletions common/app/appFactory.jsx

This file was deleted.

7 changes: 3 additions & 4 deletions common/app/components/Nav/Nav.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import React from 'react';
import { Nav, Navbar, NavItem } from 'react-bootstrap';
import NavItemFCC from './NavItem.jsx';

export default class extends React.Component {
constructor(props) {
Expand Down Expand Up @@ -34,12 +33,12 @@ export default class extends React.Component {
);
} else {
return (
<NavItemFCC
aClassName='btn signup-btn signup-btn-nav'
<NavItem
className='btn signup-btn signup-btn-nav'
eventKey={ 2 }
href='/login'>
Sign In
</NavItemFCC>
</NavItem>
);
}
}
Expand Down
81 changes: 40 additions & 41 deletions common/app/components/Nav/NavItem.jsx
Original file line number Diff line number Diff line change
@@ -1,44 +1,55 @@
var React = require('react/addons');
var joinClasses = require('react-bootstrap/lib/utils/joinClasses');
var classSet = React.addons.classSet;
var BootstrapMixin = require('react-bootstrap').BootstrapMixin;
import React from 'react';
import classnames from 'classnames';

var NavItem = React.createClass({
mixins: [BootstrapMixin],
export default class extends React.Component {
constructor(props) {
super(props);
}

propTypes: {
static displayName = 'NavItem'
static propTypes = {
onSelect: React.PropTypes.func,
active: React.PropTypes.bool,
disabled: React.PropTypes.bool,
href: React.PropTypes.string,
title: React.PropTypes.string,
eventKey: React.PropTypes.any,
target: React.PropTypes.string
},
}

getDefaultProps: function () {
return {
href: '#'
};
},
handleClick(e) {
if (this.props.onSelect) {
e.preventDefault();

if (!this.props.disabled) {
this.props.onSelect(
this.props.eventKey,
this.props.href,
this.props.target
);
}
}
}

render: function () {
var {
disabled,
active,
href,
title,
target,
children,
} = this.props,
props = this.props,
classes = {
'active': active,
'disabled': disabled
};
render() {
const {
disabled,
active,
href,
title,
target,
children,
} = this.props;

const classes = {
'active': active,
'disabled': disabled
};

return (
<li {...props} className={joinClasses(props.className, classSet(classes))}>
<li
className={ joinClasses(props.className, classSet(classes)) }
{ ...this.props }>
<a
href={href}
title={title}
Expand All @@ -50,17 +61,5 @@ var NavItem = React.createClass({
</a>
</li>
);
},

handleClick: function (e) {
if (this.props.onSelect) {
e.preventDefault();

if (!this.props.disabled) {
this.props.onSelect(this.props.eventKey, this.props.href, this.props.target);
}
}
}
});

module.exports = NavItem;
}
14 changes: 14 additions & 0 deletions common/app/components/NotFound/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import React from 'react';

export default class extends React.Component {
constructor(props) {
super(props);
}
static displayName = 'NotFound'
static propTypes = {}
componentDidMount() {
}
render() {
return null;
}
}
2 changes: 1 addition & 1 deletion common/app/routes/Jobs/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export default {
getComponents(cb) {
require.ensure([], require => {
cb(null, [
require('./components/Jobs')
require('./components/Jobs.jsx')
]);
});
}
Expand Down
29 changes: 29 additions & 0 deletions gulpfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ var gulp = require('gulp'),
envify = require('envify/custom'),
toVinylWithName = require('vinyl-source-stream'),

// react app
webpack = require('gulp-webpack'),
webpackConfig = require('./webpack.config.js'),
webpackConfigNode = require('./webpack.config.node.js'),

// server process
nodemon = require('gulp-nodemon'),
sync = require('browser-sync'),
Expand Down Expand Up @@ -41,6 +46,16 @@ var paths = {
clientName: 'lbApp'
},

client: {
src: './client',
dest: 'public/js'
},

node: {
src: './client',
dest: 'server/server'
},

syncWatch: [
'public/**/*.*'
]
Expand Down Expand Up @@ -83,6 +98,20 @@ gulp.task('loopback', function() {
.pipe(gulp.dest(paths.publicJs));
});

gulp.task('pack-client', function() {
return gulp.src(paths.client.src)
.pipe(webpack(webpackConfig))
.pipe(gulp.dest(paths.client.dest));
});

gulp.task('pack-node', function() {
return gulp.src(paths.node.src)
.pipe(webpack(webpackConfigNode))
.pipe(gulp.dest(paths.node.dest));
});

gulp.task('pack', ['pack-client', 'pack-node']);

gulp.task('serve', function(cb) {
var called = false;
nodemon({
Expand Down
12 changes: 11 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,13 @@
"dependencies": {
"accepts": "~1.2.5",
"async": "~0.9.0",
"babel-core": "^5.6.15",
"babel-loader": "^5.2.2",
"bcrypt-nodejs": "~0.0.3",
"body-parser": "~1.9.3",
"chai-jquery": "~2.0.0",
"cheerio": "~0.18.0",
"classnames": "^2.1.2",
"clockwork": "~0.1.1",
"compression": "~1.2.1",
"connect-mongo": "~0.7.0",
Expand All @@ -45,16 +48,20 @@
"express": "~4.10.4",
"express-flash": "~0.0.2",
"express-session": "~1.9.2",
"express-state": "^1.2.0",
"express-validator": "~2.8.0",
"fetchr": "^0.4.16",
"font-awesome": "~4.3.0",
"forever": "~0.14.1",
"frameguard": "^0.2.2",
"github-api": "~0.7.0",
"gulp-less": "^3.0.3",
"gulp-minify-css": "~0.5.1",
"gulp-webpack": "^1.5.0",
"helmet": "~0.9.0",
"helmet-csp": "^0.2.3",
"jade": "~1.8.0",
"json-loader": "^0.5.2",
"less": "~1.7.5",
"less-middleware": "~2.0.1",
"lodash": "^3.9.3",
Expand All @@ -67,6 +74,7 @@
"moment": "~2.10.2",
"mongodb": "^2.0.33",
"morgan": "~1.5.0",
"node-libs-browser": "^0.5.2",
"node-slack": "0.0.7",
"node-uuid": "^1.4.3",
"nodemailer": "~1.3.0",
Expand All @@ -80,15 +88,17 @@
"pmx": "^0.3.16",
"ramda": "~0.10.0",
"react": "^0.13.3",
"react-bootstrap": "^0.23.4",
"react-bootstrap": "^0.23.5",
"react-router": "^1.0.0-beta1",
"request": "~2.53.0",
"rx": "^2.5.3",
"sanitize-html": "~1.6.1",
"source-map-support": "^0.3.2",
"thundercats": "^2.0.0-rc6",
"twit": "~1.1.20",
"uglify-js": "~2.4.15",
"validator": "~3.22.1",
"webpack": "^1.9.12",
"yui": "~3.18.1"
},
"devDependencies": {
Expand Down
57 changes: 57 additions & 0 deletions server/boot/a-react.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// appFactory is an es6 module
var debug = require('debug')('freecc:servereact');
var app$ = require('../common/app/app-stream.jsx').default;
var Cat = require('thundercats').Cat;

var routes = [
'/jobs'
];

module.exports = function(app) {
var router = app.Router();

routes.forEach(function(route) {
router.get(route, serveReactApp);
});

app.use(router);

function serveReactApp(req, res, next) {
var fcc = new Cat();
var decodedUrl = decodeURI(req.path);

// returns a router wrapped app
app$(decodedUrl)
// if react-router does not find a route send down the chain
.filter(function(data) {
var state = data.state;
// this may not work with react-router 1.0.0
var notFound = state.routes.some(route => route.isNotFound);
if (notFound) {
debug('tried to find %s but got 404', state.path);
next();
}
return !notFound;
})
.flatMap(function(app) {
// call thundercats renderToString
// prefetches data and sets up it up for current state
return fcc.renderToString(app);
})
// makes sure we only get one onNext and closes subscription
.firstOrDefault()
.flatMap(function(dats) {
debug('react rendered');
res.expose(dats.data, 'data');
// now render jade file with markup injected from react
return res.render$('layout-react', { markup: dats.markup });
})
.subscribe(
function(markup) {
debug('jade rendered');
res.send(markup);
},
next
);
}
};
Loading

0 comments on commit a5e7009

Please sign in to comment.