Skip to content

Commit 4c58202

Browse files
author
Ralph Holzmann
committed
Got it workin.
0 parents  commit 4c58202

File tree

14 files changed

+335
-0
lines changed

14 files changed

+335
-0
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
build
2+
tmp
3+
node_modules

Brocfile.js

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
var esTranspiler = require('broccoli-babel-transpiler');
2+
var pickFiles = require('broccoli-static-compiler');
3+
var concat = require('broccoli-concat');
4+
var mergeTrees = require('broccoli-merge-trees');
5+
var filterES6Modules = require('broccoli-es6-module-filter');
6+
var cjsWrap = require("broccoli-cjs-wrap");
7+
var browserify = require('broccoli-browserify');
8+
9+
var serverTree = pickFiles("src", {
10+
srcDir: "",
11+
files: [
12+
'app/**/*.js',
13+
'server.js'
14+
],
15+
destDir: '/'
16+
});
17+
serverTree = esTranspiler(serverTree);
18+
19+
var clientTree = pickFiles("src", {
20+
srcDir: "",
21+
files: [
22+
"app/**/*.js",
23+
"client.js"
24+
],
25+
destDir: '/public'
26+
});
27+
clientTree = esTranspiler(clientTree);
28+
clientTree = browserify(clientTree, {
29+
entries: ["./public/client.js"],
30+
outputFile: "./public/app.js"
31+
});
32+
33+
var assetsTree = pickFiles("src/assets", {
34+
srcDir: "",
35+
files: ["*"],
36+
destDir: "public"
37+
});
38+
39+
module.exports = mergeTrees([serverTree, clientTree, assetsTree]);

Gruntfile.js

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
module.exports = function (grunt) {
2+
require('load-grunt-tasks')(grunt);
3+
4+
// Define the configuration for all the tasks
5+
grunt.initConfig({
6+
concurrent: {
7+
dev: {
8+
tasks: ['broccoli:development:watch', 'nodemon:development'],
9+
options: {
10+
logConcurrentOutput: true
11+
}
12+
}
13+
},
14+
broccoli: {
15+
development: {
16+
dest: 'build',
17+
env: 'development',
18+
host: "0.0.0.0",
19+
port: 5002,
20+
liveReload: true
21+
}
22+
},
23+
nodemon: {
24+
development: {
25+
script: 'build/server.js',
26+
watch: ["build"]
27+
}
28+
}
29+
});
30+
31+
grunt.registerTask('serve', function (environment) {
32+
if (!environment) {
33+
environment = "development";
34+
}
35+
36+
grunt.task.run([
37+
'concurrent'
38+
]);
39+
});
40+
41+
grunt.registerTask('default', [
42+
'serve'
43+
]);
44+
};

package.json

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
{
2+
"name": "htt-www",
3+
"version": "1.0.0",
4+
"description": "Hometown Tickets Website",
5+
"main": "index.js",
6+
"scripts": {
7+
"test": "echo \"Error: no test specified\" && exit 1"
8+
},
9+
"author": "Ralph Holzmann",
10+
"license": "ISC",
11+
"dependencies": {
12+
"almond": "^0.3.0",
13+
"broccoli": "^0.13.3",
14+
"broccoli-babel-transpiler": "^4.0.0",
15+
"broccoli-cjs-wrap": "0.0.6",
16+
"broccoli-concat": "0.0.12",
17+
"broccoli-es6-module-filter": "^0.1.9",
18+
"broccoli-merge-trees": "^0.2.1",
19+
"broccoli-static-compiler": "^0.2.1",
20+
"express": "^4.12.0",
21+
"grunt": "^0.4.5",
22+
"grunt-broccoli": "^0.4.0",
23+
"grunt-nodemon": "^0.4.0",
24+
"react": "^0.12.2",
25+
"react-router": "^0.12.0",
26+
"serve-favicon": "^2.2.0"
27+
},
28+
"devDependencies": {
29+
"broccoli-browserify": "^0.1.0",
30+
"grunt-concurrent": "^1.0.0",
31+
"load-grunt-tasks": "^3.1.0"
32+
}
33+
}

src/app/components/meta.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import React from "react";
2+
import Router from "react-router";
3+
4+
var {State} = Router;
5+
6+
var Meta = React.createClass({
7+
mixins: [State],
8+
9+
getInitialState() {
10+
var metaName = this.props.name;
11+
var metaParts = this.getRoutes().map((route) => {
12+
return (route.handler.meta && route.handler.meta[metaName]) || "";
13+
}).filter(Boolean);
14+
15+
return {
16+
content: metaParts.join(" ")
17+
};
18+
},
19+
20+
render() {
21+
return (
22+
<meta name={this.props.name} content={this.state.content}></meta>
23+
);
24+
}
25+
});
26+
27+
export default Meta;

src/app/components/title.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import React from "react";
2+
import Router from "react-router";
3+
4+
var {State} = Router;
5+
6+
var Title = React.createClass({
7+
mixins: [State],
8+
9+
getInitialState() {
10+
var titleParts = this.getRoutes().map(function(route) {
11+
return route.handler.title || "";
12+
}).filter(Boolean);
13+
titleParts.unshift("Hometown Tickets");
14+
15+
return {
16+
title: titleParts.join(" | ")
17+
};
18+
},
19+
20+
render() {
21+
return (
22+
<title>{this.state.title}</title>
23+
);
24+
}
25+
});
26+
27+
export default Title;

