Showing
35 changed files
with
1199 additions
and
85 deletions
... | @@ -5,6 +5,28 @@ | ... | @@ -5,6 +5,28 @@ |
5 | "version": "0.2.0", | 5 | "version": "0.2.0", |
6 | "configurations": [ | 6 | "configurations": [ |
7 | { | 7 | { |
8 | + "name": "Launch via NPM", | ||
9 | + "request": "launch", | ||
10 | + "runtimeArgs": [ | ||
11 | + "run-script", | ||
12 | + "debug" | ||
13 | + ], | ||
14 | + "runtimeExecutable": "npm run start:dev", | ||
15 | + "skipFiles": [ | ||
16 | + "<node_internals>/**" | ||
17 | + ], | ||
18 | + "type": "pwa-node" | ||
19 | + }, | ||
20 | + { | ||
21 | + "program": "${workspaceFolder}/app.js", | ||
22 | + "request": "launch", | ||
23 | + "skipFiles": [ | ||
24 | + "<node_internals>/**" | ||
25 | + ], | ||
26 | + "type": "pwa-node" | ||
27 | + }, | ||
28 | + | ||
29 | + { | ||
8 | "type": "pwa-node", | 30 | "type": "pwa-node", |
9 | "request": "launch", | 31 | "request": "launch", |
10 | "name": "Launch Program", | 32 | "name": "Launch Program", | ... | ... |
... | @@ -19,7 +19,7 @@ server use Node.js, Koa.js and frotend use flutter(Dart) | ... | @@ -19,7 +19,7 @@ server use Node.js, Koa.js and frotend use flutter(Dart) |
19 | * [Node.js](https://nodejs.org/) | 19 | * [Node.js](https://nodejs.org/) |
20 | * [Koa.js](https://koajs.com/) | 20 | * [Koa.js](https://koajs.com/) |
21 | 21 | ||
22 | -* [flutter](https://flutter.dev/) | 22 | + |
23 | 23 | ||
24 | 24 | ||
25 | 25 | ||
... | @@ -31,7 +31,6 @@ server use Node.js, Koa.js and frotend use flutter(Dart) | ... | @@ -31,7 +31,6 @@ server use Node.js, Koa.js and frotend use flutter(Dart) |
31 | ## Getting Started | 31 | ## Getting Started |
32 | 32 | ||
33 | Go to the Server [Project folder](http://khuhub.khu.ac.kr/2018102946/likeBack), and git clone. | 33 | Go to the Server [Project folder](http://khuhub.khu.ac.kr/2018102946/likeBack), and git clone. |
34 | -And go the Frontend [Project folder](http://khuhub.khu.ac.kr/2018102946/likefront)and git clone. | ||
35 | 34 | ||
36 | 35 | ||
37 | ### Installation | 36 | ### Installation |
... | @@ -72,7 +71,7 @@ _Below is an example of how you can instruct your audience on installing and set | ... | @@ -72,7 +71,7 @@ _Below is an example of how you can instruct your audience on installing and set |
72 | Your Name -- email@example.com | 71 | Your Name -- email@example.com |
73 | 72 | ||
74 | Project Link: [http://khuhub.khu.ac.kr/2018102946/likeBack](http://khuhub.khu.ac.kr/2018102946/likeBack) | 73 | Project Link: [http://khuhub.khu.ac.kr/2018102946/likeBack](http://khuhub.khu.ac.kr/2018102946/likeBack) |
75 | - [http://khuhub.khu.ac.kr/2018102946/likefront](http://khuhub.khu.ac.kr/2018102946/likefront) | 74 | + |
76 | 75 | ||
77 | <p align="right">(<a href="#top">back to top</a>)</p> | 76 | <p align="right">(<a href="#top">back to top</a>)</p> |
78 | 77 | ... | ... |
firebase-debug.log
0 → 100644
1 | +[debug] [2021-12-06T16:19:50.991Z] ---------------------------------------------------------------------- | ||
2 | +[debug] [2021-12-06T16:19:50.996Z] Command: /usr/local/bin/node /usr/local/bin/firebase login | ||
3 | +[debug] [2021-12-06T16:19:50.997Z] CLI Version: 9.23.0 | ||
4 | +[debug] [2021-12-06T16:19:50.997Z] Platform: linux | ||
5 | +[debug] [2021-12-06T16:19:50.998Z] Node Version: v16.13.0 | ||
6 | +[debug] [2021-12-06T16:19:51.007Z] Time: Tue Dec 07 2021 01:19:50 GMT+0900 (Korean Standard Time) | ||
7 | +[debug] [2021-12-06T16:19:51.008Z] ---------------------------------------------------------------------- | ||
8 | +[debug] | ||
9 | +[debug] [2021-12-06T16:19:51.014Z] >>> [apiv2][query] GET https://firebase-public.firebaseio.com/cli.json [none] | ||
10 | +[info] i Firebase optionally collects CLI usage and error reporting information to help improve our products. Data is collected in accordance with Google's privacy policy (https://policies.google.com/privacy) and is not used to identify you. | ||
11 | + | ||
12 | +[debug] [2021-12-06T16:19:52.476Z] <<< [apiv2][status] GET https://firebase-public.firebaseio.com/cli.json 200 | ||
13 | +[debug] [2021-12-06T16:19:52.476Z] <<< [apiv2][body] GET https://firebase-public.firebaseio.com/cli.json {"cloudBuildErrorAfter":1594252800000,"cloudBuildWarnAfter":1590019200000,"defaultNode10After":1594252800000,"minVersion":"3.0.5","node8DeploysDisabledAfter":1613390400000,"node8RuntimeDisabledAfter":1615809600000,"node8WarnAfter":1600128000000} | ||
14 | +[info] i To change your data collection preference at any time, run `firebase logout` and log in again. | ||
15 | +[info] | ||
16 | +[info] Visit this URL on this device to log in: | ||
17 | +[info] https://accounts.google.com/o/oauth2/auth?client_id=563584335869-fgrhgmd47bqnekij5i8b5pr03ho849e6.apps.googleusercontent.com&scope=email%20openid%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcloudplatformprojects.readonly%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Ffirebase%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcloud-platform&response_type=code&state=406504610&redirect_uri=http%3A%2F%2Flocalhost%3A9005 | ||
18 | +[info] | ||
19 | +[info] Waiting for authentication... |
... | @@ -21,12 +21,15 @@ | ... | @@ -21,12 +21,15 @@ |
21 | "koa": "^2.13.4", | 21 | "koa": "^2.13.4", |
22 | "koa-body": "^4.2.0", | 22 | "koa-body": "^4.2.0", |
23 | "koa-bodyparser": "^4.3.0", | 23 | "koa-bodyparser": "^4.3.0", |
24 | + "koa-ejs": "^4.3.0", | ||
25 | + "koa-passport": "^4.1.4", | ||
24 | "koa-router": "^10.1.1", | 26 | "koa-router": "^10.1.1", |
25 | "koa-send": "^5.0.1", | 27 | "koa-send": "^5.0.1", |
26 | "mongoose": "^6.0.12", | 28 | "mongoose": "^6.0.12", |
27 | "nodemailer": "^6.7.1", | 29 | "nodemailer": "^6.7.1", |
28 | "passport": "^0.5.0", | 30 | "passport": "^0.5.0", |
29 | "passport-google-oauth": "^2.0.0", | 31 | "passport-google-oauth": "^2.0.0", |
32 | + "passport-local": "^1.0.0", | ||
30 | "spdy": "^4.0.2" | 33 | "spdy": "^4.0.2" |
31 | }, | 34 | }, |
32 | "devDependencies": { | 35 | "devDependencies": { |
... | @@ -1109,6 +1112,11 @@ | ... | @@ -1109,6 +1112,11 @@ |
1109 | "url": "https://github.com/chalk/ansi-styles?sponsor=1" | 1112 | "url": "https://github.com/chalk/ansi-styles?sponsor=1" |
1110 | } | 1113 | } |
1111 | }, | 1114 | }, |
1115 | + "node_modules/any-promise": { | ||
1116 | + "version": "1.3.0", | ||
1117 | + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", | ||
1118 | + "integrity": "sha1-q8av7tzqUugJzcA3au0845Y10X8=" | ||
1119 | + }, | ||
1112 | "node_modules/aproba": { | 1120 | "node_modules/aproba": { |
1113 | "version": "2.0.0", | 1121 | "version": "2.0.0", |
1114 | "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", | 1122 | "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", |
... | @@ -1553,6 +1561,15 @@ | ... | @@ -1553,6 +1561,15 @@ |
1553 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", | 1561 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", |
1554 | "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" | 1562 | "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" |
1555 | }, | 1563 | }, |
1564 | + "node_modules/ejs": { | ||
1565 | + "version": "2.7.4", | ||
1566 | + "resolved": "https://registry.npmjs.org/ejs/-/ejs-2.7.4.tgz", | ||
1567 | + "integrity": "sha512-7vmuyh5+kuUyJKePhQfRQBhXV5Ce+RnaeeQArKu1EAMpL3WbgMt5WG6uQZpEVvYSSsxMXRKOewtDk9RaTKXRlA==", | ||
1568 | + "hasInstallScript": true, | ||
1569 | + "engines": { | ||
1570 | + "node": ">=0.10.0" | ||
1571 | + } | ||
1572 | + }, | ||
1556 | "node_modules/emoji-regex": { | 1573 | "node_modules/emoji-regex": { |
1557 | "version": "8.0.0", | 1574 | "version": "8.0.0", |
1558 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", | 1575 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", |
... | @@ -2620,6 +2637,39 @@ | ... | @@ -2620,6 +2637,39 @@ |
2620 | "node": ">= 10" | 2637 | "node": ">= 10" |
2621 | } | 2638 | } |
2622 | }, | 2639 | }, |
2640 | + "node_modules/koa-ejs": { | ||
2641 | + "version": "4.3.0", | ||
2642 | + "resolved": "https://registry.npmjs.org/koa-ejs/-/koa-ejs-4.3.0.tgz", | ||
2643 | + "integrity": "sha512-KK1B1YEeq8TOt7hrHwohfHxH03ZqsdhQWeFjmvcWk3arVI/uQOyE4FHQVlg0Ud9eXxlgUfkYqA2MJhfK4ADkAw==", | ||
2644 | + "dependencies": { | ||
2645 | + "debug": "^2.6.1", | ||
2646 | + "ejs": "^2.6.1", | ||
2647 | + "mz": "^2.6.0" | ||
2648 | + } | ||
2649 | + }, | ||
2650 | + "node_modules/koa-passport": { | ||
2651 | + "version": "4.1.4", | ||
2652 | + "resolved": "https://registry.npmjs.org/koa-passport/-/koa-passport-4.1.4.tgz", | ||
2653 | + "integrity": "sha512-dJBCkl4X+zdYxbI2V2OtoGy0PUenpvp2ZLLWObc8UJhsId0iQpTFT8RVcuA0709AL2txGwRHnSPoT1bYNGa6Kg==", | ||
2654 | + "dependencies": { | ||
2655 | + "passport": "^0.4.0" | ||
2656 | + }, | ||
2657 | + "engines": { | ||
2658 | + "node": ">= 4" | ||
2659 | + } | ||
2660 | + }, | ||
2661 | + "node_modules/koa-passport/node_modules/passport": { | ||
2662 | + "version": "0.4.1", | ||
2663 | + "resolved": "https://registry.npmjs.org/passport/-/passport-0.4.1.tgz", | ||
2664 | + "integrity": "sha512-IxXgZZs8d7uFSt3eqNjM9NQ3g3uQCW5avD8mRNoXV99Yig50vjuaez6dQK2qC0kVWPRTujxY0dWgGfT09adjYg==", | ||
2665 | + "dependencies": { | ||
2666 | + "passport-strategy": "1.x.x", | ||
2667 | + "pause": "0.0.1" | ||
2668 | + }, | ||
2669 | + "engines": { | ||
2670 | + "node": ">= 0.4.0" | ||
2671 | + } | ||
2672 | + }, | ||
2623 | "node_modules/koa-router": { | 2673 | "node_modules/koa-router": { |
2624 | "version": "10.1.1", | 2674 | "version": "10.1.1", |
2625 | "resolved": "https://registry.npmjs.org/koa-router/-/koa-router-10.1.1.tgz", | 2675 | "resolved": "https://registry.npmjs.org/koa-router/-/koa-router-10.1.1.tgz", |
... | @@ -3102,6 +3152,16 @@ | ... | @@ -3102,6 +3152,16 @@ |
3102 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", | 3152 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", |
3103 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" | 3153 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" |
3104 | }, | 3154 | }, |
3155 | + "node_modules/mz": { | ||
3156 | + "version": "2.7.0", | ||
3157 | + "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", | ||
3158 | + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", | ||
3159 | + "dependencies": { | ||
3160 | + "any-promise": "^1.0.0", | ||
3161 | + "object-assign": "^4.0.1", | ||
3162 | + "thenify-all": "^1.0.0" | ||
3163 | + } | ||
3164 | + }, | ||
3105 | "node_modules/natural-compare": { | 3165 | "node_modules/natural-compare": { |
3106 | "version": "1.4.0", | 3166 | "version": "1.4.0", |
3107 | "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", | 3167 | "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", |
... | @@ -3192,6 +3252,14 @@ | ... | @@ -3192,6 +3252,14 @@ |
3192 | "resolved": "https://registry.npmjs.org/oauth/-/oauth-0.9.15.tgz", | 3252 | "resolved": "https://registry.npmjs.org/oauth/-/oauth-0.9.15.tgz", |
3193 | "integrity": "sha1-vR/vr2hslrdUda7VGWQS/2DPucE=" | 3253 | "integrity": "sha1-vR/vr2hslrdUda7VGWQS/2DPucE=" |
3194 | }, | 3254 | }, |
3255 | + "node_modules/object-assign": { | ||
3256 | + "version": "4.1.1", | ||
3257 | + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", | ||
3258 | + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", | ||
3259 | + "engines": { | ||
3260 | + "node": ">=0.10.0" | ||
3261 | + } | ||
3262 | + }, | ||
3195 | "node_modules/obuf": { | 3263 | "node_modules/obuf": { |
3196 | "version": "1.1.2", | 3264 | "version": "1.1.2", |
3197 | "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", | 3265 | "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", |
... | @@ -3310,6 +3378,17 @@ | ... | @@ -3310,6 +3378,17 @@ |
3310 | "node": ">= 0.4.0" | 3378 | "node": ">= 0.4.0" |
3311 | } | 3379 | } |
3312 | }, | 3380 | }, |
3381 | + "node_modules/passport-local": { | ||
3382 | + "version": "1.0.0", | ||
3383 | + "resolved": "https://registry.npmjs.org/passport-local/-/passport-local-1.0.0.tgz", | ||
3384 | + "integrity": "sha1-H+YyaMkudWBmJkN+O5BmYsFbpu4=", | ||
3385 | + "dependencies": { | ||
3386 | + "passport-strategy": "1.x.x" | ||
3387 | + }, | ||
3388 | + "engines": { | ||
3389 | + "node": ">= 0.4.0" | ||
3390 | + } | ||
3391 | + }, | ||
3313 | "node_modules/passport-oauth1": { | 3392 | "node_modules/passport-oauth1": { |
3314 | "version": "1.2.0", | 3393 | "version": "1.2.0", |
3315 | "resolved": "https://registry.npmjs.org/passport-oauth1/-/passport-oauth1-1.2.0.tgz", | 3394 | "resolved": "https://registry.npmjs.org/passport-oauth1/-/passport-oauth1-1.2.0.tgz", |
... | @@ -3911,6 +3990,25 @@ | ... | @@ -3911,6 +3990,25 @@ |
3911 | "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", | 3990 | "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", |
3912 | "dev": true | 3991 | "dev": true |
3913 | }, | 3992 | }, |
3993 | + "node_modules/thenify": { | ||
3994 | + "version": "3.3.1", | ||
3995 | + "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", | ||
3996 | + "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", | ||
3997 | + "dependencies": { | ||
3998 | + "any-promise": "^1.0.0" | ||
3999 | + } | ||
4000 | + }, | ||
4001 | + "node_modules/thenify-all": { | ||
4002 | + "version": "1.6.0", | ||
4003 | + "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", | ||
4004 | + "integrity": "sha1-GhkY1ALY/D+Y+/I02wvMjMEOlyY=", | ||
4005 | + "dependencies": { | ||
4006 | + "thenify": ">= 3.1.0 < 4" | ||
4007 | + }, | ||
4008 | + "engines": { | ||
4009 | + "node": ">=0.8" | ||
4010 | + } | ||
4011 | + }, | ||
3914 | "node_modules/tmp": { | 4012 | "node_modules/tmp": { |
3915 | "version": "0.2.1", | 4013 | "version": "0.2.1", |
3916 | "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", | 4014 | "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", |
... | @@ -5125,6 +5223,11 @@ | ... | @@ -5125,6 +5223,11 @@ |
5125 | "color-convert": "^2.0.1" | 5223 | "color-convert": "^2.0.1" |
5126 | } | 5224 | } |
5127 | }, | 5225 | }, |
5226 | + "any-promise": { | ||
5227 | + "version": "1.3.0", | ||
5228 | + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", | ||
5229 | + "integrity": "sha1-q8av7tzqUugJzcA3au0845Y10X8=" | ||
5230 | + }, | ||
5128 | "aproba": { | 5231 | "aproba": { |
5129 | "version": "2.0.0", | 5232 | "version": "2.0.0", |
5130 | "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", | 5233 | "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", |
... | @@ -5457,6 +5560,11 @@ | ... | @@ -5457,6 +5560,11 @@ |
5457 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", | 5560 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", |
5458 | "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" | 5561 | "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" |
5459 | }, | 5562 | }, |
5563 | + "ejs": { | ||
5564 | + "version": "2.7.4", | ||
5565 | + "resolved": "https://registry.npmjs.org/ejs/-/ejs-2.7.4.tgz", | ||
5566 | + "integrity": "sha512-7vmuyh5+kuUyJKePhQfRQBhXV5Ce+RnaeeQArKu1EAMpL3WbgMt5WG6uQZpEVvYSSsxMXRKOewtDk9RaTKXRlA==" | ||
5567 | + }, | ||
5460 | "emoji-regex": { | 5568 | "emoji-regex": { |
5461 | "version": "8.0.0", | 5569 | "version": "8.0.0", |
5462 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", | 5570 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", |
... | @@ -6329,6 +6437,35 @@ | ... | @@ -6329,6 +6437,35 @@ |
6329 | "koa-compose": "^4.1.0" | 6437 | "koa-compose": "^4.1.0" |
6330 | } | 6438 | } |
6331 | }, | 6439 | }, |
6440 | + "koa-ejs": { | ||
6441 | + "version": "4.3.0", | ||
6442 | + "resolved": "https://registry.npmjs.org/koa-ejs/-/koa-ejs-4.3.0.tgz", | ||
6443 | + "integrity": "sha512-KK1B1YEeq8TOt7hrHwohfHxH03ZqsdhQWeFjmvcWk3arVI/uQOyE4FHQVlg0Ud9eXxlgUfkYqA2MJhfK4ADkAw==", | ||
6444 | + "requires": { | ||
6445 | + "debug": "^2.6.1", | ||
6446 | + "ejs": "^2.6.1", | ||
6447 | + "mz": "^2.6.0" | ||
6448 | + } | ||
6449 | + }, | ||
6450 | + "koa-passport": { | ||
6451 | + "version": "4.1.4", | ||
6452 | + "resolved": "https://registry.npmjs.org/koa-passport/-/koa-passport-4.1.4.tgz", | ||
6453 | + "integrity": "sha512-dJBCkl4X+zdYxbI2V2OtoGy0PUenpvp2ZLLWObc8UJhsId0iQpTFT8RVcuA0709AL2txGwRHnSPoT1bYNGa6Kg==", | ||
6454 | + "requires": { | ||
6455 | + "passport": "^0.4.0" | ||
6456 | + }, | ||
6457 | + "dependencies": { | ||
6458 | + "passport": { | ||
6459 | + "version": "0.4.1", | ||
6460 | + "resolved": "https://registry.npmjs.org/passport/-/passport-0.4.1.tgz", | ||
6461 | + "integrity": "sha512-IxXgZZs8d7uFSt3eqNjM9NQ3g3uQCW5avD8mRNoXV99Yig50vjuaez6dQK2qC0kVWPRTujxY0dWgGfT09adjYg==", | ||
6462 | + "requires": { | ||
6463 | + "passport-strategy": "1.x.x", | ||
6464 | + "pause": "0.0.1" | ||
6465 | + } | ||
6466 | + } | ||
6467 | + } | ||
6468 | + }, | ||
6332 | "koa-router": { | 6469 | "koa-router": { |
6333 | "version": "10.1.1", | 6470 | "version": "10.1.1", |
6334 | "resolved": "https://registry.npmjs.org/koa-router/-/koa-router-10.1.1.tgz", | 6471 | "resolved": "https://registry.npmjs.org/koa-router/-/koa-router-10.1.1.tgz", |
... | @@ -6684,6 +6821,16 @@ | ... | @@ -6684,6 +6821,16 @@ |
6684 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", | 6821 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", |
6685 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" | 6822 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" |
6686 | }, | 6823 | }, |
6824 | + "mz": { | ||
6825 | + "version": "2.7.0", | ||
6826 | + "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", | ||
6827 | + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", | ||
6828 | + "requires": { | ||
6829 | + "any-promise": "^1.0.0", | ||
6830 | + "object-assign": "^4.0.1", | ||
6831 | + "thenify-all": "^1.0.0" | ||
6832 | + } | ||
6833 | + }, | ||
6687 | "natural-compare": { | 6834 | "natural-compare": { |
6688 | "version": "1.4.0", | 6835 | "version": "1.4.0", |
6689 | "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", | 6836 | "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", |
... | @@ -6758,6 +6905,11 @@ | ... | @@ -6758,6 +6905,11 @@ |
6758 | "resolved": "https://registry.npmjs.org/oauth/-/oauth-0.9.15.tgz", | 6905 | "resolved": "https://registry.npmjs.org/oauth/-/oauth-0.9.15.tgz", |
6759 | "integrity": "sha1-vR/vr2hslrdUda7VGWQS/2DPucE=" | 6906 | "integrity": "sha1-vR/vr2hslrdUda7VGWQS/2DPucE=" |
6760 | }, | 6907 | }, |
6908 | + "object-assign": { | ||
6909 | + "version": "4.1.1", | ||
6910 | + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", | ||
6911 | + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" | ||
6912 | + }, | ||
6761 | "obuf": { | 6913 | "obuf": { |
6762 | "version": "1.1.2", | 6914 | "version": "1.1.2", |
6763 | "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", | 6915 | "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", |
... | @@ -6851,6 +7003,14 @@ | ... | @@ -6851,6 +7003,14 @@ |
6851 | "passport-oauth2": "1.x.x" | 7003 | "passport-oauth2": "1.x.x" |
6852 | } | 7004 | } |
6853 | }, | 7005 | }, |
7006 | + "passport-local": { | ||
7007 | + "version": "1.0.0", | ||
7008 | + "resolved": "https://registry.npmjs.org/passport-local/-/passport-local-1.0.0.tgz", | ||
7009 | + "integrity": "sha1-H+YyaMkudWBmJkN+O5BmYsFbpu4=", | ||
7010 | + "requires": { | ||
7011 | + "passport-strategy": "1.x.x" | ||
7012 | + } | ||
7013 | + }, | ||
6854 | "passport-oauth1": { | 7014 | "passport-oauth1": { |
6855 | "version": "1.2.0", | 7015 | "version": "1.2.0", |
6856 | "resolved": "https://registry.npmjs.org/passport-oauth1/-/passport-oauth1-1.2.0.tgz", | 7016 | "resolved": "https://registry.npmjs.org/passport-oauth1/-/passport-oauth1-1.2.0.tgz", |
... | @@ -7305,6 +7465,22 @@ | ... | @@ -7305,6 +7465,22 @@ |
7305 | "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", | 7465 | "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", |
7306 | "dev": true | 7466 | "dev": true |
7307 | }, | 7467 | }, |
7468 | + "thenify": { | ||
7469 | + "version": "3.3.1", | ||
7470 | + "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", | ||
7471 | + "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", | ||
7472 | + "requires": { | ||
7473 | + "any-promise": "^1.0.0" | ||
7474 | + } | ||
7475 | + }, | ||
7476 | + "thenify-all": { | ||
7477 | + "version": "1.6.0", | ||
7478 | + "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", | ||
7479 | + "integrity": "sha1-GhkY1ALY/D+Y+/I02wvMjMEOlyY=", | ||
7480 | + "requires": { | ||
7481 | + "thenify": ">= 3.1.0 < 4" | ||
7482 | + } | ||
7483 | + }, | ||
7308 | "tmp": { | 7484 | "tmp": { |
7309 | "version": "0.2.1", | 7485 | "version": "0.2.1", |
7310 | "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", | 7486 | "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", | ... | ... |
... | @@ -6,7 +6,7 @@ | ... | @@ -6,7 +6,7 @@ |
6 | "scripts": { | 6 | "scripts": { |
7 | "test": "echo \"Error: no test specified\" && exit 1", | 7 | "test": "echo \"Error: no test specified\" && exit 1", |
8 | "start": "node src", | 8 | "start": "node src", |
9 | - "start:dev": "nodemon --watch src/ src/index.js" | 9 | + "start:dev": "NODE_PATH=src nodemon --legacy-watch src/ src/index.js" |
10 | }, | 10 | }, |
11 | "author": "", | 11 | "author": "", |
12 | "license": "ISC", | 12 | "license": "ISC", |
... | @@ -23,12 +23,15 @@ | ... | @@ -23,12 +23,15 @@ |
23 | "koa": "^2.13.4", | 23 | "koa": "^2.13.4", |
24 | "koa-body": "^4.2.0", | 24 | "koa-body": "^4.2.0", |
25 | "koa-bodyparser": "^4.3.0", | 25 | "koa-bodyparser": "^4.3.0", |
26 | + "koa-ejs": "^4.3.0", | ||
27 | + "koa-passport": "^4.1.4", | ||
26 | "koa-router": "^10.1.1", | 28 | "koa-router": "^10.1.1", |
27 | "koa-send": "^5.0.1", | 29 | "koa-send": "^5.0.1", |
28 | "mongoose": "^6.0.12", | 30 | "mongoose": "^6.0.12", |
29 | "nodemailer": "^6.7.1", | 31 | "nodemailer": "^6.7.1", |
30 | "passport": "^0.5.0", | 32 | "passport": "^0.5.0", |
31 | "passport-google-oauth": "^2.0.0", | 33 | "passport-google-oauth": "^2.0.0", |
34 | + "passport-local": "^1.0.0", | ||
32 | "spdy": "^4.0.2" | 35 | "spdy": "^4.0.2" |
33 | }, | 36 | }, |
34 | "devDependencies": { | 37 | "devDependencies": { | ... | ... |
... | @@ -6,6 +6,9 @@ const nodemailer = require('nodemailer'); | ... | @@ -6,6 +6,9 @@ const nodemailer = require('nodemailer'); |
6 | const config = require('../../lib/config'); | 6 | const config = require('../../lib/config'); |
7 | const { Mongoose } = require('mongoose'); | 7 | const { Mongoose } = require('mongoose'); |
8 | const { exist, allow } = require('@hapi/joi'); | 8 | const { exist, allow } = require('@hapi/joi'); |
9 | +const index = require('../../../src/index'); | ||
10 | +const render = index.render; | ||
11 | + | ||
9 | const fs = require('fs'); | 12 | const fs = require('fs'); |
10 | exports.test = async (ctx) => { | 13 | exports.test = async (ctx) => { |
11 | console.log('cookie'); | 14 | console.log('cookie'); |
... | @@ -61,7 +64,7 @@ exports.signupLocal = async (ctx) => { | ... | @@ -61,7 +64,7 @@ exports.signupLocal = async (ctx) => { |
61 | 64 | ||
62 | // 응답할 데이터에서 hashedPassword 필드 제거 | 65 | // 응답할 데이터에서 hashedPassword 필드 제거 |
63 | ctx.status = 200; | 66 | ctx.status = 200; |
64 | - ctx.body = await account.serialize(); | 67 | + await ctx.render('users/new'); |
65 | } catch (e) { | 68 | } catch (e) { |
66 | ctx.throw(500, e); | 69 | ctx.throw(500, e); |
67 | } | 70 | } |
... | @@ -97,6 +100,7 @@ exports.signinLocal = async (ctx) => { | ... | @@ -97,6 +100,7 @@ exports.signinLocal = async (ctx) => { |
97 | httpOnly: false, | 100 | httpOnly: false, |
98 | }); | 101 | }); |
99 | ctx.status = 200; | 102 | ctx.status = 200; |
103 | + await ctx.render('users/index'); | ||
100 | console.log('토큰나옴'); | 104 | console.log('토큰나옴'); |
101 | } catch (e) { | 105 | } catch (e) { |
102 | ctx.throw(500, e); | 106 | ctx.throw(500, e); | ... | ... |
... | @@ -3,6 +3,7 @@ const Router = require("@koa/router"); | ... | @@ -3,6 +3,7 @@ const Router = require("@koa/router"); |
3 | const authCtrl = require("./auth.ctrl"); | 3 | const authCtrl = require("./auth.ctrl"); |
4 | const checkLoggedIn = require("../../lib/checkLoggedIn"); | 4 | const checkLoggedIn = require("../../lib/checkLoggedIn"); |
5 | var passport = require('passport'); | 5 | var passport = require('passport'); |
6 | +const User = require("../../models/user"); | ||
6 | var GoogleStrategy = require('passport-google-oauth').OAuth2Strategy; | 7 | var GoogleStrategy = require('passport-google-oauth').OAuth2Strategy; |
7 | const auth = new Router(); | 8 | const auth = new Router(); |
8 | 9 | ||
... | @@ -26,12 +27,72 @@ auth.get('/book',checkLoggedIn,authCtrl.getUserBook); | ... | @@ -26,12 +27,72 @@ auth.get('/book',checkLoggedIn,authCtrl.getUserBook); |
26 | auth.get('/user', checkLoggedIn,authCtrl.userinfo); // show user information | 27 | auth.get('/user', checkLoggedIn,authCtrl.userinfo); // show user information |
27 | auth.patch('/user', checkLoggedIn, authCtrl.updateUser); // modify user information | 28 | auth.patch('/user', checkLoggedIn, authCtrl.updateUser); // modify user information |
28 | auth.patch('/user/password', authCtrl.changePassword); // change password | 29 | auth.patch('/user/password', authCtrl.changePassword); // change password |
29 | - | 30 | +auth.post('/find/password', authCtrl.findPassword); // 비밀번호 찾기 |
30 | auth.get('/favorite',checkLoggedIn, authCtrl.showFavorite); // show a list of user's favorites | 31 | auth.get('/favorite',checkLoggedIn, authCtrl.showFavorite); // show a list of user's favorites |
31 | auth.post('/favorite',checkLoggedIn, authCtrl.addFavorite); // add favorite | 32 | auth.post('/favorite',checkLoggedIn, authCtrl.addFavorite); // add favorite |
32 | auth.delete('/favorite',checkLoggedIn, authCtrl.delFavorite); // delete favorite | 33 | auth.delete('/favorite',checkLoggedIn, authCtrl.delFavorite); // delete favorite |
33 | 34 | ||
34 | auth.post('/find/password', authCtrl.findPassword); // 비밀번호 찾기 | 35 | auth.post('/find/password', authCtrl.findPassword); // 비밀번호 찾기 |
36 | +auth.get('/new', async (ctx) => { | ||
37 | + ctx.render('users/new'); | ||
38 | + }); | ||
39 | + | ||
40 | + | ||
41 | +auth.get('/', async (ctx) => { | ||
42 | + try{ | ||
43 | + const user = await User.find({}).sort({email:-1}).exec();//1 오름차순 -1내림차순 | ||
44 | + ctx.render('users/index', {users}); | ||
45 | + }catch(e){ | ||
46 | + ctx.throw(500, e); | ||
47 | + } | ||
48 | + } | ||
49 | +); | ||
50 | + | ||
51 | + | ||
52 | +// show | ||
53 | +auth.get('/:username', async (ctx) => { | ||
54 | + const user = await User.findOne({_id:ctx.params._id}); | ||
55 | + ctx.render('users/show', {user}); | ||
56 | + }); | ||
57 | + | ||
58 | + | ||
59 | + | ||
60 | + // edit | ||
61 | + auth.get('/:username/edit', async (ctx) => { | ||
62 | + const user = await User.findOne({username:ctx.params.username}); | ||
63 | + ctx.render('users/edit', {user:user}); | ||
64 | + }); | ||
65 | + | ||
66 | + | ||
67 | + // update // 2 | ||
68 | + auth.post('/:username', async (ctx) => { | ||
69 | + await User.findOne({username:ctx.params.username}).select('password').exec(); | ||
70 | + | ||
71 | + | ||
72 | + // update user object | ||
73 | + user.originalPassword = user.password; | ||
74 | + user.password = ctx.body.newPassword? ctx.body.newPassword : user.password; // 2-3 | ||
75 | + for(var p in ctx.body) // 2-4 | ||
76 | + user[p] = ctx.body[p]; | ||
77 | + | ||
78 | + | ||
79 | + // save updated user | ||
80 | + await user.save(); | ||
81 | + | ||
82 | + ctx.redirect('/users/'+user.nickname); | ||
83 | + }); | ||
84 | + | ||
85 | + | ||
86 | + // destroy | ||
87 | + auth.delete('/:username',async (ctx) => { | ||
88 | + try{ | ||
89 | + var username = ctx.params.username; | ||
90 | + await User.deleteOne({username:username}); | ||
91 | + ctx.redirect('/users'); | ||
92 | + }catch(e){ | ||
93 | + ctx.throw(500, e); | ||
94 | + } | ||
95 | + }); | ||
35 | 96 | ||
36 | 97 | ||
37 | module.exports = auth; | 98 | module.exports = auth; |
... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
... | @@ -9,13 +9,13 @@ exports.booklist = async (ctx) => { | ... | @@ -9,13 +9,13 @@ exports.booklist = async (ctx) => { |
9 | 9 | ||
10 | try { | 10 | try { |
11 | book = await Book.find() | 11 | book = await Book.find() |
12 | - .sort({created: -1}) | 12 | + .sort({createDate: -1}) |
13 | .exec(); | 13 | .exec(); |
14 | + await ctx.render('books/index', {book:book}); | ||
14 | } catch (e) { | 15 | } catch (e) { |
15 | return ctx.throw(500, e); | 16 | return ctx.throw(500, e); |
17 | + console.log('get /book/booklist'); | ||
16 | } | 18 | } |
17 | - | ||
18 | - ctx.body = book; | ||
19 | } | 19 | } |
20 | 20 | ||
21 | 21 | ||
... | @@ -55,12 +55,12 @@ exports.addBook = async (ctx) => { | ... | @@ -55,12 +55,12 @@ exports.addBook = async (ctx) => { |
55 | if (err) throw err; | 55 | if (err) throw err; |
56 | const user = await User.findById(ctx.state.user._id).exec(); | 56 | const user = await User.findById(ctx.state.user._id).exec(); |
57 | console.log(book._id); | 57 | console.log(book._id); |
58 | - | 58 | + ctx.redirect('/books'); |
59 | }); | 59 | }); |
60 | } catch (e) { | 60 | } catch (e) { |
61 | ctx.throw(500, e); | 61 | ctx.throw(500, e); |
62 | } | 62 | } |
63 | - ctx.body = book; | 63 | + console.log('저장 성공!'); |
64 | ctx.status = 200; | 64 | ctx.status = 200; |
65 | }; | 65 | }; |
66 | 66 | ||
... | @@ -97,44 +97,67 @@ exports.updateBook = async (ctx) => { | ... | @@ -97,44 +97,67 @@ exports.updateBook = async (ctx) => { |
97 | ctx.request.body.cover = fs.readFileSync(file.image.path); | 97 | ctx.request.body.cover = fs.readFileSync(file.image.path); |
98 | else | 98 | else |
99 | ctx.request.body.cover = "" | 99 | ctx.request.body.cover = "" |
100 | - | ||
101 | var book = ctx.request.body; //require books's _id | 100 | var book = ctx.request.body; //require books's _id |
102 | try { | 101 | try { |
103 | const mybook = await Book.findOne({ _id: book._id }); | 102 | const mybook = await Book.findOne({ _id: book._id }); |
104 | - | 103 | + if(ctx.state.user._id == mybook.author){ |
105 | mybook.updateB(book); | 104 | mybook.updateB(book); |
106 | - | ||
107 | ctx.body = book._id; | 105 | ctx.body = book._id; |
108 | - } catch (e) { | 106 | + ctx.status = 200;} |
109 | - ctx.throw(500, e); | 107 | + |
110 | } | 108 | } |
111 | - ctx.body = book._id; | 109 | + catch (e) { |
110 | + ctx.throw(500, e); | ||
112 | 111 | ||
113 | - console.log(book); | 112 | + ctx.status = 400; |
114 | - ctx.status = 200; | 113 | + ctx.body = { |
114 | + message: "작성자가 아닙니다. " } | ||
115 | + } | ||
115 | }; | 116 | }; |
116 | 117 | ||
117 | 118 | ||
119 | + | ||
118 | exports.deleteBook = async (ctx) => { | 120 | exports.deleteBook = async (ctx) => { |
121 | + | ||
122 | + let bookid = ctx.query.id; | ||
119 | try { | 123 | try { |
120 | - var b = await Book.find(ctx.params.id); | 124 | + |
121 | - await Page.deleteMany({"pages":{$in:b.pages}});//book에 있던 페이지 다 지우기 | 125 | + //var foundB = await Book.findById(bookid).exec(); |
126 | + //북작가에게서 책 정보 지우기 | ||
127 | + var author = await User.findById(bookid);//북 작가. | ||
128 | + console.log(author); | ||
129 | + console.log(author.books); | ||
130 | + await User.delBook(ctx.state.user.email,bookid); | ||
131 | + //book에 있던 페이지 다 지우기 | ||
132 | + await Page.deleteMany({"pages":{$in:b.pages}}); | ||
133 | + | ||
134 | + | ||
135 | + //최종 book지우기 | ||
136 | + var b = await Book.deleteOne({_id:bookid}); | ||
122 | } catch (e) { | 137 | } catch (e) { |
123 | if(e.name === 'CastError') { | 138 | if(e.name === 'CastError') { |
124 | ctx.status = 400; | 139 | ctx.status = 400; |
125 | return; | 140 | return; |
126 | } | 141 | } |
127 | } | 142 | } |
128 | - ctx.status = 204; // No Content | 143 | + console.log('delete success'); |
144 | + ctx.body = { | ||
145 | + message: "Delete" | ||
146 | + } | ||
129 | }; | 147 | }; |
130 | 148 | ||
131 | exports.detailBook = async (ctx) => { | 149 | exports.detailBook = async (ctx) => { |
132 | - var ObjectId = require('mongodb').ObjectId; | 150 | + try{ |
133 | - var id = req.params.book_id; | 151 | + var id = ctx.params.id; |
134 | - var o_id = new ObjectId(id); | 152 | + const book = await dBook.find({_id:id}); |
135 | - const book = await db.Book.find({_id:o_id}); | 153 | + ctx.render('books/show', {book:book}); |
136 | - ctx.body = book; | ||
137 | ctx.status = 200; | 154 | ctx.status = 200; |
155 | + } catch (e) { | ||
156 | + ctx.status = 400; | ||
157 | + console.log('북 삭제 오류'); | ||
158 | + } | ||
159 | + | ||
160 | + | ||
138 | }; | 161 | }; |
139 | 162 | ||
140 | exports.scrollBook = async (ctx) => { | 163 | exports.scrollBook = async (ctx) => { |
... | @@ -154,8 +177,4 @@ exports.scrollBook = async (ctx) => { | ... | @@ -154,8 +177,4 @@ exports.scrollBook = async (ctx) => { |
154 | ctx.throw(500, e); | 177 | ctx.throw(500, e); |
155 | } | 178 | } |
156 | } | 179 | } |
157 | - | ||
158 | - else if(filter === "추천순") { //추천순 | ||
159 | - | ||
160 | - } | ||
161 | }; | 180 | }; | ... | ... |
... | @@ -11,5 +11,7 @@ book.patch('/', checkLoggedIn, bookCtrl.updateBook); // modify book information | ... | @@ -11,5 +11,7 @@ book.patch('/', checkLoggedIn, bookCtrl.updateBook); // modify book information |
11 | book.delete('/',checkLoggedIn,bookCtrl.deleteBook); // delete book | 11 | book.delete('/',checkLoggedIn,bookCtrl.deleteBook); // delete book |
12 | book.get('/booklist',bookCtrl.booklist); | 12 | book.get('/booklist',bookCtrl.booklist); |
13 | book.get('/search',bookCtrl.scrollBook); | 13 | book.get('/search',bookCtrl.scrollBook); |
14 | - | 14 | +book.get('/new', async (ctx) => { |
15 | + ctx.render('books/new'); | ||
16 | + }); | ||
15 | module.exports = book; | 17 | module.exports = book; |
... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
... | @@ -2,8 +2,11 @@ const Router = require("@koa/router"); | ... | @@ -2,8 +2,11 @@ const Router = require("@koa/router"); |
2 | const checkLoggedIn = require("../../lib/checkLoggedIn"); | 2 | const checkLoggedIn = require("../../lib/checkLoggedIn"); |
3 | const pageCtrl = require("./page.ctrl"); | 3 | const pageCtrl = require("./page.ctrl"); |
4 | const page = new Router(); | 4 | const page = new Router(); |
5 | - | 5 | +const Page = require("../../models/page"); |
6 | +const index = require('../../../src/index'); | ||
6 | //Page api | 7 | //Page api |
8 | + | ||
9 | +/* | ||
7 | page.get('/',pageCtrl.getPage); // show a list of user's pages | 10 | page.get('/',pageCtrl.getPage); // show a list of user's pages |
8 | page.post('/',checkLoggedIn,pageCtrl.addPage); // add page | 11 | page.post('/',checkLoggedIn,pageCtrl.addPage); // add page |
9 | page.patch('/', checkLoggedIn,pageCtrl.updatePage); // modify page information | 12 | page.patch('/', checkLoggedIn,pageCtrl.updatePage); // modify page information |
... | @@ -11,12 +14,60 @@ page.delete('/',checkLoggedIn,pageCtrl.deletePage); // delete book | ... | @@ -11,12 +14,60 @@ page.delete('/',checkLoggedIn,pageCtrl.deletePage); // delete book |
11 | 14 | ||
12 | page.get('/search', pageCtrl.search); // /search?title=search_query&petType=petType | 15 | page.get('/search', pageCtrl.search); // /search?title=search_query&petType=petType |
13 | //page.post('/search/filter', pageCtrl.searchFilter); //아직 구현 안함 | 16 | //page.post('/search/filter', pageCtrl.searchFilter); //아직 구현 안함 |
14 | -page.post('/detail', pageCtrl.detailPage); // detail recipe page | 17 | +page.post('/:id', pageCtrl.detailPage); // detail recipe page |
15 | 18 | ||
16 | //page.get('/recipe/slide', pageCtrl.slidRecipe); // 5 recommended videos in main page | 19 | //page.get('/recipe/slide', pageCtrl.slidRecipe); // 5 recommended videos in main page |
17 | 20 | ||
18 | // /recipe/scroll?filter=filter_query&renewal=count (filter_query: 추천순 or 조회순) | 21 | // /recipe/scroll?filter=filter_query&renewal=count (filter_query: 추천순 or 조회순) |
19 | page.get('/recipe/scroll', pageCtrl.scrollPage); // video list sorted by 추천순 or 조회순 in main page | 22 | page.get('/recipe/scroll', pageCtrl.scrollPage); // video list sorted by 추천순 or 조회순 in main page |
23 | +*/ | ||
24 | + | ||
25 | + | ||
26 | + page.get('/', async (ctx) => { | ||
27 | + | ||
28 | + const page = await Page.find({}).sort({createDate:-1}).exec(); | ||
29 | + console.log(page); | ||
30 | + await ctx.render('posts/index', {page}); | ||
31 | + }); | ||
32 | + | ||
33 | + | ||
34 | + page.get('/new', async (ctx) => { | ||
35 | + ctx.render('posts/new'); | ||
36 | + }); | ||
37 | + | ||
38 | + // create | ||
39 | + page.post('/', async (ctx, next) => { | ||
40 | + await Page.create(ctx.body); | ||
41 | + ctx.redirect('/posts'); | ||
42 | + }); | ||
43 | + | ||
44 | + | ||
45 | + | ||
46 | + // show | ||
47 | + page.get('/:id', async (ctx, next) => { | ||
48 | + const page = await Page.findOne({_id:ctx.params.id}); | ||
49 | + ctx.render('posts/show', {page}); | ||
50 | + }); | ||
51 | + | ||
52 | + | ||
53 | +// update | ||
54 | +page.post('/:id', async (ctx, next) => { | ||
55 | + ctx.body.updatedAt = Date.now(); //2 | ||
56 | + const page = await Page.findOneAndUpdate({_id:ctx.params.id}, ctx.body); | ||
57 | + ctx.redirect("/posts/"+ctx.params.id); | ||
58 | + }); | ||
59 | + | ||
60 | + // destroy | ||
61 | + page.delete('/:id', async (ctx, next) => { | ||
62 | + try{ | ||
63 | + await Page.deleteOne({_id:ctx.params.id}) | ||
64 | + ctx.redirect('/posts'); | ||
65 | + }catch(e){ | ||
66 | + ctx.throw(500, e); | ||
67 | + } | ||
68 | + }); | ||
69 | + | ||
70 | + | ||
20 | 71 | ||
21 | //page.post('/postinfo', pageCtrl.uploadInfo); | 72 | //page.post('/postinfo', pageCtrl.uploadInfo); |
22 | //page.get('/info',pageCtrl.getbyurl);//url로 recipe정보 가져오기 (flutter 내 레시피에서 쓰임.) | 73 | //page.get('/info',pageCtrl.getbyurl);//url로 recipe정보 가져오기 (flutter 내 레시피에서 쓰임.) | ... | ... |
... | @@ -4,6 +4,8 @@ const Book = require("../../models/book"); | ... | @@ -4,6 +4,8 @@ const Book = require("../../models/book"); |
4 | const Joi = require('@hapi/joi'); | 4 | const Joi = require('@hapi/joi'); |
5 | const config = require('../../lib/config'); | 5 | const config = require('../../lib/config'); |
6 | const { Mongoose } = require('mongoose'); | 6 | const { Mongoose } = require('mongoose'); |
7 | + | ||
8 | + | ||
7 | exports.search = async (ctx) => { | 9 | exports.search = async (ctx) => { |
8 | const { title } = ctx.query; //search word | 10 | const { title } = ctx.query; //search word |
9 | console.log(title) | 11 | console.log(title) |
... | @@ -19,12 +21,18 @@ exports.search = async (ctx) => { | ... | @@ -19,12 +21,18 @@ exports.search = async (ctx) => { |
19 | 21 | ||
20 | 22 | ||
21 | exports.detailPage = async (ctx) => { | 23 | exports.detailPage = async (ctx) => { |
24 | + try{ | ||
22 | var ObjectId = require('mongodb').ObjectId; | 25 | var ObjectId = require('mongodb').ObjectId; |
23 | - var id = req.params.page_id; | 26 | + var id = req.params.id; |
24 | var o_id = new ObjectId(id); | 27 | var o_id = new ObjectId(id); |
25 | const page = await db.Page.find({_id:o_id}); | 28 | const page = await db.Page.find({_id:o_id}); |
29 | + await ctx.redirect('/api/page/detail/'+req.params.id); | ||
26 | ctx.body = page; | 30 | ctx.body = page; |
27 | ctx.status = 200; | 31 | ctx.status = 200; |
32 | + }catch(e){ | ||
33 | + ctx.throw(500,e); | ||
34 | + } | ||
35 | + | ||
28 | }; | 36 | }; |
29 | 37 | ||
30 | // parameters: array with book objects as elements | 38 | // parameters: array with book objects as elements |
... | @@ -149,19 +157,21 @@ exports.scrollPage = async (ctx) => { | ... | @@ -149,19 +157,21 @@ exports.scrollPage = async (ctx) => { |
149 | else | 157 | else |
150 | ctx.request.body.image = "" | 158 | ctx.request.body.image = "" |
151 | 159 | ||
152 | - var user = ctx.request.body; //require user id | 160 | + var page = ctx.request.body; |
153 | try { | 161 | try { |
154 | - const mybook = await Book.findOne({ _id: book._id }); | 162 | + const mypage = await Page.findOne({ _id: page._id });//require page's _id |
163 | + if(ctx.state.user._id == mypage.author){ | ||
164 | + mypage.updateP(book); | ||
165 | + ctx.body = mypage; | ||
166 | + console.log(mypage); | ||
167 | + ctx.status = 200;} | ||
155 | 168 | ||
156 | - mybook.updateP(book); | ||
157 | - | ||
158 | - ctx.body = user._id; | ||
159 | } catch (e) { | 169 | } catch (e) { |
160 | ctx.throw(500, e); | 170 | ctx.throw(500, e); |
171 | + ctx.body = { | ||
172 | + message: "작성자가 아닙니다. " } | ||
161 | } | 173 | } |
162 | - ctx.body = user._id; | ||
163 | 174 | ||
164 | - console.log(user); | ||
165 | ctx.status = 200; | 175 | ctx.status = 200; |
166 | }; | 176 | }; |
167 | 177 | ||
... | @@ -178,18 +188,3 @@ exports.deletePage = async (ctx) => { | ... | @@ -178,18 +188,3 @@ exports.deletePage = async (ctx) => { |
178 | } | 188 | } |
179 | ctx.status = 204; // No Content | 189 | ctx.status = 204; // No Content |
180 | }; | 190 | }; |
181 | - | ||
182 | -exports.getPage = async (ctx) => { | ||
183 | - const pageid = ctx.request.body._id; | ||
184 | - try { | ||
185 | - const mypage = await Book.findById(pageid).exec(); | ||
186 | - const user = await User.findById(mypage.author).exec();//작가정보 | ||
187 | - const author_name = user.nickname; | ||
188 | - ctx.body = {mypage,author_name:author_name} | ||
189 | - console.log(mypage) | ||
190 | - | ||
191 | - } catch (e) { | ||
192 | - ctx.throw(500, e); | ||
193 | - } | ||
194 | - | ||
195 | -}; | ... | ... |
src/api/page/script.js
0 → 100644
1 | + | ||
2 | +$(function(){ | ||
3 | + function get2digits (num){ | ||
4 | + return ('0' + num).slice(-2); | ||
5 | + } | ||
6 | + | ||
7 | + function getDate(dateObj){ | ||
8 | + if(dateObj instanceof Date) | ||
9 | + return dateObj.getFullYear() + '-' + get2digits(dateObj.getMonth()+1)+ '-' + get2digits(dateObj.getDate()); | ||
10 | + } | ||
11 | + | ||
12 | + function getTime(dateObj){ | ||
13 | + if(dateObj instanceof Date) | ||
14 | + return get2digits(dateObj.getHours()) + ':' + get2digits(dateObj.getMinutes())+ ':' + get2digits(dateObj.getSeconds()); | ||
15 | + } | ||
16 | + | ||
17 | + function convertDate(){ | ||
18 | + $('[data-date]').each(function(index,element){ | ||
19 | + var dateString = $(element).data('date'); | ||
20 | + if(dateString){ | ||
21 | + var date = new Date(dateString); | ||
22 | + $(element).html(getDate(date)); | ||
23 | + } | ||
24 | + }); | ||
25 | + } | ||
26 | + | ||
27 | + function convertDateTime(){ | ||
28 | + $('[data-date-time]').each(function(index,element){ | ||
29 | + var dateString = $(element).data('date-time'); | ||
30 | + if(dateString){ | ||
31 | + var date = new Date(dateString); | ||
32 | + $(element).html(getDate(date)+' '+getTime(date)); | ||
33 | + } | ||
34 | + }); | ||
35 | + } | ||
36 | + | ||
37 | + convertDate(); | ||
38 | + convertDateTime(); | ||
39 | + }); | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
src/css/master.css
0 → 100644
1 | + | ||
2 | +body { | ||
3 | + font-family: 'Open Sans', sans-serif; | ||
4 | + } | ||
5 | + .breadcrumb-item { | ||
6 | + font-size: 0.8em !important; | ||
7 | + } | ||
8 | + .ellipsis{ | ||
9 | + display: block; | ||
10 | + width: 100%; | ||
11 | + white-space: nowrap; | ||
12 | + overflow: hidden; | ||
13 | + text-overflow: ellipsis; /* 1 */ | ||
14 | + } | ||
15 | + | ||
16 | + .board-table { | ||
17 | + table-layout: fixed; | ||
18 | + } | ||
19 | + .board-table .date { | ||
20 | + width: 100px; | ||
21 | + } | ||
22 | + | ||
23 | + .post-body{ | ||
24 | + white-space: pre-line; /* 2 */ | ||
25 | + } | ||
26 | + .post-info{ | ||
27 | + font-size: 0.8em; | ||
28 | + } | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
... | @@ -9,8 +9,12 @@ const mongoose = require('mongoose'); | ... | @@ -9,8 +9,12 @@ const mongoose = require('mongoose'); |
9 | const bodyParser = require('koa-bodyparser'); | 9 | const bodyParser = require('koa-bodyparser'); |
10 | const port = process.env.PORT || 3000 | 10 | const port = process.env.PORT || 3000 |
11 | //443 | 11 | //443 |
12 | +const passport = require('koa-passport') | ||
12 | const app = new Koa(); | 13 | const app = new Koa(); |
13 | const router = new Router() | 14 | const router = new Router() |
15 | +const render = require('koa-ejs'); | ||
16 | +const path = require('path'); | ||
17 | + | ||
14 | const send = require('koa-send'); | 18 | const send = require('koa-send'); |
15 | var options = { | 19 | var options = { |
16 | key: fs.readFileSync('./server.key'), | 20 | key: fs.readFileSync('./server.key'), |
... | @@ -29,53 +33,72 @@ mongoose.connect(process.env.MONGO_URI).then( | ... | @@ -29,53 +33,72 @@ mongoose.connect(process.env.MONGO_URI).then( |
29 | console.error(e); | 33 | console.error(e); |
30 | }); | 34 | }); |
31 | 35 | ||
32 | -var readFileThunk = function(src) { | 36 | + |
33 | - return new Promise(function (resolve, reject) { | ||
34 | - fs.readFile(src, {'encoding': 'utf8'}, function (err, data) { | ||
35 | - if(err) return reject(err); | ||
36 | - resolve(data); | ||
37 | - }); | ||
38 | - }); | ||
39 | -} | ||
40 | //app.use(router.routes()) | 37 | //app.use(router.routes()) |
41 | /* | 38 | /* |
42 | app | 39 | app |
43 | .use(router.routes()) | 40 | .use(router.routes()) |
44 | .use(router.allowedMethods()); | 41 | .use(router.allowedMethods()); |
45 | */ | 42 | */ |
43 | + | ||
44 | + render(app, { | ||
45 | + root: path.join(__dirname, 'views'), | ||
46 | + layout: false, | ||
47 | + viewExt: 'ejs', | ||
48 | + cache: false, | ||
49 | + debug: true | ||
50 | + }); | ||
51 | +// app.use(async function (ctx) { | ||
52 | + // await ctx.render('home/welcome'); | ||
53 | + // }); | ||
46 | app | 54 | app |
47 | .use(jwtMiddleware) | 55 | .use(jwtMiddleware) |
48 | .use(bodyParser()) // bodyParser는 라우터 코드보다 상단에 있어야 합니다. | 56 | .use(bodyParser()) // bodyParser는 라우터 코드보다 상단에 있어야 합니다. |
49 | .use(router.routes()) | 57 | .use(router.routes()) |
50 | - .use(router.allowedMethods()); | 58 | + .use(router.allowedMethods()) |
59 | + .use(passport.initialize()); | ||
51 | 60 | ||
52 | 61 | ||
62 | + router.get('/', async ctx =>{ | ||
63 | + await ctx.render('home/welcome'); | ||
64 | +}); | ||
53 | 65 | ||
54 | -/* | 66 | +router.get('/about', async ctx =>{ |
55 | -router.get('/', (ctx, next) => { | 67 | + await ctx.render('home/about'); |
56 | - ctx.body = '루트 페이지 입니다.'; | 68 | +}); |
69 | + | ||
70 | +router.get('/login', async ctx =>{ | ||
71 | + await ctx.render('users/index'); | ||
57 | }); | 72 | }); |
58 | -*/ | 73 | + |
74 | +router.get('/signup', async ctx =>{ | ||
75 | + await ctx.render('users/new'); | ||
76 | +}); | ||
77 | + | ||
78 | + | ||
79 | + | ||
80 | + | ||
59 | /* | 81 | /* |
60 | router.get('/', async (ctx, next) => { | 82 | router.get('/', async (ctx, next) => { |
61 | const rawContent = fs.readFileSync('index.html').toString('utf8') | 83 | const rawContent = fs.readFileSync('index.html').toString('utf8') |
62 | ctx.body = rawContent | 84 | ctx.body = rawContent |
63 | })*/ | 85 | })*/ |
64 | 86 | ||
65 | -router.get('/', function *(){ | 87 | + |
66 | - this.body = yield readFileThunk(__dirname + '/public/index.html'); | ||
67 | -}) | ||
68 | //router.use(api.routes()); | 88 | //router.use(api.routes()); |
69 | //app.use(router.routes()).use(router.allowedMethods()) | 89 | //app.use(router.routes()).use(router.allowedMethods()) |
70 | router.use('/api', api.routes()); | 90 | router.use('/api', api.routes()); |
71 | -app.use(router.routes()).use(router.allowedMethods()); | 91 | +//app.use(router.routes()).use(router.allowedMethods()); |
92 | + | ||
72 | 93 | ||
73 | http2 | 94 | http2 |
74 | .createSecureServer(options, app.callback()) | 95 | .createSecureServer(options, app.callback()) |
75 | .listen(port, () => console.log("listening on port %i", port)); | 96 | .listen(port, () => console.log("listening on port %i", port)); |
76 | -//app.listen(port, function () { | ||
77 | -//console.log('server listening on port %d', port); | ||
78 | - //}); | ||
79 | 97 | ||
98 | +/* | ||
99 | + app.listen(port, function () { | ||
100 | +console.log('server listening on port %d', port); | ||
101 | + }); | ||
80 | 102 | ||
81 | 103 | ||
104 | + */ | ||
... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
... | @@ -5,9 +5,9 @@ const { Schema } = mongoose; | ... | @@ -5,9 +5,9 @@ const { Schema } = mongoose; |
5 | 5 | ||
6 | const bookSchema = new Schema({ | 6 | const bookSchema = new Schema({ |
7 | id: mongoose.Schema.Types.ObjectId,//unique number of page | 7 | id: mongoose.Schema.Types.ObjectId,//unique number of page |
8 | - pages:[{type:String}],//book contains several pages. pages is the list of page id | 8 | + pages:[{type:mongoose.Schema.Types.ObjectId, ref:'page', required:false}],//book contains several pages. pages is the list of page id |
9 | title: {type:String, require:true}, // book title | 9 | title: {type:String, require:true}, // book title |
10 | - author: [{type:String, require:true, default:user.user}],//작가복수 가능 | 10 | + author: [{type:mongoose.Schema.Types.ObjectId, ref:'user', required:true}],//작가복수 가능 |
11 | contents: {type:String}, // book subtitle or detail | 11 | contents: {type:String}, // book subtitle or detail |
12 | createDate: {type:Date, require:true, default:Date.now}, | 12 | createDate: {type:Date, require:true, default:Date.now}, |
13 | updateDate: {type:Date, default:Date.now}, | 13 | updateDate: {type:Date, default:Date.now}, |
... | @@ -103,4 +103,5 @@ const bookSchema = new Schema({ | ... | @@ -103,4 +103,5 @@ const bookSchema = new Schema({ |
103 | 103 | ||
104 | 104 | ||
105 | 105 | ||
106 | + | ||
106 | module.exports = mongoose.model("Book", bookSchema); | 107 | module.exports = mongoose.model("Book", bookSchema); |
... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
... | @@ -4,9 +4,9 @@ const { Schema } = mongoose; | ... | @@ -4,9 +4,9 @@ const { Schema } = mongoose; |
4 | 4 | ||
5 | const PageSchema = new Schema({ | 5 | const PageSchema = new Schema({ |
6 | id: mongoose.Schema.Types.ObjectId,//unique number of page | 6 | id: mongoose.Schema.Types.ObjectId,//unique number of page |
7 | - book:{type:String},//book contains several pages | 7 | + book:[{type:mongoose.Schema.Types.ObjectId, ref:'book', required:false}],//book contains several pages |
8 | title: {type:String, require:true}, // title of post | 8 | title: {type:String, require:true}, // title of post |
9 | - author: [{type:String, require:true, default:user.user}], | 9 | + author: [{type:mongoose.Schema.Types.ObjectId, ref:'user', required:true}], |
10 | contents: {type:String}, // contents of page | 10 | contents: {type:String}, // contents of page |
11 | createDate: {type:Date, require:true, default:Date.now}, | 11 | createDate: {type:Date, require:true, default:Date.now}, |
12 | updateDate: {type:Date, default:Date.now}, | 12 | updateDate: {type:Date, default:Date.now}, | ... | ... |
... | @@ -12,10 +12,10 @@ const UserSchema = new Schema({ | ... | @@ -12,10 +12,10 @@ const UserSchema = new Schema({ |
12 | password: String, | 12 | password: String, |
13 | token: String, | 13 | token: String, |
14 | //user info | 14 | //user info |
15 | - username: String, | ||
16 | phone: {type: String, require: true}, | 15 | phone: {type: String, require: true}, |
17 | nickname: {type: String, default: ""}, | 16 | nickname: {type: String, default: ""}, |
18 | - books: [{type: String}],//array of bookid | 17 | + books: [{type:mongoose.Schema.Types.ObjectId, ref:'book', required:false}],//array of bookid |
18 | + pages:[{type:mongoose.Schema.Types.ObjectId, ref:'page', required:false}], | ||
19 | favorite: [{ type: String }],//String of url(book, page) | 19 | favorite: [{ type: String }],//String of url(book, page) |
20 | }); | 20 | }); |
21 | 21 | ... | ... |
src/views/books/edit.ejs
0 → 100644
1 | +<head> | ||
2 | + <%- include('../partials/head') %> | ||
3 | + </head> | ||
4 | + <body> | ||
5 | + <%- include('../partials/nav') %> | ||
6 | + | ||
7 | + <div class="container mb-3"> | ||
8 | + | ||
9 | + <nav aria-label="breadcrumb"> | ||
10 | + <ol class="breadcrumb p-1 pl-2 pr-2"> | ||
11 | + <li class="breadcrumb-item"><a href="/">Home</a></li> | ||
12 | + <li class="breadcrumb-item"><a href="/api/page">Board</a></li> | ||
13 | + <li class="breadcrumb-item"><a href="/api/page/<%= page._id %>"><%= page.title %></a></li> | ||
14 | + <li class="breadcrumb-item active" aria-current="page">Edit Post</li> | ||
15 | + </ol> | ||
16 | + </nav> | ||
17 | + | ||
18 | + <form action="/api/page/<%= page._id %>?_method=put" method="post"> | ||
19 | + | ||
20 | + <div class="form-group"> | ||
21 | + <label for="title">Title</label> | ||
22 | + <input type="text" id="title" name="title" value="<%= page.title %>" class="form-control"> | ||
23 | + </div> | ||
24 | + | ||
25 | + <div class="form-group"> | ||
26 | + <label for="body">Body</label> | ||
27 | + <textarea id="body" name="body" rows="5" class="form-control"><%= post.contents %></textarea> | ||
28 | + </div> | ||
29 | + | ||
30 | + <div> | ||
31 | + <a class="btn btn-primary" href="/api/page/<%= page._id %>">Back</a> | ||
32 | + <button type="submit" class="btn btn-primary">Submit</button> | ||
33 | + </div> | ||
34 | + | ||
35 | + </form> | ||
36 | + | ||
37 | + </div> | ||
38 | + </body> | ||
39 | +</html> | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
src/views/books/index.ejs
0 → 100644
1 | +<!DOCTYPE html> | ||
2 | +<html> | ||
3 | + <head> | ||
4 | + <%- include('../partials/head') %> | ||
5 | + </head> | ||
6 | + <body> | ||
7 | + <%- include('../partials/nav') %> | ||
8 | + | ||
9 | + <div class="container mb-3"> | ||
10 | + | ||
11 | + <h2 class="mb-3">Board</h2> | ||
12 | + | ||
13 | + <table class="board-table table table-sm border-bottom"> | ||
14 | + | ||
15 | + <thead class="thead-light"> | ||
16 | + <tr> | ||
17 | + <th scope="col">Title</th> | ||
18 | + <th scope="col" class="date">Date</th> | ||
19 | + </tr> | ||
20 | + </thead> | ||
21 | + | ||
22 | + <tbody> | ||
23 | + <% if(page == null || page.length == 0){ %> | ||
24 | + <tr> | ||
25 | + <td colspan=2> There is no data to show :( </td> | ||
26 | + </tr> | ||
27 | + <% } %> | ||
28 | + <% page.forEach(function(page) { %> | ||
29 | + <tr> | ||
30 | + <td> | ||
31 | + <a href="/api/page/<%= page._id %>"><div class="ellipsis"><%= page.title %></div></a> | ||
32 | + </td> | ||
33 | + <td class="date"> | ||
34 | + <span data-date="<%= page.createDate %>"></span> <!-- 1 --> | ||
35 | + </td> | ||
36 | + </tr> | ||
37 | + <% }) %> | ||
38 | + </tbody> | ||
39 | + | ||
40 | + </table> | ||
41 | + | ||
42 | + <div> | ||
43 | + <a class="btn btn-primary" href="/api/page/new">New</a> | ||
44 | + </div> | ||
45 | + | ||
46 | + </div> | ||
47 | + </body> | ||
48 | +</html> | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
src/views/books/new.ejs
0 → 100644
1 | +<!DOCTYPE html> | ||
2 | +<html> | ||
3 | + <head> | ||
4 | + <%- include('../partials/head') %> | ||
5 | + </head> | ||
6 | + <body> | ||
7 | + <%- include('../partials/nav') %> | ||
8 | + | ||
9 | + <div class="container mb-3"> | ||
10 | + | ||
11 | + <nav aria-label="breadcrumb"> <!-- 1 --> | ||
12 | + <ol class="breadcrumb p-1 pl-2 pr-2"> | ||
13 | + <li class="breadcrumb-item"><a href="/">Home</a></li> | ||
14 | + <li class="breadcrumb-item"><a href="/api/page">Board</a></li> | ||
15 | + <li class="breadcrumb-item active" aria-current="page">New Post</li> | ||
16 | + </ol> | ||
17 | + </nav> | ||
18 | + | ||
19 | + <form action="/api/page/" method="post"> | ||
20 | + | ||
21 | + <div class="form-group"> | ||
22 | + <label for="title">Title</label> | ||
23 | + <input type="text" id="title" name="title" value="" class="form-control"> | ||
24 | + </div> | ||
25 | + | ||
26 | + <div class="form-group"> | ||
27 | + <label for="body">Body</label> | ||
28 | + <textarea id="body" name="body" rows="5" class="form-control"></textarea> | ||
29 | + </div> | ||
30 | + | ||
31 | + <div> | ||
32 | + <a class="btn btn-primary" href="/api/page">Back</a> | ||
33 | + <button type="submit" class="btn btn-primary">Submit</button> | ||
34 | + </div> | ||
35 | + | ||
36 | + </form> | ||
37 | + | ||
38 | + </div> | ||
39 | + </body> | ||
40 | +</html> | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
src/views/books/show.ejs
0 → 100644
1 | +<!DOCTYPE html> | ||
2 | +<html> | ||
3 | + <head> | ||
4 | + <%- include('../partials/head') %> | ||
5 | + </head> | ||
6 | + <body> | ||
7 | + <%- include('../partials/nav') %> | ||
8 | + | ||
9 | + <div class="container mb-3"> | ||
10 | + | ||
11 | + <nav aria-label="breadcrumb"> | ||
12 | + <ol class="breadcrumb p-1 pl-2 pr-2"> | ||
13 | + <li class="breadcrumb-item"><a href="/">Home</a></li> | ||
14 | + <li class="breadcrumb-item"><a href="/api/book">Book</a></li> | ||
15 | + <li class="breadcrumb-item active" aria-current="page"><%= page.title %></li> | ||
16 | + </ol> | ||
17 | + </nav> | ||
18 | + | ||
19 | + <div class="card"> | ||
20 | + <h5 class="card-header p-2"><%= page.title %></h5> | ||
21 | + <div class="row"> <!-- 1 --> | ||
22 | + | ||
23 | + <div class="col-md-7 col-lg-8 col-xl-9 order-sm-2 order-md-1"> <!-- 1 --> | ||
24 | + <div class="post-body p-2"><%= page.contents %></div> | ||
25 | + </div> | ||
26 | + | ||
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"> | ||
29 | + <div><span>Created</span> : <span data-date-time="<%= page.createDate %>"></span></div> <!-- 2 --> | ||
30 | + <% if(page.updateDate) { %> | ||
31 | + <div><span>Updated</span> : <span data-date-time="<%= page.updateDate %>"></span></div> <!-- 2 --> | ||
32 | + <% } %> | ||
33 | + </div> | ||
34 | + </div> | ||
35 | + | ||
36 | + </div> | ||
37 | + </div> | ||
38 | + | ||
39 | + <div class="mt-3"> | ||
40 | + <a class="btn btn-primary" href="/api/page">Back</a> | ||
41 | + <a class="btn btn-primary" href="/api/page/<%= page._id %>/edit">Edit</a> | ||
42 | + <form action="/api/page/<%= page._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> | ||
44 | + </form> | ||
45 | + </div> | ||
46 | + | ||
47 | + </div> | ||
48 | + </body> | ||
49 | +</html> | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
src/views/home/about.ejs
0 → 100644
1 | +<!DOCTYPE html> | ||
2 | +<html> | ||
3 | + <head> | ||
4 | + <%- include('../partials/head') %> | ||
5 | + </head> | ||
6 | + <body> | ||
7 | + <%- include('../partials/nav') %> | ||
8 | + | ||
9 | + <div class="container mb-3"> | ||
10 | + | ||
11 | + <h2 class="mb-3">About</h2> | ||
12 | + | ||
13 | + <P>이 사이트는 Like Project 임시 페이지 입니다. </p> | ||
14 | + | ||
15 | + </div> | ||
16 | + </body> | ||
17 | +</html> | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
src/views/home/login.ejs
0 → 100644
1 | +<!DOCTYPE html> | ||
2 | +<html> | ||
3 | + <head> | ||
4 | + <%- include('../partials/head') %> | ||
5 | + </head> | ||
6 | + <body> | ||
7 | + <%- include('../partials/nav') %> | ||
8 | + | ||
9 | + <div class="container"> | ||
10 | + | ||
11 | + <h3 class="mb-3">Login</h3> | ||
12 | + | ||
13 | + <form class="user-form" action="/login" method="post"> | ||
14 | + | ||
15 | + <div class="form-group row"> | ||
16 | + <label for="username" class="col-sm-3 col-form-label">Username</label> | ||
17 | + <div class="col-sm-9"> | ||
18 | + <input type="text" id="username" name="username" value="<%= username %>" class="form-control <%= (errors.username)?'is-invalid':'' %>"> | ||
19 | + <% if(errors.username){ %> | ||
20 | + <span class="invalid-feedback"><%= errors.username %></span> | ||
21 | + <% } %> | ||
22 | + </div> | ||
23 | + </div> | ||
24 | + | ||
25 | + <div class="form-group row"> | ||
26 | + <label for="password" class="col-sm-3 col-form-label">Password</label> | ||
27 | + <div class="col-sm-9"> | ||
28 | + <input type="password" id="password" name="password" value="" class="form-control <%= (errors.password)?'is-invalid':'' %>"> | ||
29 | + <% if(errors.password){ %> | ||
30 | + <span class="invalid-feedback"><%= errors.password %></span> | ||
31 | + <% } %> | ||
32 | + </div> | ||
33 | + </div> | ||
34 | + | ||
35 | + <% if(errors.login){ %> | ||
36 | + <div class="invalid-feedback d-block"><%= errors.login %></div> | ||
37 | + <% } %> | ||
38 | + | ||
39 | + <div class="mt-3"> | ||
40 | + <input class="btn btn-primary" type="submit" value="Submit"> | ||
41 | + </div> | ||
42 | + | ||
43 | + </form> | ||
44 | + | ||
45 | + </div> | ||
46 | + </body> | ||
47 | +</html> | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
src/views/home/welcome.ejs
0 → 100644
1 | +<!DOCTYPE html> | ||
2 | +<html> | ||
3 | + <head> | ||
4 | + <%- include('../partials/head') %> | ||
5 | + </head> | ||
6 | + <body> | ||
7 | + <%- include('../partials/nav') %> | ||
8 | + | ||
9 | + <div class="container mb-3"> | ||
10 | + | ||
11 | + <div class="jumbotron"> | ||
12 | + <h1>My Website</h1> | ||
13 | + <P>제 웹사이트를 방문해 주셔서 감사합니다!</p> | ||
14 | + </div> | ||
15 | + | ||
16 | + </div> | ||
17 | + </body> | ||
18 | +</html> | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
src/views/partials/head.ejs
0 → 100644
1 | +<!-- views/partials/head.ejs --> | ||
2 | + | ||
3 | +<meta name="viewport" content="width=device-width,initial-scale=1"> | ||
4 | + | ||
5 | +<!-- jquery & bootstrap --> | ||
6 | +<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script> | ||
7 | +<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script> | ||
8 | +<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script> | ||
9 | +<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous"> | ||
10 | + | ||
11 | +<!-- web font --> <!-- 1 --> | ||
12 | +<link href="https://fonts.googleapis.com/css?family=Open+Sans&display=swap" rel="stylesheet"> | ||
13 | + | ||
14 | +<!-- my css --> | ||
15 | +<script src="/src/api/page/script.js"></script> | ||
16 | + | ||
17 | +<title>My Website</title> | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
src/views/partials/nav.ejs
0 → 100644
1 | +<nav class="navbar navbar-expand-sm navbar-light bg-light mb-3"> | ||
2 | + <div class="container"> | ||
3 | + <div class="navbar-brand"></a>Like</div> | ||
4 | + <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent"> | ||
5 | + <span class="navbar-toggler-icon"></span> | ||
6 | + </button> | ||
7 | + <div class="collapse navbar-collapse" id="navbarSupportedContent"> | ||
8 | + <ul class="navbar-nav"> | ||
9 | + <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="/api/book" class="nav-link">Book</a></li> | ||
12 | + <li class="nav-item"><a href="/api/page" class="nav-link">Page</a></li> | ||
13 | + </ul> | ||
14 | + <ul class="navbar-nav ml-auto"> | ||
15 | + | ||
16 | + <li class="nav-item"><a href="/api/auth" class="nav-link">Sign Up</a></li> | ||
17 | + <li class="nav-item"><a href="/api/auth/new" class="nav-link">Login</a></li> | ||
18 | + | ||
19 | + </ul> | ||
20 | + </div> | ||
21 | + </div> | ||
22 | + </nav> | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
src/views/posts/edit.ejs
0 → 100644
1 | +<!DOCTYPE html> | ||
2 | +<html> | ||
3 | + <head> | ||
4 | + <%- include('../partials/head') %> | ||
5 | + </head> | ||
6 | + <body> | ||
7 | + <%- include('../partials/nav') %> | ||
8 | + | ||
9 | + <div class="container mb-3"> | ||
10 | + | ||
11 | + <nav aria-label="breadcrumb"> | ||
12 | + <ol class="breadcrumb p-1 pl-2 pr-2"> | ||
13 | + <li class="breadcrumb-item"><a href="/">Home</a></li> | ||
14 | + <li class="breadcrumb-item"><a href="/api/page">Board</a></li> | ||
15 | + <li class="breadcrumb-item"><a href="/api/page/<%= page._id %>"><%= page.title %></a></li> | ||
16 | + <li class="breadcrumb-item active" aria-current="page">Edit Post</li> | ||
17 | + </ol> | ||
18 | + </nav> | ||
19 | + | ||
20 | + <form action="/api/page/<%= page._id %>?_method=put" method="post"> | ||
21 | + | ||
22 | + <div class="form-group"> | ||
23 | + <label for="title">Title</label> | ||
24 | + <input type="text" id="title" name="title" value="<%= page.title %>" class="form-control"> | ||
25 | + </div> | ||
26 | + | ||
27 | + <div class="form-group"> | ||
28 | + <label for="body">Body</label> | ||
29 | + <textarea id="body" name="body" rows="5" class="form-control"><%= post.contents %></textarea> | ||
30 | + </div> | ||
31 | + | ||
32 | + <div> | ||
33 | + <a class="btn btn-primary" href="/api/page/<%= page._id %>">Back</a> | ||
34 | + <button type="submit" class="btn btn-primary">Submit</button> | ||
35 | + </div> | ||
36 | + | ||
37 | + </form> | ||
38 | + | ||
39 | + </div> | ||
40 | + </body> | ||
41 | +</html> | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
src/views/posts/index.ejs
0 → 100644
1 | +<!-- views/posts/index.ejs --> | ||
2 | + | ||
3 | +<!DOCTYPE html> | ||
4 | +<html> | ||
5 | + <head> | ||
6 | + <%- include('../partials/head') %> | ||
7 | + </head> | ||
8 | + <body> | ||
9 | + <%- include('../partials/nav') %> | ||
10 | + | ||
11 | + <div class="container mb-3"> | ||
12 | + | ||
13 | + <h2 class="mb-3">Board</h2> | ||
14 | + | ||
15 | + <table class="board-table table table-sm border-bottom"> | ||
16 | + | ||
17 | + <thead class="thead-light"> | ||
18 | + <tr> | ||
19 | + <th scope="col">Title</th> | ||
20 | + <th scope="col" class="date">Date</th> | ||
21 | + </tr> | ||
22 | + </thead> | ||
23 | + | ||
24 | + <tbody> | ||
25 | + <% if(page == null || page.length == 0){ %> | ||
26 | + <tr> | ||
27 | + <td colspan=2> There is no data to show :( </td> | ||
28 | + </tr> | ||
29 | + <% } %> | ||
30 | + <% page.forEach(function(page) { %> | ||
31 | + <tr> | ||
32 | + <td> | ||
33 | + <a href="/api/page/<%= page._id %>"><div class="ellipsis"><%= page.title %></div></a> | ||
34 | + </td> | ||
35 | + <td class="date"> | ||
36 | + <span data-date="<%= page.createDate %>"></span> <!-- 1 --> | ||
37 | + </td> | ||
38 | + </tr> | ||
39 | + <% }) %> | ||
40 | + </tbody> | ||
41 | + | ||
42 | + </table> | ||
43 | + | ||
44 | + <div> | ||
45 | + <a class="btn btn-primary" href="/api/page/new">New</a> | ||
46 | + </div> | ||
47 | + | ||
48 | + </div> | ||
49 | + </body> | ||
50 | +</html> | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
src/views/posts/new.ejs
0 → 100644
1 | +<!DOCTYPE html> | ||
2 | +<html> | ||
3 | + <head> | ||
4 | + <%- include('../partials/head') %> | ||
5 | + </head> | ||
6 | + <body> | ||
7 | + <%- include('../partials/nav') %> | ||
8 | + | ||
9 | + <div class="container mb-3"> | ||
10 | + | ||
11 | + <nav aria-label="breadcrumb"> <!-- 1 --> | ||
12 | + <ol class="breadcrumb p-1 pl-2 pr-2"> | ||
13 | + <li class="breadcrumb-item"><a href="/">Home</a></li> | ||
14 | + <li class="breadcrumb-item"><a href="/api/page">Board</a></li> | ||
15 | + <li class="breadcrumb-item active" aria-current="page">New Post</li> | ||
16 | + </ol> | ||
17 | + </nav> | ||
18 | + | ||
19 | + <form action="/api/page/" method="post"> | ||
20 | + | ||
21 | + <div class="form-group"> | ||
22 | + <label for="title">Title</label> | ||
23 | + <input type="text" id="title" name="title" value="" class="form-control"> | ||
24 | + </div> | ||
25 | + | ||
26 | + <div class="form-group"> | ||
27 | + <label for="body">Body</label> | ||
28 | + <textarea id="body" name="body" rows="5" class="form-control"></textarea> | ||
29 | + </div> | ||
30 | + | ||
31 | + <div> | ||
32 | + <a class="btn btn-primary" href="/api/page">Back</a> | ||
33 | + <button type="submit" class="btn btn-primary">Submit</button> | ||
34 | + </div> | ||
35 | + | ||
36 | + </form> | ||
37 | + | ||
38 | + </div> | ||
39 | + </body> | ||
40 | +</html> | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
src/views/posts/show.ejs
0 → 100644
1 | + | ||
2 | +<!DOCTYPE html> | ||
3 | +<html> | ||
4 | + <head> | ||
5 | + <%- include('../partials/head') %> | ||
6 | + </head> | ||
7 | + <body> | ||
8 | + <%- include('../partials/nav') %> | ||
9 | + | ||
10 | + <div class="container mb-3"> | ||
11 | + | ||
12 | + <nav aria-label="breadcrumb"> | ||
13 | + <ol class="breadcrumb p-1 pl-2 pr-2"> | ||
14 | + <li class="breadcrumb-item"><a href="/">Home</a></li> | ||
15 | + <li class="breadcrumb-item"><a href="/api/book">Book</a></li> | ||
16 | + <li class="breadcrumb-item active" aria-current="page"><%= page.title %></li> | ||
17 | + </ol> | ||
18 | + </nav> | ||
19 | + | ||
20 | + <div class="card"> | ||
21 | + <h5 class="card-header p-2"><%= page.title %></h5> | ||
22 | + <div class="row"> <!-- 1 --> | ||
23 | + | ||
24 | + <div class="col-md-7 col-lg-8 col-xl-9 order-sm-2 order-md-1"> <!-- 1 --> | ||
25 | + <div class="post-body p-2"><%= page.contents %></div> | ||
26 | + </div> | ||
27 | + | ||
28 | + <div class="col-md-5 col-lg-4 col-xl-3 order-sm-1 order-md-2"> <!-- 1 --> | ||
29 | + <div class="post-info card m-2 p-2"> | ||
30 | + <div><span>Created</span> : <span data-date-time="<%= page.createDate %>"></span></div> <!-- 2 --> | ||
31 | + <% if(page.updateDate) { %> | ||
32 | + <div><span>Updated</span> : <span data-date-time="<%= page.updateDate %>"></span></div> <!-- 2 --> | ||
33 | + <% } %> | ||
34 | + </div> | ||
35 | + </div> | ||
36 | + | ||
37 | + </div> | ||
38 | + </div> | ||
39 | + | ||
40 | + <div class="mt-3"> | ||
41 | + <a class="btn btn-primary" href="/api/page">Back</a> | ||
42 | + <a class="btn btn-primary" href="/api/page/<%= page._id %>/edit">Edit</a> | ||
43 | + <form action="/api/page/<%= page._id %>?_method=delete" method="post" class="d-inline"> | ||
44 | + <a class="btn btn-primary" href="javascript:void(0)" onclick="confirm('Do you want to delete this?')?this.parentElement.submit():null;">Delete</a> | ||
45 | + </form> | ||
46 | + </div> | ||
47 | + | ||
48 | + </div> | ||
49 | + </body> | ||
50 | +</html> | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
src/views/users/edit.ejs
0 → 100644
1 | + | ||
2 | +<!DOCTYPE html> | ||
3 | +<html> | ||
4 | + <head> | ||
5 | + <%- include('../partials/head') %> | ||
6 | + </head> | ||
7 | + <body> | ||
8 | + <%- include('../partials/nav') %> | ||
9 | + | ||
10 | + <div class="container mb-3"> | ||
11 | + | ||
12 | + <h3 class="mb-3">Edit User</h3> | ||
13 | + | ||
14 | + <form action="/api/auth/users/<%= user.username %>?_method=put" method="post"> | ||
15 | + | ||
16 | + <div class="form-group row"> | ||
17 | + <label for="currentPassword" class="col-sm-3 col-form-label">Current Password*</label> | ||
18 | + <div class="col-sm-9 col-sm-offset-3"> | ||
19 | + <input type="password" id="currentPassword" name="currentPassword" value="" class="form-control"> | ||
20 | + </div> | ||
21 | + </div> | ||
22 | + | ||
23 | + <hr></hr> | ||
24 | + | ||
25 | + <div class="form-group row"> | ||
26 | + <label for="username" class="col-sm-3 col-form-label">Username*</label> | ||
27 | + <div class="col-sm-9"> | ||
28 | + <input type="text" id="username" name="username" value="<%= user.nickname %>" class="form-control"> | ||
29 | + </div> | ||
30 | + </div> | ||
31 | + | ||
32 | + <div class="form-group row"> | ||
33 | + <label for="name" class="col-sm-3 col-form-label">Name*</label> | ||
34 | + <div class="col-sm-9"> | ||
35 | + <input type="text" id="name" name="name" value="<%= user.email %>" class="form-control"> | ||
36 | + </div> | ||
37 | + </div> | ||
38 | + | ||
39 | + <div class="form-group row"> | ||
40 | + <label for="email" class="col-sm-3 col-form-label">Email</label> | ||
41 | + <div class="col-sm-9"> | ||
42 | + <input type="text" id="email" name="email" value="<%= user.email %>" class="form-control"> | ||
43 | + </div> | ||
44 | + </div> | ||
45 | + | ||
46 | + <div class="form-group row"> | ||
47 | + <label for="newPassword" class="col-sm-3 col-form-label">New Password</label> | ||
48 | + <div class="col-sm-9 col-sm-offset-3"> | ||
49 | + <input type="password" id="newPassword" name="newPassword" value="" class="form-control"> | ||
50 | + </div> | ||
51 | + </div> | ||
52 | + | ||
53 | + <div class="form-group row"> | ||
54 | + <label for="passwordConfirmation" class="col-sm-3 col-form-label">Password Confirmation</label> | ||
55 | + <div class="col-sm-9 col-sm-offset-3"> | ||
56 | + <input type="password" id="passwordConfirmation" name="passwordConfirmation" value="" class="form-control"> | ||
57 | + </div> | ||
58 | + </div> | ||
59 | + | ||
60 | + <p> | ||
61 | + <small>*Required</small> | ||
62 | + </p> | ||
63 | + | ||
64 | + <div class="buttons"> | ||
65 | + <a class="btn btn-primary" href="/api/auth/users/<%= user.username %>">Back</a> | ||
66 | + <button type="submit" class="btn btn-primary">Submit</button> | ||
67 | + </div> | ||
68 | + | ||
69 | + </form> | ||
70 | + | ||
71 | + </div> | ||
72 | + </body> | ||
73 | +</html> | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
src/views/users/index.ejs
0 → 100644
1 | + | ||
2 | +<!DOCTYPE html> | ||
3 | +<html> | ||
4 | + <head> | ||
5 | + <%- include('../partials/head') %> | ||
6 | + </head> | ||
7 | + <body> | ||
8 | + <%- include('../partials/nav') %> | ||
9 | + | ||
10 | + <div class="container mb-3"> | ||
11 | + | ||
12 | + <h3 class="mb-3">Users</h3> | ||
13 | + | ||
14 | + <ul class="list-group"> | ||
15 | + <% if(user == null || user.length == 0){ %> | ||
16 | + <li class="list-group-item"> There is no user yet.</li> | ||
17 | + <% } %> | ||
18 | + <% user.forEach(function(user) { %> | ||
19 | + <li class="list-group-item"> | ||
20 | + <a href="/api/auth/userlist/<%= user._id %>"><%= user.nickname %></a> | ||
21 | + </li> | ||
22 | + <% }) %> | ||
23 | + </ul> | ||
24 | + | ||
25 | + </div> | ||
26 | + </body> | ||
27 | +</html> | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
src/views/users/new.ejs
0 → 100644
1 | + | ||
2 | + | ||
3 | +<!DOCTYPE html> | ||
4 | +<html> | ||
5 | + <head> | ||
6 | + <%- include('../partials/head') %> | ||
7 | + </head> | ||
8 | + <body> | ||
9 | + <%- include('../partials/nav') %> | ||
10 | + | ||
11 | + <div class="container mb-3"> | ||
12 | + | ||
13 | + <h3 class="contentBoxTop mb-3">New User</h3> | ||
14 | + | ||
15 | + <form action="/api/auth/signin" method="post"> | ||
16 | + | ||
17 | + <div class="form-group row"> | ||
18 | + <label for="nickname" class="col-sm-3 col-form-label">Username*</label> | ||
19 | + <div class="col-sm-9"> | ||
20 | + <input type="text" id="nickname" name="nickname" value="" class="form-control"> | ||
21 | + </div> | ||
22 | + </div> | ||
23 | + <div class="form-group row"> | ||
24 | + <label for="email" class="col-sm-3 col-form-label">Email</label> | ||
25 | + <div class="col-sm-9"> | ||
26 | + <input type="text" id="email" name="email" value="" class="form-control"> | ||
27 | + </div> | ||
28 | + </div> | ||
29 | + <div class="form-group row"> | ||
30 | + <label for="password" class="col-sm-3 col-form-label">Password*</label> | ||
31 | + <div class="col-sm-9"> | ||
32 | + <input type="password" id="password" name="password" value="" class="form-control"> | ||
33 | + </div> | ||
34 | + </div> | ||
35 | + <div class="form-group row"> | ||
36 | + <label for="passwordConfirmation" class="col-sm-3 col-form-label">Password Confirmation*</label> | ||
37 | + <div class="col-sm-9 col-sm-offset-3"> | ||
38 | + <input type="password" id="passwordConfirmation" name="passwordConfirmation" value="" class="form-control"> | ||
39 | + </div> | ||
40 | + </div> | ||
41 | + <p> | ||
42 | + <small>*Required</small> | ||
43 | + </p> | ||
44 | + | ||
45 | + <div class="form-group"> | ||
46 | + <button type="submit" class="btn btn-primary">Submit</button> | ||
47 | + </div> | ||
48 | + </form> | ||
49 | + | ||
50 | + </div> | ||
51 | + </body> | ||
52 | +</html> | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
src/views/users/show.ejs
0 → 100644
1 | + | ||
2 | + | ||
3 | +<!DOCTYPE html> | ||
4 | +<html> | ||
5 | + <head> | ||
6 | + <%- include('../partials/head') %> | ||
7 | + </head> | ||
8 | + <body> | ||
9 | + <%- include('../partials/nav') %> | ||
10 | + | ||
11 | + <div class="container mb-3"> | ||
12 | + | ||
13 | + <h3 class="contentBoxTop"><%= user.nickname</h3> | ||
14 | + | ||
15 | + <form class="user-form" action="/users" method="post"> | ||
16 | + <fieldset disabled> | ||
17 | + <div class="form-group row"> | ||
18 | + <label for="name" class="col-sm-3 col-form-label">Name</label> | ||
19 | + <div class="col-sm-9"> | ||
20 | + <input class="form-control" type="text" id="name" name="name" value="<%= user.name %>"> | ||
21 | + </div> | ||
22 | + </div> | ||
23 | + <div class="form-group row"> | ||
24 | + <label for="email" class="col-sm-3 col-form-label">Email</label> | ||
25 | + <div class="col-sm-9"> | ||
26 | + <input class="form-control" type="text" id="email" name="email" value="<%= user.email %>"> | ||
27 | + </div> | ||
28 | + </div> | ||
29 | + </fieldset> | ||
30 | + </form> | ||
31 | + | ||
32 | + <div> | ||
33 | + <a class="btn btn-primary" href="/api/auth/users">Back</a> | ||
34 | + <a class="btn btn-primary" href="/api/auth/users/<%= user.email %>/edit">Edit</a> | ||
35 | + <form action="/users/<%= user.email %>?_method=delete" method="post" class="d-inline"> | ||
36 | + <a class="btn btn-primary" href="javascript:void(0)" onclick="confirm('Do you want to delete this?')?this.parentElement.submit():null;">Delete</a> | ||
37 | + </form> | ||
38 | + </div> | ||
39 | + | ||
40 | + </div> | ||
41 | + </body> | ||
42 | +</html> | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
-
Please register or login to post a comment