From 4ebf86f11987035ec2e80535ccadbc71dbb5154e Mon Sep 17 00:00:00 2001
From: epson220 <62466439+epson220@users.noreply.github.com>
Date: Mon, 7 Dec 2020 21:13:45 +0900
Subject: [PATCH] reviewWrite/read

---
 backend/models/comment.js              | 20 +++++++++++++
 backend/routes/users.js                | 33 ++++++++++++++++++++-
 frontend/.eslintcache                  |  2 +-
 frontend/src/components/DetailBoard.js | 40 ++++++++++++++++++++++++--
 4 files changed, 91 insertions(+), 4 deletions(-)
 create mode 100644 backend/models/comment.js

diff --git a/backend/models/comment.js b/backend/models/comment.js
new file mode 100644
index 0000000..7ebc8d0
--- /dev/null
+++ b/backend/models/comment.js
@@ -0,0 +1,20 @@
+const mongoose = require("mongoose");
+const mongooseAutoInc = require("mongoose-auto-increment");
+
+const CommentSchema = new mongoose.Schema({
+  input: { type: String, required: true },
+  created_at: { type: Date, default: Date.now },
+  writer: { type: String },
+  board_id: { type: Number },
+});
+
+// mongoose.connect("mongodb://localhost:27017/local", {
+//   useFindAndModify: false,
+//   useNewUrlParser: true,
+//   useUnifiedTopology: true,
+// });
+// mongooseAutoInc.initialize(mongoose.connection);
+
+CommentSchema.plugin(mongooseAutoInc.plugin, "comment");
+
+module.exports = mongoose.model("comment", CommentSchema);
diff --git a/backend/routes/users.js b/backend/routes/users.js
index 770996d..917be75 100644
--- a/backend/routes/users.js
+++ b/backend/routes/users.js
@@ -4,6 +4,7 @@ var flash = require("connect-flash");
 var router = express.Router();
 var UserModel = require("../models/user");
 var BoardModel = require("../models/board");
+var CommentModel = require("../models/comment");
 var cors = require("cors");
 const { ConnectionStates } = require("mongoose");
 var path = require("path");
