add comments

parent 59d20630
......@@ -6,7 +6,8 @@ const helpers = {
error
})
}
}
},
timestamp: () => Math.floor((new Date).getTime() / 1000)
}
module.exports = helpers
\ No newline at end of file
......@@ -25,6 +25,7 @@ body {
color: var(--c-dark);
font-family: -apple-system, BlinkMacSystemFont, avenir next, avenir, helvetica neue, helvetica, ubuntu, roboto, noto, segoe ui, arial, sans-serif;
line-height: 1.5;
padding-bottom: 7rem;
}
a {
......@@ -93,10 +94,18 @@ nav .nav-links a:last-child {
font-size: 1.25rem;
}
.form {
.form-w-tight {
max-width: 24rem;
}
.form-w-normal {
max-width: 32rem;
}
.form-w-wide {
max-width: 48rem;
}
.form header h2 {
margin-bottom: 0.25rem;
}
......@@ -121,10 +130,14 @@ nav .nav-links a:last-child {
padding: 0.5rem;
}
.form-input textarea {
.form-input textarea.textarea-huge {
min-height: 16rem;
}
.form-input textarea.textarea-wide {
min-height: 7rem;
}
.form-input label {
font-size: 1rem;
text-transform: uppercase;
......@@ -229,4 +242,45 @@ nav .nav-links a:last-child {
.post-page article p {
white-space: pre-line;
}
\ No newline at end of file
}
.comments-container {
margin-top: 2.875rem;
}
.comments-container h3, .comments-container h4 {
font-weight: 600;
margin-bottom: 0;
}
.comments-container h3 {
font-size: 1.5rem;
}
.comments-container h4 {
font-size: 1.25rem;
}
.comments-container .form-input:first-child {
padding-top: 0.5rem;
}
pre {
word-wrap: break-word;
white-space: pre-line;
}
.comments-list {
padding-left: 1rem;
}
.comment header h5 {
margin-top: 1.5rem;
margin-bottom: 0.25rem;
font-size: 1.25rem;
}
.comment p {
font-size: 1rem;
margin-top: 0;
}
const sprintf = require('sprintf-js').sprintf
const catchError = require('../helpers.js').catchError
const { catchError, timestamp } = require('../helpers.js')
const ObjectId = require('mongodb').ObjectID
module.exports = (app, db) => {
......@@ -7,11 +7,14 @@ module.exports = (app, db) => {
res.locals.title = 'Home'
const col = db.collection('posts')
col.find().sort('_id', -1).toArray().then((posts) => {
res.render('posts/index', {
posts
})
}).catch(catchError(res))
col.find()
.sort('_id', -1)
.toArray()
.then((posts) => {
res.render('posts/index', {
posts
})
}).catch(catchError(res))
})
app.get('/posts/new', (req, res) => {
......@@ -21,14 +24,30 @@ module.exports = (app, db) => {
})
app.get('/posts/:id', (req, res) => {
const id = req.params.id
let _id = req.params.id
try {
_id = new ObjectId(_id)
} catch (err) {
catchError(res)(err)
return
}
const col = db.collection('posts')
col.findOne({
_id: new ObjectId(id)
_id
}).then((post) => {
res.locals.title = post.title;
if (post.comments && typeof post.comments == 'object') {
post.comments.sort((a, b) => {
if (a.createdAt < b.createdAt)
return 1;
if (a.createdAt > b.createdAt)
return -1;
return 0;
})
}
const timestamp = post._id.getTimestamp()
const dates = {
raw: timestamp,
......@@ -67,4 +86,47 @@ module.exports = (app, db) => {
res.redirect(sprintf('/posts/%s', record._id))
}).catch(catchError(res))
})
app.post('/posts/:id/comments', (req, res) => {
let errors = [], comment = {}
const fields = ['name', 'body']
fields.forEach((field => {
const val = req.body[field]
if (!val || val.trim() == '') {
errors.push(sprintf("Field %s is required", field))
}
comment[field] = val
}))
if (errors.length) {
req.flash('errors', errors)
res.redirect('back')
return
}
let _id = req.params.id
try {
_id = new ObjectId(_id)
} catch (err) {
catchError(res)(err)
return
}
comment.createdAt = timestamp();
const col = db.collection('posts')
col.findOneAndUpdate(
{
_id
},
{
$push: {
comments: comment
}
}
).then((record) => {
res.redirect(sprintf('/posts/%s', record.value._id))
}).catch(catchError(res))
})
}
\ No newline at end of file
<main>
<form action="/posts" method="post" class="form">
<form action="/posts" method="post" class="form-w-normal">
<header>
<h2>New Post</h2>
</header>
......@@ -10,7 +10,7 @@
</div>
<div class="form-input">
<label for="body">Body</label>
<textarea name="body" id="body" class="ts-m" required></textarea>
<textarea name="body" id="body" class="ts-m textarea-huge" required></textarea>
</div>
<div class="form-input form-action-buttons">
<button type="submit" class="ts-l button">Post</button>
......
......@@ -13,4 +13,41 @@
{{ post.body }}
</p>
</article>
<aside>
<div class="comments-container form-w-wide">
<header>
<h3>Comments</h3>
</header>
<div class="comments-list">
{{#each post.comments}}
<div class="comment">
<header>
<h5>{{name}}</h5>
</header>
<p>{{body}}</p>
</div>
{{/each}}
</div>
<div class="comment-form">
<form action="/posts/{{post._id}}/comments" method="post" class="form form-wide">
<header>
<h4>Write a Comment</h4>
</header>
{{> errors }}
<div class="form-input form-w-tight">
<label for="name">Your Name</label>
<input type="text" name="name" id="name" class="ts-m" required>
</div>
<div class="form-input">
<label for="body">Comment</label>
<textarea name="body" id="body" class="ts-m textarea-wide" required></textarea>
</div>
<div class="form-input form-action-buttons">
<button type="submit" class="ts-l button">Post</button>
</div>
</form>
</div>
</div>
</aside>
</main>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment