Toggle navigation
Toggle navigation
This project
Loading...
Sign in
임태민
/
Mapmory
Go to a project
Toggle navigation
Toggle navigation pinning
Projects
Groups
Snippets
Help
Project
Activity
Repository
Graphs
Network
Create a new issue
Commits
Issue Boards
Authored by
임태민
2021-05-18 16:46:42 +0900
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
067d45a0ebd07b2bddc651aede118d057355cf20
067d45a0
1 parent
2adcdb35
Update project directory
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
237 additions
and
67 deletions
Project/models/Post.js
Project/public/assets/img/bg-callout.jpg
Project/public/css/master.css
Project/routes/posts.js
Project/routes/users.js
Project/util.js
Project/views/home/about.ejs
Project/views/home/welcome.ejs
Project/views/partials/nav.ejs
Project/views/posts/edit.ejs
Project/views/posts/index.ejs
Project/views/posts/new.ejs
Project/views/posts/show.ejs
Project/views/users/edit.ejs
Project/views/users/show.ejs
Project/models/Post.js
View file @
067d45a
...
...
@@ -3,8 +3,9 @@ const mongoose = require('mongoose');
// Declare the schemea of post
var
postSchema
=
mongoose
.
Schema
({
title
:{
type
:
String
,
required
:
true
},
body
:{
type
:
String
,
required
:
true
},
title
:{
type
:
String
,
required
:[
true
,
'Title is required!'
]},
body
:{
type
:
String
,
required
:[
true
,
'Content is required!'
]},
author
:{
type
:
mongoose
.
Schema
.
Types
.
ObjectId
,
ref
:
'user'
,
required
:
true
},
createdAt
:{
type
:
Date
,
default
:
Date
.
now
},
updatedAt
:{
type
:
Date
},
});
...
...
Project/public/assets/img/bg-callout.jpg
0 → 100644
View file @
067d45a
1.74 MB
Project/public/css/master.css
View file @
067d45a
body
{
background-color
:
whitesmoke
;
}
.h1
{
font-family
:
'PT Serif'
,
serif
;
...
...
@@ -21,7 +21,11 @@ body {
.board-table
.date
{
width
:
100px
;
}
.board-table
.author
,
.board-table
.date
{
width
:
100px
;
}
.post-body
{
white-space
:
pre-line
;
/* 2 */
}
...
...
@@ -31,4 +35,12 @@ body {
.user-form
{
width
:
400px
;
}
\ No newline at end of file
}
.mb-3
{
background-color
:
tan
;
}
\ No newline at end of file
...
...
Project/routes/posts.js
View file @
067d45a
var
express
=
require
(
'express'
);
var
router
=
express
.
Router
();
var
Post
=
require
(
'../models/Post'
);
var
util
=
require
(
'../util'
);
// Post home
router
.
get
(
'/'
,
function
(
req
,
res
){
Post
.
find
({})
.
populate
(
'author'
)
.
sort
(
'-createdAt'
)
.
exec
(
function
(
err
,
posts
){
if
(
err
){
return
res
.
json
(
err
)};
...
...
@@ -15,56 +17,84 @@ router.get('/', function(req, res){
// Post new
router
.
get
(
'/new'
,
function
(
req
,
res
){
res
.
render
(
'posts/new'
);
router
.
get
(
'/new'
,
util
.
isLoggedin
,
function
(
req
,
res
){
var
post
=
req
.
flash
(
'post'
)[
0
]
||
{};
var
errors
=
req
.
flash
(
'errors'
)[
0
]
||
{};
res
.
render
(
'posts/new'
,
{
post
:
post
,
errors
:
errors
});
})
// Post create
router
.
post
(
'/'
,
function
(
req
,
res
){
router
.
post
(
'/'
,
util
.
isLoggedin
,
function
(
req
,
res
){
req
.
body
.
author
=
req
.
user
.
_id
;
Post
.
create
(
req
.
body
,
function
(
err
,
post
){
if
(
err
){
return
res
.
json
(
err
)};
if
(
err
){
req
.
flash
(
'post'
,
req
.
body
);
req
.
flash
(
'errors'
,
util
.
parseError
(
err
));
return
res
.
redirect
(
'/posts/new'
);
};
res
.
redirect
(
'/posts'
);
});
});
// Post show
router
.
get
(
'/:id'
,
function
(
req
,
res
){
Post
.
findOne
({
_id
:
req
.
params
.
id
},
function
(
err
,
post
){
if
(
err
){
return
res
.
json
(
err
)};
res
.
render
(
'posts/show'
,
{
post
:
post
});
});
router
.
get
(
'/:id'
,
util
.
isLoggedin
,
function
(
req
,
res
){
Post
.
findOne
({
_id
:
req
.
params
.
id
})
.
populate
(
'author'
)
.
exec
(
function
(
err
,
post
){
if
(
err
){
return
res
.
json
(
err
)};
res
.
render
(
'posts/show'
,
{
post
:
post
});
});
});
// Post edit
router
.
get
(
'/:id/edit'
,
function
(
req
,
res
){
Post
.
findOne
({
_id
:
req
.
params
.
id
},
function
(
err
,
post
){
if
(
err
){
return
res
.
join
(
err
)};
res
.
render
(
'posts/edit'
,
{
posts
:
post
});
});
router
.
get
(
'/:id/edit'
,
util
.
isLoggedin
,
checkPermission
,
function
(
req
,
res
){
var
post
=
req
.
flash
(
'post'
)[
0
];
var
errors
=
req
.
flash
(
'errors'
)[
0
]
||
{};
if
(
!
post
){
Post
.
findOne
({
_id
:
req
.
params
.
id
},
function
(
err
,
post
){
if
(
err
){
return
res
.
join
(
err
)};
res
.
render
(
'posts/edit'
,
{
posts
:
post
,
errors
:
errors
});
});
}
else
{
post
.
_id
=
req
.
params
.
id
;
res
.
render
(
'posts/edit'
,
{
post
:
post
,
errors
:
errors
});
}
});
// Post update
router
.
get
(
'/:id'
,
function
(
req
,
res
){
router
.
put
(
'/:id'
,
util
.
isLoggedin
,
checkPermission
,
function
(
req
,
res
){
req
.
body
.
updatedAt
=
Date
.
now
();
Post
.
findOneAndUpdate
({
_id
:
req
.
params
.
id
},
req
.
body
,
function
(
err
,
post
){
if
(
err
){
return
res
.
join
(
err
)};
Post
.
findOneAndUpdate
({
_id
:
req
.
params
.
id
},
req
.
body
,
{
runValidators
:
true
},
function
(
err
,
post
){
if
(
err
){
req
.
flash
(
'post'
,
req
.
body
),
req
.
flash
(
'errors'
,
util
.
parseError
(
err
));
return
res
.
redirect
(
'/posts/'
+
req
.
params
,
id
+
'/edit'
);
};
res
.
redirect
(
'posts/'
+
req
.
params
.
id
);
});
});
// Post delete
router
.
delete
(
'/:id'
,
function
(
req
,
res
){
router
.
delete
(
'/:id'
,
util
.
isLoggedin
,
checkPermission
,
function
(
req
,
res
){
Post
.
deleteOne
({
_id
:
req
.
params
.
id
},
function
(
err
){
if
(
err
){
return
res
.
join
(
err
)};
res
.
redirect
(
'/posts'
);
});
});
function
checkPermission
(
req
,
res
,
next
){
Post
.
findOne
({
_id
:
req
.
params
.
id
},
function
(
err
,
post
){
if
(
err
){
return
res
.
json
(
err
)};
if
(
post
.
author
!=
req
.
user
.
id
){
return
util
.
noPermission
(
req
,
res
)};
next
();
});
}
// Export module
module
.
exports
=
router
;
\ No newline at end of file
...
...
Project/routes/users.js
View file @
067d45a
var
express
=
require
(
'express'
);
var
router
=
express
.
Router
();
var
User
=
require
(
'../models/User'
);
var
util
=
require
(
'../util'
);
//
Index // 1
router
.
get
(
'/'
,
function
(
req
,
res
){
User
.
find
({})
.
sort
({
username
:
1
})
.
exec
(
function
(
err
,
users
){
if
(
err
)
return
res
.
json
(
err
);
res
.
render
(
'users/index'
,
{
users
:
users
});
});
});
//
Index
//
router.get('/', function(req, res){
//
User.find({})
//
.sort({username:1})
//
.exec(function(err, users){
//
if(err) return res.json(err);
//
res.render('users/index', {users:users});
//
});
//
});
// New
router
.
get
(
'/new'
,
function
(
req
,
res
){
...
...
@@ -24,15 +25,15 @@ router.post('/', function(req, res){
User
.
create
(
req
.
body
,
function
(
err
,
user
){
if
(
err
){
req
.
flash
(
'user'
,
req
.
body
);
req
.
flash
(
'errors'
,
parseError
(
err
));
req
.
flash
(
'errors'
,
util
.
parseError
(
err
));
return
res
.
redirect
(
'/users/new'
);
}
res
.
redirect
(
'/users'
);
res
.
redirect
(
'/users
/login
'
);
});
});
// show
router
.
get
(
'/:username'
,
function
(
req
,
res
){
router
.
get
(
'/:username'
,
util
.
isLoggedin
,
function
(
req
,
res
){
User
.
findOne
({
username
:
req
.
params
.
username
},
function
(
err
,
user
){
if
(
err
)
return
res
.
json
(
err
);
res
.
render
(
'users/show'
,
{
user
:
user
});
...
...
@@ -40,7 +41,7 @@ router.get('/:username', function(req, res){
});
// edit
router
.
get
(
'/:username/edit'
,
function
(
req
,
res
){
router
.
get
(
'/:username/edit'
,
util
.
isLoggedin
,
checkPermission
,
function
(
req
,
res
){
var
user
=
req
.
flash
(
'user'
)[
0
];
var
errors
=
req
.
flash
(
'errors'
)[
0
]
||
{};
if
(
!
user
){
...
...
@@ -55,7 +56,7 @@ router.get('/:username/edit', function(req, res){
});
// update
router
.
put
(
'/:username'
,
function
(
req
,
res
,
next
){
router
.
put
(
'/:username'
,
util
.
isLoggedin
,
checkPermission
,
function
(
req
,
res
,
next
){
User
.
findOne
({
username
:
req
.
params
.
username
})
// 2-1
.
select
(
'password'
)
// 2-2
.
exec
(
function
(
err
,
user
){
...
...
@@ -72,7 +73,7 @@ router.put('/:username', function(req, res, next){
user
.
save
(
function
(
err
,
user
){
if
(
err
){
req
.
flash
(
'user'
,
req
.
body
);
req
.
flash
(
'errors'
,
parseError
(
err
));
req
.
flash
(
'errors'
,
util
.
parseError
(
err
));
return
res
.
redirect
(
'/users/'
+
req
.
params
.
username
+
'/edit'
);
}
res
.
redirect
(
'/users/'
+
user
.
username
);
...
...
@@ -81,12 +82,12 @@ router.put('/:username', function(req, res, next){
});
// destroy
router
.
delete
(
'/:username'
,
function
(
req
,
res
){
User
.
deleteOne
({
username
:
req
.
params
.
username
},
function
(
err
){
if
(
err
)
return
res
.
json
(
err
);
res
.
redirect
(
'/users'
);
});
});
//
router.delete('/:username', function(req, res){
//
User.deleteOne({username:req.params.username}, function(err){
//
if(err) return res.json(err);
//
res.redirect('/users');
//
});
//
});
module
.
exports
=
router
;
...
...
@@ -105,4 +106,12 @@ function parseError(errors){
parsed
.
unhandled
=
JSON
.
stringify
(
errors
);
}
return
parsed
;
}
function
checkPermission
(
req
,
res
,
next
){
User
.
findOne
({
username
:
req
.
params
.
username
},
function
(
err
,
post
){
if
(
err
){
return
res
.
json
(
err
)};
if
(
post
.
id
!=
req
.
user
.
id
){
return
util
.
noPermission
(
req
,
res
)};
next
();
});
}
\ No newline at end of file
...
...
Project/util.js
0 → 100644
View file @
067d45a
var
util
=
{};
util
.
parseError
=
function
(
errors
){
var
parsed
=
{};
if
(
errors
.
name
==
'ValidationError'
){
for
(
var
name
in
errors
.
errors
){
var
validationError
=
errors
.
errors
[
name
];
parsed
[
name
]
=
{
message
:
validationError
.
message
};
}
}
else
if
(
errors
.
code
==
'11000'
&&
errors
.
errmsg
.
indexOf
(
'username'
)
>
0
)
{
parsed
.
username
=
{
message
:
'This username already exists!'
};
}
else
{
parsed
.
unhandled
=
JSON
.
stringify
(
errors
);
}
return
parsed
;
}
util
.
isLoggedin
=
function
(
req
,
res
,
next
){
if
(
req
.
isAuthenticated
()){
next
();
}
else
{
req
.
flash
(
'errors'
,
{
login
:
'Please login first'
});
res
.
redirect
(
'/login'
);
}
}
util
.
noPermission
=
function
(
req
,
res
){
req
.
flash
(
'errors'
,
{
login
:
"You don't have permission"
});
req
.
logout
();
res
.
redirect
(
'/login'
);
}
module
.
exports
=
util
;
\ No newline at end of file
Project/views/home/about.ejs
View file @
067d45a
...
...
@@ -9,8 +9,9 @@
<div
class=
"container mb-3"
>
<h2
class=
"mb-3"
>
About
</h2>
<P>
이 사이트는
<a
href=
"http://a-mean-blog.com/ko/blog/Node-JS-첫걸음/게시판-만들기"
>
http://a-mean-blog.com/ko/blog/Node-JS-첫걸음/게시판-만들기
</a>
에서 작성되었습니다
!
</p>
<P>
Store and Share your precious memory in MAPMORY
!
</p>
</div>
</body>
...
...
Project/views/home/welcome.ejs
View file @
067d45a
...
...
@@ -2,17 +2,54 @@
<html>
<head>
<
%- include('../partials/head') %>
<style>
body
,
html
{
margin
:
0
;
padding
:
0
;
height
:
100%
;
}
.img
{
border
:
0
;
padding
:
0
;
background-image
:
url('assets/img/bg-callout.jpg')
;
background-size
:
cover
;
min-height
:
100%
;
background-size
:
cover
;
background-position
:
center
;
}
.img
.content
{
position
:
absolute
;
top
:
45%
;
left
:
50%
;
font-size
:
1rem
;
transform
:
translate
(
-50%
,
-50%
);
font-family
:
'PT Serif'
,
serif
;
text-align
:
center
;
}
h1
{
font-size
:
5rem
;
padding
:
0
;
margin
:
0
;
}
h3
{
font-size
:
2.5rem
;
padding
:
0
;
margin
:
2px
;
}
</style>
</head>
<body>
<
%- include('../partials/nav') %>
<div
class=
"container mb-3"
>
<div
class=
"jumbotron"
>
<h1>
My Website
</h1>
<P>
제 웹사이트를 방문해 주셔서 감사합니다!
</p>
<div
class=
"img"
>
<div
class=
"content"
>
<h1>
Mapmory
</h1>
<h3><em>
Save your reminiscence with place
</em></h3>
</div>
</div>
</body>
</html>
\ No newline at end of file
...
...
Project/views/partials/nav.ejs
View file @
067d45a
<nav class="navbar navbar-expand-sm navbar-light bg-light mb-3">
<!-- <nav class="navbar navbar-expand-sm navbar-light bg-light mb-3"> -->
<nav class="navbar navbar-expand-sm navbar-dark bg-dark mb-3">
<div class="container">
<div class="navbar-brand">M
y Website
</div>
<div class="navbar-brand">M
apmory
</div>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent">
<span class="navbar-toggler-icon"></span>
</button>
...
...
@@ -8,7 +9,7 @@
<ul class="navbar-nav">
<li class="nav-item"><a href="/" class="nav-link">Home</a></li>
<li class="nav-item"><a href="/about" class="nav-link">About</a></li>
<li class="nav-item"><a href="/posts" class="nav-link">
Posts
</a></li>
<li class="nav-item"><a href="/posts" class="nav-link">
Memory
</a></li>
</ul>
<ul class="navbar-nav ml-auto"> <!-- 우측 정렬 -->
...
...
Project/views/posts/edit.ejs
View file @
067d45a
...
...
@@ -21,14 +21,26 @@
<div
class=
"form-group"
>
<label
for=
"title"
>
Title
</label>
<input
type=
"text"
id=
"title"
name=
"title"
value=
"<%= post.title %>"
class=
"form-control"
>
<input
type=
"text"
id=
"title"
name=
"title"
value=
"<%= post.title %>"
class=
"form-control <%= (errors.title)?'is-invalid':'' %>"
>
<
% if(errors.title){ %>
<span
class=
"invalid-feedback"
>
<
%= errors.title.message %>
</span>
<
% } %>
</div>
<div
class=
"form-group"
>
<label
for=
"body"
>
Body
</label>
<textarea
id=
"body"
name=
"body"
rows=
"5"
class=
"form-control"
>
<
%= post.body %>
</textarea>
<textarea
id=
"body"
name=
"body"
rows=
"5"
class=
"form-control <%= (errors.body)?'is-invalid':''%>"
>
<
%= post.body %>
</textarea>
<
% if(errors.body){ %>
<span
class=
"invalid-feedback"
>
<
%= errors.body.message %>
</span>
<
% } %>
</div>
<
% if(errors.unhandled){ %>
<div
class=
"invalid-feedback b-block"
>
<
%= errors.unhandled %>
</div>
<
% } %>
<div>
<a
class=
"btn btn-primary"
href=
"/posts/<%= post._id %>"
>
Back
</a>
<button
type=
"submit"
class=
"btn btn-primary"
>
Submit
</button>
...
...
Project/views/posts/index.ejs
View file @
067d45a
...
...
@@ -15,6 +15,7 @@
<thead
class=
"thead-light"
>
<tr>
<th
scope=
"col"
>
Title
</th>
<th
scope=
"col"
class=
"author"
>
Author
</th>
<th
scope=
"col"
class=
"date"
>
Date
</th>
</tr>
</thead>
...
...
@@ -30,8 +31,11 @@
<td>
<a
href=
"/posts/<%= post._id %>"
><div
class=
"ellipsis"
>
<
%= post.title %>
</div></a>
</td>
<td
class=
"author"
>
<div
class=
"ellipsis"
>
<
%= post.author ? post.author.username : "" %>
</div>
</td>
<td
class=
"date"
>
<span
data-date=
"<%= post.createdAt %>"
></span>
<span
data-date=
"<%= post.createdAt %>"
>
<
%= post.createdAt %>
<
/span>
</td>
</tr>
<
% }) %>
...
...
@@ -40,7 +44,9 @@
</table>
<div>
<a
class=
"btn btn-primary"
href=
"/posts/new"
>
New
</a>
<
% if(isAuthenticated){ %>
<a
class=
"btn btn-primary"
href=
"/posts/new"
>
New
</a>
<
% } %>
</div>
</div>
...
...
Project/views/posts/new.ejs
View file @
067d45a
...
...
@@ -20,21 +20,31 @@
<div
class=
"form-group"
>
<label
for=
"title"
>
Title
</label>
<input
type=
"text"
id=
"title"
name=
"title"
value=
""
class=
"form-control"
>
<input
type=
"text"
id=
"title"
name=
"title"
value=
"<%= post.title %>"
class=
"form-control <%= (errors.title)?'is-invalid':'' %>"
>
<
% if(errors.title){ %>
<span
class=
"invalid-feedback"
>
<
%= errors.title.message %>
</span>
<
% } %>
</div>
<div
class=
"form-group"
>
<label
for=
"body"
>
Body
</label>
<textarea
id=
"body"
name=
"body"
rows=
"5"
class=
"form-control"
></textarea>
<textarea
id=
"body"
name=
"body"
rows=
"5"
class=
"form-control <%= (errors.body)?'is-invalid':''%>"
>
<
%= post.body %>
</textarea>
<
% if(errors.body){ %>
<span
class=
"invalid-feedback"
>
<
%= errors.body.message %>
</span>
<
% } %>
</div>
<
% if(errors.unhandled){ %>
<div
class=
"invalid-feedback b-block"
>
<
%= errors.unhandled %>
</div>
<
% } %>
<div>
<a
class=
"btn btn-primary"
href=
"/posts"
>
Back
</a>
<button
type=
"submit"
class=
"btn btn-primary"
>
Submit
</button>
</div>
</form>
</div>
</body>
</html>
\ No newline at end of file
...
...
Project/views/posts/show.ejs
View file @
067d45a
...
...
@@ -26,9 +26,12 @@
<div
class=
"col-md-5 col-lg-4 col-xl-3 order-sm-1 order-md-2"
>
<!-- 1 -->
<div
class=
"post-info card m-2 p-2"
>
<div><span>
Created
</span>
:
<span
data-date-time=
"<%= post.createdAt %>"
></span></div>
<!-- 2 -->
<div
class=
"border-bottom pb-1 mb-1"
>
<span>
Author
</span>
:
<
%= post.author ? post.author.username: "" %>
</div>
<div><span>
Created
</span>
:
<span
data-date-time=
"<%= post.createdAt %>"
>
<
%= post.createdAt %>
</span></div>
<
% if(post.updatedAt) { %>
<div><span>
Updated
</span>
:
<span
data-date-time=
"<%= post.updatedAt %>"
><
/span></div>
<!-- 2 --
>
<div><span>
Updated
</span>
:
<span
data-date-time=
"<%= post.updatedAt %>"
>
<
%= post.updatedAt %>
</span></div
>
<
% } %>
</div>
</div>
...
...
@@ -38,10 +41,12 @@
<div
class=
"mt-3"
>
<a
class=
"btn btn-primary"
href=
"/posts"
>
Back
</a>
<a
class=
"btn btn-primary"
href=
"/posts/<%= post._id %>/edit"
>
Edit
</a>
<form
action=
"/posts/<%= post._id %>?_method=delete"
method=
"post"
class=
"d-inline"
>
<
% if(isAuthenticated
&&
post.author
&&
currentUser.id == post.author.id){ %>
<!-- 1 -->
<a
class=
"btn btn-primary"
href=
"/posts/<%= post._id %>/edit"
>
Edit
</a>
<form
action=
"/posts/<%= post._id %>?_method=delete"
method=
"post"
class=
"d-inline"
>
<a
class=
"btn btn-primary"
href=
"javascript:void(0)"
onclick=
"confirm('Do you want to delete this?')?this.parentElement.submit():null;"
>
Delete
</a>
</form>
<
% } %>
</div>
</div>
...
...
Project/views/users/edit.ejs
View file @
067d45a
...
...
@@ -78,12 +78,18 @@
<small>
*Required
</small>
</p>
<div
class=
"buttons"
>
<a
class=
"btn btn-primary"
href=
"/users/<%= user.username %>"
>
Back
</a>
<button
type=
"submit"
class=
"btn btn-primary"
>
Submit
</button>
</div>
<
% if(errors.unhandled){ %>
<!-- 4 -->
<div
class=
"alert alert-danger"
>
<
%= errors.unhandled %>
</div>
<
% } %>
</form>
</div>
...
...
Project/views/users/show.ejs
View file @
067d45a
...
...
@@ -29,7 +29,9 @@
<div>
<a
class=
"btn btn-primary"
href=
"/users"
>
Back
</a>
<
% if(isAuthenticated
&&
currentUser.id == user.id){ %>
<a
class=
"btn btn-primary"
href=
"/users/<%= user.username %>/edit"
>
Edit
</a>
<
% } %>
<form
action=
"/users/<%= user.username %>?_method=delete"
method=
"post"
class=
"d-inline"
>
<a
class=
"btn btn-primary"
href=
"javascript:void(0)"
onclick=
"confirm('Do you want to delete this?')?this.parentElement.submit():null;"
>
Delete
</a>
</form>
...
...
Please
register
or
login
to post a comment