Skip to content

Commit 516a0e7

Browse files
committedMay 17, 2016
12-02 JSX
1 parent 22e31e9 commit 516a0e7

9 files changed

+158
-59
lines changed
 

‎.babelrc

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
{
2-
"presets": ["es2015"]
2+
"presets": ["es2015", "react"]
33
}

‎client/.eslintrc.json

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
{
2+
"extends": "airbnb",
23
"env": {
34
"browser": true
45
}

‎client/data.js

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
module.exports = {
2+
25: {
3+
name: 'Writing a Book on Web Dev Tools',
4+
descr: 'Tasks required to write a book on the tools required to develop a web application',
5+
tasks: {
6+
1: {
7+
descr: 'Figure out what kind of application to develop',
8+
completed: true,
9+
},
10+
2: {
11+
descr: 'Decide what tools to use',
12+
completed: false,
13+
},
14+
3: {
15+
descr: 'Create repositories for text and samples',
16+
completed: true,
17+
},
18+
},
19+
},
20+
34: {
21+
name: 'Cook a Spanish omelette',
22+
descr: 'Steps to cook a Spanish omelette or \'tortilla\'',
23+
tasks: {
24+
4: {
25+
descr: 'Peel and dice the potatoes',
26+
completed: true,
27+
},
28+
5: {
29+
descr: 'Fry the potatoes',
30+
completed: true,
31+
},
32+
6: {
33+
descr: 'Peel and chop the onions',
34+
completed: false,
35+
},
36+
7: {
37+
descr: 'Saute the onions',
38+
completed: false,
39+
},
40+
8: {
41+
descr: 'Beat the eggs',
42+
completed: false,
43+
},
44+
9: {
45+
descr: 'Mix everything and fry',
46+
completed: false,
47+
},
48+
},
49+
},
50+
};

‎client/index.js

+28-12
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,29 @@
1-
const axios = require('axios');
2-
module.exports = function (contentEl) {
3-
axios.get('/data/v1/projects')
4-
.then((response) => {
5-
contentEl.innerHTML =
6-
`<h1>Projects:</h1><ul>${
7-
response.data.map((item) =>
8-
`<li><a href="project.html?${item.pid}">${item.name}</a></li>`
9-
).join('\n')
10-
}</ul>`;
11-
document.title = 'Projects';
12-
});
1+
import React from 'react';
2+
import { Link } from 'react-router';
3+
const data = require('./data.js');
4+
5+
const PrjItem = ({ pid, name }) => (
6+
<li>
7+
<Link to={`project/${pid}`}>
8+
{name}
9+
</Link>
10+
</li>
11+
);
12+
13+
PrjItem.propTypes = {
14+
pid: React.PropTypes.string.isRequired,
15+
name: React.PropTypes.string.isRequired,
1316
};
17+
18+
const ProjectList = () => (
19+
<div className="index">
20+
<h1>Projects:</h1>
21+
<ul>{
22+
Object.keys(data).map(pid =>
23+
(<PrjItem key={pid} pid={pid} name={data[pid].name} />)
24+
)
25+
}</ul>
26+
</div>
27+
);
28+
29+
export default ProjectList;

‎client/project.js

+41-16
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,42 @@
1-
const axios = require('axios');
2-
module.exports = function (contentEl) {
3-
axios.get(`/data/v1/projects/${window.location.search.substr(1)}`)
4-
.then((response) => {
5-
const prj = response.data;
6-
contentEl.innerHTML =
7-
`<h1>${prj.name}</h1><p>${prj.descr}</p><ul>${
8-
Object.keys(prj.tasks).map((tid) => {
9-
const task = prj.tasks[tid];
10-
return `<li><input type="checkbox" ${
11-
task.completed ? 'checked' : ''
12-
} /> &nbsp; ${task.descr}</li>`;
13-
}).join('\n')
14-
}</ul>`;
15-
document.title = `Project ${prj.pid}: ${prj.name}`;
16-
});
1+
import React from 'react';
2+
const data = require('./data.js');
3+
4+
const Task = ({ descr, complete }) => (
5+
<li>
6+
<input type="checkbox" defaultChecked={complete} /> &nbsp; {descr}
7+
</li>
8+
);
9+
10+
Task.propTypes = {
11+
complete: React.PropTypes.bool,
12+
descr: React.PropTypes.string,
1713
};
14+
15+
const TaskList = ({ tasks }) => (
16+
<ul className="task-list">{
17+
Object.keys(tasks).map(tid => (
18+
<Task key={tid} complete={tasks[tid].complete} descr={tasks[tid].descr} />
19+
))
20+
}</ul>
21+
);
22+
23+
TaskList.propTypes = {
24+
tasks: React.PropTypes.object,
25+
};
26+
27+
const Project = ({ params: { pid } }) => {
28+
const prj = data[pid];
29+
return (<div className="project">
30+
<h1>{prj.name}</h1>
31+
<p>{prj.descr}</p>
32+
<TaskList tasks={prj.tasks} />
33+
</div>);
34+
};
35+
36+
Project.propTypes = {
37+
params: React.PropTypes.shape({
38+
pid: React.PropTypes.string.isRequired,
39+
}),
40+
};
41+
42+
export default Project;

‎client/router.js

+14-23
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,20 @@
11
import React from 'react';
22
import { render } from 'react-dom';
3-
import { Router, browserHistory } from 'react-router';
3+
import { Router, Route, IndexRoute, browserHistory } from 'react-router';
44

5-
const Index = require('./index.js');
6-
const Project = require('./project.js');
5+
import Index from './index.js';
6+
import Project from './project.js';
77

88
const App = (props) => props.children;
9+
const NotFound = () => (<h1>Not found</h1>);
910

10-
const routeConfig = {
11-
path: '/',
12-
component: App,
13-
indexRoute: { component: Index },
14-
childRoutes: [
15-
{ path: 'index', component: Index },
16-
{ path: 'project/:pid', component: Project }
17-
]
18-
};
19-
20-
render(
21-
React.createElement(
22-
Router,
23-
{
24-
routes: routeConfig,
25-
history: browserHistory
26-
}
27-
),
28-
document.getElementById('contents')
29-
);
11+
render((
12+
<Router history={browserHistory}>
13+
<Route path="/" component={App}>
14+
<IndexRoute component={Index} />
15+
<Route path="index" component={Index} />
16+
<Route path="project/:pid" component={Project} />
17+
<Route path="*" component={NotFound} />
18+
</Route>
19+
</Router>
20+
), document.getElementById('contents'));

‎package.json

+11-6
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@
88
"lint": "eslint . || exit 0",
99
"test": "mocha",
1010
"coverage": "istanbul cover node_modules/.bin/_mocha",
11-
"build": "webpack"
11+
"build": "webpack -d",
12+
"watch": "webpack --watch &",
13+
"production": "webpack -p --config webpack.production.config.js"
1214
},
1315
"myWebServer": {
1416
"port": 8080,
@@ -35,20 +37,23 @@
3537
"body-parser": "^1.15.0",
3638
"cookie-parser": "^1.4.1",
3739
"express": "^4.13.4",
40+
"history": "^2.1.1",
3841
"react": "^15.0.2",
3942
"react-dom": "^15.0.2",
4043
"react-router": "^2.4.0",
4144
"sqlite3": "^3.1.3"
4245
},
4346
"devDependencies": {
44-
"babel-core": "^6.8.0",
47+
"babel-core": "^6.9.0",
4548
"babel-loader": "^6.2.4",
46-
"babel-preset-es2015": "^6.6.0",
49+
"babel-preset-es2015": "^6.9.0",
50+
"babel-preset-react": "^6.5.0",
4751
"chai": "^3.5.0",
48-
"eslint": "^2.7.0",
49-
"eslint-config-standard": "^5.1.0",
52+
"eslint": "^2.10.2",
53+
"eslint-config-airbnb": "^9.0.1",
54+
"eslint-config-standard": "^5.3.1",
5055
"eslint-plugin-promise": "^1.1.0",
51-
"eslint-plugin-standard": "^1.3.2",
56+
"eslint-plugin-react": "^5.1.1",
5257
"istanbul": "^1.0.0-alpha.2",
5358
"mocha": "^2.4.5",
5459
"webpack": "^1.13.0"

‎public/index.html

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,6 @@
77
<body>
88
<div id="contents"></div>
99
<script src="//cdn.polyfill.io/v1/polyfill.min.js?features=Promise" defer async></script>
10-
<script src="lib/bundle.js"></script>
10+
<script src="/lib/bundle.js"></script>
1111
</body>
1212
</html>

‎webpack.production.config.js

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
const webpack = require('webpack');
2+
3+
module.exports = Object.assign(require('./webpack.config.js'), {
4+
plugins: [
5+
new webpack.DefinePlugin({
6+
'process.env': {
7+
'NODE_ENV': JSON.stringify('production')
8+
}
9+
})
10+
]
11+
});

0 commit comments

Comments
 (0)
Please sign in to comment.