Showing
15 changed files
with
237 additions
and
67 deletions
... | @@ -3,8 +3,9 @@ const mongoose = require('mongoose'); | ... | @@ -3,8 +3,9 @@ const mongoose = require('mongoose'); |
3 | 3 | ||
4 | // Declare the schemea of post | 4 | // Declare the schemea of post |
5 | var postSchema = mongoose.Schema({ | 5 | var postSchema = mongoose.Schema({ |
6 | - title:{type:String, required:true}, | 6 | + title:{type:String, required:[true, 'Title is required!']}, |
7 | - body:{type:String, required:true}, | 7 | + body:{type:String, required:[true, 'Content is required!']}, |
8 | + author:{type:mongoose.Schema.Types.ObjectId, ref:'user', required:true}, | ||
8 | createdAt:{type:Date, default:Date.now}, | 9 | createdAt:{type:Date, default:Date.now}, |
9 | updatedAt:{type:Date}, | 10 | updatedAt:{type:Date}, |
10 | }); | 11 | }); | ... | ... |
Project/public/assets/img/bg-callout.jpg
0 → 100644
1.74 MB
1 | body { | 1 | body { |
2 | - | 2 | + background-color:whitesmoke; |
3 | } | 3 | } |
4 | .h1 { | 4 | .h1 { |
5 | font-family: 'PT Serif', serif; | 5 | font-family: 'PT Serif', serif; |
... | @@ -21,7 +21,11 @@ body { | ... | @@ -21,7 +21,11 @@ body { |
21 | .board-table .date { | 21 | .board-table .date { |
22 | width: 100px; | 22 | width: 100px; |
23 | } | 23 | } |
24 | - | 24 | + .board-table .author, |
25 | + .board-table .date{ | ||
26 | + width: 100px; | ||
27 | + } | ||
28 | + | ||
25 | .post-body{ | 29 | .post-body{ |
26 | white-space: pre-line; /* 2 */ | 30 | white-space: pre-line; /* 2 */ |
27 | } | 31 | } |
... | @@ -31,4 +35,12 @@ body { | ... | @@ -31,4 +35,12 @@ body { |
31 | 35 | ||
32 | .user-form { | 36 | .user-form { |
33 | width: 400px; | 37 | width: 400px; |
34 | - } | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
38 | + } | ||
39 | + | ||
40 | + | ||
41 | +.mb-3{ | ||
42 | + background-color:tan; | ||
43 | +} | ||
44 | + | ||
45 | + | ||
46 | + | ||
... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
1 | var express = require('express'); | 1 | var express = require('express'); |
2 | var router = express.Router(); | 2 | var router = express.Router(); |
3 | var Post = require('../models/Post'); | 3 | var Post = require('../models/Post'); |
4 | +var util = require('../util'); | ||
4 | 5 | ||
5 | 6 | ||
6 | // Post home | 7 | // Post home |
7 | router.get('/', function(req, res){ | 8 | router.get('/', function(req, res){ |
8 | Post.find({}) | 9 | Post.find({}) |
10 | + .populate('author') | ||
9 | .sort('-createdAt') | 11 | .sort('-createdAt') |
10 | .exec(function(err, posts){ | 12 | .exec(function(err, posts){ |
11 | if(err){return res.json(err)}; | 13 | if(err){return res.json(err)}; |
... | @@ -15,56 +17,84 @@ router.get('/', function(req, res){ | ... | @@ -15,56 +17,84 @@ router.get('/', function(req, res){ |
15 | 17 | ||
16 | 18 | ||
17 | // Post new | 19 | // Post new |
18 | -router.get('/new', function(req, res){ | 20 | +router.get('/new', util.isLoggedin, function(req, res){ |
19 | - res.render('posts/new'); | 21 | + var post = req.flash('post')[0] || {}; |
22 | + var errors = req.flash('errors')[0] || {}; | ||
23 | + res.render('posts/new', {post:post, errors:errors}); | ||
20 | }) | 24 | }) |
21 | 25 | ||
22 | 26 | ||
23 | // Post create | 27 | // Post create |
24 | -router.post('/', function(req, res){ | 28 | +router.post('/', util.isLoggedin, function(req, res){ |
29 | + req.body.author = req.user._id; | ||
25 | Post.create(req.body, function(err, post){ | 30 | Post.create(req.body, function(err, post){ |
26 | - if(err){return res.json(err)}; | 31 | + if(err){ |
32 | + req.flash('post', req.body); | ||
33 | + req.flash('errors', util.parseError(err)); | ||
34 | + return res.redirect('/posts/new'); | ||
35 | + }; | ||
27 | res.redirect('/posts'); | 36 | res.redirect('/posts'); |
28 | }); | 37 | }); |
29 | }); | 38 | }); |
30 | 39 | ||
31 | 40 | ||
32 | // Post show | 41 | // Post show |
33 | -router.get('/:id', function(req, res){ | 42 | +router.get('/:id', util.isLoggedin, function(req, res){ |
34 | - Post.findOne({_id:req.params.id}, function(err, post){ | 43 | + Post.findOne({_id:req.params.id}) |
35 | - if(err){return res.json(err)}; | 44 | + .populate('author') |
36 | - res.render('posts/show', {post:post}); | 45 | + .exec(function(err,post){ |
37 | - }); | 46 | + if(err){return res.json(err)}; |
47 | + res.render('posts/show', {post:post}); | ||
48 | + }); | ||
38 | }); | 49 | }); |
39 | 50 | ||
40 | 51 | ||
41 | // Post edit | 52 | // Post edit |
42 | -router.get('/:id/edit', function(req, res){ | 53 | +router.get('/:id/edit', util.isLoggedin, checkPermission, function(req, res){ |
43 | - Post.findOne({_id:req.params.id}, function(err, post){ | 54 | + var post = req.flash('post')[0]; |
44 | - if(err){return res.join(err)}; | 55 | + var errors = req.flash('errors')[0] || {}; |
45 | - res.render('posts/edit', {posts:post}); | 56 | + if(!post){ |
46 | - }); | 57 | + Post.findOne({_id:req.params.id}, function(err, post){ |
58 | + if(err){return res.join(err)}; | ||
59 | + res.render('posts/edit', {posts:post, errors:errors}); | ||
60 | + }); | ||
61 | + } | ||
62 | + else{ | ||
63 | + post._id = req.params.id; | ||
64 | + res.render('posts/edit', {post:post, errors:errors}); | ||
65 | + } | ||
47 | }); | 66 | }); |
48 | 67 | ||
49 | 68 | ||
50 | // Post update | 69 | // Post update |
51 | -router.get('/:id', function(req, res){ | 70 | +router.put('/:id', util.isLoggedin, checkPermission, function(req, res){ |
52 | req.body.updatedAt = Date.now(); | 71 | req.body.updatedAt = Date.now(); |
53 | - Post.findOneAndUpdate({_id:req.params.id}, req.body, function(err, post){ | 72 | + Post.findOneAndUpdate({_id:req.params.id}, req.body, {runValidators:true}, function(err, post){ |
54 | - if(err){return res.join(err)}; | 73 | + if(err){ |
74 | + req.flash('post', req.body), | ||
75 | + req.flash('errors', util.parseError(err)); | ||
76 | + return res.redirect('/posts/'+ req.params,id + '/edit'); | ||
77 | + }; | ||
55 | res.redirect('posts/' + req.params.id); | 78 | res.redirect('posts/' + req.params.id); |
56 | }); | 79 | }); |
57 | }); | 80 | }); |
58 | 81 | ||
59 | 82 | ||
60 | // Post delete | 83 | // Post delete |
61 | -router.delete('/:id', function(req, res){ | 84 | +router.delete('/:id', util.isLoggedin, checkPermission, function(req, res){ |
62 | Post.deleteOne({_id:req.params.id}, function(err){ | 85 | Post.deleteOne({_id:req.params.id}, function(err){ |
63 | if(err){return res.join(err)}; | 86 | if(err){return res.join(err)}; |
64 | res.redirect('/posts'); | 87 | res.redirect('/posts'); |
65 | }); | 88 | }); |
66 | }); | 89 | }); |
67 | 90 | ||
91 | +function checkPermission(req, res, next){ | ||
92 | + Post.findOne({_id:req.params.id}, function(err, post){ | ||
93 | + if(err){return res.json(err)}; | ||
94 | + if(post.author != req.user.id){return util.noPermission(req,res)}; | ||
95 | + next(); | ||
96 | + }); | ||
97 | +} | ||
68 | 98 | ||
69 | // Export module | 99 | // Export module |
70 | module.exports = router; | 100 | module.exports = router; |
... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
1 | var express = require('express'); | 1 | var express = require('express'); |
2 | var router = express.Router(); | 2 | var router = express.Router(); |
3 | var User = require('../models/User'); | 3 | var User = require('../models/User'); |
4 | +var util = require('../util'); | ||
4 | 5 | ||
5 | -// Index // 1 | 6 | +//Index |
6 | -router.get('/', function(req, res){ | 7 | +// router.get('/', function(req, res){ |
7 | - User.find({}) | 8 | +// User.find({}) |
8 | - .sort({username:1}) | 9 | +// .sort({username:1}) |
9 | - .exec(function(err, users){ | 10 | +// .exec(function(err, users){ |
10 | - if(err) return res.json(err); | 11 | +// if(err) return res.json(err); |
11 | - res.render('users/index', {users:users}); | 12 | +// res.render('users/index', {users:users}); |
12 | - }); | 13 | +// }); |
13 | -}); | 14 | +// }); |
14 | 15 | ||
15 | // New | 16 | // New |
16 | router.get('/new', function(req, res){ | 17 | router.get('/new', function(req, res){ |
... | @@ -24,15 +25,15 @@ router.post('/', function(req, res){ | ... | @@ -24,15 +25,15 @@ router.post('/', function(req, res){ |
24 | User.create(req.body, function(err, user){ | 25 | User.create(req.body, function(err, user){ |
25 | if(err){ | 26 | if(err){ |
26 | req.flash('user', req.body); | 27 | req.flash('user', req.body); |
27 | - req.flash('errors', parseError(err)); | 28 | + req.flash('errors', util.parseError(err)); |
28 | return res.redirect('/users/new'); | 29 | return res.redirect('/users/new'); |
29 | } | 30 | } |
30 | - res.redirect('/users'); | 31 | + res.redirect('/users/login'); |
31 | }); | 32 | }); |
32 | }); | 33 | }); |
33 | 34 | ||
34 | // show | 35 | // show |
35 | -router.get('/:username', function(req, res){ | 36 | +router.get('/:username', util.isLoggedin, function(req, res){ |
36 | User.findOne({username:req.params.username}, function(err, user){ | 37 | User.findOne({username:req.params.username}, function(err, user){ |
37 | if(err) return res.json(err); | 38 | if(err) return res.json(err); |
38 | res.render('users/show', {user:user}); | 39 | res.render('users/show', {user:user}); |
... | @@ -40,7 +41,7 @@ router.get('/:username', function(req, res){ | ... | @@ -40,7 +41,7 @@ router.get('/:username', function(req, res){ |
40 | }); | 41 | }); |
41 | 42 | ||
42 | // edit | 43 | // edit |
43 | -router.get('/:username/edit', function(req, res){ | 44 | +router.get('/:username/edit', util.isLoggedin, checkPermission, function(req, res){ |
44 | var user = req.flash('user')[0]; | 45 | var user = req.flash('user')[0]; |
45 | var errors = req.flash('errors')[0] || {}; | 46 | var errors = req.flash('errors')[0] || {}; |
46 | if(!user){ | 47 | if(!user){ |
... | @@ -55,7 +56,7 @@ router.get('/:username/edit', function(req, res){ | ... | @@ -55,7 +56,7 @@ router.get('/:username/edit', function(req, res){ |
55 | }); | 56 | }); |
56 | 57 | ||
57 | // update | 58 | // update |
58 | -router.put('/:username', function(req, res, next){ | 59 | +router.put('/:username', util.isLoggedin, checkPermission, function(req, res, next){ |
59 | User.findOne({username:req.params.username}) // 2-1 | 60 | User.findOne({username:req.params.username}) // 2-1 |
60 | .select('password') // 2-2 | 61 | .select('password') // 2-2 |
61 | .exec(function(err, user){ | 62 | .exec(function(err, user){ |
... | @@ -72,7 +73,7 @@ router.put('/:username', function(req, res, next){ | ... | @@ -72,7 +73,7 @@ router.put('/:username', function(req, res, next){ |
72 | user.save(function(err, user){ | 73 | user.save(function(err, user){ |
73 | if(err){ | 74 | if(err){ |
74 | req.flash('user', req.body); | 75 | req.flash('user', req.body); |
75 | - req.flash('errors', parseError(err)); | 76 | + req.flash('errors', util.parseError(err)); |
76 | return res.redirect('/users/'+req.params.username+'/edit'); | 77 | return res.redirect('/users/'+req.params.username+'/edit'); |
77 | } | 78 | } |
78 | res.redirect('/users/'+user.username); | 79 | res.redirect('/users/'+user.username); |
... | @@ -81,12 +82,12 @@ router.put('/:username', function(req, res, next){ | ... | @@ -81,12 +82,12 @@ router.put('/:username', function(req, res, next){ |
81 | }); | 82 | }); |
82 | 83 | ||
83 | // destroy | 84 | // destroy |
84 | -router.delete('/:username', function(req, res){ | 85 | +// router.delete('/:username', function(req, res){ |
85 | - User.deleteOne({username:req.params.username}, function(err){ | 86 | +// User.deleteOne({username:req.params.username}, function(err){ |
86 | - if(err) return res.json(err); | 87 | +// if(err) return res.json(err); |
87 | - res.redirect('/users'); | 88 | +// res.redirect('/users'); |
88 | - }); | 89 | +// }); |
89 | -}); | 90 | +// }); |
90 | 91 | ||
91 | module.exports = router; | 92 | module.exports = router; |
92 | 93 | ||
... | @@ -105,4 +106,12 @@ function parseError(errors){ | ... | @@ -105,4 +106,12 @@ function parseError(errors){ |
105 | parsed.unhandled = JSON.stringify(errors); | 106 | parsed.unhandled = JSON.stringify(errors); |
106 | } | 107 | } |
107 | return parsed; | 108 | return parsed; |
109 | +} | ||
110 | + | ||
111 | +function checkPermission(req, res, next){ | ||
112 | + User.findOne({username:req.params.username}, function(err, post){ | ||
113 | + if(err){return res.json(err)}; | ||
114 | + if(post.id != req.user.id){return util.noPermission(req,res)}; | ||
115 | + next(); | ||
116 | + }); | ||
108 | } | 117 | } |
... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
Project/util.js
0 → 100644
1 | +var util = {}; | ||
2 | + | ||
3 | +util.parseError = function(errors){ | ||
4 | + var parsed = {}; | ||
5 | + if(errors.name == 'ValidationError'){ | ||
6 | + for(var name in errors.errors){ | ||
7 | + var validationError = errors.errors[name]; | ||
8 | + parsed[name] = { message:validationError.message }; | ||
9 | + } | ||
10 | + } | ||
11 | + else if(errors.code == '11000' && errors.errmsg.indexOf('username') > 0) { | ||
12 | + parsed.username = { message:'This username already exists!' }; | ||
13 | + } | ||
14 | + else { | ||
15 | + parsed.unhandled = JSON.stringify(errors); | ||
16 | + } | ||
17 | + return parsed; | ||
18 | +} | ||
19 | + | ||
20 | +util.isLoggedin = function(req, res, next){ | ||
21 | + if(req.isAuthenticated()){ | ||
22 | + next(); | ||
23 | + } | ||
24 | + else { | ||
25 | + req.flash('errors', {login:'Please login first'}); | ||
26 | + res.redirect('/login'); | ||
27 | + } | ||
28 | +} | ||
29 | + | ||
30 | +util.noPermission = function(req, res){ | ||
31 | + req.flash('errors', {login:"You don't have permission"}); | ||
32 | + req.logout(); | ||
33 | + res.redirect('/login'); | ||
34 | +} | ||
35 | + | ||
36 | + | ||
37 | + | ||
38 | +module.exports = util; | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
... | @@ -9,8 +9,9 @@ | ... | @@ -9,8 +9,9 @@ |
9 | <div class="container mb-3"> | 9 | <div class="container mb-3"> |
10 | 10 | ||
11 | <h2 class="mb-3">About</h2> | 11 | <h2 class="mb-3">About</h2> |
12 | + | ||
12 | 13 | ||
13 | - <P>이 사이트는 <a href="http://a-mean-blog.com/ko/blog/Node-JS-첫걸음/게시판-만들기">http://a-mean-blog.com/ko/blog/Node-JS-첫걸음/게시판-만들기</a>에서 작성되었습니다!</p> | 14 | + <P>Store and Share your precious memory in MAPMORY!</p> |
14 | 15 | ||
15 | </div> | 16 | </div> |
16 | </body> | 17 | </body> | ... | ... |
... | @@ -2,17 +2,54 @@ | ... | @@ -2,17 +2,54 @@ |
2 | <html> | 2 | <html> |
3 | <head> | 3 | <head> |
4 | <%- include('../partials/head') %> | 4 | <%- include('../partials/head') %> |
5 | + | ||
6 | + <style> | ||
7 | + body,html{ | ||
8 | + margin: 0; | ||
9 | + padding: 0; | ||
10 | + height: 100%; | ||
11 | + } | ||
12 | + .img { | ||
13 | + border: 0; | ||
14 | + padding: 0; | ||
15 | + background-image: url('assets/img/bg-callout.jpg'); | ||
16 | + background-size: cover; | ||
17 | + min-height: 100%; | ||
18 | + background-size: cover; | ||
19 | + background-position: center; | ||
20 | + } | ||
21 | + | ||
22 | + .img .content{ | ||
23 | + position: absolute; | ||
24 | + top: 45%; | ||
25 | + left: 50%; | ||
26 | + font-size: 1rem; | ||
27 | + transform: translate(-50%, -50%); | ||
28 | + font-family: 'PT Serif', serif; | ||
29 | + text-align: center; | ||
30 | + } | ||
31 | + | ||
32 | + h1{ | ||
33 | + font-size: 5rem; | ||
34 | + padding:0; | ||
35 | + margin:0; | ||
36 | + } | ||
37 | + | ||
38 | + h3{ | ||
39 | + font-size: 2.5rem; | ||
40 | + padding:0; | ||
41 | + margin:2px; | ||
42 | + } | ||
43 | + </style> | ||
5 | </head> | 44 | </head> |
6 | <body> | 45 | <body> |
7 | <%- include('../partials/nav') %> | 46 | <%- include('../partials/nav') %> |
8 | 47 | ||
9 | - <div class="container mb-3"> | 48 | + <div class="img"> |
10 | - | 49 | + <div class="content"> |
11 | - <div class="jumbotron"> | 50 | + <h1>Mapmory</h1> |
12 | - <h1>My Website</h1> | 51 | + <h3><em>Save your reminiscence with place</em></h3> |
13 | - <P>제 웹사이트를 방문해 주셔서 감사합니다!</p> | ||
14 | </div> | 52 | </div> |
15 | - | ||
16 | </div> | 53 | </div> |
17 | </body> | 54 | </body> |
18 | </html> | 55 | </html> |
... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
1 | -<nav class="navbar navbar-expand-sm navbar-light bg-light mb-3"> | 1 | +<!-- <nav class="navbar navbar-expand-sm navbar-light bg-light mb-3"> --> |
2 | +<nav class="navbar navbar-expand-sm navbar-dark bg-dark mb-3"> | ||
2 | <div class="container"> | 3 | <div class="container"> |
3 | - <div class="navbar-brand">My Website</div> | 4 | + <div class="navbar-brand">Mapmory</div> |
4 | <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent"> | 5 | <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent"> |
5 | <span class="navbar-toggler-icon"></span> | 6 | <span class="navbar-toggler-icon"></span> |
6 | </button> | 7 | </button> |
... | @@ -8,7 +9,7 @@ | ... | @@ -8,7 +9,7 @@ |
8 | <ul class="navbar-nav"> | 9 | <ul class="navbar-nav"> |
9 | <li class="nav-item"><a href="/" class="nav-link">Home</a></li> | 10 | <li class="nav-item"><a href="/" class="nav-link">Home</a></li> |
10 | <li class="nav-item"><a href="/about" class="nav-link">About</a></li> | 11 | <li class="nav-item"><a href="/about" class="nav-link">About</a></li> |
11 | - <li class="nav-item"><a href="/posts" class="nav-link">Posts</a></li> | 12 | + <li class="nav-item"><a href="/posts" class="nav-link">Memory</a></li> |
12 | </ul> | 13 | </ul> |
13 | 14 | ||
14 | <ul class="navbar-nav ml-auto"> <!-- 우측 정렬 --> | 15 | <ul class="navbar-nav ml-auto"> <!-- 우측 정렬 --> | ... | ... |
... | @@ -21,14 +21,26 @@ | ... | @@ -21,14 +21,26 @@ |
21 | 21 | ||
22 | <div class="form-group"> | 22 | <div class="form-group"> |
23 | <label for="title">Title</label> | 23 | <label for="title">Title</label> |
24 | - <input type="text" id="title" name="title" value="<%= post.title %>" class="form-control"> | 24 | + <input type="text" id="title" name="title" value="<%= post.title %>" class="form-control <%= (errors.title)?'is-invalid':'' %>"> |
25 | + <% if(errors.title){ %> | ||
26 | + <span class="invalid-feedback"><%= errors.title.message %></span> | ||
27 | + <% } %> | ||
25 | </div> | 28 | </div> |
26 | 29 | ||
27 | <div class="form-group"> | 30 | <div class="form-group"> |
28 | <label for="body">Body</label> | 31 | <label for="body">Body</label> |
29 | - <textarea id="body" name="body" rows="5" class="form-control"><%= post.body %></textarea> | 32 | + <textarea id="body" name="body" rows="5" class="form-control <%= (errors.body)?'is-invalid':''%>"><%= post.body %></textarea> |
33 | + <% if(errors.body){ %> | ||
34 | + <span class="invalid-feedback"><%= errors.body.message %></span> | ||
35 | + <% } %> | ||
30 | </div> | 36 | </div> |
31 | 37 | ||
38 | + <% if(errors.unhandled){ %> | ||
39 | + <div class="invalid-feedback b-block"> | ||
40 | + <%= errors.unhandled %> | ||
41 | + </div> | ||
42 | + <% } %> | ||
43 | + | ||
32 | <div> | 44 | <div> |
33 | <a class="btn btn-primary" href="/posts/<%= post._id %>">Back</a> | 45 | <a class="btn btn-primary" href="/posts/<%= post._id %>">Back</a> |
34 | <button type="submit" class="btn btn-primary">Submit</button> | 46 | <button type="submit" class="btn btn-primary">Submit</button> | ... | ... |
... | @@ -15,6 +15,7 @@ | ... | @@ -15,6 +15,7 @@ |
15 | <thead class="thead-light"> | 15 | <thead class="thead-light"> |
16 | <tr> | 16 | <tr> |
17 | <th scope="col">Title</th> | 17 | <th scope="col">Title</th> |
18 | + <th scope="col" class="author">Author</th> | ||
18 | <th scope="col" class="date">Date</th> | 19 | <th scope="col" class="date">Date</th> |
19 | </tr> | 20 | </tr> |
20 | </thead> | 21 | </thead> |
... | @@ -30,8 +31,11 @@ | ... | @@ -30,8 +31,11 @@ |
30 | <td> | 31 | <td> |
31 | <a href="/posts/<%= post._id %>"><div class="ellipsis"><%= post.title %></div></a> | 32 | <a href="/posts/<%= post._id %>"><div class="ellipsis"><%= post.title %></div></a> |
32 | </td> | 33 | </td> |
34 | + <td class="author"> | ||
35 | + <div class="ellipsis"><%= post.author ? post.author.username : "" %></div> | ||
36 | + </td> | ||
33 | <td class="date"> | 37 | <td class="date"> |
34 | - <span data-date="<%= post.createdAt %>"></span> | 38 | + <span data-date="<%= post.createdAt %>"><%= post.createdAt %></span> |
35 | </td> | 39 | </td> |
36 | </tr> | 40 | </tr> |
37 | <% }) %> | 41 | <% }) %> |
... | @@ -40,7 +44,9 @@ | ... | @@ -40,7 +44,9 @@ |
40 | </table> | 44 | </table> |
41 | 45 | ||
42 | <div> | 46 | <div> |
43 | - <a class="btn btn-primary" href="/posts/new">New</a> | 47 | + <% if(isAuthenticated){ %> |
48 | + <a class="btn btn-primary" href="/posts/new">New</a> | ||
49 | + <% } %> | ||
44 | </div> | 50 | </div> |
45 | 51 | ||
46 | </div> | 52 | </div> | ... | ... |
... | @@ -20,21 +20,31 @@ | ... | @@ -20,21 +20,31 @@ |
20 | 20 | ||
21 | <div class="form-group"> | 21 | <div class="form-group"> |
22 | <label for="title">Title</label> | 22 | <label for="title">Title</label> |
23 | - <input type="text" id="title" name="title" value="" class="form-control"> | 23 | + <input type="text" id="title" name="title" value="<%= post.title %>" class="form-control <%= (errors.title)?'is-invalid':'' %>"> |
24 | + <% if(errors.title){ %> | ||
25 | + <span class="invalid-feedback"><%= errors.title.message %></span> | ||
26 | + <% } %> | ||
24 | </div> | 27 | </div> |
25 | 28 | ||
26 | <div class="form-group"> | 29 | <div class="form-group"> |
27 | - <label for="body">Body</label> | 30 | + <textarea id="body" name="body" rows="5" class="form-control <%= (errors.body)?'is-invalid':''%>"><%= post.body %></textarea> |
28 | - <textarea id="body" name="body" rows="5" class="form-control"></textarea> | 31 | + <% if(errors.body){ %> |
32 | + <span class="invalid-feedback"><%= errors.body.message %></span> | ||
33 | + <% } %> | ||
29 | </div> | 34 | </div> |
30 | 35 | ||
36 | + <% if(errors.unhandled){ %> | ||
37 | + <div class="invalid-feedback b-block"> | ||
38 | + <%= errors.unhandled %> | ||
39 | + </div> | ||
40 | + <% } %> | ||
41 | + | ||
31 | <div> | 42 | <div> |
32 | <a class="btn btn-primary" href="/posts">Back</a> | 43 | <a class="btn btn-primary" href="/posts">Back</a> |
33 | <button type="submit" class="btn btn-primary">Submit</button> | 44 | <button type="submit" class="btn btn-primary">Submit</button> |
34 | </div> | 45 | </div> |
35 | 46 | ||
36 | </form> | 47 | </form> |
37 | - | ||
38 | </div> | 48 | </div> |
39 | </body> | 49 | </body> |
40 | </html> | 50 | </html> |
... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
... | @@ -26,9 +26,12 @@ | ... | @@ -26,9 +26,12 @@ |
26 | 26 | ||
27 | <div class="col-md-5 col-lg-4 col-xl-3 order-sm-1 order-md-2"> <!-- 1 --> | 27 | <div class="col-md-5 col-lg-4 col-xl-3 order-sm-1 order-md-2"> <!-- 1 --> |
28 | <div class="post-info card m-2 p-2"> | 28 | <div class="post-info card m-2 p-2"> |
29 | - <div><span>Created</span> : <span data-date-time="<%= post.createdAt %>"></span></div> <!-- 2 --> | 29 | + <div class="border-bottom pb-1 mb-1"> |
30 | + <span>Author</span> : <%= post.author ? post.author.username: "" %> | ||
31 | + </div> | ||
32 | + <div><span>Created</span> : <span data-date-time="<%= post.createdAt %>"><%= post.createdAt %></span></div> | ||
30 | <% if(post.updatedAt) { %> | 33 | <% if(post.updatedAt) { %> |
31 | - <div><span>Updated</span> : <span data-date-time="<%= post.updatedAt %>"></span></div> <!-- 2 --> | 34 | + <div><span>Updated</span> : <span data-date-time="<%= post.updatedAt %>"><%= post.updatedAt %></span></div> |
32 | <% } %> | 35 | <% } %> |
33 | </div> | 36 | </div> |
34 | </div> | 37 | </div> |
... | @@ -38,10 +41,12 @@ | ... | @@ -38,10 +41,12 @@ |
38 | 41 | ||
39 | <div class="mt-3"> | 42 | <div class="mt-3"> |
40 | <a class="btn btn-primary" href="/posts">Back</a> | 43 | <a class="btn btn-primary" href="/posts">Back</a> |
41 | - <a class="btn btn-primary" href="/posts/<%= post._id %>/edit">Edit</a> | 44 | + <% if(isAuthenticated && post.author && currentUser.id == post.author.id){ %> <!-- 1 --> |
42 | - <form action="/posts/<%= post._id %>?_method=delete" method="post" class="d-inline"> | 45 | + <a class="btn btn-primary" href="/posts/<%= post._id %>/edit">Edit</a> |
46 | + <form action="/posts/<%= post._id %>?_method=delete" method="post" class="d-inline"> | ||
43 | <a class="btn btn-primary" href="javascript:void(0)" onclick="confirm('Do you want to delete this?')?this.parentElement.submit():null;">Delete</a> | 47 | <a class="btn btn-primary" href="javascript:void(0)" onclick="confirm('Do you want to delete this?')?this.parentElement.submit():null;">Delete</a> |
44 | </form> | 48 | </form> |
49 | + <% } %> | ||
45 | </div> | 50 | </div> |
46 | 51 | ||
47 | </div> | 52 | </div> | ... | ... |
... | @@ -78,12 +78,18 @@ | ... | @@ -78,12 +78,18 @@ |
78 | <small>*Required</small> | 78 | <small>*Required</small> |
79 | </p> | 79 | </p> |
80 | 80 | ||
81 | + <div class="buttons"> | ||
82 | + <a class="btn btn-primary" href="/users/<%= user.username %>">Back</a> | ||
83 | + <button type="submit" class="btn btn-primary">Submit</button> | ||
84 | + </div> | ||
85 | + | ||
81 | <% if(errors.unhandled){ %> <!-- 4 --> | 86 | <% if(errors.unhandled){ %> <!-- 4 --> |
82 | <div class="alert alert-danger"> | 87 | <div class="alert alert-danger"> |
83 | <%= errors.unhandled %> | 88 | <%= errors.unhandled %> |
84 | </div> | 89 | </div> |
85 | <% } %> | 90 | <% } %> |
86 | - | 91 | + |
92 | + | ||
87 | </form> | 93 | </form> |
88 | 94 | ||
89 | </div> | 95 | </div> | ... | ... |
... | @@ -29,7 +29,9 @@ | ... | @@ -29,7 +29,9 @@ |
29 | 29 | ||
30 | <div> | 30 | <div> |
31 | <a class="btn btn-primary" href="/users">Back</a> | 31 | <a class="btn btn-primary" href="/users">Back</a> |
32 | + <% if(isAuthenticated && currentUser.id == user.id){ %> | ||
32 | <a class="btn btn-primary" href="/users/<%= user.username %>/edit">Edit</a> | 33 | <a class="btn btn-primary" href="/users/<%= user.username %>/edit">Edit</a> |
34 | + <% } %> | ||
33 | <form action="/users/<%= user.username %>?_method=delete" method="post" class="d-inline"> | 35 | <form action="/users/<%= user.username %>?_method=delete" method="post" class="d-inline"> |
34 | <a class="btn btn-primary" href="javascript:void(0)" onclick="confirm('Do you want to delete this?')?this.parentElement.submit():null;">Delete</a> | 36 | <a class="btn btn-primary" href="javascript:void(0)" onclick="confirm('Do you want to delete this?')?this.parentElement.submit():null;">Delete</a> |
35 | </form> | 37 | </form> | ... | ... |
-
Please register or login to post a comment