Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions src/apis/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,14 @@ export const updateComment = async (id, data) => {
};

// 과제 !!
export const deleteComment = async (id) => {

export const deleteComment = async (id, data) => {
const response = await instanceWithToken.delete(`/comment/${id}/`, data);
if (response.status === 204) {
console.log("COMMENT DELETE SUCCESS");
window.location.reload();
} else {
console.log("[ERROR] error while deleting comment");
}
};

export const getUser = async () => {
Expand Down
49 changes: 27 additions & 22 deletions src/components/Comment/CommentElement.jsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { useState, useEffect } from "react";
import { getCookie } from "../../utils/cookie";
import { getUser, updateComment } from "../../apis/api";

const CommentElement = (props) => {
const { comment, handleCommentDelete, postId } = props;
const [content, setContent] = useState(comment.content);
const CommentElement = ({ comment, handleCommentDelete }) => {
const [isEdit, setIsEdit] = useState(false);

const [onChangeValue, setOnChangeValue] = useState(content); // 수정 취소 시 직전 content 값으로 변경을 위한 state

const [onChangeValue, setOnChangeValue] = useState(comment.content); // 수정 취소 시 직전 content 값으로 변경을 위한 state
const [user, setUser] = useState();
// comment created_at 전처리
const date = new Date(comment.created_at);
const year = date.getFullYear();
Expand All @@ -15,43 +15,48 @@ const CommentElement = (props) => {
let day = date.getDate();
day = day < 10 ? `0${day}` : day;

const handleEditComment = () => { // add api call for editing comment
setContent(onChangeValue);
setIsEdit(!isEdit);
console.log({
post: postId,
comment: comment.id,
content: content
});
};
useEffect(() => {
// access_token이 있으면 유저 정보 가져옴
const fetchUser = async () => {

try { if (getCookie("access_token"))

{ const user = await getUser(); setUser(user); }

} catch (error) { console.error("Error fetching user:", error); }

};

fetchUser();
}, []);

useEffect(() => { // add api call to check if user is the author of the comment
}, []);
const handleEditComment = () => { // add api call for editing comment
updateComment(comment.id, { content: onChangeValue})
};

return (
<div className="w-full flex flex-row justify-between items-center mb-5">
<div className="w-3/4 flex flex-col gap-1">
{isEdit ? (
<input className="input mb-2" value={onChangeValue} onChange={(e) => setOnChangeValue(e.target.value)} />
) : (
<p className="text-lg">{content}</p>
<p className="text-lg">{comment.content}</p>
)}

<span className="text-base text-gray-300">{year}.{month}.{day}</span>
</div>

<div className="flex flex-row items-center gap-3">
{isEdit ? (
<>
<button onClick={() => { setIsEdit(!isEdit); setOnChangeValue(content); }}>취소</button>
<button onClick={() => { setIsEdit(!isEdit); setOnChangeValue(comment.content); }}>취소</button>
<button onClick={handleEditComment}>완료</button>
</>
) : (
) : user?.id === comment?.author ? (
<>
<button onClick={() => handleCommentDelete(comment.id)}>삭제</button>
<button onClick={() => setIsEdit(!isEdit)}>수정</button>
</>
)}
) : null}
</div>
</div>
);
Expand Down
118 changes: 74 additions & 44 deletions src/components/Comment/index.jsx
Original file line number Diff line number Diff line change
@@ -1,53 +1,83 @@
import { useState } from "react";
import comments from "../../data/comments"; // dummy data
import { useState, useEffect } from "react";
import CommentElement from "./CommentElement";
import { getComments, createComment, deleteComment } from "../../apis/api";
import { getCookie } from "../../utils/cookie";

const Comment = ({ postId }) => {
const [commentList, setCommentList] = useState(comments); // state for comments
const [newContent, setNewContent] = useState(""); // state for new comment

const handleCommentSubmit = (e) => {
e.preventDefault();
setCommentList([ // TODO: add api call for creating comment
...commentList,
{
id: commentList.length + 1,
content: newContent,
created_at: new Date().toISOString(),
post: postId,
author: {
id: 1,
username: "user1"
}
}
]);
console.log({
post: postId,
content: newContent
});
setNewContent("");
const [commentList, setCommentList] = useState([]); // state for comments
const [comment, setComment] = useState({
post: postId,
content: "",
}); // state for new comment
const [isUserLoggedIn, setIsUserLoggedIn] = useState(false);

useEffect(() => {

const getCommentsAPI = async () => {
const comments = await getComments(postId);
setCommentList(comments);
};
getCommentsAPI();

const handleCommentDelete = (commentId) => {
console.log("comment: ", commentId);
setCommentList(commentList.filter((comment) => comment.id !== commentId)); // TODO: add api call for deleting comment
};
const loggedIn = getCookie("access_token") ? true : false;
setIsUserLoggedIn(loggedIn);
}, []);

const handleChange = (e) => {
setComment({ ...comment, content: e.target.value });
};

const handleCommentSubmit = (e) => {
e.preventDefault();
if (!isUserLoggedIn) {
alert("댓글을 작성하려면 로그인하세요")
return;
}
createComment(comment);
};

const handleCommentDelete = (commentId) => {
const confirmDelete = window.confirm("정말 삭제하시겠습니까?");
if (!confirmDelete) return;
try {
deleteComment(commentId);
} catch (error) {
console.error(error);
}
};

return (
<div className="w-full mt-5 self-start">
<h1 className="text-3xl font-bold my-5">Comments</h1>
{commentList.map((comment) => {
return (
<CommentElement key={comment.id} comment={comment} handleCommentDelete={handleCommentDelete} postId={postId} />
);
})}

<form className="flex flex-row mt-10 gap-3" onSubmit={handleCommentSubmit}>
<input type="text" value={newContent} placeholder="댓글을 입력해주세요" className="input" style={{ width: "calc(100% - 100px)" }} onChange={(e) => setNewContent(e.target.value)} />
<button type="submit" className="button">작성</button>
</form>
</div>
);
return (
<div className="w-full mt-5 self-start">
<h1 className="text-3xl font-bold my-5">Comments</h1>
{commentList.map((comment) => {
return (
<CommentElement
key={comment.id}
comment={comment}
handleCommentDelete={handleCommentDelete}
postId={postId}
/>
);
})}

<form
className="flex flex-row mt-10 gap-3"
onSubmit={handleCommentSubmit}
>
<input
type="text"
value={comment.content}
placeholder="댓글을 입력해주세요"
className="input"
style={{ width: "calc(100% - 100px)" }}
onChange={handleChange}
/>
<button type="submit" className="button">
작성
</button>
</form>
</div>
);
};

export default Comment;
7 changes: 3 additions & 4 deletions src/routes/PostDetailPage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,13 @@ import { BigPost } from "../components/Posts";
import Comment from "../components/Comment";
import { getPost, getUser, deletePost } from "../apis/api";
import { getCookie } from "../utils/cookie";

const PostDetailPage = () => {

const { postId } = useParams();

const [post, setPost] = useState(null);

const [user, setUser] = useState()

const [user, setUser] = useState();

useEffect(() => {
// access_token이 있으면 유저 정보 가져옴
if (getCookie("access_token")) {
Expand All @@ -31,6 +29,7 @@ const PostDetailPage = () => {
};
getPostAPI();
}, [postId]);

// 작성했던 getPost()를 호출한 후, setPostList를 통해 postList에 저장
const navigate = useNavigate();
const onClickDelete = async () => {
Expand Down