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-06-04 21:25:52 +0900
Browse Files
Options
Browse Files
Download
Plain Diff
Commit
ad628c69f7883e15667112492817559b9d408d91
ad628c69
2 parents
6839bf03
93ef0e4e
Merge branch 'release'
Show whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
171 additions
and
16 deletions
README.md
index.js
models/Post.js
routes/posts.js
util.js
views/partials/gmap.ejs
views/partials/showgmap.ejs
views/posts/index.ejs
views/posts/show.ejs
README.md
View file @
ad628c6
# 📒 Mapmory
#### Mapmory provides location-based recording sevices utilizing Google Maps API.
### Mapmory functions
-----------------
-
[
x
]
Register
-
[
x
]
Log in/out
-
[
x
]
Member information edit
-
[
x
]
Create your memories(With Title, Date, Author, Address)
-
[
x
]
Delete your memories
-
[
x
]
Save your memory with map
-
[
x
]
Show your memory with map
-
[
x
]
Edit your memory with map
-
[
x
]
Search your memories
### Stack
-----------------
+
Front end : EJS template engine
+
Back end : Express/NodeJS
+
Database : Mongo DB
+
Server : AWS EC2
## ✏️ Quick Start (build, install, setup manual)
$ git clone http://khuhub.khu.ac.kr/2017101294/Mapmory.git
$ npm install
$ node index.js
If it does not work well
$ npm install nodemon-g
At package.json, add
``` "start" : "nodemon index.js" ```
"scripts": {
"test": "echo
\"
Error: no test specified
\"
&& exit 1",
"start" : "nodemon index.js"
}
$ npm start
### Dependency
-----------------
+
bcryptjs : 2.4.3,
+
body-parser : 1.19.0,
+
connect-flash : 0.1.1,
+
ejs : 3.1.6,
+
express : 4.17.1,
+
express-session : 1.17.1,
+
method-override : 3.0.0,
+
mongoose : 5.12.8,
+
passport : 0.4.1,
+
passport-local : 1.0.0
### 👬 Team members
-----------------
+
Im Taemin (@devTaemin)
+
Hong Jiyoon (@fheldgktpdy)
\ No newline at end of file
...
...
index.js
View file @
ad628c6
...
...
@@ -16,7 +16,7 @@ mongoose.set('useCreateIndex', true);
mongoose
.
set
(
'useUnifiedTopology'
,
true
);
// Connect DB environment variable
mongoose
.
connect
(
'mongodb
+srv://Mapmory_admin:admin@cluster0.ncnjj.mongodb.net/Project-Mapmory?retryWrites=true&w=majority
'
);
mongoose
.
connect
(
'mongodb
key입력하는곳
'
);
// Store DB in the variable 'db'
var
db
=
mongoose
.
connection
;
...
...
models/Post.js
View file @
ad628c6
...
...
@@ -7,7 +7,7 @@ var postSchema = mongoose.Schema({
address
:{
type
:
String
,
required
:[
true
,
'address 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
()
},
createdAt
:{
type
:
Date
,
default
:
Date
.
now
},
updatedAt
:{
type
:
Date
}
});
...
...
routes/posts.js
View file @
ad628c6
...
...
@@ -6,13 +6,31 @@ var util = require('../util');
// Post home
router
.
get
(
'/'
,
function
(
req
,
res
){
Post
.
find
({})
router
.
get
(
'/'
,
async
function
(
req
,
res
){
// Paging 기능 추가
var
page
=
Math
.
max
(
1
,
parseInt
(
req
.
query
.
page
));
var
limit
=
Math
.
max
(
1
,
parseInt
(
req
.
query
.
limit
));
page
=
!
isNaN
(
page
)?
page
:
1
;
limit
=
!
isNaN
(
limit
)?
limit
:
10
;
var
searchQuery
=
createSearchQuery
(
req
.
query
);
var
skip
=
(
page
-
1
)
*
limit
;
var
count
=
await
Post
.
countDocuments
(
searchQuery
);
var
maxPage
=
Math
.
ceil
(
count
/
limit
);
var
posts
=
await
Post
.
find
(
searchQuery
)
.
populate
(
'author'
)
.
sort
(
'-createdAt'
)
.
exec
(
function
(
err
,
posts
){
if
(
err
){
return
res
.
json
(
err
)};
res
.
render
(
'posts/index'
,
{
posts
:
posts
});
.
skip
(
skip
)
.
limit
(
limit
)
.
exec
();
res
.
render
(
'posts/index'
,
{
posts
:
posts
,
currentPage
:
page
,
maxPage
:
maxPage
,
limit
:
limit
,
searchType
:
req
.
query
.
searchType
,
searchText
:
req
.
query
.
searchText
});
});
...
...
@@ -97,5 +115,23 @@ function checkPermission(req, res, next){
});
}
// Search function
function
createSearchQuery
(
queries
){
var
searchQuery
=
{};
if
(
queries
.
searchType
&&
queries
.
searchText
&&
queries
.
searchText
.
length
>=
3
){
var
searchTypes
=
queries
.
searchType
.
toLowerCase
().
split
(
','
);
var
postQueries
=
[];
if
(
searchTypes
.
indexOf
(
'title'
)
>=
0
){
postQueries
.
push
({
title
:
{
$regex
:
new
RegExp
(
queries
.
searchText
,
'i'
)
}
});
}
if
(
searchTypes
.
indexOf
(
'body'
)
>=
0
){
postQueries
.
push
({
body
:
{
$regex
:
new
RegExp
(
queries
.
searchText
,
'i'
)
}
});
}
if
(
postQueries
.
length
>
0
)
searchQuery
=
{
$or
:
postQueries
};
}
return
searchQuery
;
}
// Export module
module
.
exports
=
router
;
\ No newline at end of file
...
...
util.js
View file @
ad628c6
...
...
@@ -33,6 +33,26 @@ util.noPermission = function(req, res){
res
.
redirect
(
'/login'
);
}
// 검색 기능 추가
util
.
getPostQueryString
=
function
(
req
,
res
,
next
){
res
.
locals
.
getPostQueryString
=
function
(
isAppended
=
false
,
overwrites
=
{}){
var
queryString
=
''
;
var
queryArray
=
[];
var
page
=
overwrites
.
page
?
overwrites
.
page
:(
req
.
query
.
page
?
req
.
query
.
page
:
''
);
var
limit
=
overwrites
.
limit
?
overwrites
.
limit
:(
req
.
query
.
limit
?
req
.
query
.
limit
:
''
);
var
searchType
=
overwrites
.
searchType
?
overwrites
.
searchType
:(
req
.
query
.
searchType
?
req
.
query
.
searchType
:
''
);
var
searchText
=
overwrites
.
searchText
?
overwrites
.
searchText
:(
req
.
query
.
searchText
?
req
.
query
.
searchText
:
''
);
if
(
page
)
queryArray
.
push
(
'page='
+
page
);
if
(
limit
)
queryArray
.
push
(
'limit='
+
limit
);
if
(
searchType
)
queryArray
.
push
(
'searchType='
+
searchType
);
if
(
searchText
)
queryArray
.
push
(
'searchText='
+
searchText
);
if
(
queryArray
.
length
>
0
)
queryString
=
(
isAppended
?
'&'
:
'?'
)
+
queryArray
.
join
(
'&'
);
return
queryString
;
}
next
();
}
module
.
exports
=
util
;
\ No newline at end of file
...
...
views/partials/gmap.ejs
View file @
ad628c6
...
...
@@ -135,7 +135,7 @@
<!-- Async script executes immediately and must be after any DOM elements used in callback. -->
<script
src=
"https://maps.googleapis.com/maps/api/js?key=
AIzaSyDK6K4iDdo9cKQdrNoOJaaYg29nEG0BIjw
&callback=initMap&libraries=&v=weekly"
src=
"https://maps.googleapis.com/maps/api/js?key=
googlekey값을 입력하세요
&callback=initMap&libraries=&v=weekly"
async
></script>
</body>
...
...
views/partials/showgmap.ejs
View file @
ad628c6
...
...
@@ -142,7 +142,7 @@
<!-- Async script executes immediately and must be after any DOM elements used in callback. -->
<script
src=
"https://maps.googleapis.com/maps/api/js?key=
AIzaSyDK6K4iDdo9cKQdrNoOJaaYg29nEG0BIjw
&callback=initMap&libraries=&v=weekly"
src=
"https://maps.googleapis.com/maps/api/js?key=
googlekey값을 입력하세요
&callback=initMap&libraries=&v=weekly"
async
></script>
...
...
views/posts/index.ejs
View file @
ad628c6
...
...
@@ -47,15 +47,49 @@
</tr>
<
% }) %>
</tbody>
</table>
</div>
<nav
class=
"nav justify-content-center bg-light"
>
<
%
var offset = 2;
var previousBtnEnabled = currentPage>1;
var nextBtnEnabled = currentPage
<maxPage
;
%
>
<ul
class=
"pagination pagination-sm justify-content-center align-items-center h-100 mb-0"
>
<li
class=
"page-item <%= previousBtnEnabled?'':'disabled' %>"
>
<a
class=
"page-link"
href=
"/posts?page=<%= currentPage-1 %>&limit=<%= limit %>"
<%=
previousBtnEnabled
?''
:
'
tabindex=
-1'
%
>
>«
</a>
</li>
<
% for(i=1;i
<
=maxPage;i++){ %>
<
% if(i==1 || i==maxPage || (i>=currentPage-offset
&&
i
<
=currentPage+offset)){ %>
<li
class=
"page-item <%= currentPage==i?'active':'' %>"
><a
class=
"page-link"
href=
"/posts?page=<%= i %>&limit=<%= limit %>"
>
<
%= i %>
</a></li>
<
% } else if(i==2 || i==maxPage-1){ %>
<li><a
class=
"page-link"
>
...
</a></li>
<
% } %>
<
% } %>
<li
class=
"page-item <%= nextBtnEnabled?'':'disabled' %>"
>
<a
class=
"page-link"
href=
"/posts?page=<%= currentPage+1 %>&limit=<%= limit %>"
<%=
nextBtnEnabled
?''
:
'
tabindex=
-1'
%
>
>»
</a>
</li>
</ul>
</nav>
<form
action=
"/posts"
method=
"get"
style=
"float:right"
>
<div
class=
"form-row"
>
<div
class=
"form-group"
>
<div
class=
"input-group"
>
<select
name=
"searchType"
class=
"custom-select"
>
<option
value=
"title"
<%=
searchType=
='title'?'selected':''
%
>
>Title
</option>
</select>
<input
minLength=
"3"
type=
"text"
name=
"searchText"
value=
"<%= searchText %>"
>
<div
class=
"input-group-append"
>
<button
class=
"btn btn-outline-primary"
type=
"submit"
>
Search
</button>
</div>
</div>
</div>
</div>
</form>
</div>
</div>
</body>
</html>
\ No newline at end of file
...
...
views/posts/show.ejs
View file @
ad628c6
...
...
@@ -13,12 +13,13 @@
<ol
class=
"breadcrumb p-1 pl-2 pr-2"
>
<li
class=
"breadcrumb-item"
><a
href=
"/"
>
Home
</a></li>
<li
class=
"breadcrumb-item"
><a
href=
"/posts"
>
Board
</a></li>
<li
class=
"breadcrumb-item active"
aria-current=
"page"
>
<
%= post.
title
%>
</li>
<li
class=
"breadcrumb-item active"
aria-current=
"page"
>
<
%= post.
address
%>
</li>
</ol>
</nav>
<div
class=
"card"
>
<h5
class=
"card-header p-2"
style=
"font-weight: bold; font-family: 'Archivo', sans-serif;"
>
<
%= post.title %>
</h5>
<h5
class=
"card-header p-2"
style=
"font-weight: bold; font-family: 'Archivo', sans-serif; background-color:goldenrod;"
>
<
%= post.title %>
</h5>
<!-- <h5 class="card-header p-1" style="font-family: 'Archivo', sans-serif;"><%= post.address %></h5> -->
<div
class=
"row"
>
<!-- 1 -->
<div
class=
"col-md-7 col-lg-8 col-xl-9 order-sm-2 order-md-1"
>
<!-- 1 -->
...
...
@@ -45,7 +46,7 @@
<
% if(isAuthenticated
&&
post.author
&&
currentUser.id == post.author.id){ %>
<!-- 1 -->
<a
class=
"btn btn-outline-primary"
href=
"/posts/<%= post._id %>/edit"
>
Edit
</a>
<form
action=
"/posts/<%= post._id %>?_method=delete"
method=
"post"
class=
"d-inline"
>
<a
class=
"btn btn-outline-primary"
href=
"javascript:void(0)"
onclick=
"confirm('
Do you want to delete this
?')?this.parentElement.submit():null;"
>
Delete
</a>
<a
class=
"btn btn-outline-primary"
href=
"javascript:void(0)"
onclick=
"confirm('
기록을 삭제하시겠습니까
?')?this.parentElement.submit():null;"
>
Delete
</a>
</form>
<
% } %>
</div>
...
...
Please
register
or
login
to post a comment