From 4c33b42402201d7cfd9f8f63b70a20da047ce683 Mon Sep 17 00:00:00 2001
From: epson220 <62466439+epson220@users.noreply.github.com>
Date: Sat, 12 Dec 2020 04:41:50 +0900
Subject: [PATCH] =?UTF-8?q?=EA=B2=8C=EC=8B=9C=ED=8C=90=20=EB=8C=93?=
 =?UTF-8?q?=EA=B8=80=EC=97=90=20=EB=8B=B5=EA=B8=80=EB=8B=AC=EA=B8=B0?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 backend/models/reply.js                | 21 +++++++++++++++
 backend/routes/users.js                | 33 ++++++++++++++++++++++-
 frontend/.eslintcache                  |  2 +-
 frontend/src/components/DetailBoard.js | 37 +++++++++++++++++++++++++-
 4 files changed, 90 insertions(+), 3 deletions(-)
 create mode 100644 backend/models/reply.js

diff --git a/backend/models/reply.js b/backend/models/reply.js
new file mode 100644
index 0000000..c34c1bc
--- /dev/null
+++ b/backend/models/reply.js
@@ -0,0 +1,21 @@
+const mongoose = require("mongoose");
+const mongooseAutoInc = require("mongoose-auto-increment");
+
+const ReplySchema = new mongoose.Schema({
+  reply_content: { type: String, required: true },
+  created_at: { type: Date, default: Date.now },
+  writer: { type: String },
+  board_id: { type: Number },
+  comment_id: { type: Number },
+});
+
+// mongoose.connect("mongodb://localhost:27017/local", {
+//   useFindAndModify: false,
+//   useNewUrlParser: true,
+//   useUnifiedTopology: true,
+// });
+// mongooseAutoInc.initialize(mongoose.connection);
+
+ReplySchema.plugin(mongooseAutoInc.plugin, "reply");
+
+module.exports = mongoose.model("reply", ReplySchema);
diff --git a/backend/routes/users.js b/backend/routes/users.js
index fbdfa55..101a8ee 100644
--- a/backend/routes/users.js
+++ b/backend/routes/users.js
@@ -6,6 +6,7 @@ var UserModel = require("../models/user");
 var BoardModel = require("../models/board");
 var CommentModel = require("../models/comment");
 var ProfileModel = require("../models/profile");
+var ReplyModel = require("../models/reply");
 var cors = require("cors");
 const { ConnectionStates } = require("mongoose");
 var path = require("path");
