이승윤

feat: 카테고리 DB 연동 및 뷰 구현

...@@ -4,7 +4,8 @@ var Schema = mongoose.Schema; ...@@ -4,7 +4,8 @@ var Schema = mongoose.Schema;
4 var CategoriSchema = new Schema({ 4 var CategoriSchema = new Schema({
5 title: { 5 title: {
6 type: String, 6 type: String,
7 - required: [true, '카테고리명을 입력해주세요'], 7 + default: 'default',
8 + required: [true, '카테고리명이 비어있습니다!'],
8 }, 9 },
9 videoNum: String, 10 videoNum: String,
10 description: String, //설명 11 description: String, //설명
...@@ -16,7 +17,7 @@ var CategoriSchema = new Schema({ ...@@ -16,7 +17,7 @@ var CategoriSchema = new Schema({
16 }); 17 });
17 18
18 CategoriSchema.virtual('getDate').get(function () { 19 CategoriSchema.virtual('getDate').get(function () {
19 - var date = new Date(this.created_at); 20 + var date = new Date(this.created_at);
20 return { 21 return {
21 year: date.getFullYear(), 22 year: date.getFullYear(),
22 month: date.getMonth() + 1, 23 month: date.getMonth() + 1,
...@@ -24,4 +25,4 @@ CategoriSchema.virtual('getDate').get(function () { ...@@ -24,4 +25,4 @@ CategoriSchema.virtual('getDate').get(function () {
24 }; 25 };
25 }); 26 });
26 27
27 -module.exports = mongoose.model('categories', CategoriSchema);
...\ No newline at end of file ...\ No newline at end of file
28 +module.exports = mongoose.model('categories', CategoriSchema);
......
...@@ -4,13 +4,12 @@ var youtube = new Youtube(); ...@@ -4,13 +4,12 @@ var youtube = new Youtube();
4 var express = require('express'); 4 var express = require('express');
5 var router = express.Router(); 5 var router = express.Router();
6 6
7 -var word = '백종원 레시피'; // 검색어 지정 7 +var word = '백종원'; // 검색어 지정
8 var limit = 10; // 출력 갯수 8 var limit = 10; // 출력 갯수
9 var video = []; 9 var video = [];
10 var test = 'test'; 10 var test = 'test';
11 var count = 0; 11 var count = 0;
12 youtube.setKey('AIzaSyAsKr_oWGZIBbL5tLdIl98Lf9Pzqj8jX4o'); // API 키 입력 12 youtube.setKey('AIzaSyAsKr_oWGZIBbL5tLdIl98Lf9Pzqj8jX4o'); // API 키 입력
13 -
14 youtube.addParam('order', 'rating'); // 평점 순으로 정렬 13 youtube.addParam('order', 'rating'); // 평점 순으로 정렬
15 youtube.addParam('type', 'video'); // 타입 지정 14 youtube.addParam('type', 'video'); // 타입 지정
16 youtube.addParam('videoLicense', 'creativeCommon'); // 크리에이티브 커먼즈 아이템만 불러옴 15 youtube.addParam('videoLicense', 'creativeCommon'); // 크리에이티브 커먼즈 아이템만 불러옴
......
1 var express = require('express'); 1 var express = require('express');
2 var router = express.Router(); 2 var router = express.Router();
3 var CategoriModel = require('../models/CategoriModel'); 3 var CategoriModel = require('../models/CategoriModel');
4 -var csrf = require('csurf'); 4 +//var csrf = require('csurf');
5 -var csrfProtection = csrf({ cookie: true }); 5 +//var csrfProtection = csrf({ cookie: true });
6 var loginRequired = require('../libs/loginRequired'); 6 var loginRequired = require('../libs/loginRequired');
7 7
8 var path = require('path'); 8 var path = require('path');
...@@ -34,56 +34,43 @@ router.get('/', function (req, res) { ...@@ -34,56 +34,43 @@ router.get('/', function (req, res) {
34 router.get('/products', function (req, res) { 34 router.get('/products', function (req, res) {
35 CategoriModel.find(function (err, products) { 35 CategoriModel.find(function (err, products) {
36 res.render( 36 res.render(
37 - 'admin/products', 37 + 'category/products',
38 - { products: products } 38 + { categories: products }
39 //ProductModel의 products를 받아서 39 //ProductModel의 products를 받아서
40 //categori/products로 response를 보낸다. 40 //categori/products로 response를 보낸다.
41 ); 41 );
42 }); 42 });
43 }); 43 });
44 44
45 -router.get( 45 +router.get('/categories/write', loginRequired, function (req, res) {
46 - '/products/write', 46 + //edit에서도 같은 form을 사용하므로 빈 변수( product )를 넣어서 에러를 피해준다
47 - loginRequired, 47 + res.render('category/form', { categories: '' });
48 - csrfProtection, 48 +});
49 - function (req, res) {
50 - //edit에서도 같은 form을 사용하므로 빈 변수( product )를 넣어서 에러를 피해준다
51 - res.render('categori/form', { product: '', csrfToken: req.csrfToken() });
52 - }
53 -);
54 49
55 -router.post( 50 +router.post('/categories/write', loginRequired, function (req, res) {
56 - '/products/write', 51 + var category = new CategoriModel({
57 - upload.single('thumbnail'), 52 + title: req.body.title,
58 - loginRequired, 53 + description: req.body.description,
59 - csrfProtection, 54 + username: req.user.username,
60 - function (req, res) { 55 + });
61 - var product = new CategoriModel({ 56 + //이 아래는 수정되지 않았음
62 - name: req.body.name, 57 + var validationError = category.validateSync();
63 - thumbnail: req.file ? req.file.filename : '', 58 + if (validationError) {
64 - price: req.body.price, 59 + res.send(validationError);
65 - description: req.body.description, 60 + } else {
66 - username: req.user.username, 61 + category.save(function (err) {
62 + res.redirect('/categori/products');
67 }); 63 });
68 - //이 아래는 수정되지 않았음
69 - var validationError = product.validateSync();
70 - if (validationError) {
71 - res.send(validationError);
72 - } else {
73 - product.save(function (err) {
74 - res.redirect('/categori/products');
75 - });
76 - }
77 - //이 위는 수정되지 않았음
78 } 64 }
79 -); 65 + //이 위는 수정되지 않았음
66 +});
80 67
81 router.get('/products/detail/:id', function (req, res) { 68 router.get('/products/detail/:id', function (req, res) {
82 //url 에서 변수 값을 받아올떈 req.params.id 로 받아온다 69 //url 에서 변수 값을 받아올떈 req.params.id 로 받아온다
83 - CategoriModel.findOne({ id: req.params.id }, function (err, product) { 70 + CategoriModel.findOne({ _id: req.params.id }, function (err, product) {
84 //제품정보를 받고 그안에서 댓글을 받아온다. 71 //제품정보를 받고 그안에서 댓글을 받아온다.
85 CategoriModel.find({ product_id: req.params.id }, function (err, comments) { 72 CategoriModel.find({ product_id: req.params.id }, function (err, comments) {
86 - res.render('categori/productsDetail', { 73 + res.render('category/productsDetail', {
87 product: product, 74 product: product,
88 comments: comments, 75 comments: comments,
89 }); 76 });
...@@ -91,29 +78,23 @@ router.get('/products/detail/:id', function (req, res) { ...@@ -91,29 +78,23 @@ router.get('/products/detail/:id', function (req, res) {
91 }); 78 });
92 }); 79 });
93 80
94 -router.get( 81 +router.get('/products/edit/:id', loginRequired, function (req, res) {
95 - '/products/edit/:id', 82 + //기존에 폼에 value안에 값을 셋팅하기 위해 만든다.
96 - loginRequired, 83 + CategoriModel.findOne({ _id: req.params.id }, function (err, product) {
97 - csrfProtection, 84 + res.render('category/form', {
98 - function (req, res) { 85 + categories: product,
99 - //기존에 폼에 value안에 값을 셋팅하기 위해 만든다.
100 - CategoriModel.findOne({ id: req.params.id }, function (err, product) {
101 - res.render('categori/form', {
102 - product: product,
103 - csrfToken: req.csrfToken(),
104 - });
105 }); 86 });
106 - } 87 + });
107 -); 88 +});
108 89
109 router.post( 90 router.post(
110 '/products/edit/:id', 91 '/products/edit/:id',
111 loginRequired, 92 loginRequired,
112 upload.single('thumbnail'), 93 upload.single('thumbnail'),
113 - csrfProtection, 94 + // csrfProtection,
114 function (req, res) { 95 function (req, res) {
115 //그전에 지정되 있는 파일명을 받아온다 96 //그전에 지정되 있는 파일명을 받아온다
116 - CategoriModel.findOne({ id: req.params.id }, function (err, product) { 97 + CategoriModel.findOne({ _id: req.params.id }, function (err, product) {
117 //아래의 코드만 추가되면 된다. 98 //아래의 코드만 추가되면 된다.
118 if (req.file && product.thumbnail) { 99 if (req.file && product.thumbnail) {
119 //요청중에 파일이 존재 할시 이전이미지 지운다. 100 //요청중에 파일이 존재 할시 이전이미지 지운다.
...@@ -131,7 +112,7 @@ router.post( ...@@ -131,7 +112,7 @@ router.post(
131 { id: req.params.id }, 112 { id: req.params.id },
132 { $set: query }, 113 { $set: query },
133 function (err) { 114 function (err) {
134 - res.redirect('/categori/products/detail/' + req.params.id); 115 + res.redirect('/category/products/detail/' + req.params.id);
135 } 116 }
136 ); 117 );
137 }); 118 });
...@@ -139,7 +120,7 @@ router.post( ...@@ -139,7 +120,7 @@ router.post(
139 ); 120 );
140 121
141 router.get('/products/delete/:id', function (req, res) { 122 router.get('/products/delete/:id', function (req, res) {
142 - CategoriModel.remove({ id: req.params.id }, function (err) { 123 + CategoriModel.deleteMany({ _id: req.params.id }, function (err) {
143 res.redirect('/categori/products'); 124 res.redirect('/categori/products');
144 }); 125 });
145 }); 126 });
...@@ -159,7 +140,7 @@ router.post('/products/ajax_comment/insert', function (req, res) { ...@@ -159,7 +140,7 @@ router.post('/products/ajax_comment/insert', function (req, res) {
159 }); 140 });
160 141
161 router.post('/products/ajax_comment/delete', function (req, res) { 142 router.post('/products/ajax_comment/delete', function (req, res) {
162 - CategoriModel.remove({ id: req.body.comment_id }, function (err) { 143 + CategoriModel.remove({ _id: req.body.comment_id }, function (err) {
163 res.json({ message: 'success' }); 144 res.json({ message: 'success' });
164 }); 145 });
165 }); 146 });
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
10 </div> 10 </div>
11 <div class="panel-body"> 11 <div class="panel-body">
12 <form role="form" action="" id="login_form" method="post"> 12 <form role="form" action="" id="login_form" method="post">
13 - QKQKQfieldset> 13 + <fieldset>
14 <div class="form-group"> 14 <div class="form-group">
15 <input class="form-control" placeholder="ID" name="username" type="text" autofocus="" required=""> 15 <input class="form-control" placeholder="ID" name="username" type="text" autofocus="" required="">
16 </div> 16 </div>
......
1 +<% include ../includes/header.ejs %>
2 + <form action="" method="post" >
3 + <table class="table table-bordered">
4 + <tr>
5 + <th>카테고리명</th>
6 + <td><input type="text" name="title" class="form-control" value="<%=categories.title%>"/></td>
7 + </tr>
8 + <tr>
9 + <th>설명</th>
10 + <td><input type="text" name="description" class="form-control" value="<%=categories.description%>"/></td>
11 + </tr>
12 + </table>
13 + <input type="submit" name="submit" value="submit" class="btn btn-primary">
14 + </form>
15 +<% include ../includes/footer.ejs %>
...\ No newline at end of file ...\ No newline at end of file
1 +<% include ../includes/header.ejs %>
2 + <table class="table table-bordered table-hover">
3 + <tr>
4 + <th width="100px" style="text-align: center;">카테고리명</th>
5 + <th style="text-align: center;">개설 날짜</th>
6 + <th>내용</th>
7 + <th>사용자명</th>
8 + <th>삭제</th>
9 + </tr>
10 + <%categories.forEach(function(product){%>
11 + <tr>
12 + <td>
13 + <a href="/categori/products/detail/<%=product.id%>"><%=product.title%></a>
14 + </td>
15 + <td>
16 + <%=product.getDate.year%> -
17 + <%=product.getDate.month%> -
18 + <%=product.getDate.day%>
19 + </td>
20 + <td>
21 + <%=product.description%> -
22 + </td>
23 + <td>
24 + <%=product.username%> -
25 + </td>
26 + <td>
27 + <a href="/categori/products/delete/<%=product.id%>" class="btn btn-danger" onclick="return confirm('삭제하시겠습니까?')">삭제</a>
28 + </td>
29 + </tr>
30 + <% }); %>
31 + </table>
32 +
33 + <a href="categori/write" class="btn btn-default">작성하기</a>
34 +
35 +<% include ../includes/footer.ejs %>
...\ No newline at end of file ...\ No newline at end of file
1 +<% include ../includes/header.ejs %>
2 + <div class="panel panel-default">
3 + <div class="panel-heading">
4 + <%=product.title%>
5 + </div>
6 + <div class="panel-body">
7 + <div style="padding-bottom: 10px">
8 + 작성일 :
9 + <%=product.getDate.year%> -
10 + <%=product.getDate.month%> -
11 + <%=product.getDate.day%>
12 + </div>
13 + <% if(product.thumbnail){%>
14 + <p>
15 + <img src="/uploads/<%=product.thumbnail%>" style="max-width: 100%"/>
16 + </p>
17 + <% } %>
18 + <%=product.description%>
19 + <!-- 댓글영역 -->
20 + <div>
21 + 댓글작성하기
22 + <form id="commentForm" action="" method="post">
23 + <input type="hidden" name="product_id" value="<%=product._id%>" />
24 + <textarea class="form-control" name="content"></textarea>
25 + <button class="btn btn-primary" style="margin-top: 10px">댓글작성</button>
26 + </form>
27 + </div>
28 + <!-- 댓글영역 -->
29 + <hr />
30 + <div id="comment_area">
31 + <% comments.forEach(function(comment){ %>
32 + <div>
33 + <%=comment.content%>
34 + ( <a class='comment_delete' comment_id='<%=comment._id%>'>삭제</a> )
35 + </div>
36 + <% }); %>
37 + </div>
38 + </div>
39 + </div>
40 +
41 + <a href="/categori/products" class="btn btn-default">목록으로</a>
42 + <a href="/categori/products/edit/<%=product._id%>" class="btn btn-primary">수정</a>
43 +<% include ../includes/footer.ejs %>
44 +<script>
45 +(function(){
46 + $(document).ready(function() {
47 + $('#commentForm').submit(function(){
48 + var $contentVal = $(this).children('textarea[name=content]').val();
49 + if($contentVal){
50 + $.ajax({
51 + url: '/admin/products/ajax_comment/insert',
52 + type: 'POST',
53 + data: $(this).serialize(),
54 + })
55 + .done(function(args) {
56 + if(args.message==="success"){
57 + $('#comment_area').append(
58 + '<div>' + args.content +
59 + " ( <a class='comment_delete' comment_id='"+ args._id +"'>삭제</a> ) </div>"
60 + );
61 + $('#commentForm textarea[name=content]').val("");
62 + }
63 + })
64 + .fail(function(args) {
65 + console.log(args);
66 + });
67 + }else{
68 + alert('댓글 내용을 입력해주세요.')
69 + }
70 + return false;
71 + });
72 + });
73 +})();
74 +</script>
75 +<script>
76 +$(document).on('click' , '.comment_delete' , function(){
77 + if(confirm('삭제하시겠습니까?')){ //확인창 예 눌렀을 시만 진행
78 + var $self = $(this);
79 + $.ajax({
80 + url: '/admin/products/ajax_comment/delete',
81 + type: 'POST',
82 + data: { comment_id : $self.attr('comment_id') },
83 + })
84 + .done(function() {
85 + $self.parent().remove();
86 + alert("삭제가 완료되었습니다.");
87 + })
88 + .fail(function(args) {
89 + console.log(args);
90 + });
91 + }
92 +});
93 +</script>
...\ No newline at end of file ...\ No newline at end of file
1 <% include ./includes/header.ejs %> 1 <% include ./includes/header.ejs %>
2 - <div class="container" id="masonry_container"> 2 + <div id="masonry_container">
3 + 한식
3 <% for (var i in videos) { %> 4 <% for (var i in videos) { %>
4 <div id="<%=videos[i].id%>" vid="<%=videos[i].video_id%>"> 5 <div id="<%=videos[i].id%>" vid="<%=videos[i].video_id%>">
5 </div> 6 </div>
......