diff --git a/package-lock.json b/package-lock.json
index 5d7e156..a12f7fa 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -14,7 +14,7 @@
"@mui/material": "^5.14.18",
"@types/jsonwebtoken": "^9.0.5",
"axios": "^1.6.2",
- "base-64": "^1.0.0",
+ "bcryptjs": "^2.4.3",
"cookie": "^0.6.0",
"js-cookie": "^3.0.5",
"jsonwebtoken": "^9.0.2",
@@ -26,6 +26,7 @@
"sass": "^1.69.5"
},
"devDependencies": {
+ "@types/bcryptjs": "^2.4.6",
"@types/js-cookie": "^3.0.6",
"@types/node": "^20",
"@types/react": "^18",
@@ -1037,6 +1038,12 @@
"tslib": "^2.4.0"
}
},
+ "node_modules/@types/bcryptjs": {
+ "version": "2.4.6",
+ "resolved": "https://registry.npmjs.org/@types/bcryptjs/-/bcryptjs-2.4.6.tgz",
+ "integrity": "sha512-9xlo6R2qDs5uixm0bcIqCeMCE6HiQsIyel9KQySStiyqNl2tnj2mP3DX1Nf56MD6KMenNNlBBsy3LJ7gUEQPXQ==",
+ "dev": true
+ },
"node_modules/@types/js-cookie": {
"version": "3.0.6",
"resolved": "https://registry.npmjs.org/@types/js-cookie/-/js-cookie-3.0.6.tgz",
@@ -1562,10 +1569,10 @@
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
"dev": true
},
- "node_modules/base-64": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/base-64/-/base-64-1.0.0.tgz",
- "integrity": "sha512-kwDPIFCGx0NZHog36dj+tHiwP4QMzsZ3AgMViUBKI0+V5n4U0ufTCUMhnQ04diaRI8EX/QcPfql7zlhZ7j4zgg=="
+ "node_modules/bcryptjs": {
+ "version": "2.4.3",
+ "resolved": "https://registry.npmjs.org/bcryptjs/-/bcryptjs-2.4.3.tgz",
+ "integrity": "sha512-V/Hy/X9Vt7f3BbPJEi8BdVFMByHi+jNXrYkW3huaybV/kQ0KJg0Y6PkEMbn+zeT+i+SiKZ/HMqJGIIt4LZDqNQ=="
},
"node_modules/binary-extensions": {
"version": "2.2.0",
diff --git a/package.json b/package.json
index 34933a3..56c120c 100644
--- a/package.json
+++ b/package.json
@@ -15,7 +15,7 @@
"@mui/material": "^5.14.18",
"@types/jsonwebtoken": "^9.0.5",
"axios": "^1.6.2",
- "base-64": "^1.0.0",
+ "bcryptjs": "^2.4.3",
"cookie": "^0.6.0",
"js-cookie": "^3.0.5",
"jsonwebtoken": "^9.0.2",
@@ -27,6 +27,7 @@
"sass": "^1.69.5"
},
"devDependencies": {
+ "@types/bcryptjs": "^2.4.6",
"@types/js-cookie": "^3.0.6",
"@types/node": "^20",
"@types/react": "^18",
diff --git a/src/app/detail/page.tsx b/src/app/detail/page.tsx
index 6238ce2..168a9eb 100644
--- a/src/app/detail/page.tsx
+++ b/src/app/detail/page.tsx
@@ -38,8 +38,7 @@ export default function Detail(): JSX.Element {
const fetchData = async () => {
try {
const response = await axios.get(
- // `https://www.jerneithe.site/board/detail/${boardDetail.boardId}`,
- "https://www.jerneithe.site/board/detail/15",
+ `https://www.jerneithe.site/board/detail/${boardDetail.boardId}`,
);
setBoardDetail(response.data);
} catch (error) {
@@ -109,7 +108,8 @@ export default function Detail(): JSX.Element {
{decoded_nickName === boardDetail.nickName && (
+ className="ml-auto flex flex-col items-center"
+ >
diff --git a/src/app/mypage/page.tsx b/src/app/mypage/page.tsx
index d0fb9f1..f67fca1 100644
--- a/src/app/mypage/page.tsx
+++ b/src/app/mypage/page.tsx
@@ -96,12 +96,23 @@ export default function Mypage() {
const response = await axios.post(
`https://www.jerneithe.site/user/api/profile`,
- { email: "user94@test.com" }
+ { email: "user95@test.com" }
);
setUserProfile(response.data);
// 비밀번호 디코딩
- let pw_jwt: string = response.data.password;
+ // console.log("회원정보 pw: ", response.data.password);
+ // let pw_jwt = response.data.password;
+ // let pw_payload = pw_jwt.substring(
+ // pw_jwt.indexOf(".") + 1,
+ // pw_jwt.lastIndexOf(".")
+ // );
+
+ // console.log("pw_payload: ", pw_payload);
+
+ // let pw_decode = base64.decode(pw_payload);
+
+ // console.log("pw 디코딩: ", pw_decode);
// 기존 것
// let password_jwt: string = response.data.password;
@@ -112,7 +123,7 @@ export default function Mypage() {
// const decoded_password = decodedPass?.sub;
// setPassword(decoded_password);
- console.log("postData: ", response.data);
+ console.log("회원정보 Data: ", response.data);
} catch (error) {
console.error("회원정보 에러: ", error);
}
@@ -120,22 +131,20 @@ export default function Mypage() {
profileData();
}, []);
- // ---------------------------------------------------------
+ // ------------------------------------------------------------------------
// board 이미지 데이터 불러오기
useEffect(() => {
const postData = async () => {
const req = await axios.get("https://www.jerneithe.site/board/list");
const data: FEEDATA[] = req.data;
- const filteredData = data.filter((item) => item.nickName === "dongdong");
+ const filteredData = data.filter((item) => item.nickName === "테스터");
console.log("filterData: ", filteredData);
setMyPostData(filteredData);
};
postData();
}, []);
- console.log("디코딩 비번: ", password);
-
// 회원 정보 수정 모달 이벤트
const handleSettingsClick = () => {
setShowProfileModify(!showProfileModify);
@@ -155,12 +164,16 @@ export default function Mypage() {
{/* ------------- 프로필 부분 ------------- */}
{userPofile && (
<>
-
+
>
)}
{/* --------------------------------------- */}
{/* ------------- tap 부분 ------------- */}
-
+ {/* */}
@@ -177,7 +190,7 @@ export default function Mypage() {
handleSettingsClick={handleSettingsClick}
email={userPofile.email}
name={userPofile.name}
- password={password}
+ password={userPofile.password}
/>
)}
>
diff --git a/src/component/CommentModal.tsx b/src/component/CommentModal.tsx
index 478f10e..184be66 100644
--- a/src/component/CommentModal.tsx
+++ b/src/component/CommentModal.tsx
@@ -2,6 +2,8 @@ import { useState } from "react";
import "../style/modal_comment.scss";
import Comment from "./Comment";
import Reply from "./Reply";
+import axios from "axios";
+import { Result } from "postcss";
// interface handleCommentClickProps {
// handleCommentClick: () => void;
@@ -12,11 +14,13 @@ interface CommentModalProps {
}
interface ReplyType {
+ id: number;
text: string;
createdAt: Date;
}
interface CommentType {
+ id: number;
nickname: string;
comment: string;
reply: ReplyType[];
@@ -50,44 +54,121 @@ export default function CommentModal(props: CommentModalProps) {
index: number
) => {
const newReply = [...reply];
- newReply[index] = { text: e.target.value, createdAt: new Date() };
+ newReply[index] = { id: 0, text: e.target.value, createdAt: new Date() };
setReply(newReply);
};
- const handleFormSubmit = (e: React.FormEvent) => {
+ const handleFormSubmit = async (e: React.FormEvent) => {
e.preventDefault();
+
if (comment.trim() === "") {
alert("댓글을 입력해주세요");
return;
}
- setComments([
- ...comments,
- {
- nickname: user.nickname,
- comment: comment,
- reply: [],
- showReplyInput: false,
- isDeleted: false,
- createdAt: new Date(),
- },
- ]);
- setComment("");
+
+ try {
+ const comRes = await axios({
+ method: "POST",
+ url: "https://www.jerneithe.site/comment/write",
+ headers: {
+ Authorization:
+ "Bearer eyJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE3MDEzOTI0NTUsImV4cCI6MTcwMTQwMzI1NSwic3ViIjoi7YWM7Iqk7YSwIn0.IW2xr6LD3aq0Wsxl1kBqce-YtxQBn4whGBAsrTDKNc0",
+ },
+ data: {
+ boardId: 4,
+ content: comment,
+ },
+ });
+
+ console.log("댓글 작성 응답: ", comRes.data);
+
+ const comResData = comRes.data;
+
+ setComments([
+ ...comments,
+ {
+ id: comResData.id, // 댓글 아이디
+ nickname: comResData.nickname,
+ comment: comment,
+ reply: [],
+ showReplyInput: false,
+ isDeleted: false,
+ createdAt: new Date(),
+ },
+ ]);
+ setComment("");
+ } catch (err) {
+ console.log("댓글 작성 에러: ", err);
+ }
+
+ // 기존 코드
+ // if (comment.trim() === "") {
+ // alert("댓글을 입력해주세요");
+ // return;
+ // }
+ // setComments([
+ // ...comments,
+ // {
+ // nickname: user.nickname,
+ // comment: comment,
+ // reply: [],
+ // showReplyInput: false,
+ // isDeleted: false,
+ // createdAt: new Date(),
+ // },
+ // ]);
+ // setComment("");
};
- const handleReplySubmit = (e: React.FormEvent, index: number) => {
+ const handleReplySubmit = async (e: React.FormEvent, index: number) => {
e.preventDefault();
if (!reply[index]?.text || reply[index]?.text.trim() === "") {
alert("답글을 입력해주세요");
return;
}
- comments[index].reply.push(reply[index]);
- setComments([...comments]);
- setReply([
- ...reply.slice(0, index),
- { text: "", createdAt: new Date() },
- ...reply.slice(index + 1),
- ]);
+ try {
+ const repRes = await axios({
+ method: "POST",
+ url: "https://www.jerneithe.site/comment/reply",
+ headers: {
+ Authorization:
+ "Bearer eyJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE3MDEzOTI0NTUsImV4cCI6MTcwMTQwMzI1NSwic3ViIjoi7YWM7Iqk7YSwIn0.IW2xr6LD3aq0Wsxl1kBqce-YtxQBn4whGBAsrTDKNc0",
+ },
+ data: {
+ commentId: comments[index].id, // 답글을 작성할 댓글 ID
+ content: reply[index].text, // 답글 내용
+ },
+ });
+
+ console.log("답글 작성 응답: ", repRes.data);
+
+ // 서버로부터 받은 답글 id를 저장함
+ const newReply: ReplyType = {
+ id: repRes.data.id, // 답글 id 추가
+ text: reply[index].text,
+ createdAt: new Date(),
+ };
+
+ comments[index].reply.push(newReply);
+ setComments([...comments]);
+ setReply([
+ ...reply.slice(0, index),
+ { id: repRes.data.id, text: "", createdAt: new Date() },
+ ...reply.slice(index + 1),
+ ]);
+ } catch (err) {
+ console.log(err);
+ }
+
+ // 기존 코드
+ // comments[index].reply.push(reply[index]);
+ // setComments([...comments]);
+ // setReply([
+ // ...reply.slice(0, index),
+ // { text: "", createdAt: new Date() },
+ // ...reply.slice(index + 1),
+ // ]);
};
const handleReplyClick = (index: number) => {
@@ -117,18 +198,79 @@ export default function CommentModal(props: CommentModalProps) {
setEditText(e.target.value);
};
- const handleEditSubmit = (e: React.FormEvent) => {
+ const handleEditSubmit = async (e: React.FormEvent) => {
e.preventDefault();
+
+ // 댓글 수정
if (editing) {
if (editing.type === "comment") {
- comments[editing.index].comment = editText;
- } else if (editing.type === "reply" && editing.replyIndex !== undefined) {
- comments[editing.index].reply[editing.replyIndex].text = editText;
+ try {
+ const comEdit = await axios({
+ method: "PATCH",
+ url: "https://www.jerneithe.site/comment/modify",
+ headers: {
+ Authorization:
+ "Bearer eyJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE3MDEzOTI0NTUsImV4cCI6MTcwMTQwMzI1NSwic3ViIjoi7YWM7Iqk7YSwIn0.IW2xr6LD3aq0Wsxl1kBqce-YtxQBn4whGBAsrTDKNc0",
+ },
+ data: {
+ id: comments[editing.index].id, // 수정할 댓글 ID
+ content: editText, // 수정할 내용
+ },
+ });
+
+ console.log("댓글 수정 결과: ", comEdit);
+
+ comments[editing.index].comment = editText; // 상태 업데이트
+ setComments([...comments]);
+ setEditing(undefined);
+ setEditText("");
+ } catch (err) {
+ console.log(err);
+ }
+ }
+
+ // 답글 수정
+ if (editing) {
+ if (editing.type === "reply" && editing.replyIndex !== undefined) {
+ try {
+ const repEditRes = await axios({
+ method: "PATCH",
+ url: "https://www.jerneithe.site/comment/modify/reply",
+ headers: {
+ Authorization:
+ "Bearer eyJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE3MDEzOTI0NTUsImV4cCI6MTcwMTQwMzI1NSwic3ViIjoi7YWM7Iqk7YSwIn0.IW2xr6LD3aq0Wsxl1kBqce-YtxQBn4whGBAsrTDKNc0",
+ },
+ data: {
+ id: comments[editing.index].reply[editing.replyIndex].id, // 수정할 답글 ID
+ content: editText, // 수정할 내용
+ },
+ });
+
+ console.log("답글 수정 결과: ", repEditRes.data);
+
+ comments[editing.index].reply[editing.replyIndex].text = editText; // 상태 업데이트
+ setComments([...comments]);
+ setEditing(undefined);
+ setEditText("");
+ } catch (err) {
+ console.log(err);
+ }
+ }
+ // 나머지 코드...
}
- setComments([...comments]);
- setEditing(undefined);
- setEditText("");
}
+
+ // 기존 코드
+ // if (editing) {
+ // if (editing.type === "comment") {
+ // comments[editing.index].comment = editText;
+ // } else if (editing.type === "reply" && editing.replyIndex !== undefined) {
+ // comments[editing.index].reply[editing.replyIndex].text = editText;
+ // }
+ // setComments([...comments]);
+ // setEditing(undefined);
+ // setEditText("");
+ // }
};
const handleDelete = (index: number) => {
@@ -146,6 +288,7 @@ export default function CommentModal(props: CommentModalProps) {
setComments([...comments]);
};
+ // 시간 표시 데이터
const getTimeDiff = (date: Date) => {
const now = new Date();
const diffInMilliseconds = now.getTime() - date.getTime();
@@ -169,6 +312,8 @@ export default function CommentModal(props: CommentModalProps) {
nickname: "김똥이",
};
+ // ----------------------------------------------------------------------------------------------------------------------
+
return (
<>
diff --git a/src/component/MyPost.tsx b/src/component/MyPost.tsx
index 049966b..1c0d0c7 100644
--- a/src/component/MyPost.tsx
+++ b/src/component/MyPost.tsx
@@ -26,16 +26,34 @@ interface MyPostProps {
export default function MyPost(props: MyPostProps) {
const { myPostData } = props;
- // const posts = [1, 2, 3, 4, 5, 6, 7];
-
- // const [feedata, setFeedd] = useState
([]);
- // const email = "user91@test.com";
+ console.log("mypost 데이터: ", myPostData);
return (
- {/* {myPostData.map((item) => (
-
- {item.images ? (
+ {myPostData.length > 0 ? (
+ myPostData.map((item) => (
+
+ {item.images && (
+
+ )}
+
+ ))
+ ) : (
+ <>
+
게시물을 등록해주세요.
+ >
+ )}
+
+ );
+}
+
+{
+ /* {item.images ? (
게시물을 등록해주세요.
>
- )}
-
- ))} */}
-
- );
+ )} */
}
diff --git a/src/component/MypageProfile.tsx b/src/component/MypageProfile.tsx
index 0d3d623..7402b39 100644
--- a/src/component/MypageProfile.tsx
+++ b/src/component/MypageProfile.tsx
@@ -3,9 +3,12 @@ import React, { useEffect, useState } from "react";
import { useRecoilState } from "recoil";
import AccountCircleOutlinedIcon from "@mui/icons-material/AccountCircleOutlined";
import { FeedContent } from "@/recoilAtom/FeedContents";
+import TabBar from "./TabBar";
interface MyPageProfileProps {
nickname: string;
+ postnum: number;
+ myPostData: FEEDATA[];
}
interface IMAGE {
@@ -24,27 +27,7 @@ interface FEEDATA {
}
export default function MypageProfile(props: MyPageProfileProps) {
- const { nickname } = props;
-
- // const [feedata, setFeedd] = useRecoilState(FeedContent);
-
- // useEffect(() => {
-
- // const feed_data = async() => {
- // const req = await axios({
- // method: "GET",
- // url: "https://www.jerneithe.site/board/list",
- // });
-
- // console.log("받아온 데이터", req.data);
-
- // const copy:FEEDATA[] = req.data;
-
- // console.log("카피" ,copy);
-
- // }
-
- // feed_data(); }, []);
+ const { nickname, postnum, myPostData } = props;
return (
<>
@@ -56,7 +39,7 @@ export default function MypageProfile(props: MyPageProfileProps) {
좋아요 한 게시물
@@ -64,6 +47,7 @@ export default function MypageProfile(props: MyPageProfileProps) {
+
>
);
}
diff --git a/src/component/ProfileModal.tsx b/src/component/ProfileModal.tsx
index 075030c..a7c09db 100644
--- a/src/component/ProfileModal.tsx
+++ b/src/component/ProfileModal.tsx
@@ -3,6 +3,7 @@ import "../style/modal.scss";
import AccountCircleOutlinedIcon from "@mui/icons-material/AccountCircleOutlined";
import CloseIcon from "@mui/icons-material/Close";
import axios from "axios";
+import bcrypt from "bcryptjs";
// 회원 정보 수정 모달 컴포넌트
@@ -10,7 +11,7 @@ interface handleSettingsClickProps {
handleSettingsClick: () => void;
email: string;
name: string;
- password: string | undefined;
+ password: string;
}
export default function ProfileModal(props: handleSettingsClickProps) {
@@ -72,11 +73,18 @@ export default function ProfileModal(props: handleSettingsClickProps) {
e.preventDefault();
// 현재 비밀번호 확인
- if (currentPassword !== password) {
+ const isPasswordMatch = await bcrypt.compare(currentPassword, password);
+
+ if (!isPasswordMatch) {
alert("현재 비밀번호를 다시 입력하세요.");
return;
}
+ // if (currentPassword !== password) {
+ // alert("현재 비밀번호를 다시 입력하세요.");
+ // return;
+ // }
+
// 변경 비밀번호 확인
if (newPassword !== confirmPassword) {
alert("비밀번호 재확인을 다시 입력하세요.");
@@ -136,7 +144,6 @@ export default function ProfileModal(props: handleSettingsClickProps) {
{/* */}
이메일
-
비번: {password}
{email}
diff --git a/src/component/TestCommentModal.tsx b/src/component/TestCommentModal.tsx
new file mode 100644
index 0000000..1cb2bad
--- /dev/null
+++ b/src/component/TestCommentModal.tsx
@@ -0,0 +1 @@
+export default function TestCommentModal() {}
diff --git a/src/style/modal_comment.scss b/src/style/modal_comment.scss
index 682f136..bfbd902 100644
--- a/src/style/modal_comment.scss
+++ b/src/style/modal_comment.scss
@@ -16,10 +16,10 @@
position: fixed;
bottom: 0px;
height: 75%;
- .comment_form {
- position: fixed;
- bottom: 30px;
- }
+ // .comment_form {
+ // position: fixed;
+ // bottom: 30px;
+ // }
.commentList {
height: 80%;
overflow-y: auto;
diff --git a/src/style/mypage.scss b/src/style/mypage.scss
index 5e7167e..a46c074 100644
--- a/src/style/mypage.scss
+++ b/src/style/mypage.scss
@@ -27,6 +27,7 @@
}
.mypage_body {
width: 90%;
+ height: 100%;
// ------------ 프로필 부분
.user {
display: flex;
@@ -97,6 +98,7 @@
font-weight: bold;
text-align: center;
background-color: thistle;
+ position: relative;
}
}
}