@@ -318,7 +319,11 @@ router.post("/getDetailBoard", async function (req, res) {
     console.log("boardComments: ");
     console.log(boardComments);
 
-    let d = { detailBoard, boardComments };
+    let boardReplies = await ReplyModel.find({ board_id: id });
+    console.log("boardReplies: ");
+    console.log(boardReplies);
+
+    let d = { detailBoard, boardComments, boardReplies };
 
     res.status(200).send(d);
   } catch (err) {
@@ -517,4 +522,30 @@ router.post("/searchHobby", async function (req, res) {
   }
 });
 
+router.post("/postReply", async function (req, res) {
+  console.log(
+    "postReply post 호출" +
+      req.body.reply +
+      req.body.comment_id +
+      req.body.boardId
+  );
+  try {
+    let reply = new ReplyModel({
+      reply_content: req.body.reply,
+      writer: req.session.user.id,
+      board_id: req.body.boardId,
+      comment_id: req.body.comment_id,
+    });
+
+    await reply.save();
+
+    let replies = await ReplyModel.find({ comment_id: req.body.comment_id });
+    console.log(replies);
+    console.log("답글 작성 완료");
+    res.redirect("http://localhost:3000/detailBoard/" + req.body.boardId);
+  } catch (err) {
+    console.log(err);
+  }
+});
+
 module.exports = router;
diff --git a/frontend/.eslintcache b/frontend/.eslintcache
index c2e7241..44e8fb1 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","C:\\WYH\\frontend\\src\\components\\WriteProfile.js":"11"},{"size":362,"mtime":1606157613272,"results":"12","hashOfConfig":"13"},{"size":1764,"mtime":1607415610889,"results":"14","hashOfConfig":"13"},{"size":544,"mtime":1606240034288,"results":"15","hashOfConfig":"13"},{"size":2234,"mtime":1607425040281,"results":"16","hashOfConfig":"13"},{"size":4100,"mtime":1607506999836,"results":"17","hashOfConfig":"13"},{"size":370,"mtime":1606662762631,"results":"18","hashOfConfig":"13"},{"size":1575,"mtime":1607345129868,"results":"19","hashOfConfig":"13"},{"size":1232,"mtime":1606662786263,"results":"20","hashOfConfig":"13"},{"size":3419,"mtime":1607104090152,"results":"21","hashOfConfig":"13"},{"size":2882,"mtime":1607519522761,"results":"22","hashOfConfig":"13"},{"size":3396,"mtime":1607369801073,"results":"23","hashOfConfig":"13"},{"filePath":"24","messages":"25","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"26"},"10w9ldj",{"filePath":"27","messages":"28","errorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},{"filePath":"29","messages":"30","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"31"},{"filePath":"32","messages":"33","errorCount":0,"warningCount":3,"fixableErrorCount":0,"fixableWarningCount":0,"source":"34","usedDeprecatedRules":"31"},{"filePath":"35","messages":"36","errorCount":0,"warningCount":3,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},{"filePath":"37","messages":"38","errorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},{"filePath":"39","messages":"40","errorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"41"},{"filePath":"42","messages":"43","errorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"44"},{"filePath":"45","messages":"46","errorCount":0,"warningCount":4,"fixableErrorCount":0,"fixableWarningCount":0,"source":"47","usedDeprecatedRules":"48"},{"filePath":"49","messages":"50","errorCount":0,"warningCount":4,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},{"filePath":"51","messages":"52","errorCount":0,"warningCount":6,"fixableErrorCount":0,"fixableWarningCount":0,"source":"53","usedDeprecatedRules":"31"},"C:\\WYH\\frontend\\src\\reportWebVitals.js",[],["54","55"],"C:\\WYH\\frontend\\src\\App.js",["56"],"C:\\WYH\\frontend\\src\\index.js",[],["57","58"],"C:\\WYH\\frontend\\src\\components\\Profile.js",["59","60","61"],"import React, { useEffect, useState } from \"react\";\r\nimport axios from \"axios\";\r\nimport { Link } from \"react-router-dom\";\r\nimport { withRouter } from \"react-router-dom\";\r\naxios.defaults.withCredentials = true; // 기존에 해당 설정으로 cors 에러가 나게 한 부분\r\n\r\nconst Profile = ({ match, history }) => {\r\n  const { email } = match.params;\r\n  const [Profile, setProfile] = useState({\r\n    profile_photo: \"\",\r\n    created_at: \"\",\r\n    self_intro: \"\",\r\n    user_id: \"\",\r\n    user_email: \"\",\r\n    age: \"\",\r\n    location: \"\",\r\n  });\r\n\r\n  const [User, setUser] = useState({\r\n    email: \"\",\r\n    password: \"\",\r\n    name: \"\",\r\n    created_at: \"\",\r\n    deleted_at: \"\",\r\n  });\r\n\r\n  const [Img, setImg] = useState(\"\");\r\n\r\n  useEffect(async () => {\r\n    const fetchData = async () => {\r\n      const result = await axios.post(\"http://localhost:3001/profile\", {\r\n        email: email,\r\n      });\r\n      console.dir(result);\r\n      setProfile(result.data.p);\r\n      setUser(result.data.u);\r\n\r\n      setImg(\"http://localhost:3001/uploads/\" + result.data.p.profile_photo);\r\n    };\r\n    fetchData();\r\n  }, []);\r\n\r\n  return (\r\n    <>\r\n      <h1>{Profile.user_email} 의 프로필화면</h1>\r\n      <div>닉네임:{User.name}</div>\r\n      <div>자기소게:{Profile.self_intro}</div>\r\n      <div>나이:{Profile.age}</div>\r\n      <div>사는곳:{Profile.location}</div>\r\n      <div>\r\n        프로필사진:<img src={Img} width=\"200px\" height=\"200px\"></img>\r\n      </div>\r\n      <Link to=\"/board\">메인화면으로 돌아가기</Link>\r\n      <button onClick={() => history.goBack()}>뒤로가기</button>\r\n    </>\r\n  );\r\n};\r\n\r\n// const Profile = (login_info) => {\r\n//   const [user, setUser] = useState(\"\");\r\n\r\n//   fetch(\"/profile\", {\r\n//     method: \"get\",\r\n//     headers: {\r\n//       \"Content-Type\": \"application/json; charset=utf-8\",\r\n//     },\r\n//     credentials: \"same-origin\",\r\n//     body: JSON.stringify(login_info),\r\n//   })\r\n//     .then((res) => res.json())\r\n//     .then((data) => {\r\n//       console.dir(data);\r\n//       setUser(data);\r\n//     });\r\n\r\n//   return (\r\n//     <div>\r\n//       <h1>{user.username}</h1>\r\n//       <h1>{user.nicname}</h1>\r\n//     </div>\r\n//   );\r\n// };\r\n\r\nexport default withRouter(Profile);\r\n","C:\\WYH\\frontend\\src\\components\\Board.js",["62","63","64"],"C:\\WYH\\frontend\\src\\components\\Home.js",["65"],"C:\\WYH\\frontend\\src\\components\\Signup.js",["66"],"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",["67"],"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",["68","69","70","71"],"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",["72","73"],"C:\\WYH\\frontend\\src\\components\\DetailBoard.js",["74","75","76","77"],"C:\\WYH\\frontend\\src\\components\\WriteProfile.js",["78","79","80","81","82","83"],"import React, { useEffect, useState } from \"react\";\r\nimport axios from \"axios\";\r\n\r\nconst WriteProfile = () => {\r\n  const [Profile, setProfile] = useState({\r\n    profile_photo: \"\",\r\n    created_at: \"\",\r\n    self_intro: \"\",\r\n    user_id: \"\",\r\n    user_email: \"\",\r\n    location: \"\",\r\n    age: \"\",\r\n  });\r\n  const [Img, setImg] = useState(\"\");\r\n  const [imgBase64, setImgBase64] = useState(\"\");\r\n  const [imgFile, setImgFile] = useState(null);\r\n\r\n  const handleChangeFile = (event) => {\r\n    let reader = new FileReader();\r\n    reader.onloadend = () => {\r\n      // 2. 읽기가 완료되면 아래코드가 실행됩니다.\r\n      const base64 = reader.result;\r\n      if (base64) {\r\n        setImgBase64(base64.toString()); // 파일 base64 상태 업데이트\r\n      }\r\n    };\r\n    if (event.target.files[0]) {\r\n      reader.readAsDataURL(event.target.files[0]); // 1. 파일을 읽어 버퍼에 저장합니다.\r\n      setImgFile(event.target.files[0]); // 파일 상태 업데이트\r\n    }\r\n  };\r\n\r\n  const onChangeProfilePhoto = (e) =>\r\n    setProfile({ profile_photo: e.target.value });\r\n  const onChangeSelfIntro = (e) => setProfile({ self_intro: e.target.value });\r\n  const onChangeLocation = (e) => setProfile({ location: e.target.value });\r\n  const onChangeAge = (e) => setProfile({ age: e.target.value });\r\n\r\n  useEffect(async () => {\r\n    async function fetchData() {\r\n      console.log(\"writeProfile axios get 호출\");\r\n      let res = await axios.get(\"http://localhost:3001/getProfileInfo\");\r\n      console.log(res);\r\n      console.dir(res.data[0]);\r\n      if (res.data[0] != undefined) {\r\n        setProfile(res.data[0]);\r\n        setImg(\"http://localhost:3001/uploads/\" + res.data[0].profile_photo);\r\n      }\r\n    }\r\n    fetchData();\r\n  }, []);\r\n\r\n  return (\r\n    <div>\r\n      <label>기존 프로필 사진</label>\r\n      <br></br>\r\n      <img src={Img} width=\"200px\" height=\"200px\"></img>\r\n      <br></br>\r\n      <label>선택한 프로필 사진</label>\r\n      <br></br>\r\n      {/* <div\r\n        style={{ backgroundColor: \"#efefef\", width: \"200px\", height: \"200px\" }}\r\n      > */}\r\n      <img src={imgBase64} width=\"200px\" height=\"200px\" />\r\n      {/* </div> */}\r\n      <form\r\n        method=\"post\"\r\n        action=\"http://localhost:3001/writeProfile\"\r\n        encType=\"multipart/form-data\"\r\n      >\r\n        <label>프로필 사진</label>\r\n        <input\r\n          type=\"file\"\r\n          name=\"photo\"\r\n          //value=\"http://localhost:3001/uploads/\"+`{Profile.profile_photo}`\r\n          // onChange={onChangeProfilePhoto}\r\n          onChange={handleChangeFile}\r\n        ></input>\r\n        <br></br>\r\n        <input\r\n          type=\"text\"\r\n          name=\"self_intro\"\r\n          placeholder=\"간단한 자기소개 및 관심사\"\r\n          value={Profile.self_intro}\r\n          onChange={onChangeSelfIntro}\r\n        ></input>\r\n        <br></br>\r\n        <input\r\n          type=\"text\"\r\n          name=\"age\"\r\n          placeholder=\"나이\"\r\n          value={Profile.age}\r\n          onChange={onChangeAge}\r\n        ></input>\r\n        <br></br>\r\n        <input\r\n          type=\"text\"\r\n          name=\"loc\"\r\n          placeholder=\"사는 곳\"\r\n          value={Profile.location}\r\n          onChange={onChangeLocation}\r\n        ></input>\r\n        <br></br>\r\n        <button type=\"submit\">작성 완료</button>\r\n      </form>\r\n    </div>\r\n  );\r\n};\r\n\r\nexport default WriteProfile;\r\n",{"ruleId":"84","replacedBy":"85"},{"ruleId":"86","replacedBy":"87"},{"ruleId":"88","severity":1,"message":"89","line":1,"column":17,"nodeType":"90","messageId":"91","endLine":1,"endColumn":26},{"ruleId":"84","replacedBy":"92"},{"ruleId":"86","replacedBy":"93"},{"ruleId":"94","severity":1,"message":"95","line":29,"column":13,"nodeType":"96","endLine":41,"endColumn":4},{"ruleId":"94","severity":1,"message":"97","line":41,"column":6,"nodeType":"98","endLine":41,"endColumn":8,"suggestions":"99"},{"ruleId":"100","severity":1,"message":"101","line":51,"column":15,"nodeType":"102","endLine":51,"endColumn":59},{"ruleId":"88","severity":1,"message":"103","line":2,"column":10,"nodeType":"90","messageId":"91","endLine":2,"endColumn":15},{"ruleId":"94","severity":1,"message":"95","line":18,"column":13,"nodeType":"96","endLine":39,"endColumn":4},{"ruleId":"94","severity":1,"message":"104","line":39,"column":6,"nodeType":"98","endLine":39,"endColumn":8,"suggestions":"105"},{"ruleId":"88","severity":1,"message":"103","line":2,"column":10,"nodeType":"90","messageId":"91","endLine":2,"endColumn":15},{"ruleId":"88","severity":1,"message":"106","line":3,"column":10,"nodeType":"90","messageId":"91","endLine":3,"endColumn":14},{"ruleId":"88","severity":1,"message":"106","line":2,"column":10,"nodeType":"90","messageId":"91","endLine":2,"endColumn":14},{"ruleId":"88","severity":1,"message":"107","line":4,"column":10,"nodeType":"90","messageId":"91","endLine":4,"endColumn":15},{"ruleId":"88","severity":1,"message":"108","line":5,"column":10,"nodeType":"90","messageId":"91","endLine":5,"endColumn":17},{"ruleId":"88","severity":1,"message":"109","line":6,"column":10,"nodeType":"90","messageId":"91","endLine":6,"endColumn":15},{"ruleId":"88","severity":1,"message":"110","line":10,"column":9,"nodeType":"90","messageId":"91","endLine":10,"endColumn":22},{"ruleId":"84","replacedBy":"111"},{"ruleId":"86","replacedBy":"112"},{"ruleId":"94","severity":1,"message":"95","line":31,"column":13,"nodeType":"96","endLine":56,"endColumn":4},{"ruleId":"113","severity":1,"message":"114","line":43,"column":38,"nodeType":"115","messageId":"116","endLine":43,"endColumn":40},{"ruleId":"94","severity":1,"message":"117","line":56,"column":6,"nodeType":"98","endLine":56,"endColumn":8,"suggestions":"118"},{"ruleId":"100","severity":1,"message":"101","line":69,"column":11,"nodeType":"102","endLine":69,"endColumn":73},{"ruleId":"88","severity":1,"message":"119","line":16,"column":10,"nodeType":"90","messageId":"91","endLine":16,"endColumn":17},{"ruleId":"88","severity":1,"message":"120","line":33,"column":9,"nodeType":"90","messageId":"91","endLine":33,"endColumn":29},{"ruleId":"94","severity":1,"message":"95","line":39,"column":13,"nodeType":"96","endLine":51,"endColumn":4},{"ruleId":"113","severity":1,"message":"114","line":45,"column":23,"nodeType":"115","messageId":"116","endLine":45,"endColumn":25},{"ruleId":"100","severity":1,"message":"101","line":57,"column":7,"nodeType":"102","endLine":57,"endColumn":51},{"ruleId":"100","severity":1,"message":"101","line":64,"column":7,"nodeType":"102","endLine":64,"endColumn":59},"no-native-reassign",["121"],"no-negated-in-lhs",["122"],"no-unused-vars","'Component' is defined but never used.","Identifier","unusedVar",["121"],["122"],"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","React Hook useEffect has a missing dependency: 'email'. Either include it or remove the dependency array.","ArrayExpression",["123"],"jsx-a11y/alt-text","img elements must have an alt prop, either with meaningful text, or an empty string for decorative images.","JSXOpeningElement","'Route' is defined but never used.","React Hook useEffect has a missing dependency: 'input'. Either include it or remove the dependency array.",["124"],"'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.",["121"],["122"],"eqeqeq","Expected '!==' and instead saw '!='.","BinaryExpression","unexpected","React Hook useEffect has missing dependencies: 'Board' and 'board_id'. Either include them or remove the dependency array.",["125"],"'imgFile' is assigned a value but never used.","'onChangeProfilePhoto' is assigned a value but never used.","no-global-assign","no-unsafe-negation",{"desc":"126","fix":"127"},{"desc":"128","fix":"129"},{"desc":"130","fix":"131"},"Update the dependencies array to be: [email]",{"range":"132","text":"133"},"Update the dependencies array to be: [input]",{"range":"134","text":"135"},"Update the dependencies array to be: [Board, board_id]",{"range":"136","text":"137"},[1071,1073],"[email]",[1141,1143],"[input]",[1542,1544],"[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","C:\\WYH\\frontend\\src\\components\\WriteProfile.js":"11"},{"size":362,"mtime":1606157613272,"results":"12","hashOfConfig":"13"},{"size":1764,"mtime":1607415610889,"results":"14","hashOfConfig":"13"},{"size":544,"mtime":1606240034288,"results":"15","hashOfConfig":"13"},{"size":2234,"mtime":1607425040281,"results":"16","hashOfConfig":"13"},{"size":4100,"mtime":1607506999836,"results":"17","hashOfConfig":"13"},{"size":370,"mtime":1606662762631,"results":"18","hashOfConfig":"13"},{"size":1575,"mtime":1607345129868,"results":"19","hashOfConfig":"13"},{"size":1232,"mtime":1606662786263,"results":"20","hashOfConfig":"13"},{"size":3419,"mtime":1607104090152,"results":"21","hashOfConfig":"13"},{"size":4431,"mtime":1607715505644,"results":"22","hashOfConfig":"13"},{"size":3396,"mtime":1607369801073,"results":"23","hashOfConfig":"13"},{"filePath":"24","messages":"25","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"26"},"10w9ldj",{"filePath":"27","messages":"28","errorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},{"filePath":"29","messages":"30","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"31"},{"filePath":"32","messages":"33","errorCount":0,"warningCount":3,"fixableErrorCount":0,"fixableWarningCount":0,"source":"34","usedDeprecatedRules":"35"},{"filePath":"36","messages":"37","errorCount":0,"warningCount":3,"fixableErrorCount":0,"fixableWarningCount":0,"source":"38","usedDeprecatedRules":"39"},{"filePath":"40","messages":"41","errorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},{"filePath":"42","messages":"43","errorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"44"},{"filePath":"45","messages":"46","errorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"47"},{"filePath":"48","messages":"49","errorCount":0,"warningCount":4,"fixableErrorCount":0,"fixableWarningCount":0,"source":"50","usedDeprecatedRules":"31"},{"filePath":"51","messages":"52","errorCount":0,"warningCount":9,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},{"filePath":"53","messages":"54","errorCount":0,"warningCount":6,"fixableErrorCount":0,"fixableWarningCount":0,"source":"55","usedDeprecatedRules":"31"},"C:\\WYH\\frontend\\src\\reportWebVitals.js",[],["56","57"],"C:\\WYH\\frontend\\src\\App.js",["58"],"C:\\WYH\\frontend\\src\\index.js",[],["59","60"],"C:\\WYH\\frontend\\src\\components\\Profile.js",["61","62","63"],"import React, { useEffect, useState } from \"react\";\r\nimport axios from \"axios\";\r\nimport { Link } from \"react-router-dom\";\r\nimport { withRouter } from \"react-router-dom\";\r\naxios.defaults.withCredentials = true; // 기존에 해당 설정으로 cors 에러가 나게 한 부분\r\n\r\nconst Profile = ({ match, history }) => {\r\n  const { email } = match.params;\r\n  const [Profile, setProfile] = useState({\r\n    profile_photo: \"\",\r\n    created_at: \"\",\r\n    self_intro: \"\",\r\n    user_id: \"\",\r\n    user_email: \"\",\r\n    age: \"\",\r\n    location: \"\",\r\n  });\r\n\r\n  const [User, setUser] = useState({\r\n    email: \"\",\r\n    password: \"\",\r\n    name: \"\",\r\n    created_at: \"\",\r\n    deleted_at: \"\",\r\n  });\r\n\r\n  const [Img, setImg] = useState(\"\");\r\n\r\n  useEffect(async () => {\r\n    const fetchData = async () => {\r\n      const result = await axios.post(\"http://localhost:3001/profile\", {\r\n        email: email,\r\n      });\r\n      console.dir(result);\r\n      setProfile(result.data.p);\r\n      setUser(result.data.u);\r\n\r\n      setImg(\"http://localhost:3001/uploads/\" + result.data.p.profile_photo);\r\n    };\r\n    fetchData();\r\n  }, []);\r\n\r\n  return (\r\n    <>\r\n      <h1>{Profile.user_email} 의 프로필화면</h1>\r\n      <div>닉네임:{User.name}</div>\r\n      <div>자기소게:{Profile.self_intro}</div>\r\n      <div>나이:{Profile.age}</div>\r\n      <div>사는곳:{Profile.location}</div>\r\n      <div>\r\n        프로필사진:<img src={Img} width=\"200px\" height=\"200px\"></img>\r\n      </div>\r\n      <Link to=\"/board\">메인화면으로 돌아가기</Link>\r\n      <button onClick={() => history.goBack()}>뒤로가기</button>\r\n    </>\r\n  );\r\n};\r\n\r\n// const Profile = (login_info) => {\r\n//   const [user, setUser] = useState(\"\");\r\n\r\n//   fetch(\"/profile\", {\r\n//     method: \"get\",\r\n//     headers: {\r\n//       \"Content-Type\": \"application/json; charset=utf-8\",\r\n//     },\r\n//     credentials: \"same-origin\",\r\n//     body: JSON.stringify(login_info),\r\n//   })\r\n//     .then((res) => res.json())\r\n//     .then((data) => {\r\n//       console.dir(data);\r\n//       setUser(data);\r\n//     });\r\n\r\n//   return (\r\n//     <div>\r\n//       <h1>{user.username}</h1>\r\n//       <h1>{user.nicname}</h1>\r\n//     </div>\r\n//   );\r\n// };\r\n\r\nexport default withRouter(Profile);\r\n",["64","65"],"C:\\WYH\\frontend\\src\\components\\Board.js",["66","67","68"],"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  const [input, setInput] = useState(\"\");\r\n  const handleInputChange = (e) => {\r\n    setInput(e.target.value);\r\n    console.log(input);\r\n  };\r\n  const [choice, setChoice] = useState(\"ex/sp\");\r\n  const handleChangeSelect = (e) => {\r\n    setChoice(e.target.value);\r\n    console.log(choice);\r\n  };\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        input: input,\r\n      });\r\n      console.log(result.data);\r\n      setResponse(result.data);\r\n    }\r\n    fetchData();\r\n  }, []);\r\n\r\n  const handleOnSubmit = () => {\r\n    async function fetchData2() {\r\n      console.log(\"react board search axios 호출\");\r\n      const result2 = await axios.post(\"http://localhost:3001/searchBoard\", {\r\n        input: input,\r\n      });\r\n      console.log(result2.data);\r\n      setResponse(result2.data);\r\n    }\r\n    fetchData2();\r\n  };\r\n\r\n  const handleOnSubmit2 = () => {\r\n    async function fetchData3() {\r\n      console.log(\"react board search axios2 호출\");\r\n      const result3 = await axios.post(\"http://localhost:3001/searchHobby\", {\r\n        hobby: choice,\r\n      });\r\n      console.log(result3.data);\r\n      setResponse(result3.data);\r\n    }\r\n    fetchData3();\r\n  };\r\n\r\n  return (\r\n    <div>\r\n      <button>\r\n        <Link to=\"/writeBoard\">게시글 작성</Link>\r\n      </button>\r\n      <button>\r\n        <Link to=\"/updateProf\">프로필 작성</Link>\r\n      </button>\r\n\r\n      <input\r\n        type=\"text\"\r\n        //name=\"searchKeyword\"\r\n        onChange={handleInputChange}\r\n      ></input>\r\n      <button type=\"submit\" onClick={handleOnSubmit}>\r\n        게시글검색\r\n      </button>\r\n\r\n      {/* <form\r\n        action=\"http://localhost:3001/searchHobby\"\r\n        method=\"post\"\r\n        onSubmit={handleOnSubmit2}\r\n      > */}\r\n      <select name=\"choice\" onChange={handleChangeSelect}>\r\n        <option value=\"\" disabled>\r\n          검색할 취미를 선택하세요.\r\n        </option>\r\n        <option value=\"ex/sp\">운동/스포츠</option>\r\n        <option value=\"out/tr\">아웃도어/여행</option>\r\n        <option value=\"bk/wr\">인문학/책/글</option>\r\n        <option value=\"fg/lg\">외국/언어</option>\r\n        <option value=\"cul/pfm\">문화/공연</option>\r\n        <option value=\"mu/inst\">음악/악기</option>\r\n        <option value=\"cft\">공예/만들기</option>\r\n        <option value=\"dan\">댄스/무용</option>\r\n        <option value=\"volu\">봉사활동</option>\r\n        <option value=\"par\">사교/인맥</option>\r\n        <option value=\"game\">게임/오락</option>\r\n        <option value=\"pic\">사진/편집/촬영/영상</option>\r\n        <option value=\"inv\">제테크/투자</option>\r\n        <option value=\"cok/fod\">요리/음식/맛집</option>\r\n        <option value=\"fas/bea\">패션/뷰티/코디</option>\r\n        <option value=\"art/draw\">미술/그림</option>\r\n      </select>\r\n      <button type=\"submit\" onClick={handleOnSubmit2}>\r\n        게시글검색\r\n      </button>\r\n      {/* </form> */}\r\n\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",["69","70"],"C:\\WYH\\frontend\\src\\components\\Home.js",["71"],"C:\\WYH\\frontend\\src\\components\\Signup.js",["72"],"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",["73"],"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",["74","75","76","77"],"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",["78","79","80","81","82","83","84","85","86"],"C:\\WYH\\frontend\\src\\components\\WriteProfile.js",["87","88","89","90","91","92"],"import React, { useEffect, useState } from \"react\";\r\nimport axios from \"axios\";\r\n\r\nconst WriteProfile = () => {\r\n  const [Profile, setProfile] = useState({\r\n    profile_photo: \"\",\r\n    created_at: \"\",\r\n    self_intro: \"\",\r\n    user_id: \"\",\r\n    user_email: \"\",\r\n    location: \"\",\r\n    age: \"\",\r\n  });\r\n  const [Img, setImg] = useState(\"\");\r\n  const [imgBase64, setImgBase64] = useState(\"\");\r\n  const [imgFile, setImgFile] = useState(null);\r\n\r\n  const handleChangeFile = (event) => {\r\n    let reader = new FileReader();\r\n    reader.onloadend = () => {\r\n      // 2. 읽기가 완료되면 아래코드가 실행됩니다.\r\n      const base64 = reader.result;\r\n      if (base64) {\r\n        setImgBase64(base64.toString()); // 파일 base64 상태 업데이트\r\n      }\r\n    };\r\n    if (event.target.files[0]) {\r\n      reader.readAsDataURL(event.target.files[0]); // 1. 파일을 읽어 버퍼에 저장합니다.\r\n      setImgFile(event.target.files[0]); // 파일 상태 업데이트\r\n    }\r\n  };\r\n\r\n  const onChangeProfilePhoto = (e) =>\r\n    setProfile({ profile_photo: e.target.value });\r\n  const onChangeSelfIntro = (e) => setProfile({ self_intro: e.target.value });\r\n  const onChangeLocation = (e) => setProfile({ location: e.target.value });\r\n  const onChangeAge = (e) => setProfile({ age: e.target.value });\r\n\r\n  useEffect(async () => {\r\n    async function fetchData() {\r\n      console.log(\"writeProfile axios get 호출\");\r\n      let res = await axios.get(\"http://localhost:3001/getProfileInfo\");\r\n      console.log(res);\r\n      console.dir(res.data[0]);\r\n      if (res.data[0] != undefined) {\r\n        setProfile(res.data[0]);\r\n        setImg(\"http://localhost:3001/uploads/\" + res.data[0].profile_photo);\r\n      }\r\n    }\r\n    fetchData();\r\n  }, []);\r\n\r\n  return (\r\n    <div>\r\n      <label>기존 프로필 사진</label>\r\n      <br></br>\r\n      <img src={Img} width=\"200px\" height=\"200px\"></img>\r\n      <br></br>\r\n      <label>선택한 프로필 사진</label>\r\n      <br></br>\r\n      {/* <div\r\n        style={{ backgroundColor: \"#efefef\", width: \"200px\", height: \"200px\" }}\r\n      > */}\r\n      <img src={imgBase64} width=\"200px\" height=\"200px\" />\r\n      {/* </div> */}\r\n      <form\r\n        method=\"post\"\r\n        action=\"http://localhost:3001/writeProfile\"\r\n        encType=\"multipart/form-data\"\r\n      >\r\n        <label>프로필 사진</label>\r\n        <input\r\n          type=\"file\"\r\n          name=\"photo\"\r\n          //value=\"http://localhost:3001/uploads/\"+`{Profile.profile_photo}`\r\n          // onChange={onChangeProfilePhoto}\r\n          onChange={handleChangeFile}\r\n        ></input>\r\n        <br></br>\r\n        <input\r\n          type=\"text\"\r\n          name=\"self_intro\"\r\n          placeholder=\"간단한 자기소개 및 관심사\"\r\n          value={Profile.self_intro}\r\n          onChange={onChangeSelfIntro}\r\n        ></input>\r\n        <br></br>\r\n        <input\r\n          type=\"text\"\r\n          name=\"age\"\r\n          placeholder=\"나이\"\r\n          value={Profile.age}\r\n          onChange={onChangeAge}\r\n        ></input>\r\n        <br></br>\r\n        <input\r\n          type=\"text\"\r\n          name=\"loc\"\r\n          placeholder=\"사는 곳\"\r\n          value={Profile.location}\r\n          onChange={onChangeLocation}\r\n        ></input>\r\n        <br></br>\r\n        <button type=\"submit\">작성 완료</button>\r\n      </form>\r\n    </div>\r\n  );\r\n};\r\n\r\nexport default WriteProfile;\r\n",{"ruleId":"93","replacedBy":"94"},{"ruleId":"95","replacedBy":"96"},{"ruleId":"97","severity":1,"message":"98","line":1,"column":17,"nodeType":"99","messageId":"100","endLine":1,"endColumn":26},{"ruleId":"93","replacedBy":"101"},{"ruleId":"95","replacedBy":"102"},{"ruleId":"103","severity":1,"message":"104","line":29,"column":13,"nodeType":"105","endLine":41,"endColumn":4},{"ruleId":"103","severity":1,"message":"106","line":41,"column":6,"nodeType":"107","endLine":41,"endColumn":8,"suggestions":"108"},{"ruleId":"109","severity":1,"message":"110","line":51,"column":15,"nodeType":"111","endLine":51,"endColumn":59},{"ruleId":"93","replacedBy":"112"},{"ruleId":"95","replacedBy":"113"},{"ruleId":"97","severity":1,"message":"114","line":2,"column":10,"nodeType":"99","messageId":"100","endLine":2,"endColumn":15},{"ruleId":"103","severity":1,"message":"104","line":18,"column":13,"nodeType":"105","endLine":39,"endColumn":4},{"ruleId":"103","severity":1,"message":"115","line":39,"column":6,"nodeType":"107","endLine":39,"endColumn":8,"suggestions":"116"},{"ruleId":"93","replacedBy":"117"},{"ruleId":"95","replacedBy":"118"},{"ruleId":"97","severity":1,"message":"114","line":2,"column":10,"nodeType":"99","messageId":"100","endLine":2,"endColumn":15},{"ruleId":"97","severity":1,"message":"119","line":3,"column":10,"nodeType":"99","messageId":"100","endLine":3,"endColumn":14},{"ruleId":"97","severity":1,"message":"119","line":2,"column":10,"nodeType":"99","messageId":"100","endLine":2,"endColumn":14},{"ruleId":"97","severity":1,"message":"120","line":4,"column":10,"nodeType":"99","messageId":"100","endLine":4,"endColumn":15},{"ruleId":"97","severity":1,"message":"121","line":5,"column":10,"nodeType":"99","messageId":"100","endLine":5,"endColumn":17},{"ruleId":"97","severity":1,"message":"122","line":6,"column":10,"nodeType":"99","messageId":"100","endLine":6,"endColumn":15},{"ruleId":"97","severity":1,"message":"123","line":10,"column":9,"nodeType":"99","messageId":"100","endLine":10,"endColumn":22},{"ruleId":"97","severity":1,"message":"124","line":25,"column":10,"nodeType":"99","messageId":"100","endLine":25,"endColumn":15},{"ruleId":"97","severity":1,"message":"125","line":29,"column":9,"nodeType":"99","messageId":"100","endLine":29,"endColumn":22},{"ruleId":"103","severity":1,"message":"104","line":34,"column":13,"nodeType":"105","endLine":60,"endColumn":4},{"ruleId":"126","severity":1,"message":"127","line":47,"column":38,"nodeType":"128","messageId":"129","endLine":47,"endColumn":40},{"ruleId":"103","severity":1,"message":"130","line":60,"column":6,"nodeType":"107","endLine":60,"endColumn":8,"suggestions":"131"},{"ruleId":"97","severity":1,"message":"132","line":62,"column":9,"nodeType":"99","messageId":"100","endLine":62,"endColumn":20},{"ruleId":"109","severity":1,"message":"110","line":84,"column":11,"nodeType":"111","endLine":84,"endColumn":73},{"ruleId":"133","severity":1,"message":"134","line":106,"column":33,"nodeType":"105","messageId":"135","endLine":106,"endColumn":35},{"ruleId":"126","severity":1,"message":"136","line":107,"column":35,"nodeType":"128","messageId":"129","endLine":107,"endColumn":37},{"ruleId":"97","severity":1,"message":"137","line":16,"column":10,"nodeType":"99","messageId":"100","endLine":16,"endColumn":17},{"ruleId":"97","severity":1,"message":"138","line":33,"column":9,"nodeType":"99","messageId":"100","endLine":33,"endColumn":29},{"ruleId":"103","severity":1,"message":"104","line":39,"column":13,"nodeType":"105","endLine":51,"endColumn":4},{"ruleId":"126","severity":1,"message":"127","line":45,"column":23,"nodeType":"128","messageId":"129","endLine":45,"endColumn":25},{"ruleId":"109","severity":1,"message":"110","line":57,"column":7,"nodeType":"111","endLine":57,"endColumn":51},{"ruleId":"109","severity":1,"message":"110","line":64,"column":7,"nodeType":"111","endLine":64,"endColumn":59},"no-native-reassign",["139"],"no-negated-in-lhs",["140"],"no-unused-vars","'Component' is defined but never used.","Identifier","unusedVar",["139"],["140"],"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","React Hook useEffect has a missing dependency: 'email'. Either include it or remove the dependency array.","ArrayExpression",["141"],"jsx-a11y/alt-text","img elements must have an alt prop, either with meaningful text, or an empty string for decorative images.","JSXOpeningElement",["139"],["140"],"'Route' is defined but never used.","React Hook useEffect has a missing dependency: 'input'. Either include it or remove the dependency array.",["142"],["139"],["140"],"'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.","'reply' is assigned a value but never used.","'onChangeReply' is assigned a value but never used.","eqeqeq","Expected '!==' and instead saw '!='.","BinaryExpression","unexpected","React Hook useEffect has missing dependencies: 'Board' and 'board_id'. Either include them or remove the dependency array.",["143"],"'handleReply' is assigned a value but never used.","array-callback-return","Array.prototype.map() expects a value to be returned at the end of arrow function.","expectedAtEnd","Expected '===' and instead saw '=='.","'imgFile' is assigned a value but never used.","'onChangeProfilePhoto' is assigned a value but never used.","no-global-assign","no-unsafe-negation",{"desc":"144","fix":"145"},{"desc":"146","fix":"147"},{"desc":"148","fix":"149"},"Update the dependencies array to be: [email]",{"range":"150","text":"151"},"Update the dependencies array to be: [input]",{"range":"152","text":"153"},"Update the dependencies array to be: [Board, board_id]",{"range":"154","text":"155"},[1071,1073],"[email]",[1141,1143],"[input]",[1732,1734],"[Board, board_id]"]
\ No newline at end of file
diff --git a/frontend/src/components/DetailBoard.js b/frontend/src/components/DetailBoard.js
index a3303b5..993ba61 100644
--- a/frontend/src/components/DetailBoard.js
+++ b/frontend/src/components/DetailBoard.js
@@ -22,8 +22,11 @@ const DetailBoard = ({ match }) => {
   const [Comments, setComments] = useState([]);
   const [Imgurl, setImgurl] = useState("");
   const [Comment, setComment] = useState("");
+  const [reply, setReply] = useState("");
+  const [Replies, setReplies] = useState([]);
 
   const onChangeComment = (e) => setComment(e.target.value);
+  const onChangeReply = (e) => setReply(e.target.value);
 
   console.dir(match.params);
   console.log("board_id : " + board_id);
@@ -39,6 +42,7 @@ const DetailBoard = ({ match }) => {
       setBoard(res.data.detailBoard);
       console.log(Board);
       setComments(res.data.boardComments);
+      setReplies(res.data.boardReplies);
       if (
         res.data.detailBoard.picture != "" &&
         res.data.detailBoard.picture != null
@@ -55,6 +59,17 @@ const DetailBoard = ({ match }) => {
     fetchData();
   }, []);
 
+  const handleReply = async (id) => {
+    const c_id = id;
+    async function fetchReplies(cid) {
+      console.log("fetch reply axios 호출");
+      const result = await axios.post("http://localhost:3001/postReply");
+      console.log(result);
+      setReplies(result);
+    }
+    fetchReplies(c_id);
+  };
+
   return (
     <>
       <Link to="/board">홈으로</Link>
@@ -87,7 +102,27 @@ const DetailBoard = ({ match }) => {
         <ol>
           {Comments.map((c) => (
             <li key={c._id}>
-              {c.input} <Link to={`/profile/${c.writer}`}>{c.writer}</Link>
+              {c.input} <Link to={`/profile/${c.writer}`}>{c.writer}</Link>{" "}
+              {Replies.map((re) => {
+                if (re.comment_id == c._id) {
+                  return (
+                    <div key={re._id}>
+                      - {re.reply_content}{" "}
+                      <Link to={`/profile/${re.writer}`}>{re.writer}</Link>
+                    </div>
+                  );
+                }
+              })}
+              <form method="post" action="http://localhost:3001/postReply">
+                <input type="text" name="reply"></input>
+                <input type="hidden" name="comment_id" value={c._id}></input>
+                <input type="hidden" name="boardId" value={Board._id}></input>
+                <input type="hidden" name="writer"></input>
+                <button type="submit">답글작성</button>
+              </form>
+              {/* <input type="text" value={reply} onChange={onChangeReply}></input>
+              <input type="hidden" value={c._id}></input>
+              <button onClick={() => handleReply(c._id)}>답글작성</button> */}
             </li>
           ))}
         </ol>
-- 
GitLab