diff --git a/client/README.md b/client/README.md
new file mode 100644
index 0000000000..b75516ce38
--- /dev/null
+++ b/client/README.md
@@ -0,0 +1,3 @@
+This is the entry point for the client
+Code that should only run on the client should be put here.
+NOTE(berks): For react specific stuff this should be the entry point
diff --git a/client/index.js b/client/index.js
new file mode 100644
index 0000000000..68baa7ec0a
--- /dev/null
+++ b/client/index.js
@@ -0,0 +1,20 @@
+import BrowserHistory from 'react-router/lib/BrowserHistory';
+import debugFactory from 'debug';
+import { Cat } from 'thundercats';
+
+import AppFactory from '../common/app/appFactory';
+
+const debug = debugFactory('fcc:client');
+const DOMContianer = document.getElemenetById('#fCC');
+const fcc = new Cat();
+
+// returns an observable
+fcc.render(AppFactory(BrowserHistory), DOMContianer)
+ .subscribe(
+ function() {
+ debug('react rendered');
+ },
+ function(err) {
+ debug('an error has occured', err.stack);
+ }
+ );
diff --git a/common/app/App.jsx b/common/app/App.jsx
new file mode 100644
index 0000000000..f3a77cae51
--- /dev/null
+++ b/common/app/App.jsx
@@ -0,0 +1,25 @@
+import React, { PropTypes } from 'react';
+
+import Nav from './components/Nav';
+import Footer from './components/Footer';
+
+export default class extends React.Component {
+ constructor(props) {
+ super(props);
+ }
+
+ static displayName = 'FreeCodeCamp'
+ static propTypes = {
+ children: PropTypes.node
+ }
+
+ render() {
+ return (
+
+
+ { this.props.children }
+
+
+ );
+ }
+}
diff --git a/common/app/appFactory.jsx b/common/app/appFactory.jsx
new file mode 100644
index 0000000000..b8732a89c6
--- /dev/null
+++ b/common/app/appFactory.jsx
@@ -0,0 +1,18 @@
+import React from 'react';
+import { Router, Route } from 'react-router';
+
+// components
+import App from './App.jsx';
+import Jobs from './screens/App/screens/Jobs';
+
+module.exports = function appFactory(history) {
+ return (
+
+
+
+
+
+ );
+};
diff --git a/common/app/components/Footer/Footer.jsx b/common/app/components/Footer/Footer.jsx
new file mode 100644
index 0000000000..f95e0e3adc
--- /dev/null
+++ b/common/app/components/Footer/Footer.jsx
@@ -0,0 +1,50 @@
+import React from 'react';
+import { Col, Row, Grid } from 'react-bootstrap';
+
+import links from './links.json';
+
+export default class extends React.Component {
+ static displayName = 'Footer'
+ renderLinks(mobile) {
+ return links.map(link => {
+ return (
+
+ { this.renderContent(mobile, link.content) }
+
+ );
+ });
+ }
+
+ renderContent(mobile, content) {
+ if (mobile) {
+ return (
+
+ content;
+
+ );
+ }
+ return content;
+ }
+
+ render() {
+ return (
+
+
+
+ { this.renderLinks() }
+
+
+ { this.renderLinks(true) }
+
+
+
+ );
+ }
+}
diff --git a/common/app/components/Footer/index.js b/common/app/components/Footer/index.js
new file mode 100644
index 0000000000..c50e0cda87
--- /dev/null
+++ b/common/app/components/Footer/index.js
@@ -0,0 +1 @@
+export { default as Footer } from './Footer.jsx';
diff --git a/common/app/components/Footer/links.json b/common/app/components/Footer/links.json
new file mode 100644
index 0000000000..54071917b4
--- /dev/null
+++ b/common/app/components/Footer/links.json
@@ -0,0 +1,44 @@
+[
+ {
+ "className": "ion-speakerphone",
+ "content": " Blog ",
+ "href": "http://blog.freecodecamp.com",
+ "target": "_blank"
+ },
+ {
+ "className": "ion-social-twitch-outline",
+ "content": " Twitch ",
+ "href": "http://www.twitch.tv/freecodecamp",
+ "target": "_blank"
+ },
+ {
+ "className": "ion-social-github",
+ "content": " Github ",
+ "href": "http://github.com/freecodecamp",
+ "target": "_blank"
+ },
+ {
+ "className": "ion-social-twitter",
+ "content": " Twitter ",
+ "href": "http://twitter.com/freecodecamp",
+ "target": "_blank"
+ },
+ {
+ "className": "ion-social-facebook",
+ "content": " Facebook ",
+ "href": "http://facebook.com/freecodecamp",
+ "target": "_blank"
+ },
+ {
+ "className": "ion-information-circled",
+ "content": " About ",
+ "href": "/learn-to-code",
+ "target": "_self"
+ },
+ {
+ "className": "ion-locked",
+ "content": " Privacy ",
+ "href": "/privacy'",
+ "target": "_self"
+ }
+]
diff --git a/common/screens/nav/Nav.jsx b/common/app/components/Nav/Nav.jsx
similarity index 56%
rename from common/screens/nav/Nav.jsx
rename to common/app/components/Nav/Nav.jsx
index 52a9a8728b..f5c339c2c1 100644
--- a/common/screens/nav/Nav.jsx
+++ b/common/app/components/Nav/Nav.jsx
@@ -1,31 +1,30 @@
-var React = require('react'),
- bootStrap = require('react-bootstrap'),
- Navbar = bootStrap.Navbar,
- Nav = bootStrap.Nav,
- NavItem = bootStrap.NavItem,
- NavItemFCC = require('./NavItem.jsx');
+import React from 'react';
+import { Nav, Navbar, NavItem } from 'react-bootstrap';
+import NavItemFCC from './NavItem.jsx';
-var NavBarComp = React.createClass({
+export default class extends React.Component {
+ constructor(props) {
+ super(props);
+ }
- propTypes: { signedIn: React.PropTypes.bool },
+ static displayName = 'Nav'
+ static propTypes = {
+ signedIn: React.PropTypes.bool
+ }
- getDefaultProps: function() {
- return { signedIn: false };
- },
-
- _renderBrand: function() {
+ renderBrand() {
var fCClogo = 'https://s3.amazonaws.com/freecodecamp/freecodecamp_logo.svg';
return (
+ className='img-responsive nav-logo'
+ src={ fCClogo } />
);
- },
+ }
- _renderSignin: function() {
+ renderSignin() {
if (this.props.signedIn) {
return (
- Sign In
+ href='/login'>
+ Sign In
);
}
- },
-
- render: function() {
+ }
+ render() {
return (
+ toggleNavKey={ 0 }>
);
}
-});
-module.exports = NavBarComp;
+}
diff --git a/common/screens/nav/NavItem.jsx b/common/app/components/Nav/NavItem.jsx
similarity index 100%
rename from common/screens/nav/NavItem.jsx
rename to common/app/components/Nav/NavItem.jsx
diff --git a/common/app/components/Nav/index.js b/common/app/components/Nav/index.js
new file mode 100644
index 0000000000..d04d01f62d
--- /dev/null
+++ b/common/app/components/Nav/index.js
@@ -0,0 +1 @@
+export { default as Nav } from './Nav.jsx';
diff --git a/common/app/components/README.md b/common/app/components/README.md
new file mode 100644
index 0000000000..e5b2bbdca3
--- /dev/null
+++ b/common/app/components/README.md
@@ -0,0 +1 @@
+things like NavBar and Footer go here
diff --git a/common/app/routes/Admin/README.md b/common/app/routes/Admin/README.md
new file mode 100644
index 0000000000..7d48e2a6bd
--- /dev/null
+++ b/common/app/routes/Admin/README.md
@@ -0,0 +1 @@
+in case we ever want an admin panel
diff --git a/common/screens/bonfires/Actions.js b/common/app/routes/Bonfires/Actions.js
similarity index 100%
rename from common/screens/bonfires/Actions.js
rename to common/app/routes/Bonfires/Actions.js
diff --git a/common/app/routes/Bonfires/README.md b/common/app/routes/Bonfires/README.md
new file mode 100644
index 0000000000..d28c45c44e
--- /dev/null
+++ b/common/app/routes/Bonfires/README.md
@@ -0,0 +1 @@
+This folder contains things relative to the bonfires screens
diff --git a/common/screens/bonfires/Store.js b/common/app/routes/Bonfires/Store.js
similarity index 100%
rename from common/screens/bonfires/Store.js
rename to common/app/routes/Bonfires/Store.js
diff --git a/common/screens/bonfires/Bonfires.jsx b/common/app/routes/Bonfires/components/Bonfires.jsx
similarity index 100%
rename from common/screens/bonfires/Bonfires.jsx
rename to common/app/routes/Bonfires/components/Bonfires.jsx
diff --git a/common/screens/bonfires/Results.jsx b/common/app/routes/Bonfires/components/Results.jsx
similarity index 100%
rename from common/screens/bonfires/Results.jsx
rename to common/app/routes/Bonfires/components/Results.jsx
diff --git a/common/screens/bonfires/SidePanel.jsx b/common/app/routes/Bonfires/components/SidePanel.jsx
similarity index 100%
rename from common/screens/bonfires/SidePanel.jsx
rename to common/app/routes/Bonfires/components/SidePanel.jsx
diff --git a/common/screens/bonfires/executeBonfire.js b/common/app/routes/Bonfires/executeBonfire.js
similarity index 100%
rename from common/screens/bonfires/executeBonfire.js
rename to common/app/routes/Bonfires/executeBonfire.js
diff --git a/common/app/routes/Bonfires/index.js b/common/app/routes/Bonfires/index.js
new file mode 100644
index 0000000000..edcb26c104
--- /dev/null
+++ b/common/app/routes/Bonfires/index.js
@@ -0,0 +1,6 @@
+export default {
+ path: 'bonfires/(:bonfireName)',
+ getComponents(cb) {
+ // TODO(berks): add bonfire component
+ }
+};
diff --git a/common/app/routes/FAVS/README.md b/common/app/routes/FAVS/README.md
new file mode 100644
index 0000000000..c02922da56
--- /dev/null
+++ b/common/app/routes/FAVS/README.md
@@ -0,0 +1 @@
+future home of FAVS app
diff --git a/common/app/routes/Jobs/README.md b/common/app/routes/Jobs/README.md
new file mode 100644
index 0000000000..5dde417dab
--- /dev/null
+++ b/common/app/routes/Jobs/README.md
@@ -0,0 +1 @@
+This folder contains everything relative to Jobs board
diff --git a/common/app/routes/Jobs/components/Actions.js b/common/app/routes/Jobs/components/Actions.js
new file mode 100644
index 0000000000..b590678e30
--- /dev/null
+++ b/common/app/routes/Jobs/components/Actions.js
@@ -0,0 +1,15 @@
+import { Actions } from 'thundercats';
+
+export default class JobsActions extends Actions {
+ constructor() {
+ super();
+ }
+ static displayName = 'JobsActions'
+
+ getJob(id) {
+ return { id };
+ }
+ getJobs(params) {
+ return { params };
+ }
+}
diff --git a/common/app/routes/Jobs/components/Jobs.jsx b/common/app/routes/Jobs/components/Jobs.jsx
new file mode 100644
index 0000000000..4725abc09c
--- /dev/null
+++ b/common/app/routes/Jobs/components/Jobs.jsx
@@ -0,0 +1,28 @@
+import React, { PropTypes } from 'react';
+import { createContainer } from 'thundercats';
+import { Grid, Row } from 'react-bootstrap';
+
+@createContainer({
+ store: 'JobsStore'
+})
+export default class extends React.Component {
+ constructor(props) {
+ super(props);
+ }
+
+
+ static displayName = 'Jobs'
+ static propTypes = {
+ jobs: PropTypes.array
+ }
+
+ render() {
+ return (
+
+
+ foo
+
+
+ );
+ }
+}
diff --git a/common/app/routes/Jobs/components/List.jsx b/common/app/routes/Jobs/components/List.jsx
new file mode 100644
index 0000000000..7eccffbe05
--- /dev/null
+++ b/common/app/routes/Jobs/components/List.jsx
@@ -0,0 +1,13 @@
+import React, { PropTypes } from 'react';
+
+export default class extends React.Component {
+ constructor(props) {
+ super(props);
+ }
+
+ static displayName = 'JobsList'
+ static propTypes = {}
+ render() {
+ return null;
+ }
+}
diff --git a/common/app/routes/Jobs/components/Store.js b/common/app/routes/Jobs/components/Store.js
new file mode 100644
index 0000000000..6c022f4773
--- /dev/null
+++ b/common/app/routes/Jobs/components/Store.js
@@ -0,0 +1,9 @@
+import { Store } from 'thundercats';
+
+export default class JobsStore extends Store {
+ constructor(cat) {
+ super();
+ let JobsActions = cat.getActions('JobsActions');
+ }
+ static displayName = 'JobsStore'
+}
diff --git a/common/app/routes/Jobs/index.js b/common/app/routes/Jobs/index.js
new file mode 100644
index 0000000000..44813f34f6
--- /dev/null
+++ b/common/app/routes/Jobs/index.js
@@ -0,0 +1,19 @@
+/*
+ * show: /jobs
+ * showOne: /jobs/:id
+ * edit /jobs/:id
+ * delete /jobs/:id
+ * createOne /jobs/new
+ */
+
+export default {
+ path: '/jobs/(:jobId)',
+
+ getComponents(cb) {
+ require.ensure([], require => {
+ cb(null, [
+ require('./components/Jobs')
+ ]);
+ });
+ }
+};
diff --git a/common/app/routes/index.js b/common/app/routes/index.js
new file mode 100644
index 0000000000..6e67b86742
--- /dev/null
+++ b/common/app/routes/index.js
@@ -0,0 +1,11 @@
+export default {
+ path: '/',
+ getRoutes(cb) {
+ require.ensure([], require => {
+ cb(null, [
+ // require('./Bonfires'),
+ require('./Jobs')
+ ]);
+ });
+ }
+};
diff --git a/common/app/shared/README.md b/common/app/shared/README.md
new file mode 100644
index 0000000000..afddf4a4ce
--- /dev/null
+++ b/common/app/shared/README.md
@@ -0,0 +1 @@
+Here is where all components that are shared between multiple views
diff --git a/common/screens/displayCode/Display.jsx b/common/app/shared/displayCode/Display.jsx
similarity index 100%
rename from common/screens/displayCode/Display.jsx
rename to common/app/shared/displayCode/Display.jsx
diff --git a/common/screens/displayCode/index.js b/common/app/shared/displayCode/index.js
similarity index 100%
rename from common/screens/displayCode/index.js
rename to common/app/shared/displayCode/index.js
diff --git a/common/screens/editor/Editor.jsx b/common/app/shared/editor/Editor.jsx
similarity index 100%
rename from common/screens/editor/Editor.jsx
rename to common/app/shared/editor/Editor.jsx
diff --git a/common/screens/editor/index.js b/common/app/shared/editor/index.js
similarity index 100%
rename from common/screens/editor/index.js
rename to common/app/shared/editor/index.js
diff --git a/common/screens/App.jsx b/common/screens/App.jsx
deleted file mode 100644
index a0756abc14..0000000000
--- a/common/screens/App.jsx
+++ /dev/null
@@ -1,19 +0,0 @@
-var React = require('react'),
- RouteHandler = require('react-router').RouteHandler,
-
- // ## components
- Nav = require('./nav'),
- Footer = require('./footer');
-
-var App = React.createClass({
- render: function() {
- return (
-
-
-
-
-
- );
- }
-});
-module.exports = App;
diff --git a/common/screens/Router.jsx b/common/screens/Router.jsx
deleted file mode 100644
index 650c4107ad..0000000000
--- a/common/screens/Router.jsx
+++ /dev/null
@@ -1,34 +0,0 @@
-var React = require('react'),
-
- // react router
- Router = require('react-router'),
- Route = Router.Route,
- // NotFound = Router.NotFoundRoute,
- DefaultRoute = Router.DefaultRoute,
-
- // # Components
- App = require('./App.jsx'),
- Bonfires = require('./bonfires');
-
-var routes = (
-
-
-
-
-
-
-);
-
-module.exports = function(Location) {
- return Router.create({
- routes: routes,
- location: Location
- });
-};
diff --git a/common/screens/bonfires/index.js b/common/screens/bonfires/index.js
deleted file mode 100644
index 5557fd9f16..0000000000
--- a/common/screens/bonfires/index.js
+++ /dev/null
@@ -1 +0,0 @@
-module.exports = require('./Bonfires.jsx');
diff --git a/common/screens/context/Actions.js b/common/screens/context/Actions.js
deleted file mode 100644
index 83e06c38e1..0000000000
--- a/common/screens/context/Actions.js
+++ /dev/null
@@ -1,34 +0,0 @@
-var debug = require('debug')('freecc:context'),
- BonfireActions = require('../bonfires/Actions'),
- BonfireStore = require('../bonfires/Store');
-
-var {
- Action,
- waitFor
-} = require('thundercats');
-
-var actions = Action.createActions([
- 'setContext',
- 'renderToUser'
-]);
-
-actions
- .setContext
- .filter(function(ctx) {
- return ctx.state.path.indexOf('/bonfire') !== -1;
- })
- .subscribe(function(ctx) {
- debug('set ctx');
- BonfireActions.getBonfire(ctx.state.params);
- waitFor(BonfireStore)
- .firstOrDefault()
- .catch(function(err) {
- // handle timeout error
- debug('err', err);
- })
- .subscribe(function() {
- actions.renderToUser(ctx);
- });
- });
-
-module.exports = actions;
diff --git a/common/screens/context/Store.js b/common/screens/context/Store.js
deleted file mode 100644
index f94308ace1..0000000000
--- a/common/screens/context/Store.js
+++ /dev/null
@@ -1,18 +0,0 @@
-var Store = require('thundercats').Store,
- ContextActions = require('./Actions');
-
-var ContextStore = Store.create({
- getInitialValue: function() {
- return {};
- },
-
- getOperations: function() {
- return ContextActions
- .renderToUser
- .map(function(ctx) {
- return { value: ctx };
- });
- }
-});
-
-module.exports = ContextStore;
diff --git a/common/screens/footer/Footer.jsx b/common/screens/footer/Footer.jsx
deleted file mode 100644
index 5dd5e1b296..0000000000
--- a/common/screens/footer/Footer.jsx
+++ /dev/null
@@ -1,106 +0,0 @@
-var React = require('react');
-
-var Footer = React.createClass({
- render: function() {
- return (
-
- );
- }
-});
-
-module.exports = Footer;
diff --git a/common/screens/footer/index.js b/common/screens/footer/index.js
deleted file mode 100644
index 286ef5f0fb..0000000000
--- a/common/screens/footer/index.js
+++ /dev/null
@@ -1 +0,0 @@
-module.exports = require('./Footer.jsx');
diff --git a/common/screens/nav/index.js b/common/screens/nav/index.js
deleted file mode 100644
index cdf087548a..0000000000
--- a/common/screens/nav/index.js
+++ /dev/null
@@ -1 +0,0 @@
-module.exports = require('./Nav.jsx');
diff --git a/package.json b/package.json
index d156bb0873..8213e9ac72 100644
--- a/package.json
+++ b/package.json
@@ -72,7 +72,6 @@
"node-uuid": "^1.4.3",
"nodemailer": "~1.3.0",
"passport-facebook": "^2.0.0",
- "passport-google-oauth": "^0.2.0",
"passport-google-oauth2": "^0.1.6",
"passport-linkedin-oauth2": "^1.2.1",
"passport-local": "^1.0.0",
@@ -80,9 +79,13 @@
"passport-twitter": "^1.0.3",
"pmx": "^0.3.16",
"ramda": "~0.10.0",
+ "react": "^0.13.3",
+ "react-bootstrap": "^0.23.4",
+ "react-router": "^1.0.0-beta1",
"request": "~2.53.0",
"rx": "^2.5.3",
"sanitize-html": "~1.6.1",
+ "thundercats": "^2.0.0-rc6",
"twit": "~1.1.20",
"uglify-js": "~2.4.15",
"validator": "~3.22.1",