diff --git a/.gitignore b/.gitignore index 36170a7..17e43c0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ node_modules public +db.json diff --git a/db.json b/db.json index f08c31c..78e8ee5 100644 --- a/db.json +++ b/db.json @@ -1,16 +1,34 @@ { - "posts": [ - { - "id": 1, - "title": "json-server", - "author": "typicode" - } - ], "comments": [ { - "id": 1, - "body": "some comment", - "postId": 1 + "author": "Maki Nishikino", + "text": "imi wakannai", + "postdate": 1427032542268, + "id": "c9fd1ac6-b2f7-4a6c-b63e-099c851a0f31" + }, + { + "author": "Nico Yazawa", + "text": "Nico nico nii~", + "postdate": 1427034542268, + "id": "e8686677-41da-4bef-b033-cc678e08e814" + }, + { + "author": "Aoba Suzukaze", + "text": "zoi", + "postdate": 1427038542268, + "id": "a5a3e078-8033-44dc-8f3b-43e443415b5a" + }, + { + "author": "Kou Yagami", + "text": "Shigoto bakka sitettoyo-", + "postdate": 1427040542268, + "id": "cb550e14-8063-4113-9948-48d996e29d26" + }, + { + "author": "Yuiko Kuroki", + "text": "Tomoya!", + "postdate": 1427041542268, + "id": "66c06445-8de5-4f0d-83bf-6e00c45bbb8b" } ], "favicon.ico": [] diff --git a/gulpfile.js b/gulpfile.js index 66a1fd6..81f0469 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -14,7 +14,7 @@ gulp.task('build.copy', function() { gulp.task('build.react', function(){ var b = browserify({ - entries: ['./src/javascripts/hello.jsx'], + entries: ['./src/javascripts/main.js'], transform: [reactify] }); return b.bundle() @@ -24,8 +24,16 @@ gulp.task('build.react', function(){ gulp.task('build', ['build.copy','build.react']); -gulp.task('run', ['build'], function() { - var exec = require("child_process").exec - exec('json-server db.json') - console.log('db ok') -}); +gulp.task('json-server', function() { + var jsonServer = require('json-server') + var object = require('./db.json'); + + var router = jsonServer.router('./db.json'); // Express router + var server = jsonServer.create() // Express server + var port = 3000; + server.use(router) + server.listen(port) + console.log('json-server is ready at port:' + port) +}) + +gulp.task('run', ['build', 'json-server']); diff --git a/package.json b/package.json index a203de8..ea58b9b 100644 --- a/package.json +++ b/package.json @@ -31,5 +31,10 @@ "json-server": "0.6.4" }, "favicon.ico": [], - "javascripts": [] -} \ No newline at end of file + "javascripts": [], + "dependencies": { + "dateformat": "^1.0.11", + "glob": "^5.0.3", + "superagent": "^1.1.0" + } +} diff --git a/src/index.html b/src/index.html index 5fd21db..95c6577 100644 --- a/src/index.html +++ b/src/index.html @@ -1,9 +1,12 @@ + + -
+
+ diff --git a/src/javascripts/main.js b/src/javascripts/main.js new file mode 100644 index 0000000..27c13dc --- /dev/null +++ b/src/javascripts/main.js @@ -0,0 +1,148 @@ +var React = require('react'); +var converter = new Showdown.converter(); +var dateFormat = require('dateformat'); +var request = require('superagent'); + +var CommentHeader = React.createClass({ + render: function() { + return ( +
+ + { this.props.author } +
+ ) + } +}) +var CommentFooter = React.createClass({ + render: function() { + return( +
+ + { dateFormat(this.props.postdate, "yyyy-mm-dd HH:MM") } +
+ ) + } +}) + +var Comment = React.createClass({ + render: function() { + var rawMarkup = converter.makeHtml(this.props.children.toString()) + return ( +
+ +
+ +
+
+ +
+ ) + } +}); + +var EditButton = React.createClass({ + handleClick: function(e) { + console.log('edit is not implemented yet, sorry....') + }, + render: function() { + return( + + ) + } +}) + +var CommentList = React.createClass({ + render: function() { + var comments = this.props.data.map(function(c) { + return ( + + { c.text } + + ) + }) + return ( +
+ {comments} +
+ ) + } +}); + +var CommentForm = React.createClass({ + getValues: function() { + return { + author: React.findDOMNode(this.refs.author).value.trim(), + text: React.findDOMNode(this.refs.text).value.trim(), + postdate: Date.now() + } + }, + handleSubmit: function(e) { + e.preventDefault(); + var d = this.getValues(); + if(!d.author || !d.text) { + return; + } + this.props.onCommentSubmit(d); + React.findDOMNode(this.refs.author).value = ''; + React.findDOMNode(this.refs.text).value = ''; + }, + render: function() { + return ( +
+

New Comment

+
+ + +
+ ) + } +}); + +var CommentBox = React.createClass({ + fetchComments: function() { + return request.get(this.props.url); + }, + loadCommentsFromServer: function() { + this.fetchComments().end(function(err, res) { + if (err) { + console.log(err) + } else { + this.setState({data: res.body}) + } + }.bind(this)) + }, + postComment: function(d) { + return request.post(this.props.url).send(d) + }, + handleCommentSubmit: function(d) { + var s = this.state; + s.data.push(d); + this.setState(s); + this.postComment(d).end(function(err, res) { + if (err) { + console.error(err) + } + }) + }, + getInitialState: function() { + return { data: [] } + }, + componentDidMount: function() { + this.loadCommentsFromServer(); + setInterval(this.loadCommentsFromServer, this.props.pollInterval); + }, + render: function() { + return ( +
+

Comments

+ + +
+ ) + } +}); + +React.render( + , + document.getElementById('content') +) diff --git a/src/stylesheets/comment.css b/src/stylesheets/comment.css new file mode 100644 index 0000000..1d7fca8 --- /dev/null +++ b/src/stylesheets/comment.css @@ -0,0 +1,20 @@ +.comment { + width: 400px; + border: 1px gray solid; + padding: 5px; + margin: 5px; +} + +.commentFooter { + color: gray; + text-align: right; +} + +.commentBody { + margin-left: 5px; + display: inline-block; +} + +.author { + padding-left: 5px; +}