Jeongmin Seo

Merge branches

Showing 59 changed files with 0 additions and 3203 deletions
File mode changed
1 -# Logs
2 -logs
3 -*.log
4 -npm-debug.log*
5 -yarn-debug.log*
6 -yarn-error.log*
7 -lerna-debug.log*
8 -.pnpm-debug.log*
9 -
10 -# Diagnostic reports (https://nodejs.org/api/report.html)
11 -report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
12 -
13 -# Runtime data
14 -pids
15 -*.pid
16 -*.seed
17 -*.pid.lock
18 -
19 -# Directory for instrumented libs generated by jscoverage/JSCover
20 -lib-cov
21 -
22 -# Coverage directory used by tools like istanbul
23 -coverage
24 -*.lcov
25 -
26 -# nyc test coverage
27 -.nyc_output
28 -
29 -# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
30 -.grunt
31 -
32 -# Bower dependency directory (https://bower.io/)
33 -bower_components
34 -
35 -# node-waf configuration
36 -.lock-wscript
37 -
38 -# Compiled binary addons (https://nodejs.org/api/addons.html)
39 -build/Release
40 -
41 -# Dependency directories
42 -**node_modules/
43 -jspm_packages/
44 -
45 -# Snowpack dependency directory (https://snowpack.dev/)
46 -web_modules/
47 -
48 -# TypeScript cache
49 -*.tsbuildinfo
50 -
51 -# Optional npm cache directory
52 -.npm
53 -
54 -# Optional eslint cache
55 -.eslintcache
56 -
57 -# Microbundle cache
58 -.rpt2_cache/
59 -.rts2_cache_cjs/
60 -.rts2_cache_es/
61 -.rts2_cache_umd/
62 -
63 -# Optional REPL history
64 -.node_repl_history
65 -
66 -# Output of 'npm pack'
67 -*.tgz
68 -
69 -# Yarn Integrity file
70 -.yarn-integrity
71 -
72 -# dotenv environment variables file
73 -.env
74 -.env.test
75 -.env.production
76 -
77 -# parcel-bundler cache (https://parceljs.org/)
78 -.cache
79 -.parcel-cache
80 -
81 -# Next.js build output
82 -.next
83 -out
84 -
85 -# Nuxt.js build / generate output
86 -.nuxt
87 -dist
88 -
89 -# Gatsby files
90 -.cache/
91 -# Comment in the public line in if your project uses Gatsby and not Next.js
92 -# https://nextjs.org/blog/next-9-1#public-directory-support
93 -# public
94 -
95 -# vuepress build output
96 -.vuepress/dist
97 -
98 -# Serverless directories
99 -.serverless/
100 -
101 -# FuseBox cache
102 -.fusebox/
103 -
104 -# DynamoDB Local files
105 -.dynamodb/
106 -
107 -# TernJS port file
108 -.tern-port
109 -
110 -# Stores VSCode versions used for testing VSCode extensions
111 -.vscode-test
112 -
113 -# yarn v2
114 -.yarn/cache
115 -.yarn/unplugged
116 -.yarn/build-state.yml
117 -.yarn/install-state.gz
118 -.pnp.*
119 -
120 -#보안관련
121 -.package-lock.json
...\ No newline at end of file ...\ No newline at end of file
1 -const express = require("express");
2 -const http = require("http");
3 -const app = express();
4 -const path = require("path")
5 -const server = http.createServer(app);
6 -const socketIO = require("socket.io")
7 -const moment = require("moment")
8 -
9 -
10 -const io = socketIO(server);
11 -
12 -app.use(express.static(path.join(__dirname, "src")))
13 -const PORT = process.env.PORT || 3000;
14 -
15 -io.on('connection', (socket) => {
16 - socket.on("chatting", (data)=>{
17 - const { name, msg } = data;
18 - io.emit("chatting", {
19 - name,
20 - msg,
21 - time: moment(new Date()).format("h:ss A")
22 - })
23 - })
24 -});
25 -
26 -server.listen(PORT, ()=>console.log(`server is running ${PORT}`))
...\ No newline at end of file ...\ No newline at end of file
This diff is collapsed. Click to expand it.
1 -{
2 - "name": "chat",
3 - "version": "1.0.0",
4 - "description": "",
5 - "main": "index.js",
6 - "scripts": {
7 - "start": "nodemon ./app.js",
8 - "test": "echo \"Error: no test specified\" && exit 1"
9 - },
10 - "keywords": [],
11 - "author": "",
12 - "license": "ISC",
13 - "dependencies": {
14 - "dayjs": "^1.11.2",
15 - "express": "^4.18.1",
16 - "moment": "^2.29.3",
17 - "socket.io": "^4.5.1"
18 - }
19 -}
1 -* {
2 - margin: 0;
3 - padding: 0;
4 -}
5 -
6 -html, body {
7 - height : 100%;
8 -}
9 -
10 -.wrapper {
11 - height : 100%;
12 - width: 100%;
13 - display: flex;
14 - flex-direction: column;
15 - overflow: hidden;
16 -}
17 -
18 -.user-container {
19 - background: rebeccapurple;
20 - flex: 1;
21 - display: flex;
22 - justify-content: flex-start;
23 - align-items: center;
24 - padding: 0.5rem;
25 -}
26 -
27 -.user-container .nickname {
28 - font-size : 14px;
29 - margin-right : 1.5rem;
30 - margin-left : 1rem;
31 - color:#fff;
32 -}
33 -
34 -.user-container input {
35 - border-radius: 3px;
36 - border: none;
37 - height: 80%;
38 -}
39 -
40 -.display-container {
41 - background: #D2D2FF;
42 - flex : 12;
43 - overflow-y:scroll;
44 -}
45 -
46 -.input-container {
47 - flex:1;
48 - display:flex;
49 - justify-content: stretch;
50 - align-items: stretch;
51 -}
52 -
53 -.input-container span {
54 - display: flex;
55 - justify-content: flex-start;
56 - align-items:center;
57 - padding: 0.3rem;
58 - width: 100%;
59 -}
60 -
61 -.chatting-input {
62 - font-size:12px;
63 - height:100%;
64 - flex:8;
65 - border:none;
66 -}
67 -
68 -.send-button {
69 - flex:1;
70 - background: rebeccapurple;
71 - color:#fff;
72 - border:none;
73 - height:100%;
74 - border-radius:3px;
75 -}
76 -
77 -.chatting-list li {
78 - width:50%;
79 - padding:0.3rem;
80 - display:flex;
81 - justify-content: flex-start;
82 - align-items:flex-end;
83 - margin-top:0.5rem;
84 -}
85 -
86 -.profile {
87 - display: flex;
88 - flex-direction: column;
89 - align-items: center;
90 - justify-content: center;
91 - flex: 1;
92 -}
93 -
94 -.profile .user {
95 - font-size: 10px;
96 - margin-bottom: 0.3rem;
97 -}
98 -
99 -.profile .image {
100 - border-radius: 50%;
101 - object-fit: cover;
102 - width: 50px;
103 - height: 50px;
104 -}
105 -
106 -.message {
107 - border-radius: 5px;
108 - padding: 0.5rem;
109 - font-size: 12px;
110 - margin: 0 5px;
111 - flex: 10;
112 -}
113 -
114 -.time {
115 - font-size: 10px;
116 - margin: 0 5px;
117 -}
118 -
119 -.sent {
120 - flex-direction: row-reverse;
121 - float: right;
122 -}
123 -
124 -.sent .message {
125 - background: #9986EE;
126 - color: #fff;
127 -}
128 -
129 -.received .message {
130 - background: #fff;
131 -}
...\ No newline at end of file ...\ No newline at end of file
1 -<!DOCTYPE html>
2 -<html lang="en">
3 -<head>
4 - <meta charset="UTF-8">
5 - <meta http-equiv="X-UA-Compatible" content="IE=edge">
6 - <meta name="viewport" content="width=device-width, initial-scale=1.0">
7 - <title>Document</title>
8 - <link rel="stylesheet" href="css/style.css">
9 -</head>
10 -<body>
11 - <div class="wrapper">
12 - <div class="user-container">
13 - <lable class="nickname" for="nickname">닉네임설정</lable>
14 - <input type="text" id="nickname">
15 - </div>
16 - <div class="display-container">
17 - <ul class="chatting-list">
18 -
19 - </ul>
20 - </div>
21 - <div class="input-container">
22 - <span>
23 - <input type="text" class="chatting-input">
24 - <button class="send-button">전송</button>
25 - </span>
26 - </div>
27 - </div>
28 -
29 - <script src="/socket.io/socket.io.js"></script>
30 - <script src="js/chat.js"></script>
31 -</body>
32 -</html>
...\ No newline at end of file ...\ No newline at end of file
1 -"use strict"
2 -//const socket = io.connect("http://localhost:3000/", {transports:['websocket']});
3 -const socket = io();
4 -
5 -const nickname = document.querySelector("#nickname")
6 -const chatlist = document.querySelector(".chatting-list")
7 -const chatInput = document.querySelector(".chatting-input")
8 -const sendButton = document.querySelector(".send-button")
9 -const displayContainer = document.querySelector(".display-container")
10 -
11 -chatInput.addEventListener("keypress", (event)=> {
12 - if(event.keyCode === 13) {
13 - send()
14 - }
15 -})
16 -
17 -function send() {
18 - const param = {
19 - name: nickname.value,
20 - msg: chatInput.value
21 - }
22 - socket.emit("chatting", param)
23 -}
24 -
25 -sendButton.addEventListener("click", send)
26 -
27 -socket.on("chatting", (data)=>{
28 - console.log(data)
29 - const {name, msg, time} = data;
30 - const item = new LiModel(name, msg, time);
31 - item.makeLi()
32 - displayContainer.scrollTo(0, displayContainer.scrollHeight)
33 -})
34 -
35 -//console.log(socket);
36 -
37 -function LiModel(name, msg, time) {
38 - this.name = name;
39 - this.msg = msg;
40 - this.time = time;
41 -
42 - this.makeLi = ()=>{
43 - const li = document.createElement("li");
44 - li.classList.add(nickname.value === this.name ? "sent":"received")
45 - const dom = `<span class="profile">
46 - <span class="user">${this.name}</span>
47 - <img class="image" src="https://placeimg.com/50/50/any" alt="any">
48 - </span>
49 - <span class="message">${this.msg}</span>
50 - <span class="time">${this.time}</span>`;
51 -
52 - li.innerHTML = dom;
53 - chatlist.appendChild(li)
54 - }
55 -}
...\ No newline at end of file ...\ No newline at end of file
This diff is collapsed. Click to expand it.
1 -<!DOCTYPE html>
2 -<html lang="en">
3 - <head>
4 - <meta charset="UTF-8" />
5 - <meta http-equiv="X-UA-Compatible" content="IE=edge" />
6 - <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7 - <title>맛집지도</title>
8 - <meta name="author" content="양주미" />
9 - <meta name="description" content="맛집지도 서비스" />
10 - <meta
11 - name="keywords"
12 - content="맛집지도, 맛집추천, 실시간채팅"
13 - />
14 - <link rel="stylesheet" href="style.css" />
15 - </head>
16 -
17 - <body>
18 - <nav>
19 - <div class="inner">
20 - <div class="nav-container">
21 - <h1 class="nav-title">맛집지도</h1>
22 - <button class="nav-contact">Contact</button>
23 - </div>
24 - </div>
25 - </nav>
26 -
27 - <main>
28 - <section id="category">
29 - <div class="inner">
30 - <div class="category-container">
31 - <h2 class="category-title">💜맛집지도 카테고리를 선택해보세요💜</h2>
32 - <div class="category-list">
33 - <button class="category-item" id="korea">한식🍚</button
34 - ><button class="category-item" id="china">중식🍜</button
35 - ><button class="category-item" id="japan">일식🍙</button
36 - ><button class="category-item" id="america">양식🍝</button
37 - ><button class="category-item" id="wheat">분식🍭</button
38 - ><button class="category-item" id="meat">구이🍖</button
39 - ><button class="category-item" id="sushi">회/초밥🍣</button
40 - ><button class="category-item" id="etc">기타🍴</button>
41 - </div>
42 - </div>
43 - </div>
44 - </section>
45 - <!-- 카테고리 -->
46 - <div id="map" class="inner"></div>
47 -
48 - <!-- 카카오지도 -->
49 - </main>
50 -
51 - <script
52 - type="text/javascript"
53 - src="//dapi.kakao.com/v2/maps/sdk.js?appkey=2263ae9eb197ad864a94eb1ed7b912c9&libraries=services">
54 -</script>
55 -
56 - <script src="script.js"></script>
57 - </body>
58 -</html>
...\ No newline at end of file ...\ No newline at end of file
1 -# Logs
2 -logs
3 -*.log
4 -npm-debug.log*
5 -yarn-debug.log*
6 -yarn-error.log*
7 -lerna-debug.log*
8 -.pnpm-debug.log*
9 -
10 -# Diagnostic reports (https://nodejs.org/api/report.html)
11 -report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
12 -
13 -# Runtime data
14 -pids
15 -*.pid
16 -*.seed
17 -*.pid.lock
18 -
19 -# Directory for instrumented libs generated by jscoverage/JSCover
20 -lib-cov
21 -
22 -# Coverage directory used by tools like istanbul
23 -coverage
24 -*.lcov
25 -
26 -# nyc test coverage
27 -.nyc_output
28 -
29 -# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
30 -.grunt
31 -
32 -# Bower dependency directory (https://bower.io/)
33 -bower_components
34 -
35 -# node-waf configuration
36 -.lock-wscript
37 -
38 -# Compiled binary addons (https://nodejs.org/api/addons.html)
39 -build/Release
40 -
41 -# Dependency directories
42 -**node_modules/
43 -jspm_packages/
44 -
45 -# Snowpack dependency directory (https://snowpack.dev/)
46 -web_modules/
47 -
48 -# TypeScript cache
49 -*.tsbuildinfo
50 -
51 -# Optional npm cache directory
52 -.npm
53 -
54 -# Optional eslint cache
55 -.eslintcache
56 -
57 -# Microbundle cache
58 -.rpt2_cache/
59 -.rts2_cache_cjs/
60 -.rts2_cache_es/
61 -.rts2_cache_umd/
62 -
63 -# Optional REPL history
64 -.node_repl_history
65 -
66 -# Output of 'npm pack'
67 -*.tgz
68 -
69 -# Yarn Integrity file
70 -.yarn-integrity
71 -
72 -# dotenv environment variables file
73 -.env
74 -.env.test
75 -.env.production
76 -
77 -# parcel-bundler cache (https://parceljs.org/)
78 -.cache
79 -.parcel-cache
80 -
81 -# Next.js build output
82 -.next
83 -out
84 -
85 -# Nuxt.js build / generate output
86 -.nuxt
87 -dist
88 -
89 -# Gatsby files
90 -.cache/
91 -# Comment in the public line in if your project uses Gatsby and not Next.js
92 -# https://nextjs.org/blog/next-9-1#public-directory-support
93 -# public
94 -
95 -# vuepress build output
96 -.vuepress/dist
97 -
98 -# Serverless directories
99 -.serverless/
100 -
101 -# FuseBox cache
102 -.fusebox/
103 -
104 -# DynamoDB Local files
105 -.dynamodb/
106 -
107 -# TernJS port file
108 -.tern-port
109 -
110 -# Stores VSCode versions used for testing VSCode extensions
111 -.vscode-test
112 -
113 -# yarn v2
114 -.yarn/cache
115 -.yarn/unplugged
116 -.yarn/build-state.yml
117 -.yarn/install-state.gz
118 -.pnp.*
...\ No newline at end of file ...\ No newline at end of file
1 -"use strict";
2 -//모듈
3 -const express = require("express");
4 -const bodyParser = require("body-parser");
5 -//환경변수 (운영체제간 gap 없애고자)
6 -const dotenv = require("dotenv");
7 -dotenv.config();
8 -const app = express();
9 -//라우팅
10 -const home = require("./src/routes/home");
11 -// 앱 세팅
12 -app.set("views", "./src/views");
13 -app.set("view engine", "ejs");
14 -app.use(express.static(`${__dirname}/src/public`));
15 -app.use(bodyParser.json());
16 -//url통해 전달되는 데이터에 한글, 공백 등의 문자 오류 해결
17 -app.use(bodyParser.urlencoded({extended: true}));
18 -
19 -app.use("/", home); //미들웨어 등록해주는 method
20 -
21 -module.exports = app;
...\ No newline at end of file ...\ No newline at end of file
1 -"use strict";
2 -
3 -const app = require("../app");
4 -const PORT = process.env.PORT || 3000;
5 -
6 -app.listen(PORT, () => {
7 - console.log("서버 가동");
8 -});
...\ No newline at end of file ...\ No newline at end of file
This diff is collapsed. Click to expand it.
1 -{
2 - "name": "login",
3 - "version": "1.0.0",
4 - "main": "app.js",
5 - "bin": {
6 - "login": "www.js"
7 - },
8 - "dependencies": {
9 - "body-parser": "^1.20.0",
10 - "dotenv": "^16.0.1",
11 - "ejs": "^3.1.8",
12 - "express": "^4.18.1",
13 - "mysql": "^2.18.1"
14 - },
15 - "devDependencies": {},
16 - "scripts": {
17 - "start": "nodemon ./bin/www.js",
18 - "test": "echo \"Error: no test specified\" && exit 1"
19 - },
20 - "author": "",
21 - "license": "ISC",
22 - "keywords": [],
23 - "description": ""
24 -}
1 -const mysql = require("mysql");
2 -
3 -const db = mysql.createConnection({
4 - host: process.env.DB_HOST,
5 - user: process.env.DB_USER,
6 - password: process.env.DB_PASSWORD,
7 - database: process.env.DB_DATABASE,
8 -});
9 -
10 -db.connect();
11 -
12 -module.exports = db;
...\ No newline at end of file ...\ No newline at end of file
1 -'use strict';
2 -//for DB manipulate
3 -const UserStorage = require("./UserStorage");
4 -
5 -class User {
6 - constructor(body) {
7 - this.body = body;
8 - }
9 -
10 - async login() {
11 - const client = this.body;
12 - try {
13 -
14 - const {id, password} = await UserStorage.getUserInfo(client.id);
15 - // console.log(id, password);
16 -
17 - if (id) {
18 - if (id === client.id && password === client.password) {
19 - return { success: true};
20 - }
21 - return { success : false, msg: "비밀번호가 틀렸습니다."};
22 - }
23 - return {success: false, msg: "존재하지 않는 아이디입니다."};
24 - } catch (err) {
25 - return {success: false, msg: err};
26 - }
27 - }
28 -
29 - async register() {
30 - const client = this.body;
31 - try {
32 - const response = await UserStorage.save(client);
33 - // console.log(response);
34 - return response;
35 - } catch (err) {
36 -
37 - return {success: false, msg : err};
38 - }
39 - }
40 -}
41 -
42 -module.exports = User;
...\ No newline at end of file ...\ No newline at end of file
1 -'use strict';
2 -//for DB CRUD
3 -const db = require("../config/db");
4 -
5 -
6 -class UserStorage {
7 - // static getUsers(isAll, ...fields) {
8 - // }
9 -
10 - static getUserInfo(id) {
11 - return new Promise((resolve, reject) => {
12 - const query = "SELECT * FROM users WHERE id = ?;";
13 - db.query(query, [id], (err, data) => {
14 - if (err) reject(`${err}`);
15 - // console.log(data[0]);
16 - resolve(data[0]);
17 - });
18 - });
19 - }
20 -
21 - static async save(userInfo) {
22 - return new Promise((resolve, reject) => {
23 - const query = "INSERT INTO users(id, name, password) VALUES(?, ?, ?);";
24 - db.query(
25 - query,
26 - [userInfo.id, userInfo.name, userInfo.password],
27 - (err, data) => {
28 - if (err) reject(`${err}`);
29 - // console.log(data[0]);
30 - resolve({ success: true});
31 - }
32 - );
33 - });
34 - }
35 -}
36 -
37 -module.exports = UserStorage;
...\ No newline at end of file ...\ No newline at end of file
1 -@import url(https://fonts.googleapis.com/css?family=Roboto:300);
2 -
3 -.login-page {
4 - width: 360px;
5 - padding: 12% 0 0;
6 - margin: auto;
7 -}
8 -.form {
9 - position: relative;
10 - z-index: 1;
11 - background: #FFFFFF;
12 - max-width: 360px;
13 - margin: 0 auto 100px;
14 - padding: 45px;
15 - text-align: center;
16 - box-shadow: 0 0 20px 0 rgba(0, 0, 0, 0.2), 0 5px 5px 0 rgba(0, 0, 0, 0.24);
17 -}
18 -.form input {
19 - font-family: "Roboto", sans-serif;
20 - outline: 0;
21 - background: #f2f2f2;
22 - width: 100%;
23 - border: 0;
24 - margin: 0 0 15px;
25 - padding: 15px;
26 - box-sizing: border-box;
27 - font-size: 14px;
28 -}
29 -.form #button {
30 - font-family: "Roboto", sans-serif;
31 - text-transform: uppercase;
32 - outline: 0;
33 - background: rebeccapurple;
34 - width: 89%;
35 - border: 0;
36 - margin: 0 auto;
37 - padding: 15px;
38 - color: #FFFFFF;
39 - font-size: 14px;
40 - -webkit-transition: all 0.3 ease;
41 - transition: all 0.3 ease;
42 - cursor: pointer;
43 -}
44 -.form #button:hover,.form #button:active,.form #button:focus {
45 - background: rebeccapurple;
46 -}
47 -.form .message {
48 - margin: 15px 0 0;
49 - color: #b3b3b3;
50 - font-size: 12px;
51 -}
52 -.form .message a {
53 - color: rebeccapurple;
54 - text-decoration: none;
55 -}
56 -.form .register-form {
57 - display: none;
58 -}
59 -.container {
60 - position: relative;
61 - z-index: 1;
62 - max-width: 300px;
63 - margin: 0 auto;
64 -}
65 -.container:before, .container:after {
66 - content: "";
67 - display: block;
68 - clear: both;
69 -}
70 -.container .info {
71 - margin: 50px auto;
72 - text-align: center;
73 -}
74 -.container .info h1 {
75 - margin: 0 0 15px;
76 - padding: 0;
77 - font-size: 36px;
78 - font-weight: 300;
79 - color: #1a1a1a;
80 -}
81 -.container .info span {
82 - color: #4d4d4d;
83 - font-size: 12px;
84 -}
85 -.container .info span a {
86 - color: #000000;
87 - text-decoration: none;
88 -}
89 -.container .info span .fa {
90 - color: #EF3B3A;
91 -}
92 -
93 -/* #id::placeholder #password::placeholder {
94 - color: black;
95 - font-style: italic;
96 - font-weight: bold;
97 -} */
98 -
99 -body {
100 - background: rebeccapurple; /* fallback for old browsers */
101 - /* background: rebeccapurple; */
102 - background: linear-gradient(90deg, rebeccapurple 0%, rebeccapurple 0%);
103 - font-family: "Roboto", sans-serif;
104 - -webkit-font-smoothing: antialiased;
105 - -moz-osx-font-smoothing: grayscale;
106 -}
107 -
108 -/* Copyright (c) 2022 by Aigars Silkalns (https://codepen.io/colorlib/pen/rxddKy) */
...\ No newline at end of file ...\ No newline at end of file
1 -@import url(https://fonts.googleapis.com/css?family=Roboto:300);
2 -
3 -.login-page {
4 - width: 360px;
5 - padding: 8% 0 0;
6 - margin: auto;
7 -}
8 -.form {
9 - position: relative;
10 - z-index: 1;
11 - background: #FFFFFF;
12 - max-width: 360px;
13 - margin: 0 auto 100px;
14 - padding: 45px;
15 - text-align: center;
16 - box-shadow: 0 0 20px 0 rgba(0, 0, 0, 0.2), 0 5px 5px 0 rgba(0, 0, 0, 0.24);
17 -}
18 -.form input {
19 - font-family: "Roboto", sans-serif;
20 - outline: 0;
21 - background: #f2f2f2;
22 - width: 100%;
23 - border: 0;
24 - margin: 0 0 15px;
25 - padding: 15px;
26 - box-sizing: border-box;
27 - font-size: 14px;
28 -}
29 -.form #button {
30 - font-family: "Roboto", sans-serif;
31 - text-transform: uppercase;
32 - outline: 0;
33 - background: rebeccapurple;
34 - width: 89%;
35 - border: 0;
36 - margin: 0 auto;
37 - padding: 15px;
38 - color: #FFFFFF;
39 - font-size: 14px;
40 - -webkit-transition: all 0.3 ease;
41 - transition: all 0.3 ease;
42 - cursor: pointer;
43 -}
44 -.form #button:hover,.form #button:active,.form #button:focus {
45 - background: rebeccapurple;
46 -}
47 -.form .message {
48 - margin: 15px 0 0;
49 - color: #b3b3b3;
50 - font-size: 12px;
51 -}
52 -.form .message a {
53 - color: rebeccapurple;
54 - text-decoration: none;
55 -}
56 -.form .register-form {
57 - display: none;
58 -}
59 -.container {
60 - position: relative;
61 - z-index: 1;
62 - max-width: 300px;
63 - margin: 0 auto;
64 -}
65 -.container:before, .container:after {
66 - content: "";
67 - display: block;
68 - clear: both;
69 -}
70 -.container .info {
71 - margin: 50px auto;
72 - text-align: center;
73 -}
74 -.container .info h1 {
75 - margin: 0 0 15px;
76 - padding: 0;
77 - font-size: 36px;
78 - font-weight: 300;
79 - color: #1a1a1a;
80 -}
81 -.container .info span {
82 - color: #4d4d4d;
83 - font-size: 12px;
84 -}
85 -.container .info span a {
86 - color: #000000;
87 - text-decoration: none;
88 -}
89 -.container .info span .fa {
90 - color: #EF3B3A;
91 -}
92 -
93 -/* #id::placeholder #password::placeholder {
94 - color: black;
95 - font-style: italic;
96 - font-weight: bold;
97 -} */
98 -
99 -body {
100 - background: rebeccapurple; /* fallback for old browsers */
101 - /* background: rebeccapurple; */
102 - background: linear-gradient(90deg, rebeccapurple 0%, rebeccapurple 0%);
103 - font-family: "Roboto", sans-serif;
104 - -webkit-font-smoothing: antialiased;
105 - -moz-osx-font-smoothing: grayscale;
106 -}
107 -
108 -/* Copyright (c) 2022 by Aigars Silkalns (https://codepen.io/colorlib/pen/rxddKy) */
...\ No newline at end of file ...\ No newline at end of file
1 -'use strict';
2 -
3 -const id = document.querySelector("#id"),
4 - password = document.querySelector("#password"),
5 - loginBtn = document.querySelector("#button");
6 -
7 -loginBtn.addEventListener("click", login);
8 -
9 -function login() {
10 - const req = {
11 - id : id.value,
12 - password : password.value,
13 - };
14 -
15 - fetch("/login", {
16 - method: "POST",
17 - headers: {
18 - "Content-Type": "application/json"
19 - },
20 - body: JSON.stringify(req),
21 - })
22 - .then((res) => res.json())
23 - .then((res) => {
24 - if (res.success) {
25 - //성공하면 이동
26 - location.href = "/";
27 - } else {
28 - alert(res.msg);
29 - }
30 - })
31 - .catch((err) => {
32 - console.error("로그인 중 에러 발생");
33 - });
34 -}
...\ No newline at end of file ...\ No newline at end of file
1 -'use strict';
2 -
3 -const id = document.querySelector("#id"),
4 - name = document.querySelector("#name"),
5 - password = document.querySelector("#password"),
6 - confirmPassword = document.querySelector("#confirm-password"),
7 - registerBtn = document.querySelector("#button");
8 -
9 -registerBtn.addEventListener("click", register);
10 -
11 -function register() {
12 - if(!id.value) {
13 - return alert("아이디를 입력해주세요.")
14 - }
15 -
16 - if(!name.value) {
17 - return alert("이름을 입력해주세요.")
18 - }
19 - if(!password.value) {
20 - return alert("비밀번호를 입력해주세요.")
21 - }
22 - if(!confirmPassword.value) {
23 - return alert("비밀번호를 확인해주세요.")
24 - }
25 - if (password.value !== confirmPassword.value) {
26 - return alert("비밀번호가 일치하지 않습니다.")
27 - }
28 -
29 - const req = {
30 - id : id.value,
31 - name : name.value,
32 - password : password.value,
33 - };
34 -
35 - fetch("/register", {
36 - method: "POST",
37 - headers: {
38 - "Content-Type": "application/json"
39 - },
40 - body: JSON.stringify(req),
41 - })
42 - .then((res) => res.json())
43 - .then((res) => {
44 - if (res.success) {
45 - //성공하면 이동
46 - location.href = "/login";
47 - } else {
48 - alert(res.msg);
49 - }
50 - })
51 - .catch((err) => {
52 - console.error("회원가입 중 에러 발생");
53 - });
54 -}
...\ No newline at end of file ...\ No newline at end of file
1 -"use strict";
2 -
3 -const User = require("../../models/User");
4 -
5 -const output = {
6 - hello: (req, res) => {
7 - res.render("home/index");
8 - },
9 -
10 - login: (req, res) => {
11 - res.render("home/login");
12 - },
13 -
14 - register: (req, res) => {
15 - res.render("home/register");
16 - }
17 -};
18 -
19 -const process = {
20 - login: async (req, res) => {
21 - const user = new User(req.body);
22 - const response = await user.login();
23 - return res.json(response);
24 - },
25 -
26 - register: async (req, res) => {
27 - const user = new User(req.body);
28 - const response = await user.register();
29 - return res.json(response);
30 - },
31 - // const id = req.body.id,
32 - // password = req.body.password;
33 - // const users = UserStorage.getUsers("id", "password");
34 - // // console.log(UserStorage.getUsers("id", "password","name"));
35 - // const response = {};
36 -
37 - // if (users.id.includes(id)) {
38 - // const idx = users.id.indexOf(id);
39 - // if (users.password[idx] === password) {
40 - // response.success = true;
41 - // return res.json(response);
42 - // }
43 - // }
44 -
45 - // response.success = false;
46 - // response.msg = "로그인에 실패하였습니다."
47 - // return res.json(response);
48 -};
49 -
50 -module.exports = {
51 - output,
52 - process,
53 -};
...\ No newline at end of file ...\ No newline at end of file
1 -"use strict";
2 -
3 -const express = require("express");
4 -const router = express.Router();
5 -
6 -const ctrl = require("./home.ctrl");
7 -
8 -router.get("/", ctrl.output.hello);
9 -router.get("/login", ctrl.output.login);
10 -router.get("/register", ctrl.output.register);
11 -
12 -router.post("/login", ctrl.process.login);
13 -router.post("/register", ctrl.process.register);
14 -
15 -module.exports = router;
...\ No newline at end of file ...\ No newline at end of file
1 -<!DOCTYPE html>
2 -<html lang="ko">
3 - <head>
4 - <meta charset="UTF-8" />
5 - <meta http-equiv="X-UA-Compatible" content="IE=edge" />
6 - <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7 - <title>Document</title>
8 - </head>
9 - <body>
10 - 여기는 루트입니다.
11 - </body>
12 -</html>
1 -<!DOCTYPE html>
2 -<html lang="ko">
3 - <head>
4 - <meta charset="UTF-8" />
5 - <meta http-equiv="X-UA-Compatible" content="IE=edge" />
6 - <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7 - <link rel="stylesheet" href="/css/home/login.css" />
8 - <script src="/js/home/login.js" defer></script>
9 - <title>Document</title>
10 - </head>
11 - <body>
12 - <div class="login-page">
13 - <div class="form">
14 - <!-- <form class="register-form">
15 - <input type="text" placeholder="name" />
16 - <input type="password" placeholder="password" />
17 - <input type="text" placeholder="email address" />
18 - <button>create</button>
19 - <p class="message">Already registered? <a href="#">Sign In</a></p>
20 - </form> -->
21 - <form class="login-form">
22 - <input id="id" type="text" placeholder="아이디" />
23 - <input id="password" type="password" placeholder="비밀번호" />
24 - <p id="button">LOGIN</p>
25 - <p class="message">
26 - 계정이 없으신가요? <a href="/register">회원가입</a>
27 - </p>
28 - </form>
29 - </div>
30 - </div>
31 - </body>
32 -</html>
33 -
34 -<!-- Copyright (c) 2022 by Aigars Silkalns (https://codepen.io/colorlib/pen/rxddKy) -->
1 -<!DOCTYPE html>
2 -<html lang="ko">
3 - <head>
4 - <meta charset="UTF-8" />
5 - <meta http-equiv="X-UA-Compatible" content="IE=edge" />
6 - <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7 - <link rel="stylesheet" href="/css/home/register.css" />
8 - <script src="/js/home/register.js" defer></script>
9 - <title>Document</title>
10 - </head>
11 - <body>
12 - <div class="login-page">
13 - <div class="form">
14 - <!-- <form class="register-form">
15 - <input type="text" placeholder="name" />
16 - <input type="password" placeholder="password" />
17 - <input type="text" placeholder="email address" />
18 - <button>create</button>
19 - <p class="message">Already registered? <a href="#">Sign In</a></p>
20 - </form> -->
21 - <form class="login-form">
22 - <input id="id" type="text" placeholder="아이디" />
23 - <input id="name" type="text" placeholder="이름" />
24 - <input id="password" type="password" placeholder="비밀번호" />
25 - <input
26 - id="confirm-password"
27 - type="password"
28 - placeholder="비밀번호 확인"
29 - />
30 - <p id="button">SIGN UP</p>
31 - <p class="message">계정이 있으신가요? <a href="/login">로그인</a></p>
32 - </form>
33 - </div>
34 - </div>
35 - </body>
36 -</html>
37 -
38 -<!-- Copyright (c) 2022 by Aigars Silkalns (https://codepen.io/colorlib/pen/rxddKy) -->
1 -{
2 - "lockfileVersion": 1
3 -}
1 -# Logs
2 -logs
3 -*.log
4 -npm-debug.log*
5 -yarn-debug.log*
6 -yarn-error.log*
7 -lerna-debug.log*
8 -.pnpm-debug.log*
9 -app/log/*
10 -# Diagnostic reports (https://nodejs.org/api/report.html)
11 -report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
12 -
13 -# Runtime data
14 -pids
15 -*.pid
16 -*.seed
17 -*.pid.lock
18 -
19 -# Directory for instrumented libs generated by jscoverage/JSCover
20 -lib-cov
21 -
22 -# Coverage directory used by tools like istanbul
23 -coverage
24 -*.lcov
25 -
26 -# nyc test coverage
27 -.nyc_output
28 -
29 -# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
30 -.grunt
31 -
32 -# Bower dependency directory (https://bower.io/)
33 -bower_components
34 -
35 -# node-waf configuration
36 -.lock-wscript
37 -
38 -# Compiled binary addons (https://nodejs.org/api/addons.html)
39 -build/Release
40 -
41 -# Dependency directories
42 -**node_modules/
43 -jspm_packages/
44 -
45 -# Snowpack dependency directory (https://snowpack.dev/)
46 -web_modules/
47 -
48 -# TypeScript cache
49 -*.tsbuildinfo
50 -
51 -# Optional npm cache directory
52 -.npm
53 -
54 -# Optional eslint cache
55 -.eslintcache
56 -
57 -# Microbundle cache
58 -.rpt2_cache/
59 -.rts2_cache_cjs/
60 -.rts2_cache_es/
61 -.rts2_cache_umd/
62 -
63 -# Optional REPL history
64 -.node_repl_history
65 -
66 -# Output of 'npm pack'
67 -*.tgz
68 -
69 -# Yarn Integrity file
70 -.yarn-integrity
71 -
72 -# dotenv environment variables file
73 -.env
74 -.env.test
75 -.env.production
76 -
77 -# parcel-bundler cache (https://parceljs.org/)
78 -.cache
79 -.parcel-cache
80 -
81 -# Next.js build output
82 -.next
83 -out
84 -
85 -# Nuxt.js build / generate output
86 -.nuxt
87 -dist
88 -
89 -# Gatsby files
90 -.cache/
91 -# Comment in the public line in if your project uses Gatsby and not Next.js
92 -# https://nextjs.org/blog/next-9-1#public-directory-support
93 -# public
94 -
95 -# vuepress build output
96 -.vuepress/dist
97 -
98 -# Serverless directories
99 -.serverless/
100 -
101 -# FuseBox cache
102 -.fusebox/
103 -
104 -# DynamoDB Local files
105 -.dynamodb/
106 -
107 -# TernJS port file
108 -.tern-port
109 -
110 -# Stores VSCode versions used for testing VSCode extensions
111 -.vscode-test
112 -
113 -# yarn v2
114 -.yarn/cache
115 -.yarn/unplugged
116 -.yarn/build-state.yml
117 -.yarn/install-state.gz
118 -<<<<<<< HEAD
119 -.pnp.*
120 -=======
121 -.pnp.*
122 -
123 -.package-lock.json
124 ->>>>>>> release_v0.2.0
1 -"use strict";
2 -//모듈
3 -const express = require("express");
4 -const bodyParser = require("body-parser");
5 -//환경변수 (운영체제간 gap 없애고자)
6 -const dotenv = require("dotenv");
7 -dotenv.config();
8 -<<<<<<< HEAD
9 -
10 -const compression = require("compression");
11 -const methodOverride = require("method-override");
12 -var cors = require("cors");
13 -const { logger } = require("./src/config/winston");
14 -//app이라는 express 객체 생성
15 -const app = express();
16 -//라우팅
17 -const home = require("./src/routes/home");
18 -
19 -const port = 3000;
20 -
21 -const jwtMiddleware = require("./src/config/jwtMiddleware");
22 -=======
23 -const compression = require("compression");
24 -const methodOverride = require("method-override");
25 -const path = require("path")
26 -const socketIO = require("socket.io")
27 -const moment = require("moment")
28 -const http = require("http");
29 -const app = express();
30 -const server = http.createServer(app);
31 -
32 -var cors = require("cors");
33 -const { logger } = require("./src/config/winston");
34 -//app이라는 express 객체 생성
35 -//라우팅
36 -const home = require("./src/routes/home");
37 -const port = 3000;
38 -const jwtMiddleware = require("./src/config/jwtMiddleware");
39 -const io = socketIO(server);
40 ->>>>>>> release_v0.2.0
41 -
42 -// 앱 세팅
43 -app.set("views", "./src/views");
44 -app.set("view engine", "ejs");
45 -app.use(express.static(`${__dirname}/src/public`));
46 -<<<<<<< HEAD
47 -app.use(bodyParser.json());
48 -//url통해 전달되는 데이터에 한글, 공백 등의 문자 오류 해결
49 -app.use(bodyParser.urlencoded({extended: true}));
50 -=======
51 -app.use(express.static(path.join(__dirname, "src")))
52 -
53 -app.use(bodyParser.json());
54 -//url통해 전달되는 데이터에 한글, 공백 등의 문자 오류 해결
55 -app.use(bodyParser.urlencoded({extended: true}));
56 -
57 ->>>>>>> release_v0.2.0
58 -app.use(compression()); // HTTP 요청을 압축 및 해제
59 -app.use(express.json());
60 -app.use(express.urlencoded({ extended: true }));
61 -app.use(methodOverride());
62 -app.use(cors());
63 -// app.use("/restaurants", require("../app/src/routes/home/restaurant.route"));
64 -<<<<<<< HEAD
65 -require("../app/src/routes/home/restaurant.route")(app);
66 -
67 -app.use("/", home); //미들웨어 등록해주는 method
68 -=======
69 -// require("../app/src/routes/home/restaurant.route")(app);
70 -
71 -app.use("/", home); //미들웨어 등록해주는 method
72 -
73 -io.on('connection', (socket) => {
74 - socket.on("chatting", (data)=>{
75 - const { name, msg } = data;
76 - io.emit("chatting", {
77 - name,
78 - msg,
79 - time : moment(new Date()).format("h:ss A")})
80 - })
81 -});
82 -
83 ->>>>>>> release_v0.2.0
84 -logger.info(`${process.env.NODE_ENV} - API Server Start At Port ${port}`);
85 -
86 -module.exports = app;
...\ No newline at end of file ...\ No newline at end of file
1 -"use strict";
2 -
3 -const app = require("../app");
4 -const PORT = process.env.PORT || 3000;
5 -
6 -app.listen(PORT, () => {
7 - console.log("서버 가동");
8 -});
This diff is collapsed. Click to expand it.
1 -{
2 - "name": "login",
3 - "version": "1.0.0",
4 - "main": "app.js",
5 - "bin": {
6 - "login": "www.js"
7 - },
8 - "dependencies": {
9 - "body-parser": "^1.20.0",
10 - "compression": "^1.7.4",
11 - "cors": "^2.8.5",
12 - "crypto": "^1.0.1",
13 - "dateformat": "^4.3.1",
14 - "dotenv": "^16.0.1",
15 - "ejs": "^3.1.8",
16 - "express": "^4.18.1",
17 - "jsonwebtoken": "^8.5.1",
18 - "method-override": "^3.0.0",
19 -<<<<<<< HEAD
20 -=======
21 - "moment": "^2.29.3",
22 ->>>>>>> release_v0.2.0
23 - "mysql": "^2.18.1",
24 - "mysql2": "^2.2.0",
25 - "regex-email": "^1.0.2",
26 - "request": "^2.88.2",
27 -<<<<<<< HEAD
28 -=======
29 - "socket.io": "^4.5.1",
30 ->>>>>>> release_v0.2.0
31 - "winston": "^3.2.1",
32 - "winston-daily-rotate-file": "^4.2.1"
33 - },
34 - "devDependencies": {},
35 - "scripts": {
36 - "start": "nodemon ./bin/www.js",
37 - "test": "echo \"Error: no test specified\" && exit 1",
38 - "dev": "NODE_ENV=development node index.js",
39 - "prod": "NODE_ENV=production node index.js"
40 - },
41 - "author": "Jeongmin Seo, Jumi Yang",
42 -<<<<<<< HEAD
43 - "license": "ISC",
44 -=======
45 - "license": "MIT",
46 ->>>>>>> release_v0.2.0
47 - "keywords": [],
48 - "description": "Node.js API Server"
49 -}
1 -// const mysql = require("mysql");
2 -const { logger } = require("./winston");
3 -const mysql2 = require("mysql2/promise");
4 -
5 -// const db = mysql.createConnection({
6 -// host: process.env.DB_HOST,
7 -// user: process.env.DB_USER,
8 -// password: process.env.DB_PASSWORD,
9 -// database: process.env.DB_DATABASE, //schema
10 -// });
11 -
12 -const pool = mysql2.createPool({
13 - host: process.env.DB_HOST,
14 - user: process.env.DB_USER,
15 - password: process.env.DB_PASSWORD,
16 - database: process.env.DB_DATABASE, //schema
17 - connectionLimit: 10000,
18 - multipleStatements: true,
19 -});
20 -
21 -// db.connect();
22 -
23 -module.exports = {
24 - pool: pool,
25 -};
26 -
27 -
...\ No newline at end of file ...\ No newline at end of file
1 -const jwt = require("jsonwebtoken");
2 -const secret_config = require("./db");
3 -const jwtMiddleware = function (req, res, next) {
4 - // read the token from header or url
5 - const token = req.headers["x-access-token"] || req.query.token;
6 - // token does not exist
7 - if (!token) {
8 - return res.status(403).json({
9 - isSuccess: false,
10 - code: 403,
11 - message: "로그인이 되어 있지 않습니다.",
12 - });
13 - }
14 -
15 - try {
16 - const verifiedToken = jwt.verify(token, secret_config.jwtsecret);
17 - req.verifiedToken = verifiedToken;
18 - next();
19 - } catch {
20 - res.status(403).json({
21 - isSuccess: false,
22 - code: 403,
23 - message: "검증 실패",
24 - });
25 - }
26 -};
27 -
28 -module.exports = jwtMiddleware;
1 -const { createLogger, format, transports } = require('winston');
2 -require('winston-daily-rotate-file');
3 -const fs = require('fs');
4 -
5 -const env = process.env.NODE_ENV || 'development';
6 -const logDir = 'log';
7 -
8 -// https://lovemewithoutall.github.io/it/winston-example/
9 -// Create the log directory if it does not exist
10 -if (!fs.existsSync(logDir)) {
11 - fs.mkdirSync(logDir)
12 -}
13 -
14 -const dailyRotateFileTransport = new transports.DailyRotateFile({
15 - level: 'debug',
16 - filename: `${logDir}/%DATE%-smart-push.log`,
17 - datePattern: 'YYYY-MM-DD',
18 - zippedArchive: true,
19 - maxSize: '20m',
20 - maxFiles: '14d'
21 -});
22 -
23 -const logger = createLogger({
24 - level: env === 'development' ? 'debug' : 'info',
25 - format: format.combine(
26 - format.timestamp({
27 - format: 'YYYY-MM-DD HH:mm:ss'
28 - }),
29 - format.json()
30 - ),
31 - transports: [
32 - new transports.Console({
33 - level: 'info',
34 - format: format.combine(
35 - format.colorize(),
36 - format.printf(
37 - info => `${info.timestamp} ${info.level}: ${info.message}`
38 - )
39 - )
40 - }),
41 - dailyRotateFileTransport
42 - ]
43 -});
44 -
45 -module.exports = {
46 - logger: logger
47 -};
...\ No newline at end of file ...\ No newline at end of file
1 -'use strict';
2 -//for DB manipulate
3 -const RestaurantStorage = require("./RestaurantStorage");
4 -
5 -const {pool} = require("../config/db");
6 -const { logger } = require("../config/winston");
7 -const jwt = require("jsonwebtoken");
8 -
9 -exports.readRestaurants = async function (req,res) {
10 - const {category} = req.query;
11 -
12 - if (category) {
13 - const validCategory = ["한식", "중식", "일식", "양식", "분식", "구이", "회/초밥", "기타",];
14 -
15 - if (!validCategory.includes(category)) {
16 - return res.send({
17 - isSuccess: false,
18 - code: 400,
19 - message: "유효한 카테고리가 아닙니다.",
20 - });
21 - }
22 - }
23 -
24 - try {
25 - const connection = await pool.getConnection(async (conn) => conn);
26 - try {
27 - //mysql접속 관련 부분 정의하는 함수
28 - //es6 비구조할당
29 - const [rows] = await RestaurantStorage.selectRestaurants(connection, category);
30 -
31 - return res.send({
32 - result: rows,
33 - isSuccess: true,
34 - code: 200, // 요청 성공시 200번대 코드를 뿌려주고, 실패시 400번대 코드
35 - message: "식당 목록 요청 성공",
36 - });
37 - } catch (err) {
38 - logger.error(`readRestaurants Query error\n: ${JSON.stringify(err)}`);
39 - return false;
40 - } finally {
41 - connection.release();
42 - }
43 - } catch (err) {
44 - logger.error(`readRestaurants DB Connection error\n: ${JSON.stringify(err)}`);
45 - return false;
46 - }
47 -}
...\ No newline at end of file ...\ No newline at end of file
1 -'use strict';
2 -//for DB CRUD
3 -// const db = require("../config/db");
4 -const { pool } = require("../config/db");
5 -
6 -exports.selectRestaurants = async function (connection, category) {
7 -
8 - const selectAllRestaurantsQuery = `select title, address, category from restaurants where status='A';`;
9 - const selectCategorizedRestaurantsQuery = `select title, address, category from restaurants where status='A' and category=?;`;
10 -
11 - const Params = [category];
12 -
13 - const Query = category ? selectCategorizedRestaurantsQuery : selectAllRestaurantsQuery;
14 -
15 - const rows = await connection.query(Query, Params);
16 -
17 - return rows;
18 -
19 -}
...\ No newline at end of file ...\ No newline at end of file
1 -'use strict';
2 -//for DB manipulate
3 -const UserStorage = require("./UserStorage");
4 -const {pool} = require("../config/db");
5 -const { logger } = require("../config/winston");
6 -const jwt = require("jsonwebtoken");
7 -
8 -class User {
9 - constructor(body) {
10 - this.body = body;
11 - }
12 -
13 - async login() {
14 - const client = this.body;
15 -<<<<<<< HEAD
16 -
17 - try {
18 - try {
19 - const {id, password} = await UserStorage.getUserInfo(connection, client.id);
20 - // console.log(id, password);
21 -
22 - if (id) {
23 - if (id === client.id && password === client.password) {
24 - return { success: true};
25 - }
26 - return { success : false, msg: "비밀번호가 틀렸습니다."};
27 - }
28 - return {success: false, msg: "존재하지 않는 아이디입니다."};
29 - } catch (err) {
30 - return {success: false, msg: err};
31 - } finally {
32 - connection.release();
33 - }
34 - } catch (err) {
35 - logger.error(`login DB Connection error\n: ${JSON.stringify(err)}`);
36 - return false;
37 - }
38 - }
39 -
40 -=======
41 -
42 - try {
43 - const connection = await pool.getConnection(async (conn) => conn);
44 - try {
45 - const { id, password } = await UserStorage.getUserInfo(
46 - connection,
47 - client.id
48 - );
49 - if (id) {
50 - if (id === client.id && password === client.password) {
51 - return { success: true };
52 - }
53 - return { success: false, msg: "비밀번호가 틀렸습니다." };
54 - }
55 - return { success: false, msg: "존재하지 않는 아이디입니다." };
56 - } catch (err) {
57 - return { success: false, msg: err };
58 - } finally {
59 - connection.release();
60 - }
61 - } catch (err) {
62 - logger.error(`login DB Connection error\n: ${JSON.stringify(err)}`);
63 - return false;
64 - }
65 - }
66 -
67 ->>>>>>> release_v0.2.0
68 - async register() {
69 - const client = this.body;
70 - try {
71 - const connection = await pool.getConnection(async (conn) => conn);
72 - // console.log(client);
73 - try {
74 - const response = await UserStorage.save(connection, client);
75 - // console.log("테스트2 : ", response);
76 - return response;
77 - } catch (err) {
78 - console.log(err);
79 - return {success: false, msg : err};
80 - } finally {
81 - connection.release();
82 - }
83 - } catch (err) {
84 - logger.error(`usersaving DB Connection error\n: ${JSON.stringify(err)}`);
85 - return false;
86 - }
87 - }
88 -}
89 -module.exports = User;
1 -'use strict';
2 -
3 -const { pool } = require("../config/db");
4 -
5 - //for DB CRUD
6 -
7 -
8 -class UserStorage {
9 - constructor(body) {
10 - this.body = body;
11 - // this.connection = await pool.getConnection(async (conn) => conn);
12 - }
13 -
14 - // static getUsers(isAll, ...fields) {}
15 - static async getUserInfo(connection, id) {
16 -<<<<<<< HEAD
17 - return new Promise((resolve, reject) => {
18 - const query = "SELECT * FROM users WHERE id = ?;";
19 - connection.query(query, [id], (err, data) => {
20 - if (err) reject(`${err}`);
21 - // console.log(data[0]);
22 - resolve(data[0]);
23 - pool.releaseConnection(conn);
24 - });
25 - });
26 - }
27 -=======
28 - const query = `SELECT * FROM users WHERE id = '${id}';`;
29 - console.log(query);
30 - let [row] = await connection.query(query);
31 - console.log(row[0]);
32 - return row[0];
33 - // , [id], (err, data) => {
34 - // console.log("44444444");
35 - // if (err) reject(`${err}`);
36 - // resolve(data[0]);
37 - // pool.releaseConnection(conn);
38 - // });
39 - }
40 ->>>>>>> release_v0.2.0
41 -
42 - static async save (connection, userInfo) {
43 - const query = "INSERT INTO users(id, name, password) VALUES(?, ?, ?);";
44 - try {
45 - const [rows] = await connection.query({
46 - sql: query,
47 - timeout: 30000,
48 - values: [userInfo.id, userInfo.name, userInfo.password]
49 - });
50 - // console.log(fields);
51 - if (rows.affectedRows) {
52 - return {success: true};
53 - } else {
54 - return {success: false};
55 - }
56 - } catch (error) {
57 - console.log(error);
58 - }
59 - }
60 -
61 -}
62 -// static getUserInfo(id) {
63 -// return new Promise((resolve, reject) => {
64 -// const query = "SELECT * FROM users WHERE id = ?;";
65 -// pool.query(query, [id], (err, data) => {
66 -// if (err) reject(`${err}`);
67 -// // console.log(data[0]);
68 -// resolve(data[0]);
69 -// });
70 -// });
71 -// }
72 -
73 -module.exports = UserStorage;
...\ No newline at end of file ...\ No newline at end of file
1 -* {
2 - margin: 0;
3 - padding: 0;
4 -}
5 -
6 -html, body {
7 - height : 100%;
8 -}
9 -
10 -.wrapper {
11 - height : 100%;
12 - width: 100%;
13 - display: flex;
14 - flex-direction: column;
15 - overflow: hidden;
16 -}
17 -
18 -.user-container {
19 - background: rebeccapurple;
20 - flex: 1;
21 - display: flex;
22 - justify-content: flex-start;
23 - align-items: center;
24 - padding: 0.5rem;
25 -}
26 -
27 -.user-container .nickname {
28 - font-size : 14px;
29 - margin-right : 1.5rem;
30 - margin-left : 1rem;
31 - color:#fff;
32 -}
33 -
34 -.user-container input {
35 - border-radius: 3px;
36 - border: none;
37 - height: 80%;
38 -}
39 -
40 -.display-container {
41 - background: #D2D2FF;
42 - flex : 12;
43 - overflow-y:scroll;
44 -}
45 -
46 -.input-container {
47 - flex:1;
48 - display:flex;
49 - justify-content: stretch;
50 - align-items: stretch;
51 -}
52 -
53 -.input-container span {
54 - display: flex;
55 - justify-content: flex-start;
56 - align-items:center;
57 - padding: 0.3rem;
58 - width: 100%;
59 -}
60 -
61 -.chatting-input {
62 - font-size:12px;
63 - height:100%;
64 - flex:8;
65 - border:none;
66 -}
67 -
68 -.send-button {
69 - flex:1;
70 - background: rebeccapurple;
71 - color:#fff;
72 - border:none;
73 - height:100%;
74 - border-radius:3px;
75 -}
76 -
77 -.chatting-list li {
78 - width:50%;
79 - padding:0.3rem;
80 - display:flex;
81 - justify-content: flex-start;
82 - align-items:flex-end;
83 - margin-top:0.5rem;
84 -}
85 -
86 -.profile {
87 - display: flex;
88 - flex-direction: column;
89 - align-items: center;
90 - justify-content: center;
91 - flex: 1;
92 -}
93 -
94 -.profile .user {
95 - font-size: 10px;
96 - margin-bottom: 0.3rem;
97 -}
98 -
99 -.profile .image {
100 - border-radius: 50%;
101 - object-fit: cover;
102 - width: 50px;
103 - height: 50px;
104 -}
105 -
106 -.message {
107 - border-radius: 5px;
108 - padding: 0.5rem;
109 - font-size: 12px;
110 - margin: 0 5px;
111 - flex: 10;
112 -}
113 -
114 -.time {
115 - font-size: 10px;
116 - margin: 0 5px;
117 -}
118 -
119 -.sent {
120 - flex-direction: row-reverse;
121 - float: right;
122 -}
123 -
124 -.sent .message {
125 - background: #9986EE;
126 - color: #fff;
127 -}
128 -
129 -.received .message {
130 - background: #fff;
131 -}
...\ No newline at end of file ...\ No newline at end of file
1 -@font-face {
2 - font-family: 'Noto Sans KR', sans-serif;
3 - src: url('https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@700&display=swap');
4 - font-weight: normal;
5 - font-style: normal;
6 - }
7 -
8 - * {
9 - padding: 0;
10 - margin: 0;
11 - box-sizing: border-box;
12 - }
13 -
14 - html {
15 - font-size: 10px;
16 - font-family: 'Noto Sans KR', sans-serif;
17 - }
18 -
19 - nav {
20 - /* background-color: #e69a06; */
21 - }
22 -
23 - .nav-container {
24 - padding: 1rem 0;
25 - display: flex;
26 - flex-direction: row;
27 - justify-content: space-between;
28 - align-items: center;
29 - }
30 -
31 - .nav-title {
32 - font-size: 2.5rem;
33 - color :rebeccapurple;
34 - }
35 -
36 - .nav-contact {
37 - font-size: 1.5rem;
38 - border: 0;
39 - background: none;
40 - cursor: pointer;
41 - font-family: inherit;
42 - color :lightslategray;
43 -<<<<<<< HEAD
44 - margin-right: 30px;
45 -=======
46 - margin-right: 0px;
47 ->>>>>>> release_v0.2.0
48 - }
49 -
50 - .category-title {
51 - font-size: 2rem;
52 - padding : 0 30%;
53 - }
54 -
55 - .category-list {
56 - padding: 15px 1rem;
57 - }
58 -
59 - .category-item {
60 - width: 24%;
61 - height: 5rem;
62 - background: none;
63 - border: none;
64 - font-family: inherit;
65 - font-size: 1.6rem;
66 - }
67 -
68 - .category-item:hover {
69 - color: #e69a06;
70 - cursor: pointer;
71 - }
72 -
73 - .inner {
74 - padding: 0 1.5rem;
75 - }
76 -
77 - @media all and (min-width: 1024px) {
78 - .inner {
79 - max-width: 1024px;
80 - margin: 0 auto;
81 - }
82 - }
83 -
84 - /* 카카오맵 CSS */
85 -
86 - body {
87 - height: 100vh;
88 - }
89 -
90 - nav {
91 - height: 59px;
92 - }
93 -
94 - main {
95 - padding-top: 1.5rem;
96 - height: calc(100% - 59px);
97 - display: flex;
98 - flex-direction: column;
99 - }
100 -
101 - #map {
102 - flex-grow: 1;
103 - width: 100%;
104 - height: 100%;
105 - }
...\ No newline at end of file ...\ No newline at end of file
1 -@import url(https://fonts.googleapis.com/css?family=Roboto:300);
2 -
3 -.login-page {
4 - width: 360px;
5 - padding: 12% 0 0;
6 - margin: auto;
7 -}
8 -.form {
9 - position: relative;
10 - z-index: 1;
11 - background: #FFFFFF;
12 - max-width: 360px;
13 - margin: 0 auto 100px;
14 - padding: 45px;
15 - text-align: center;
16 - box-shadow: 0 0 20px 0 rgba(0, 0, 0, 0.2), 0 5px 5px 0 rgba(0, 0, 0, 0.24);
17 -}
18 -.form input {
19 - font-family: "Roboto", sans-serif;
20 - outline: 0;
21 - background: #f2f2f2;
22 - width: 100%;
23 - border: 0;
24 - margin: 0 0 15px;
25 - padding: 15px;
26 - box-sizing: border-box;
27 - font-size: 14px;
28 -}
29 -.form #button {
30 - font-family: "Roboto", sans-serif;
31 - text-transform: uppercase;
32 - outline: 0;
33 - background: rebeccapurple;
34 - width: 89%;
35 - border: 0;
36 - margin: 0 auto;
37 - padding: 15px;
38 - color: #FFFFFF;
39 - font-size: 14px;
40 - -webkit-transition: all 0.3 ease;
41 - transition: all 0.3 ease;
42 - cursor: pointer;
43 -}
44 -.form #button:hover,.form #button:active,.form #button:focus {
45 - background: rebeccapurple;
46 -}
47 -.form .message {
48 - margin: 15px 0 0;
49 - color: #b3b3b3;
50 - font-size: 12px;
51 -}
52 -.form .message a {
53 - color: rebeccapurple;
54 - text-decoration: none;
55 -}
56 -.form .register-form {
57 - display: none;
58 -}
59 -.container {
60 - position: relative;
61 - z-index: 1;
62 - max-width: 300px;
63 - margin: 0 auto;
64 -}
65 -.container:before, .container:after {
66 - content: "";
67 - display: block;
68 - clear: both;
69 -}
70 -.container .info {
71 - margin: 50px auto;
72 - text-align: center;
73 -}
74 -.container .info h1 {
75 - margin: 0 0 15px;
76 - padding: 0;
77 - font-size: 36px;
78 - font-weight: 300;
79 - color: #1a1a1a;
80 -}
81 -.container .info span {
82 - color: #4d4d4d;
83 - font-size: 12px;
84 -}
85 -.container .info span a {
86 - color: #000000;
87 - text-decoration: none;
88 -}
89 -.container .info span .fa {
90 - color: #EF3B3A;
91 -}
92 -
93 -/* #id::placeholder #password::placeholder {
94 - color: black;
95 - font-style: italic;
96 - font-weight: bold;
97 -} */
98 -
99 -body {
100 - background: rebeccapurple; /* fallback for old browsers */
101 - /* background: rebeccapurple; */
102 - background: linear-gradient(90deg, rebeccapurple 0%, rebeccapurple 0%);
103 - font-family: "Roboto", sans-serif;
104 - -webkit-font-smoothing: antialiased;
105 - -moz-osx-font-smoothing: grayscale;
106 -}
107 -
108 -/* Copyright (c) 2022 by Aigars Silkalns (https://codepen.io/colorlib/pen/rxddKy) */
...\ No newline at end of file ...\ No newline at end of file
1 -/*인포윈도우 설정*/
2 -.infowindow {
3 - width : 25rem;
4 - border : 1px solid black;
5 - border-radius: 5px;
6 - background-color : white;
7 -}
8 -
9 -.infowindow-title {
10 -<<<<<<< HEAD
11 - font-size: 3rem;
12 -}
13 -
14 -.infowindow-address {
15 - font-size: 1.6rem;
16 -}
17 -
18 -.infowindow-btn {
19 - font-size: 1.6rem;
20 -=======
21 - font-size: 15px;
22 - color: rebeccapurple;
23 - font-weight: 600;
24 -}
25 -
26 -.infowindow-address {
27 - font-size: 8px;
28 -}
29 -
30 -.infowindow-btn {
31 - font-size: 8px;
32 ->>>>>>> release_v0.2.0
33 -}
...\ No newline at end of file ...\ No newline at end of file
1 -@import url(https://fonts.googleapis.com/css?family=Roboto:300);
2 -
3 -.login-page {
4 - width: 360px;
5 - padding: 8% 0 0;
6 - margin: auto;
7 -}
8 -.form {
9 - position: relative;
10 - z-index: 1;
11 - background: #FFFFFF;
12 - max-width: 360px;
13 - margin: 0 auto 100px;
14 - padding: 45px;
15 - text-align: center;
16 - box-shadow: 0 0 20px 0 rgba(0, 0, 0, 0.2), 0 5px 5px 0 rgba(0, 0, 0, 0.24);
17 -}
18 -.form input {
19 - font-family: "Roboto", sans-serif;
20 - outline: 0;
21 - background: #f2f2f2;
22 - width: 100%;
23 - border: 0;
24 - margin: 0 0 15px;
25 - padding: 15px;
26 - box-sizing: border-box;
27 - font-size: 14px;
28 -}
29 -.form #button {
30 - font-family: "Roboto", sans-serif;
31 - text-transform: uppercase;
32 - outline: 0;
33 - background: rebeccapurple;
34 - width: 89%;
35 - border: 0;
36 - margin: 0 auto;
37 - padding: 15px;
38 - color: #FFFFFF;
39 - font-size: 14px;
40 - -webkit-transition: all 0.3 ease;
41 - transition: all 0.3 ease;
42 - cursor: pointer;
43 -}
44 -.form #button:hover,.form #button:active,.form #button:focus {
45 - background: rebeccapurple;
46 -}
47 -.form .message {
48 - margin: 15px 0 0;
49 - color: #b3b3b3;
50 - font-size: 12px;
51 -}
52 -.form .message a {
53 - color: rebeccapurple;
54 - text-decoration: none;
55 -}
56 -.form .register-form {
57 - display: none;
58 -}
59 -.container {
60 - position: relative;
61 - z-index: 1;
62 - max-width: 300px;
63 - margin: 0 auto;
64 -}
65 -.container:before, .container:after {
66 - content: "";
67 - display: block;
68 - clear: both;
69 -}
70 -.container .info {
71 - margin: 50px auto;
72 - text-align: center;
73 -}
74 -.container .info h1 {
75 - margin: 0 0 15px;
76 - padding: 0;
77 - font-size: 36px;
78 - font-weight: 300;
79 - color: #1a1a1a;
80 -}
81 -.container .info span {
82 - color: #4d4d4d;
83 - font-size: 12px;
84 -}
85 -.container .info span a {
86 - color: #000000;
87 - text-decoration: none;
88 -}
89 -.container .info span .fa {
90 - color: #EF3B3A;
91 -}
92 -
93 -/* #id::placeholder #password::placeholder {
94 - color: black;
95 - font-style: italic;
96 - font-weight: bold;
97 -} */
98 -
99 -body {
100 - background: rebeccapurple; /* fallback for old browsers */
101 - /* background: rebeccapurple; */
102 - background: linear-gradient(90deg, rebeccapurple 0%, rebeccapurple 0%);
103 - font-family: "Roboto", sans-serif;
104 - -webkit-font-smoothing: antialiased;
105 - -moz-osx-font-smoothing: grayscale;
106 -}
107 -
108 -/* Copyright (c) 2022 by Aigars Silkalns (https://codepen.io/colorlib/pen/rxddKy) */
...\ No newline at end of file ...\ No newline at end of file
1 -/*********************************************************************************
2 - * 1. 지도 생성 및 확대 축소 컨트롤러
3 - */
4 -
5 - var container = document.getElementById('map'); //지도를 담을 영역의 DOM 레퍼런스
6 - var options = { //지도를 생성할 때 필요한 기본 옵션
7 -<<<<<<< HEAD
8 - center: new kakao.maps.LatLng(37.54, 126.96), //지도의 중심좌표.
9 - level: 7 //지도의 레벨(확대, 축소 정도)
10 -=======
11 - center: new kakao.maps.LatLng(37.248, 127.08), //지도의 중심좌표.
12 - level: 4 //지도의 레벨(확대, 축소 정도)
13 ->>>>>>> release_v0.2.0
14 - };
15 -
16 - var map = new kakao.maps.Map(container, options); //지도 생성 및 객체 리턴
17 -
18 - // 확대 축소 컨트롤러
19 - var zoomControl = new kakao.maps.ZoomControl();
20 - map.addControl(zoomControl, kakao.maps.ControlPosition.RIGHT);
21 -
22 - /******************************************************************************
23 - * 2. 데이터 준비하기(제목, 주소, 카테고리)
24 - */
25 -
26 -<<<<<<< HEAD
27 -const dataSet = [
28 - {
29 - title: "희락돈까스",
30 - address: "서울 영등포구 양산로 210",
31 - category: "양식",
32 - },
33 - {
34 - title: "즉석우동짜장",
35 - address: "서울 영등포구 대방천로 260",
36 - category: "한식",
37 - },
38 - {
39 - title: "아카사카",
40 - address: "서울 서초구 서초대로74길 23",
41 - category: "일식",
42 - }
43 -];
44 -
45 -// async function getDataSet(category) {
46 -// let qs = category;
47 -// if(!qs) {
48 -// qs = "";
49 -// }
50 -
51 -// const dataSet = await axios({
52 -// method: "get", // http method
53 -// url: `http://localhost:3000/restaurants?category=${qs}`,
54 -// headers: {},
55 -// data: {},
56 -// });
57 -
58 -// return dataSet.data.result;
59 -// }
60 -
61 -// getDataSet();
62 -=======
63 -// const dataSet = [
64 -// {
65 -// title: "희락돈까스",
66 -// address: "서울 영등포구 양산로 210",
67 -// category: "양식",
68 -// },
69 -// {
70 -// title: "즉석우동짜장",
71 -// address: "서울 영등포구 대방천로 260",
72 -// category: "한식",
73 -// },
74 -// {
75 -// title: "아카사카",
76 -// address: "서울 서초구 서초대로74길 23",
77 -// category: "일식",
78 -// }
79 -// ];
80 -
81 - async function getDataSet(category) {
82 - let qs = category;
83 - if(!qs) {
84 - qs = "";
85 - }
86 -
87 - const dataSet = await axios({
88 - method: "get", // http method
89 - url: `http://localhost:3000/restaurants?category=${qs}`,
90 - headers: {},
91 - data: {},
92 - });
93 - // console.log(dataSet);
94 -
95 - return dataSet.data.result;
96 -}
97 -
98 -// }
99 -
100 - getDataSet();
101 ->>>>>>> release_v0.2.0
102 -
103 - /******************************************************************************
104 - * 3. 여러개 마커찍기
105 - */
106 -
107 - // 주소-좌표 변환 객체를 생성합니다
108 - var geocoder = new kakao.maps.services.Geocoder();
109 -
110 - function getCoordsByAddress(address) {
111 - return new Promise((resolve, reject) => {
112 - // 주소로 좌표를 검색합니다
113 - geocoder.addressSearch(address, function (result, status) {
114 - // 정상적으로 검색이 완료됐으면
115 - if (status === kakao.maps.services.Status.OK) {
116 - var coords = new kakao.maps.LatLng(result[0].y, result[0].x);
117 - return resolve(coords);
118 - }
119 - reject(new Error("getCoordsByAddress Error: not valid Address"));
120 - });
121 - });
122 - }
123 -
124 -<<<<<<< HEAD
125 - setMap(dataSet);
126 -=======
127 -// setMap(dataSet);
128 ->>>>>>> release_v0.2.0
129 -
130 - /*
131 - *************************************************************
132 - 4. 마커에 인포윈도우 붙이기
133 - */
134 -
135 - function getContent(data) {
136 - // 인포윈도우 가공하기
137 - return `
138 - <div class="infowindow">
139 - <div class="infowindow-body">
140 - <h5 class="infowindow-title">${data.title}</h5>
141 - <p class="infowindow-address">${data.address}</p>
142 - <a href='/chat' class="infowindow-btn" target="_blank">채팅방이동</a>
143 - </div>
144 - </div>
145 - `;
146 - }
147 -
148 - async function setMap(dataSet) {
149 - for (var i = 0; i < dataSet.length; i++) {
150 - // 마커를 생성합니다
151 - let coords = await getCoordsByAddress(dataSet[i].address);
152 - var marker = new kakao.maps.Marker({
153 - map: map, // 마커를 표시할 지도
154 - position: coords,
155 - });
156 -
157 - markerArray.push(marker);
158 -
159 - // 마커에 표시할 인포윈도우를 생성합니다
160 - var infowindow = new kakao.maps.InfoWindow({
161 - content: getContent(dataSet[i]),// 인포윈도우에 표시할 내용
162 - });
163 -
164 - infowindowArray.push(infowindow);
165 -
166 - // 마커에 mouseover 이벤트와 mouseout 이벤트를 등록합니다
167 - // 이벤트 리스너로는 클로저를 만들어 등록합니다
168 - // for문에서 클로저를 만들어 주지 않으면 마지막 마커에만 이벤트가 등록됩니다
169 - kakao.maps.event.addListener(marker, 'click', makeOverListener(map, marker, infowindow, coords));
170 - kakao.maps.event.addListener(map, 'click', makeOutListener(infowindow));
171 - }
172 - }
173 -
174 - // 인포윈도우를 표시하는 클로저를 만드는 함수입니다
175 - function makeOverListener(map, marker, infowindow, coords) {
176 - return function() {
177 - // 1. 클릭시 다른 인포윈도우 닫기
178 - closeInfoWindow();
179 - infowindow.open(map, marker);
180 - // 2. 클릭한 곳으로 지도 중심 옮기기
181 - map.panTo(coords);
182 - };
183 - }
184 -
185 - let infowindowArray = [];
186 - function closeInfoWindow() {
187 - for (let infowindow of infowindowArray) {
188 - infowindow.close();
189 - }
190 - }
191 -
192 - // 인포윈도우를 닫는 클로저를 만드는 함수입니다
193 - function makeOutListener(infowindow) {
194 - return function() {
195 - infowindow.close();
196 - };
197 - }
198 -
199 - /*
200 - **********************************************
201 - 5. 카테고리 분류
202 - */
203 -
204 - // 카테고리
205 - const categoryMap = {
206 - korea: "한식",
207 - china: "중식",
208 - japan: "일식",
209 - america: "양식",
210 - wheat: "분식",
211 - meat: "구이",
212 - sushi: "회/초밥",
213 - etc: "기타",
214 - };
215 -
216 - const categoryList = document.querySelector(".category-list");
217 - categoryList.addEventListener("click", categoryHandler);
218 -
219 - async function categoryHandler(event) {
220 - const categoryId = event.target.id;
221 - const category = categoryMap[categoryId];
222 -
223 -<<<<<<< HEAD
224 -=======
225 -
226 ->>>>>>> release_v0.2.0
227 - try {
228 - // 데이터 분류
229 - let categorizedDataSet = await getDataSet(category);
230 -
231 - // 기존 마커 삭제
232 - closeMarker();
233 -
234 - // 기존 인포윈도우 닫기
235 - closeInfoWindow();
236 -
237 - setMap(categorizedDataSet);
238 -
239 - } catch (error) {
240 - console.error(error);
241 - }
242 - }
243 -
244 - let markerArray = [];
245 - function closeMarker() {
246 - for (marker of markerArray) {
247 - marker.setMap(null);
248 - }
249 - }
250 -
251 -<<<<<<< HEAD
252 - setMap(dataSet);
253 -
254 -// async function setting() {
255 -// try {
256 -// const dataSet = await getDataSet();
257 -// setMap(dataSet);
258 -
259 -// } catch (error) {
260 -// console.error(error);
261 -// }
262 -// }
263 -
264 -// setting();
265 -=======
266 - async function setting() {
267 - try {
268 - const dataSet = await getDataSet();
269 - setMap(dataSet);
270 - } catch (error) {
271 - console.error(error);
272 - }
273 - }
274 -
275 - setting();
276 ->>>>>>> release_v0.2.0
1 -"use strict";
2 -
3 -const socketIO = require("socket.io");
4 -const http = require("http");
5 -const app = express();
6 -const server = http.createServer(app);
7 -const io = socketIO(server);
8 -const socket = io();
9 -//.connect("http://localhost:3000/chat", {transports:['websocket']});
10 -
11 -const nickname = document.querySelector("#nickname")
12 -const chatlist = document.querySelector(".chatting-list")
13 -const chatInput = document.querySelector(".chatting-input")
14 -const sendButton = document.querySelector(".send-button")
15 -const displayContainer = document.querySelector(".display-container")
16 -
17 -chatInput.addEventListener("keypress", (event)=> {
18 - if(event.keyCode === 13) {
19 - send()
20 - }
21 -})
22 -
23 -function send() {
24 - const param = {
25 - name: nickname.value,
26 - msg: chatInput.value
27 - }
28 - socket.emit("chatting", param)
29 -}
30 -
31 -sendButton.addEventListener("click", send)
32 -
33 -socket.on("chatting", (data)=>{
34 - console.log(data)
35 - const {name, msg, time} = data;
36 - const item = new LiModel(name, msg, time);
37 - item.makeLi()
38 - displayContainer.scrollTo(0, displayContainer.scrollHeight)
39 -})
40 -
41 -//console.log(socket);
42 -
43 -function LiModel(name, msg, time) {
44 - this.name = name;
45 - this.msg = msg;
46 - this.time = time;
47 -
48 - this.makeLi = ()=>{
49 - const li = document.createElement("li");
50 - li.classList.add(nickname.value === this.name ? "sent":"received")
51 - const dom = `<span class="profile">
52 - <span class="user">${this.name}</span>
53 - <img class="image" src="https://placeimg.com/50/50/any" alt="any">
54 - </span>
55 - <span class="message">${this.msg}</span>
56 - <span class="time">${this.time}</span>`;
57 -
58 - li.innerHTML = dom;
59 - chatlist.appendChild(li)
60 - }
61 -}
...\ No newline at end of file ...\ No newline at end of file
1 -'use strict';
2 -
3 -const id = document.querySelector("#id"),
4 - password = document.querySelector("#password"),
5 - loginBtn = document.querySelector("#button");
6 -
7 -loginBtn.addEventListener("click", login);
8 -
9 -function login() {
10 - const req = {
11 - id : id.value,
12 - password : password.value,
13 - };
14 -
15 -<<<<<<< HEAD
16 -=======
17 - // console.log("login value : ", id.value);
18 ->>>>>>> release_v0.2.0
19 - fetch("/login", {
20 - method: "POST",
21 - headers: {
22 - "Content-Type": "application/json"
23 - },
24 - body: JSON.stringify(req),
25 - })
26 - .then((res) => res.json())
27 - .then((res) => {
28 - if (res.success) {
29 - //성공하면 이동
30 - location.href = "/";
31 - } else {
32 - alert(res.msg);
33 - }
34 - })
35 - .catch((err) => {
36 - console.error("로그인 중 에러 발생");
37 - });
38 -}
...\ No newline at end of file ...\ No newline at end of file
1 -'use strict';
2 -
3 -const id = document.querySelector("#id"),
4 - name = document.querySelector("#name"),
5 - password = document.querySelector("#password"),
6 - confirmPassword = document.querySelector("#confirm-password"),
7 - registerBtn = document.querySelector("#button");
8 -
9 -registerBtn.addEventListener("click", register);
10 -
11 -async function register() {
12 - if(!id.value) {
13 - return alert("아이디를 입력해주세요.")
14 - }
15 -<<<<<<< HEAD
16 -
17 -=======
18 ->>>>>>> release_v0.2.0
19 - if(!name.value) {
20 - return alert("이름을 입력해주세요.")
21 - }
22 - if(!password.value) {
23 - return alert("비밀번호를 입력해주세요.")
24 - }
25 - if(!confirmPassword.value) {
26 - return alert("비밀번호를 확인해주세요.")
27 - }
28 - if (password.value !== confirmPassword.value) {
29 - return alert("비밀번호가 일치하지 않습니다.")
30 - }
31 -<<<<<<< HEAD
32 -
33 -=======
34 -
35 ->>>>>>> release_v0.2.0
36 - const req = {
37 - id: id.value,
38 - name: name.value,
39 - password: password.value,
40 - };
41 -
42 -<<<<<<< HEAD
43 - console.log("id : ", req.id);
44 - try {
45 - const response = await fetch("/register", {
46 - method: "POST",
47 - headers: {
48 - "Content-Type": "application/json"
49 - },
50 - body: JSON.stringify(req),
51 - });
52 - console.log("테스트 : ", response);
53 - } catch(e) {
54 - console.log(e);
55 - }
56 -=======
57 - fetch("/register", {
58 - method: "POST",
59 - headers: {
60 - "Content-Type": "application/json",
61 - },
62 - body: JSON.stringify(req),
63 - })
64 - .then((res) => res.json())
65 - .then((res) => {
66 - if (res.success) {
67 - location.href = "/login";
68 - } else {
69 - if (res.err) return alert(res.err);
70 - alert(res.msg);
71 - }
72 - })
73 - .catch((err) => {
74 - console.error("회원가입 중 에러 발생");
75 - });
76 -
77 - // try {
78 - // const response = await fetch("/register", {
79 - // method: "POST",
80 - // headers: {
81 - // "Content-Type": "application/json"
82 - // },
83 - // body: JSON.stringify(req),
84 - // });
85 - // console.log("테스트 : ", response);
86 - // } catch(e) {
87 - // console.log(e);
88 - // }
89 ->>>>>>> release_v0.2.0
90 -
91 -}
...\ No newline at end of file ...\ No newline at end of file
1 -"use strict";
2 -
3 -const User = require("../../models/User");
4 -// const Restaurant = require("../../models/Restaurant");
5 -
6 -const output = {
7 - hello: (req, res) => {
8 - res.render("home/index");
9 - },
10 -
11 - login: (req, res) => {
12 - res.render("home/login");
13 - },
14 -
15 - register: (req, res) => {
16 - res.render("home/register");
17 - },
18 -
19 -<<<<<<< HEAD
20 -=======
21 - chat: (req, res) => {
22 - res.render("home/chat");
23 - },
24 -
25 ->>>>>>> release_v0.2.0
26 - // restaurants: (req, res) => {
27 - // res.render("home/restaurants");
28 - // }
29 -};
30 -
31 -const process = {
32 - login: async (req, res) => {
33 - const user = new User(req.body);
34 - const response = await user.login();
35 - return res.json(response);
36 - },
37 -
38 - register: async (req, res) => {
39 - const user = new User(req.body);
40 - const response = await user.register();
41 -<<<<<<< HEAD
42 -=======
43 - // console.log("req.body", req.body);
44 ->>>>>>> release_v0.2.0
45 - // console.log(res.json(response));
46 - // console.log(res.json(response).statusCode); => 이거도 잘 찍혔음.
47 - return res.json(response);
48 - },
49 -
50 - // restaurants: async (req, res) => {
51 - // const restaurant = new Restaurant(req.body);
52 - // const response = await restaurant.restaurants();
53 - // return res.json(response);
54 - // },
55 -};
56 -
57 -module.exports = {
58 - output,
59 - process,
60 -};
...\ No newline at end of file ...\ No newline at end of file
1 -"use strict";
2 -
3 -const express = require("express");
4 -const router = express.Router();
5 -const jwtMiddleware = require("../../config/jwtMiddleware");
6 -// const Restaurant = require("../../models/Restaurant");
7 -
8 -const ctrl = require("./home.ctrl");
9 -<<<<<<< HEAD
10 -=======
11 -const index = require("../../models/Restaurant");
12 ->>>>>>> release_v0.2.0
13 -
14 -router.get("/", ctrl.output.hello);
15 -router.get("/login", ctrl.output.login);
16 -router.get("/register", ctrl.output.register);
17 -<<<<<<< HEAD
18 -=======
19 -router.get("/restaurants", index.readRestaurants);
20 -router.get("/chat", ctrl.output.chat);
21 ->>>>>>> release_v0.2.0
22 -// router.get("/restaurants", Restaurant.restaurants);
23 -// router.get("/restaurants", ctrl.output.restaurants);
24 -
25 -router.post("/login", ctrl.process.login);
26 -router.post("/register", ctrl.process.register);
27 -
28 -module.exports = router;
...\ No newline at end of file ...\ No newline at end of file
1 -module.exports = function (app) {
2 - //controller갖고있는 모듈 생성
3 - const index = require("../../models/Restaurant");
4 - // const user = require("../../models/User");
5 - const jwtMiddleware = require("../../config/jwtMiddleware");
6 -
7 - // 식당 목록 조회
8 - app.get("/restaurants", index.readRestaurants);
9 - };
10 -
...\ No newline at end of file ...\ No newline at end of file
1 -<!DOCTYPE html>
2 -<html lang="en">
3 - <head>
4 - <meta charset="UTF-8" />
5 - <meta http-equiv="X-UA-Compatible" content="IE=edge" />
6 - <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7 -<<<<<<< HEAD
8 - <title>채팅</title>
9 - </head>
10 - <body></body>
11 -=======
12 - <title>채팅방</title>
13 - <link rel="stylesheet" href="/css/home/chat.css" />
14 - </head>
15 - <body>
16 - <div class="wrapper">
17 - <div class="user-container">
18 - <lable class="nickname" for="nickname">닉네임설정</lable>
19 - <input type="text" id="nickname" />
20 - </div>
21 - <div class="display-container">
22 - <ul class="chatting-list"></ul>
23 - </div>
24 - <div class="input-container">
25 - <span>
26 - <input type="text" class="chatting-input" />
27 - <button class="send-button">전송</button>
28 - </span>
29 - </div>
30 - </div>
31 - <script
32 - src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.5.1/socket.io.js"
33 - integrity="sha512-9mpsATI0KClwt+xVZfbcf2lJ8IFBAwsubJ6mI3rtULwyM3fBmQFzj0It4tGqxLOGQwGfJdk/G+fANnxfq9/cew=="
34 - crossorigin="anonymous"
35 - referrerpolicy="no-referrer"
36 - ></script>
37 - <script src="/js/home/chat.js"></script>
38 - </body>
39 ->>>>>>> release_v0.2.0
40 -</html>
1 -<!DOCTYPE html>
2 -<html lang="en">
3 - <head>
4 - <meta charset="UTF-8" />
5 - <meta http-equiv="X-UA-Compatible" content="IE=edge" />
6 - <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7 - <title>맛집지도</title>
8 - <meta name="author" content="양주미" />
9 - <meta name="description" content="맛집지도 서비스" />
10 - <meta name="keywords" content="맛집지도, 맛집추천, 실시간채팅" />
11 - <link rel="stylesheet" href="/css/home/index.css" />
12 -<<<<<<< HEAD
13 - <script src="/js/home/axios-index.js"></script>
14 -=======
15 - <link rel="stylesheet" href="/css/home/map.css" />
16 ->>>>>>> release_v0.2.0
17 - </head>
18 - <body>
19 - <nav>
20 - <div class="inner">
21 - <div class="nav-container">
22 - <h1 class="nav-title">맛집지도</h1>
23 -<<<<<<< HEAD
24 - <button class="nav-contact">Chatting Rooms</button>
25 -=======
26 - <button class="nav-contact">Contact : balljm@naver.com</button>
27 ->>>>>>> release_v0.2.0
28 - </div>
29 - </div>
30 - </nav>
31 -
32 - <main>
33 - <section id="category">
34 - <div class="inner">
35 - <div class="category-container">
36 - <h2 class="category-title">💜맛집지도 카테고리를 선택해보세요💜</h2>
37 - <div class="category-list">
38 - <button class="category-item" id="korea">한식🍚</button>
39 - <button class="category-item" id="china">중식🍜</button>
40 - <button class="category-item" id="japan">일식🍙</button>
41 - <button class="category-item" id="america">양식🍝</button>
42 - <button class="category-item" id="wheat">분식🍭</button>
43 - <button class="category-item" id="meat">구이🍖</button>
44 - <button class="category-item" id="sushi">회/초밥🍣</button>
45 - <button class="category-item" id="etc">기타🍴</button>
46 - </div>
47 - </div>
48 - </div>
49 - </section>
50 - <!-- 카테고리 -->
51 - <div id="map" class="inner"></div>
52 -
53 - <!-- 카카오지도 -->
54 - </main>
55 -
56 - <script
57 - type="text/javascript"
58 - src="//dapi.kakao.com/v2/maps/sdk.js?appkey=e55f753363b95e27b799aa6286a6c398&libraries=services"
59 - ></script>
60 -<<<<<<< HEAD
61 - <!-- <script
62 -=======
63 - <script
64 ->>>>>>> release_v0.2.0
65 - src="https://cdnjs.cloudflare.com/ajax/libs/axios/1.0.0-alpha.1/axios.min.js"
66 - integrity="sha512-xIPqqrfvUAc/Cspuj7Bq0UtHNo/5qkdyngx6Vwt+tmbvTLDszzXM0G6c91LXmGrRx8KEPulT+AfOOez+TeVylg=="
67 - crossorigin="anonymous"
68 - referrerpolicy="no-referrer"
69 -<<<<<<< HEAD
70 - ></script> -->
71 -=======
72 - ></script>
73 - <script src="/js/home/axios-index.js"></script>
74 ->>>>>>> release_v0.2.0
75 - </body>
76 -</html>
1 -<!DOCTYPE html>
2 -<html lang="ko">
3 - <head>
4 - <meta charset="UTF-8" />
5 - <meta http-equiv="X-UA-Compatible" content="IE=edge" />
6 - <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7 - <link rel="stylesheet" href="/css/home/login.css" />
8 - <script src="/js/home/login.js" defer></script>
9 - <title>로그인</title>
10 - </head>
11 - <body>
12 - <div class="login-page">
13 - <div class="form">
14 - <!-- <form class="register-form">
15 - <input type="text" placeholder="name" />
16 - <input type="password" placeholder="password" />
17 - <input type="text" placeholder="email address" />
18 - <button>create</button>
19 - <p class="message">Already registered? <a href="#">Sign In</a></p>
20 - </form> -->
21 - <form class="login-form">
22 - <input id="id" type="text" placeholder="아이디" />
23 - <input id="password" type="password" placeholder="비밀번호" />
24 - <p id="button">LOGIN</p>
25 - <p class="message">
26 - 계정이 없으신가요? <a href="/register">회원가입</a>
27 - </p>
28 - </form>
29 - </div>
30 - </div>
31 - </body>
32 -</html>
33 -
34 -<!-- Copyright (c) 2022 by Aigars Silkalns (https://codepen.io/colorlib/pen/rxddKy) -->
1 -<!DOCTYPE html>
2 -<html lang="ko">
3 - <head>
4 - <meta charset="UTF-8" />
5 - <meta http-equiv="X-UA-Compatible" content="IE=edge" />
6 - <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7 - <link rel="stylesheet" href="/css/home/register.css" />
8 - <script src="/js/home/register.js" defer></script>
9 - <title>회원가입</title>
10 - </head>
11 - <body>
12 - <div class="login-page">
13 - <div class="form">
14 - <!-- <form class="register-form">
15 - <input type="text" placeholder="name" />
16 - <input type="password" placeholder="password" />
17 - <input type="text" placeholder="email address" />
18 - <button>create</button>
19 - <p class="message">Already registered? <a href="#">Sign In</a></p>
20 - </form> -->
21 - <form class="login-form">
22 - <input id="id" type="text" placeholder="아이디" />
23 - <input id="name" type="text" placeholder="이름" />
24 - <input id="password" type="password" placeholder="비밀번호" />
25 - <input
26 - id="confirm-password"
27 - type="password"
28 - placeholder="비밀번호 확인"
29 - />
30 - <p id="button">SIGN UP</p>
31 - <p class="message">계정이 있으신가요? <a href="/login">로그인</a></p>
32 - </form>
33 - </div>
34 - </div>
35 - </body>
36 -</html>
37 -
38 -<!-- Copyright (c) 2022 by Aigars Silkalns (https://codepen.io/colorlib/pen/rxddKy) -->
1 -{
2 - "lockfileVersion": 1
3 -}
1 -/*인포윈도우 설정*/
2 -.infowindow {
3 - width : 25rem;
4 - border : 1px solid black;
5 - border-radius: 5px;
6 - background-color : white;
7 -}
8 -
9 -.infowindow-title {
10 - font-size: 3rem;
11 -}
12 -
13 -.infowindow-address {
14 - font-size: 1.6rem;
15 -}
16 -
17 -.infowindow-btn {
18 - font-size: 1.6rem;
19 -}
...\ No newline at end of file ...\ No newline at end of file
1 -/*********************************************************************************
2 - * 1. 지도 생성 및 확대 축소 컨트롤러
3 - */
4 -
5 -var container = document.getElementById('map'); //지도를 담을 영역의 DOM 레퍼런스
6 -var options = { //지도를 생성할 때 필요한 기본 옵션
7 - center: new kakao.maps.LatLng(37.54, 126.96), //지도의 중심좌표.
8 - level: 7 //지도의 레벨(확대, 축소 정도)
9 -};
10 -
11 -var map = new kakao.maps.Map(container, options); //지도 생성 및 객체 리턴
12 -
13 -// 확대 축소 컨트롤러
14 -var zoomControl = new kakao.maps.ZoomControl();
15 -map.addControl(zoomControl, kakao.maps.ControlPosition.RIGHT);
16 -
17 -/******************************************************************************
18 - * 2. 더미데이터 준비하기(제목, 주소, 카테고리)
19 - */
20 -
21 - const dataSet = [
22 - {
23 - title: "희락돈까스",
24 - address: "서울 영등포구 양산로 210",
25 - category: "양식",
26 - },
27 - {
28 - title: "즉석우동짜장",
29 - address: "서울 영등포구 대방천로 260",
30 - category: "한식",
31 - },
32 - {
33 - title: "아카사카",
34 - address: "서울 서초구 서초대로74길 23",
35 - category: "일식",
36 - },
37 - {
38 - title: "한우만",
39 - address: "서울 서초구 서초3동 효령로 216",
40 - category: "한식",
41 - },
42 -
43 - ];
44 -
45 -
46 -/******************************************************************************
47 - * 3. 여러개 마커찍기
48 - */
49 -
50 -// 주소-좌표 변환 객체를 생성합니다
51 -var geocoder = new kakao.maps.services.Geocoder();
52 -
53 -function getCoordsByAddress(address) {
54 - return new Promise((resolve, reject) => {
55 - // 주소로 좌표를 검색합니다
56 - geocoder.addressSearch(address, function (result, status) {
57 - // 정상적으로 검색이 완료됐으면
58 - if (status === kakao.maps.services.Status.OK) {
59 - var coords = new kakao.maps.LatLng(result[0].y, result[0].x);
60 - return resolve(coords);
61 - }
62 - reject(new Error("getCoordsByAddress Error: not valid Address"));
63 - });
64 - });
65 -}
66 -
67 -setMap(dataSet);
68 -
69 -/*
70 -*************************************************************
71 -4. 마커에 인포윈도우 붙이기
72 -*/
73 -
74 -function getContent(data) {
75 - // 인포윈도우 가공하기
76 - return `
77 - <div class="infowindow">
78 - <div class="infowindow-body">
79 - <h5 class="infowindow-title">${data.title}</h5>
80 - <p class="infowindow-address">${data.address}</p>
81 - <a href='/chat' class="infowindow-btn" target="_blank">채팅방이동</a>
82 - </div>
83 - </div>
84 - `;
85 -}
86 -
87 -async function setMap(dataSet) {
88 - for (var i = 0; i < dataSet.length; i++) {
89 - // 마커를 생성합니다
90 - let coords = await getCoordsByAddress(dataSet[i].address);
91 - var marker = new kakao.maps.Marker({
92 - map: map, // 마커를 표시할 지도
93 - position: coords,
94 - });
95 -
96 - markerArray.push(marker);
97 -
98 - // 마커에 표시할 인포윈도우를 생성합니다
99 - var infowindow = new kakao.maps.InfoWindow({
100 - content: getContent(dataSet[i]),// 인포윈도우에 표시할 내용
101 - });
102 -
103 - infowindowArray.push(infowindow);
104 -
105 - // 마커에 mouseover 이벤트와 mouseout 이벤트를 등록합니다
106 - // 이벤트 리스너로는 클로저를 만들어 등록합니다
107 - // for문에서 클로저를 만들어 주지 않으면 마지막 마커에만 이벤트가 등록됩니다
108 - kakao.maps.event.addListener(marker, 'click', makeOverListener(map, marker, infowindow, coords));
109 - kakao.maps.event.addListener(map, 'click', makeOutListener(infowindow));
110 - }
111 - }
112 -
113 - // 인포윈도우를 표시하는 클로저를 만드는 함수입니다
114 -function makeOverListener(map, marker, infowindow, coords) {
115 - return function() {
116 - // 1. 클릭시 다른 인포윈도우 닫기
117 - closeInfoWindow();
118 - infowindow.open(map, marker);
119 - // 2. 클릭한 곳으로 지도 중심 옮기기
120 - map.panTo(coords);
121 - };
122 -}
123 -
124 -let infowindowArray = [];
125 -function closeInfoWindow() {
126 - for (let infowindow of infowindowArray) {
127 - infowindow.close();
128 - }
129 -}
130 -
131 -// 인포윈도우를 닫는 클로저를 만드는 함수입니다
132 -function makeOutListener(infowindow) {
133 - return function() {
134 - infowindow.close();
135 - };
136 -}
137 -
138 -/*
139 -**********************************************
140 -5. 카테고리 분류
141 -*/
142 -
143 -// 카테고리
144 -const categoryMap = {
145 - korea: "한식",
146 - china: "중식",
147 - japan: "일식",
148 - america: "양식",
149 - wheat: "분식",
150 - meat: "구이",
151 - sushi: "회/초밥",
152 - etc: "기타",
153 - };
154 -
155 -const categoryList = document.querySelector(".category-list");
156 -categoryList.addEventListener("click", categoryHandler);
157 -
158 -function categoryHandler(event) {
159 - const categoryId = event.target.id;
160 - const category = categoryMap[categoryId];
161 -
162 - // 데이터 분류
163 - let categorizedDataSet = [];
164 - for (let data of dataSet) {
165 - if (data.category === category) {
166 - categorizedDataSet.push(data);
167 - }
168 - }
169 -
170 - // 기존 마커 삭제
171 - closeMarker();
172 -
173 - // 기존 인포윈도우 닫기
174 - closeInfoWindow();
175 -
176 - setMap(categorizedDataSet);
177 -}
178 -
179 -let markerArray = [];
180 -function closeMarker() {
181 - for (marker of markerArray) {
182 - marker.setMap(null);
183 - }
184 -}
...\ No newline at end of file ...\ No newline at end of file