src/app/handlers/application.js

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import React from "react";
2+
import Router from "react-router";
3+
import Title from "../components/title";
4+
import Meta from "../components/meta";
5+
6+
var RouteHandler = Router.RouteHandler;
7+
8+
var Application = React.createClass({
9+
10+
renderBodyContents() {
11+
return (
12+
<div>
13+
<RouteHandler/>
14+
</div>
15+
);
16+
},
17+
18+
renderApplication() {
19+
return (
20+
<html>
21+
<head>
22+
<meta name="charset" content="utf-8" />
23+
<meta httpEquiv="X-UA-Compatible" content="IE=edge" />
24+
<Meta name="description" />
25+
<meta name="viewport" content="width=device-width, initial-scale=1" />
26+
<link rel="stylesheet" href="" />
27+
<Title></Title>
28+
</head>
29+
<body>
30+
{this.renderBodyContents()}
31+
<script src="app.js"></script>
32+
</body>
33+
</html>
34+
);
35+
},
36+
37+
render() {
38+
return process.browser ? this.renderBodyContents() : this.renderApplication();
39+
}
40+
});
41+
42+
export default Application;

src/app/handlers/index.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import React from "react";
2+
import Router from "react-router";
3+
var RouteHandler = Router.RouteHandler;
4+
5+
var Index = React.createClass({
6+
statics: {
7+
title: "This will be the page title",
8+
meta: {
9+
description: "This will be the meta description"
10+
}
11+
},
12+
13+
render() {
14+
return (
15+
<div>
16+
Welcome! {process.browser ? 'Client' : 'Server'}
17+
<RouteHandler/>
18+
</div>
19+
);
20+
}
21+
});
22+
23+
export default Index;

src/app/handlers/not-found.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import React from "react";
2+
3+
var NotFound = React.createClass({
4+
5+
render () {
6+
return <h1>404 Not Found</h1>;
7+
}
8+
9+
});
10+
11+
export default NotFound;

src/app/mixins/title.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
var PortalComponentMixin = {
2+
componentWillUnmount: function() {
3+
this._unrenderLayer();
4+
if(!this.props.portal) document.body.removeChild(this._target);
5+
},
6+
componentDidUpdate: function() {
7+
this._renderLayer();
8+
},
9+
componentDidMount: function() {
10+
if(this.props.portal) {
11+
this._target = document.getElementById(this.props.portal);
12+
} else {
13+
this._target = document.createElement('div');
14+
document.body.appendChild(this._target);
15+
}
16+
this._renderLayer();
17+
},
18+
_renderLayer: function() {
19+
React.renderComponent(this.renderLayer(), this._target);
20+
},
21+
_unrenderLayer: function() {
22+
React.unmountComponentAtNode(this._target);
23+
},
24+
render: function() {
25+
return <title />;
26+
}
27+
};

src/app/routes.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import React from "react";
2+
import Router from "react-router";
3+
import Application from "./handlers/application";
4+
import Index from "./handlers/index";
5+
import NotFound from "./handlers/not-found";
6+
7+
var {DefaultRoute, Link, Route, RouteHandler, NotFoundRoute} = Router;
8+
9+
var routes = [
10+
<Route handler={Application} path="">
11+
<DefaultRoute handler={Index} />
12+
</Route>,
13+
<NotFoundRoute name="not-found" handler={NotFound}/>
14+
];
15+
16+
export default routes;

src/assets/favicon.ico

6.37 KB
Binary file not shown.

src/client.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import React from "react";
2+
import Router from "react-router";
3+
import routes from "./app/routes.js";
4+
5+
Router.run(routes, Router.HistoryLocation, function (Handler) {
6+
React.render(React.createElement(Handler, null), document.body);
7+
});

src/server.js

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
var React = require('react');
2+
var Router = require('react-router');
3+
var routes = require("./app/routes.js");
4+
var express = require('express');
5+
var favicon = require('serve-favicon');
6+
var app = express();
7+
var {join} = require("path");
8+
9+
app.use(favicon("build/public/favicon.ico"));
10+
app.use(express.static(join(__dirname, "public")));
11+
12+
app.get('*', function(req, res) {
13+
var path = req.url;
14+
var router = Router.create({
15+
routes: routes,
16+
location: path,
17+
onAbort: function (redirect) {
18+
cb(redirect);
19+
},
20+
onError: function (err) {
21+
console.log('Routing Error');
22+
console.log(err);
23+
}
24+
});
25+
26+
router.run(function(Handler, state) {
27+
if (state.routes[0].name === "not-found") {
28+
res.status(404);
29+
}
30+
res.send("<!doctype html>" + React.renderToStaticMarkup(<Handler />));
31+
});
32+
});
33+
34+
app.listen(process.env.PORT || 5000, function() {
35+
console.log("React router server listening on port 5000");
36+
});

0 commit comments

Comments
 (0)