@@ -302,6 +303,7 @@ router.post("/writeBoard", upload.array("photo", 1), function (req, res) {
 
 router.post("/getDetailBoard", async function (req, res) {
   let id = req.body.id;
+  let d = {};
   console.log("/getDetailBoard호츨됨." + req.body.id);
 
   try {
@@ -310,7 +312,36 @@ router.post("/getDetailBoard", async function (req, res) {
     console.log("detailBoard: ");
     console.log(detailBoard);
 
-    res.send(detailBoard);
+    let boardComments = await CommentModel.find({ board_id: id });
+    console.log("boardComments: ");
+    console.log(boardComments);
+
+    let d = { detailBoard, boardComments };
+
+    res.status(200).send(d);
+  } catch (err) {
+    console.log(err);
+  }
+});
+
+router.post("/writeComment", function (req, res) {
+  console.log(
+    "/writeComment post 호출" +
+      req.body.comment +
+      req.body.writer +
+      req.body.boardId
+  );
+
+  try {
+    let comment = new CommentModel({
+      input: req.body.comment,
+      writer: req.body.writer,
+      board_id: req.body.boardId,
+    });
+
+    comment.save();
+    console.log("댓글 작성 완료");
+    res.redirect("http://localhost:3000/detailBoard/" + req.body.boardId);
   } catch (err) {
     console.log(err);
   }
diff --git a/frontend/.eslintcache b/frontend/.eslintcache
index dbd4cd2..bfa24ee 100644
--- a/frontend/.eslintcache
+++ b/frontend/.eslintcache
@@ -1 +1 @@
-[{"C:\\WYH\\frontend\\src\\reportWebVitals.js":"1","C:\\WYH\\frontend\\src\\App.js":"2","C:\\WYH\\frontend\\src\\index.js":"3","C:\\WYH\\frontend\\src\\components\\Profile.js":"4","C:\\WYH\\frontend\\src\\components\\Board.js":"5","C:\\WYH\\frontend\\src\\components\\Home.js":"6","C:\\WYH\\frontend\\src\\components\\Signup.js":"7","C:\\WYH\\frontend\\src\\components\\Login.js":"8","C:\\WYH\\frontend\\src\\components\\WriteBoard.js":"9","C:\\WYH\\frontend\\src\\components\\DetailBoard.js":"10"},{"size":362,"mtime":1606157613272,"results":"11","hashOfConfig":"12"},{"size":1342,"mtime":1607184086712,"results":"13","hashOfConfig":"12"},{"size":544,"mtime":1606240034288,"results":"14","hashOfConfig":"12"},{"size":1175,"mtime":1607184077239,"results":"15","hashOfConfig":"12"},{"size":1622,"mtime":1607166854480,"results":"16","hashOfConfig":"12"},{"size":370,"mtime":1606662762631,"results":"17","hashOfConfig":"12"},{"size":1575,"mtime":1606662809909,"results":"18","hashOfConfig":"12"},{"size":1232,"mtime":1606662786263,"results":"19","hashOfConfig":"12"},{"size":3419,"mtime":1607104090152,"results":"20","hashOfConfig":"12"},{"size":1360,"mtime":1607187325157,"results":"21","hashOfConfig":"12"},{"filePath":"22","messages":"23","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},"10w9ldj",{"filePath":"24","messages":"25","errorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},{"filePath":"26","messages":"27","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"28"},{"filePath":"29","messages":"30","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"31","messages":"32","errorCount":0,"warningCount":2,"fixableErrorCount":0,"fixableWarningCount":0,"source":"33","usedDeprecatedRules":"28"},{"filePath":"34","messages":"35","errorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},{"filePath":"36","messages":"37","errorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"38"},{"filePath":"39","messages":"40","errorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"41"},{"filePath":"42","messages":"43","errorCount":0,"warningCount":4,"fixableErrorCount":0,"fixableWarningCount":0,"source":"44","usedDeprecatedRules":"28"},{"filePath":"45","messages":"46","errorCount":0,"warningCount":3,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},"C:\\WYH\\frontend\\src\\reportWebVitals.js",[],"C:\\WYH\\frontend\\src\\App.js",["47"],"C:\\WYH\\frontend\\src\\index.js",[],["48","49"],"C:\\WYH\\frontend\\src\\components\\Profile.js",[],"C:\\WYH\\frontend\\src\\components\\Board.js",["50","51"],"import React, { useEffect, useState } from \"react\";\r\nimport { Route, Link } from \"react-router-dom\";\r\nimport axios from \"axios\";\r\n\r\nconst Board = () => {\r\n  const [response, setResponse] = useState([]);\r\n\r\n  useEffect(async () => {\r\n    // try {\r\n    //   console.log(\"axios 실행\");\r\n    //   let res = [];\r\n    //   res = await axios.get(\"http://localhost:3001/board\");\r\n    //   console.log(res);\r\n    //   setResponse(res.data);\r\n    //   console.log(response);\r\n    // } catch (err) {\r\n    //   console.log(\"axios err\");\r\n    //   console.log(err);\r\n    // }\r\n    async function fetchData() {\r\n      console.log(\"react board get axios 호출\");\r\n      const result = await axios.get(\"http://localhost:3001/board\");\r\n      console.log(result.data);\r\n      setResponse(result.data);\r\n    }\r\n    fetchData();\r\n  }, []);\r\n\r\n  return (\r\n    <div>\r\n      <button>\r\n        <Link to=\"/writeBoard\">게시글 작성</Link>\r\n      </button>\r\n      <form action=\"http://localhost:3001/searchBoard\" method=\"post\">\r\n        <input type=\"text\" name=\"searchKeyword\"></input>\r\n        <button type=\"submit\">게시글검색</button>\r\n      </form>\r\n      <ol>\r\n        {response.map((res) => (\r\n          <li key={res._id}>\r\n            {/* <Link to={`/detailBoard/${res._id}`}>\r\n              <div onClick={handleOnClick(res._id)}>\r\n                {res.title} {res.created_at}\r\n              </div>\r\n            </Link> */}\r\n            <Link to={`/detailBoard/${res._id}`}>\r\n              {res.title} {res.created_at}\r\n            </Link>\r\n          </li>\r\n        ))}\r\n      </ol>\r\n    </div>\r\n  );\r\n};\r\n\r\nexport default Board;\r\n","C:\\WYH\\frontend\\src\\components\\Home.js",["52"],"C:\\WYH\\frontend\\src\\components\\Signup.js",["53"],"import React, { useState } from \"react\";\r\n//import { post } from \"../../backend/app\";\r\nimport { post } from \"axios\";\r\n\r\nconst Signup = () => {\r\n  const [email, setEmail] = useState(\"\");\r\n  const [nicname, setNicname] = useState(\"\");\r\n  const [password, setPassword] = useState(\"\");\r\n\r\n  const onChangeEmail = (e) => setEmail(e.target.value);\r\n  const onChangeNicname = (e) => setNicname(e.target.value);\r\n  const onChangePassword = (e) => setPassword(e.target.value);\r\n\r\n  // const handleFormSubmit = () => {\r\n  //   const url = \"/signup\";\r\n  //   const formData = new FormData();\r\n  //   formData.append(\"username\", username);\r\n  //   formData.append(\"password\", password);\r\n  //   formData.append(\"nicname\", nicname);\r\n\r\n  //   const config = {\r\n  //     headers: {\r\n  //       \"content-type\": \"multipart/form-data\",\r\n  //     },\r\n  //   };\r\n\r\n  //   return post(url, formData, config);\r\n  // };\r\n\r\n  return (\r\n    <form action=\"http://localhost:3001/signup\" method=\"post\">\r\n      <h1>회원가입</h1>\r\n      이메일:\r\n      <input\r\n        type=\"text\"\r\n        name=\"email\"\r\n        value={email}\r\n        onChange={onChangeEmail}\r\n      ></input>\r\n      비밀번호:\r\n      <input\r\n        type=\"password\"\r\n        name=\"password\"\r\n        value={password}\r\n        onChange={onChangePassword}\r\n      ></input>\r\n      닉네임:\r\n      <input\r\n        type=\"text\"\r\n        name=\"nicname\"\r\n        value={nicname}\r\n        onChange={onChangeNicname}\r\n      ></input>\r\n      <button type=\"submit\">가입완료</button>\r\n    </form>\r\n  );\r\n};\r\n\r\nexport default Signup;\r\n","C:\\WYH\\frontend\\src\\components\\Login.js",["54"],"import React, { useState } from \"react\";\r\nimport { post } from \"axios\";\r\n\r\nconst Login = () => {\r\n  const [username, setUsername] = useState(\"\");\r\n  const [password, setPassword] = useState(\"\");\r\n\r\n  const onChangeUsername = (e) => setUsername(e.target.value);\r\n  const onChangePassword = (e) => setPassword(e.target.value);\r\n\r\n  // const handleFormSubmit = () => {\r\n  //   const url = \"/login\";\r\n  //   let formData = new FormData();\r\n  //   formData.append(\"username\", username);\r\n  //   formData.append(\"password\", password);\r\n\r\n  //   let config = {\r\n  //     headers: {\r\n  //       \"content-type\": \"multipart/form-data\",\r\n  //     },\r\n  //   };\r\n\r\n  //   return post(url, formData, config);\r\n  // };\r\n\r\n  return (\r\n    <form action=\"http://localhost:3001/login\" method=\"post\">\r\n      <h1>로그인 화면</h1>\r\n      이메일:\r\n      <input\r\n        type=\"text\"\r\n        name=\"email\"\r\n        value={username}\r\n        onChange={onChangeUsername}\r\n      ></input>\r\n      비밀번호:\r\n      <input\r\n        type=\"password\"\r\n        name=\"password\"\r\n        value={password}\r\n        onChange={onChangePassword}\r\n      ></input>\r\n      <button type=\"submit\">로그인</button>\r\n    </form>\r\n  );\r\n};\r\n\r\nexport default Login;\r\n","C:\\WYH\\frontend\\src\\components\\WriteBoard.js",["55","56","57","58"],"import React, { useState } from \"react\";\r\n\r\nconst WriteBoard = () => {\r\n  const [title, setTitle] = useState(\"\");\r\n  const [content, setContent] = useState(\"\");\r\n  const [hobby, setHobby] = useState(\"\");\r\n\r\n  const onChangeTitle = (e) => setTitle(e.target.value);\r\n  const onChangeContent = (e) => setContent(e.target.value);\r\n  const onChangeHobby = (e) => setHobby(e.target.value);\r\n\r\n  return (\r\n    <div>\r\n      <form\r\n        action=\"http://localhost:3001/writeBoard\"\r\n        method=\"post\"\r\n        encType=\"multipart/form-data\"\r\n      >\r\n        <label>제목</label>\r\n        <input type=\"text\" name=\"title\" onChange={onChangeTitle}></input>\r\n        <br></br>\r\n        <label>본문</label>\r\n        <textarea\r\n          type=\"text\"\r\n          name=\"content\"\r\n          onChange={onChangeContent}\r\n        ></textarea>\r\n        <br></br>\r\n        <label>취미</label>\r\n        <br></br>\r\n        <label>\r\n          <input type=\"radio\" value=\"ex/sp\" name=\"hobby\" />\r\n          운동/스포츠\r\n        </label>\r\n        <br></br>\r\n        <label>\r\n          <input type=\"radio\" value=\"out/tr\" name=\"hobby\" />\r\n          아웃도어/여행\r\n        </label>\r\n        <br></br>\r\n        <label>\r\n          <input type=\"radio\" value=\"bk/wr\" name=\"hobby\" />\r\n          인문학/책/글\r\n        </label>\r\n        <br></br>\r\n        <label>\r\n          <input type=\"radio\" value=\"fg/lg\" name=\"hobby\" />\r\n          외국/언어\r\n        </label>\r\n        <br></br>\r\n        <label>\r\n          <input type=\"radio\" value=\"cul/pfm\" name=\"hobby\" />\r\n          문화/공연\r\n        </label>\r\n        <br></br>\r\n        <label>\r\n          <input type=\"radio\" value=\"mu/inst\" name=\"hobby\" />\r\n          음악/악기\r\n        </label>\r\n        <br></br>\r\n        <label>\r\n          <input type=\"radio\" value=\"cft\" name=\"hobby\" />\r\n          공예/만들기\r\n        </label>\r\n        <br></br>\r\n        <label>\r\n          <input type=\"radio\" value=\"dan\" name=\"hobby\" />\r\n          댄스/무용\r\n        </label>\r\n        <br></br>\r\n        <label>\r\n          <input type=\"radio\" value=\"volu\" name=\"hobby\" />\r\n          봉사활동\r\n        </label>\r\n        <br></br>\r\n        <label>\r\n          <input type=\"radio\" value=\"par\" name=\"hobby\" />\r\n          사교/인맥\r\n        </label>\r\n        <br></br>\r\n        <label>\r\n          <input type=\"radio\" value=\"game\" name=\"hobby\" />\r\n          게임/오락\r\n        </label>\r\n        <br></br>\r\n        <label>\r\n          <input type=\"radio\" value=\"pic\" name=\"hobby\" />\r\n          사진/편집/촬영/영상\r\n        </label>\r\n        <br></br>\r\n        <label>\r\n          <input type=\"radio\" value=\"inv\" name=\"hobby\" />\r\n          제테크/투자\r\n        </label>\r\n        <br></br>\r\n        <label>\r\n          <input type=\"radio\" value=\"cok/fod\" name=\"hobby\" />\r\n          요리/음식/맛집\r\n        </label>\r\n        <br></br>\r\n        <label>\r\n          <input type=\"radio\" value=\"fas/bea\" name=\"hobby\" />\r\n          패션/뷰티/코디\r\n        </label>\r\n        <br></br>\r\n        <label>\r\n          <input type=\"radio\" value=\"art/draw\" name=\"hobby\" />\r\n          미술/그림\r\n        </label>\r\n        <br></br>\r\n        <br></br>\r\n        <label>사진첨부</label>\r\n        <input type=\"file\" name=\"photo\"></input>\r\n        <br></br>\r\n        <button type=\"submit\">ok</button>\r\n      </form>\r\n    </div>\r\n  );\r\n};\r\n\r\nexport default WriteBoard;\r\n","C:\\WYH\\frontend\\src\\components\\DetailBoard.js",["59","60","61"],{"ruleId":"62","severity":1,"message":"63","line":1,"column":17,"nodeType":"64","messageId":"65","endLine":1,"endColumn":26},{"ruleId":"66","replacedBy":"67"},{"ruleId":"68","replacedBy":"69"},{"ruleId":"62","severity":1,"message":"70","line":2,"column":10,"nodeType":"64","messageId":"65","endLine":2,"endColumn":15},{"ruleId":"71","severity":1,"message":"72","line":8,"column":13,"nodeType":"73","endLine":27,"endColumn":4},{"ruleId":"62","severity":1,"message":"70","line":2,"column":10,"nodeType":"64","messageId":"65","endLine":2,"endColumn":15},{"ruleId":"62","severity":1,"message":"74","line":3,"column":10,"nodeType":"64","messageId":"65","endLine":3,"endColumn":14},{"ruleId":"62","severity":1,"message":"74","line":2,"column":10,"nodeType":"64","messageId":"65","endLine":2,"endColumn":14},{"ruleId":"62","severity":1,"message":"75","line":4,"column":10,"nodeType":"64","messageId":"65","endLine":4,"endColumn":15},{"ruleId":"62","severity":1,"message":"76","line":5,"column":10,"nodeType":"64","messageId":"65","endLine":5,"endColumn":17},{"ruleId":"62","severity":1,"message":"77","line":6,"column":10,"nodeType":"64","messageId":"65","endLine":6,"endColumn":15},{"ruleId":"62","severity":1,"message":"78","line":10,"column":9,"nodeType":"64","messageId":"65","endLine":10,"endColumn":22},{"ruleId":"71","severity":1,"message":"72","line":21,"column":13,"nodeType":"73","endLine":34,"endColumn":4},{"ruleId":"71","severity":1,"message":"79","line":34,"column":6,"nodeType":"80","endLine":34,"endColumn":8,"suggestions":"81"},{"ruleId":"82","severity":1,"message":"83","line":44,"column":9,"nodeType":"84","endLine":44,"endColumn":71},"no-unused-vars","'Component' is defined but never used.","Identifier","unusedVar","no-native-reassign",["85"],"no-negated-in-lhs",["86"],"'Route' is defined but never used.","react-hooks/exhaustive-deps","Effect callbacks are synchronous to prevent race conditions. Put the async function inside:\n\nuseEffect(() => {\n  async function fetchData() {\n    // You can await here\n    const response = await MyAPI.getData(someId);\n    // ...\n  }\n  fetchData();\n}, [someId]); // Or [] if effect doesn't need props or state\n\nLearn more about data fetching with Hooks: https://reactjs.org/link/hooks-data-fetching","ArrowFunctionExpression","'post' is defined but never used.","'title' is assigned a value but never used.","'content' is assigned a value but never used.","'hobby' is assigned a value but never used.","'onChangeHobby' is assigned a value but never used.","React Hook useEffect has missing dependencies: 'Board' and 'board_id'. Either include them or remove the dependency array.","ArrayExpression",["87"],"jsx-a11y/alt-text","img elements must have an alt prop, either with meaningful text, or an empty string for decorative images.","JSXOpeningElement","no-global-assign","no-unsafe-negation",{"desc":"88","fix":"89"},"Update the dependencies array to be: [Board, board_id]",{"range":"90","text":"91"},[926,928],"[Board, board_id]"]
\ No newline at end of file
+[{"C:\\WYH\\frontend\\src\\reportWebVitals.js":"1","C:\\WYH\\frontend\\src\\App.js":"2","C:\\WYH\\frontend\\src\\index.js":"3","C:\\WYH\\frontend\\src\\components\\Profile.js":"4","C:\\WYH\\frontend\\src\\components\\Board.js":"5","C:\\WYH\\frontend\\src\\components\\Home.js":"6","C:\\WYH\\frontend\\src\\components\\Signup.js":"7","C:\\WYH\\frontend\\src\\components\\Login.js":"8","C:\\WYH\\frontend\\src\\components\\WriteBoard.js":"9","C:\\WYH\\frontend\\src\\components\\DetailBoard.js":"10"},{"size":362,"mtime":1606157613272,"results":"11","hashOfConfig":"12"},{"size":1342,"mtime":1607184086712,"results":"13","hashOfConfig":"12"},{"size":544,"mtime":1606240034288,"results":"14","hashOfConfig":"12"},{"size":1175,"mtime":1607184077239,"results":"15","hashOfConfig":"12"},{"size":1622,"mtime":1607166854480,"results":"16","hashOfConfig":"12"},{"size":370,"mtime":1606662762631,"results":"17","hashOfConfig":"12"},{"size":1575,"mtime":1606662809909,"results":"18","hashOfConfig":"12"},{"size":1232,"mtime":1606662786263,"results":"19","hashOfConfig":"12"},{"size":3419,"mtime":1607104090152,"results":"20","hashOfConfig":"12"},{"size":2475,"mtime":1607341349582,"results":"21","hashOfConfig":"12"},{"filePath":"22","messages":"23","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},"10w9ldj",{"filePath":"24","messages":"25","errorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},{"filePath":"26","messages":"27","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"28"},{"filePath":"29","messages":"30","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"31","messages":"32","errorCount":0,"warningCount":2,"fixableErrorCount":0,"fixableWarningCount":0,"source":"33","usedDeprecatedRules":"28"},{"filePath":"34","messages":"35","errorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},{"filePath":"36","messages":"37","errorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"38"},{"filePath":"39","messages":"40","errorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"41"},{"filePath":"42","messages":"43","errorCount":0,"warningCount":4,"fixableErrorCount":0,"fixableWarningCount":0,"source":"44","usedDeprecatedRules":"28"},{"filePath":"45","messages":"46","errorCount":0,"warningCount":3,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},"C:\\WYH\\frontend\\src\\reportWebVitals.js",[],"C:\\WYH\\frontend\\src\\App.js",["47"],"C:\\WYH\\frontend\\src\\index.js",[],["48","49"],"C:\\WYH\\frontend\\src\\components\\Profile.js",[],"C:\\WYH\\frontend\\src\\components\\Board.js",["50","51"],"import React, { useEffect, useState } from \"react\";\r\nimport { Route, Link } from \"react-router-dom\";\r\nimport axios from \"axios\";\r\n\r\nconst Board = () => {\r\n  const [response, setResponse] = useState([]);\r\n\r\n  useEffect(async () => {\r\n    // try {\r\n    //   console.log(\"axios 실행\");\r\n    //   let res = [];\r\n    //   res = await axios.get(\"http://localhost:3001/board\");\r\n    //   console.log(res);\r\n    //   setResponse(res.data);\r\n    //   console.log(response);\r\n    // } catch (err) {\r\n    //   console.log(\"axios err\");\r\n    //   console.log(err);\r\n    // }\r\n    async function fetchData() {\r\n      console.log(\"react board get axios 호출\");\r\n      const result = await axios.get(\"http://localhost:3001/board\");\r\n      console.log(result.data);\r\n      setResponse(result.data);\r\n    }\r\n    fetchData();\r\n  }, []);\r\n\r\n  return (\r\n    <div>\r\n      <button>\r\n        <Link to=\"/writeBoard\">게시글 작성</Link>\r\n      </button>\r\n      <form action=\"http://localhost:3001/searchBoard\" method=\"post\">\r\n        <input type=\"text\" name=\"searchKeyword\"></input>\r\n        <button type=\"submit\">게시글검색</button>\r\n      </form>\r\n      <ol>\r\n        {response.map((res) => (\r\n          <li key={res._id}>\r\n            {/* <Link to={`/detailBoard/${res._id}`}>\r\n              <div onClick={handleOnClick(res._id)}>\r\n                {res.title} {res.created_at}\r\n              </div>\r\n            </Link> */}\r\n            <Link to={`/detailBoard/${res._id}`}>\r\n              {res.title} {res.created_at}\r\n            </Link>\r\n          </li>\r\n        ))}\r\n      </ol>\r\n    </div>\r\n  );\r\n};\r\n\r\nexport default Board;\r\n","C:\\WYH\\frontend\\src\\components\\Home.js",["52"],"C:\\WYH\\frontend\\src\\components\\Signup.js",["53"],"import React, { useState } from \"react\";\r\n//import { post } from \"../../backend/app\";\r\nimport { post } from \"axios\";\r\n\r\nconst Signup = () => {\r\n  const [email, setEmail] = useState(\"\");\r\n  const [nicname, setNicname] = useState(\"\");\r\n  const [password, setPassword] = useState(\"\");\r\n\r\n  const onChangeEmail = (e) => setEmail(e.target.value);\r\n  const onChangeNicname = (e) => setNicname(e.target.value);\r\n  const onChangePassword = (e) => setPassword(e.target.value);\r\n\r\n  // const handleFormSubmit = () => {\r\n  //   const url = \"/signup\";\r\n  //   const formData = new FormData();\r\n  //   formData.append(\"username\", username);\r\n  //   formData.append(\"password\", password);\r\n  //   formData.append(\"nicname\", nicname);\r\n\r\n  //   const config = {\r\n  //     headers: {\r\n  //       \"content-type\": \"multipart/form-data\",\r\n  //     },\r\n  //   };\r\n\r\n  //   return post(url, formData, config);\r\n  // };\r\n\r\n  return (\r\n    <form action=\"http://localhost:3001/signup\" method=\"post\">\r\n      <h1>회원가입</h1>\r\n      이메일:\r\n      <input\r\n        type=\"text\"\r\n        name=\"email\"\r\n        value={email}\r\n        onChange={onChangeEmail}\r\n      ></input>\r\n      비밀번호:\r\n      <input\r\n        type=\"password\"\r\n        name=\"password\"\r\n        value={password}\r\n        onChange={onChangePassword}\r\n      ></input>\r\n      닉네임:\r\n      <input\r\n        type=\"text\"\r\n        name=\"nicname\"\r\n        value={nicname}\r\n        onChange={onChangeNicname}\r\n      ></input>\r\n      <button type=\"submit\">가입완료</button>\r\n    </form>\r\n  );\r\n};\r\n\r\nexport default Signup;\r\n","C:\\WYH\\frontend\\src\\components\\Login.js",["54"],"import React, { useState } from \"react\";\r\nimport { post } from \"axios\";\r\n\r\nconst Login = () => {\r\n  const [username, setUsername] = useState(\"\");\r\n  const [password, setPassword] = useState(\"\");\r\n\r\n  const onChangeUsername = (e) => setUsername(e.target.value);\r\n  const onChangePassword = (e) => setPassword(e.target.value);\r\n\r\n  // const handleFormSubmit = () => {\r\n  //   const url = \"/login\";\r\n  //   let formData = new FormData();\r\n  //   formData.append(\"username\", username);\r\n  //   formData.append(\"password\", password);\r\n\r\n  //   let config = {\r\n  //     headers: {\r\n  //       \"content-type\": \"multipart/form-data\",\r\n  //     },\r\n  //   };\r\n\r\n  //   return post(url, formData, config);\r\n  // };\r\n\r\n  return (\r\n    <form action=\"http://localhost:3001/login\" method=\"post\">\r\n      <h1>로그인 화면</h1>\r\n      이메일:\r\n      <input\r\n        type=\"text\"\r\n        name=\"email\"\r\n        value={username}\r\n        onChange={onChangeUsername}\r\n      ></input>\r\n      비밀번호:\r\n      <input\r\n        type=\"password\"\r\n        name=\"password\"\r\n        value={password}\r\n        onChange={onChangePassword}\r\n      ></input>\r\n      <button type=\"submit\">로그인</button>\r\n    </form>\r\n  );\r\n};\r\n\r\nexport default Login;\r\n","C:\\WYH\\frontend\\src\\components\\WriteBoard.js",["55","56","57","58"],"import React, { useState } from \"react\";\r\n\r\nconst WriteBoard = () => {\r\n  const [title, setTitle] = useState(\"\");\r\n  const [content, setContent] = useState(\"\");\r\n  const [hobby, setHobby] = useState(\"\");\r\n\r\n  const onChangeTitle = (e) => setTitle(e.target.value);\r\n  const onChangeContent = (e) => setContent(e.target.value);\r\n  const onChangeHobby = (e) => setHobby(e.target.value);\r\n\r\n  return (\r\n    <div>\r\n      <form\r\n        action=\"http://localhost:3001/writeBoard\"\r\n        method=\"post\"\r\n        encType=\"multipart/form-data\"\r\n      >\r\n        <label>제목</label>\r\n        <input type=\"text\" name=\"title\" onChange={onChangeTitle}></input>\r\n        <br></br>\r\n        <label>본문</label>\r\n        <textarea\r\n          type=\"text\"\r\n          name=\"content\"\r\n          onChange={onChangeContent}\r\n        ></textarea>\r\n        <br></br>\r\n        <label>취미</label>\r\n        <br></br>\r\n        <label>\r\n          <input type=\"radio\" value=\"ex/sp\" name=\"hobby\" />\r\n          운동/스포츠\r\n        </label>\r\n        <br></br>\r\n        <label>\r\n          <input type=\"radio\" value=\"out/tr\" name=\"hobby\" />\r\n          아웃도어/여행\r\n        </label>\r\n        <br></br>\r\n        <label>\r\n          <input type=\"radio\" value=\"bk/wr\" name=\"hobby\" />\r\n          인문학/책/글\r\n        </label>\r\n        <br></br>\r\n        <label>\r\n          <input type=\"radio\" value=\"fg/lg\" name=\"hobby\" />\r\n          외국/언어\r\n        </label>\r\n        <br></br>\r\n        <label>\r\n          <input type=\"radio\" value=\"cul/pfm\" name=\"hobby\" />\r\n          문화/공연\r\n        </label>\r\n        <br></br>\r\n        <label>\r\n          <input type=\"radio\" value=\"mu/inst\" name=\"hobby\" />\r\n          음악/악기\r\n        </label>\r\n        <br></br>\r\n        <label>\r\n          <input type=\"radio\" value=\"cft\" name=\"hobby\" />\r\n          공예/만들기\r\n        </label>\r\n        <br></br>\r\n        <label>\r\n          <input type=\"radio\" value=\"dan\" name=\"hobby\" />\r\n          댄스/무용\r\n        </label>\r\n        <br></br>\r\n        <label>\r\n          <input type=\"radio\" value=\"volu\" name=\"hobby\" />\r\n          봉사활동\r\n        </label>\r\n        <br></br>\r\n        <label>\r\n          <input type=\"radio\" value=\"par\" name=\"hobby\" />\r\n          사교/인맥\r\n        </label>\r\n        <br></br>\r\n        <label>\r\n          <input type=\"radio\" value=\"game\" name=\"hobby\" />\r\n          게임/오락\r\n        </label>\r\n        <br></br>\r\n        <label>\r\n          <input type=\"radio\" value=\"pic\" name=\"hobby\" />\r\n          사진/편집/촬영/영상\r\n        </label>\r\n        <br></br>\r\n        <label>\r\n          <input type=\"radio\" value=\"inv\" name=\"hobby\" />\r\n          제테크/투자\r\n        </label>\r\n        <br></br>\r\n        <label>\r\n          <input type=\"radio\" value=\"cok/fod\" name=\"hobby\" />\r\n          요리/음식/맛집\r\n        </label>\r\n        <br></br>\r\n        <label>\r\n          <input type=\"radio\" value=\"fas/bea\" name=\"hobby\" />\r\n          패션/뷰티/코디\r\n        </label>\r\n        <br></br>\r\n        <label>\r\n          <input type=\"radio\" value=\"art/draw\" name=\"hobby\" />\r\n          미술/그림\r\n        </label>\r\n        <br></br>\r\n        <br></br>\r\n        <label>사진첨부</label>\r\n        <input type=\"file\" name=\"photo\"></input>\r\n        <br></br>\r\n        <button type=\"submit\">ok</button>\r\n      </form>\r\n    </div>\r\n  );\r\n};\r\n\r\nexport default WriteBoard;\r\n","C:\\WYH\\frontend\\src\\components\\DetailBoard.js",["59","60","61"],{"ruleId":"62","severity":1,"message":"63","line":1,"column":17,"nodeType":"64","messageId":"65","endLine":1,"endColumn":26},{"ruleId":"66","replacedBy":"67"},{"ruleId":"68","replacedBy":"69"},{"ruleId":"62","severity":1,"message":"70","line":2,"column":10,"nodeType":"64","messageId":"65","endLine":2,"endColumn":15},{"ruleId":"71","severity":1,"message":"72","line":8,"column":13,"nodeType":"73","endLine":27,"endColumn":4},{"ruleId":"62","severity":1,"message":"70","line":2,"column":10,"nodeType":"64","messageId":"65","endLine":2,"endColumn":15},{"ruleId":"62","severity":1,"message":"74","line":3,"column":10,"nodeType":"64","messageId":"65","endLine":3,"endColumn":14},{"ruleId":"62","severity":1,"message":"74","line":2,"column":10,"nodeType":"64","messageId":"65","endLine":2,"endColumn":14},{"ruleId":"62","severity":1,"message":"75","line":4,"column":10,"nodeType":"64","messageId":"65","endLine":4,"endColumn":15},{"ruleId":"62","severity":1,"message":"76","line":5,"column":10,"nodeType":"64","messageId":"65","endLine":5,"endColumn":17},{"ruleId":"62","severity":1,"message":"77","line":6,"column":10,"nodeType":"64","messageId":"65","endLine":6,"endColumn":15},{"ruleId":"62","severity":1,"message":"78","line":10,"column":9,"nodeType":"64","messageId":"65","endLine":10,"endColumn":22},{"ruleId":"71","severity":1,"message":"72","line":31,"column":13,"nodeType":"73","endLine":47,"endColumn":4},{"ruleId":"71","severity":1,"message":"79","line":47,"column":6,"nodeType":"80","endLine":47,"endColumn":8,"suggestions":"81"},{"ruleId":"82","severity":1,"message":"83","line":57,"column":9,"nodeType":"84","endLine":57,"endColumn":71},"no-unused-vars","'Component' is defined but never used.","Identifier","unusedVar","no-native-reassign",["85"],"no-negated-in-lhs",["86"],"'Route' is defined but never used.","react-hooks/exhaustive-deps","Effect callbacks are synchronous to prevent race conditions. Put the async function inside:\n\nuseEffect(() => {\n  async function fetchData() {\n    // You can await here\n    const response = await MyAPI.getData(someId);\n    // ...\n  }\n  fetchData();\n}, [someId]); // Or [] if effect doesn't need props or state\n\nLearn more about data fetching with Hooks: https://reactjs.org/link/hooks-data-fetching","ArrowFunctionExpression","'post' is defined but never used.","'title' is assigned a value but never used.","'content' is assigned a value but never used.","'hobby' is assigned a value but never used.","'onChangeHobby' is assigned a value but never used.","React Hook useEffect has missing dependencies: 'Board' and 'board_id'. Either include them or remove the dependency array.","ArrayExpression",["87"],"jsx-a11y/alt-text","img elements must have an alt prop, either with meaningful text, or an empty string for decorative images.","JSXOpeningElement","no-global-assign","no-unsafe-negation",{"desc":"88","fix":"89"},"Update the dependencies array to be: [Board, board_id]",{"range":"90","text":"91"},[1309,1311],"[Board, board_id]"]
\ No newline at end of file
diff --git a/frontend/src/components/DetailBoard.js b/frontend/src/components/DetailBoard.js
index 6f3b21d..c93ba88 100644
--- a/frontend/src/components/DetailBoard.js
+++ b/frontend/src/components/DetailBoard.js
@@ -13,7 +13,17 @@ const DetailBoard = ({ match }) => {
     created_at: "",
     _id: "",
   });
+  // const [Comments, setComments] = useState({
+  //   _id: "",
+  //   board_id: "",
+  //   writer: "",
+  //   input: "",
+  // });
+  const [Comments, setComments] = useState([]);
   const [Imgurl, setImgurl] = useState("");
+  const [Comment, setComment] = useState("");
+
+  const onChangeComment = (e) => setComment(e.target.value);
 
   console.dir(match.params);
   console.log("board_id : " + board_id);
@@ -26,9 +36,12 @@ const DetailBoard = ({ match }) => {
       });
       console.log("res : ");
       console.dir(res);
-      setBoard(res.data);
+      setBoard(res.data.detailBoard);
       console.log(Board);
-      setImgurl("http://localhost:3001/uploads/" + res.data.picture);
+      setComments(res.data.boardComments);
+      setImgurl(
+        "http://localhost:3001/uploads/" + res.data.detailBoard.picture
+      );
     }
     fetchData();
   }, []);
@@ -43,6 +56,29 @@ const DetailBoard = ({ match }) => {
       <div>
         <img src={Imgurl} style={{ width: "600px", height: "600px" }}></img>
       </div>
+      <div>
+        <form method="post" action="http://localhost:3001/writeComment">
+          <input
+            type="text"
+            placeholder="댓글을 작성해 주세요."
+            name="comment"
+            value={Comment}
+            onChange={onChangeComment}
+          ></input>
+          <input type="hidden" name="writer" value={Board.writer}></input>
+          <input type="hidden" name="boardId" value={Board._id}></input>
+          <button type="submit">작성완료</button>
+        </form>
+      </div>
+      <div>
+        <ol>
+          {Comments.map((c) => (
+            <li key={c._id}>
+              {c.input} {c.writer}
+            </li>
+          ))}
+        </ol>
+      </div>
     </>
   );
 };
-- 
GitLab