diff --git a/src/apis/api.js b/src/apis/api.js index af51a909..99c5a904 100644 --- a/src/apis/api.js +++ b/src/apis/api.js @@ -74,7 +74,17 @@ export const deletePost = async (id, navigate) => { // 과제!! export const likePost = async (postId) => { - + try { + const response = await instanceWithToken.post(`/post/${postId}/like/`); + if(response.status === 200) { + console.log("LIKE SUCCESS"); + window.location.reload(); + } else { + console.log("[ERROR] error while liking post"); + } + } catch (error) { + console.log(error); + } }; // Tag 관련 API들 @@ -100,12 +110,16 @@ export const getComments = async (postId) => { }; export const createComment = async (data) => { - const response = await instanceWithToken.post("/comment/", data); - if (response.status === 201) { - console.log("COMMENT SUCCESS"); - window.location.reload(); // 새로운 코멘트 생성시 새로고침으로 반영 - } else { - console.log("[ERROR] error while creating comment"); + try { + const response = await instanceWithToken.post("/comment/", data); + if (response.status === 201) { + console.log("COMMENT SUCCESS"); + window.location.reload(); // 새로운 코멘트 생성시 새로고침으로 반영 + } else { + console.log("[ERROR] error while creating comment"); + } + } catch(error) { + console.log(error); } }; @@ -121,5 +135,11 @@ export const updateComment = async (id, data) => { // 과제 !! export const deleteComment = async (id) => { - + const response = await instanceWithToken.delete(`/comment/${id}/`); + if(response.status === 204) { + console.log("DELETE SUCCESS"); + window.location.reload(); // 코멘트 삭제시 새로고침으로 반영 + } else { + console.log("[ERROR] error while deleting comment"); + } }; \ No newline at end of file diff --git a/src/apis/axios.js b/src/apis/axios.js index d2f85b9a..3ee2c838 100644 --- a/src/apis/axios.js +++ b/src/apis/axios.js @@ -22,7 +22,8 @@ instanceWithToken.interceptors.request.use( if (!accessToken) { // token 없으면 리턴 - return; + alert("Please login first.") + throw new Error("No Token"); } else { // token 있으면 헤더에 담아주기 (Authorization은 장고에서 JWT 토큰을 인식하는 헤더 key) config.headers["Authorization"] = `Bearer ${accessToken}`; diff --git a/src/components/Comment/CommentElement.jsx b/src/components/Comment/CommentElement.jsx index fd48385e..5850eb9f 100644 --- a/src/components/Comment/CommentElement.jsx +++ b/src/components/Comment/CommentElement.jsx @@ -1,9 +1,12 @@ import { useState, useEffect } from "react"; +import { updateComment, getUser } from "../../apis/api"; +import { getCookie } from "../../utils/cookie"; const CommentElement = (props) => { const { comment, handleCommentDelete, postId } = props; const [content, setContent] = useState(comment.content); const [isEdit, setIsEdit] = useState(false); + const [user, setUser] = useState(null); // state for user const [onChangeValue, setOnChangeValue] = useState(content); // 수정 취소 시 직전 content 값으로 변경을 위한 state @@ -15,17 +18,20 @@ const CommentElement = (props) => { let day = date.getDate(); day = day < 10 ? `0${day}` : day; - const handleEditComment = () => { // add api call for editing comment - setContent(onChangeValue); + const handleEditComment = async () => { + await updateComment(comment.id, { content: onChangeValue}); setIsEdit(!isEdit); - console.log({ - post: postId, - comment: comment.id, - content: content - }); }; - useEffect(() => { // add api call to check if user is the author of the comment + // get user info + useEffect(() => { + if(getCookie("access_token")) { + const getUserAPI = async () => { + const user = await getUser(); + setUser(user); + } + getUserAPI(); + } }, []); return ( @@ -41,17 +47,22 @@ const CommentElement = (props) => {
- {isEdit ? ( - <> - - - - ) : ( - <> - - - - )} + { + user?.id === comment.author.id ? ( + isEdit ? ( + <> + + + + ) : ( + <> + + + + ) + ) : null + } + {}
); diff --git a/src/components/Comment/index.jsx b/src/components/Comment/index.jsx index c8c4a27e..de87670f 100644 --- a/src/components/Comment/index.jsx +++ b/src/components/Comment/index.jsx @@ -1,36 +1,38 @@ -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"; const Comment = ({ postId }) => { - const [commentList, setCommentList] = useState(comments); // state for comments + const [commentList, setCommentList] = useState([]); // state for comments const [newContent, setNewContent] = useState(""); // state for new comment - const handleCommentSubmit = (e) => { + // get comments of the post + useEffect(() => { + const getCommentsAPI = async () => { + const comments = await getComments(postId); + setCommentList(comments); + } + getCommentsAPI(); + }, [postId]); + + const handleCommentSubmit = async (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 - }); + // add new comment to the list + await createComment({post: postId , content: newContent}); + // reset newContent setNewContent(""); + // comments will be updated by reloading the page in createComment function }; - const handleCommentDelete = (commentId) => { - console.log("comment: ", commentId); - setCommentList(commentList.filter((comment) => comment.id !== commentId)); // TODO: add api call for deleting comment + const handleCommentDelete = async (commentId) => { + const confirmDelete = window.confirm("정말 삭제하시겠습니까?"); + if(!confirmDelete) return; + + try { + await deleteComment(commentId); + } catch (error) { + console.error(error); + } }; return ( diff --git a/src/components/Posts/index.jsx b/src/components/Posts/index.jsx index ca0e0bac..e1c7f3ab 100644 --- a/src/components/Posts/index.jsx +++ b/src/components/Posts/index.jsx @@ -1,10 +1,12 @@ import { Link } from "react-router-dom"; +import { likePost } from "../../apis/api"; export const SmallPost = ({ post }) => { - const onClickLike = () => { - alert("나도 좋아!"); - // add api call for liking post here + const onClickLike = async (e) => { + e.preventDefault(); // Link 클릭 이벤트 막기 + await likePost(post.id); }; + return ( { ))} -
- {post.like_users.length > 0 && `❤️ ${post.like_users.length}`} -
+ ); }; export const BigPost = ({ post }) => { - const onClickLike = () => { - alert("나도 좋아!"); - // add api call for liking post here + const onClickLike = async (e) => { + e.preventDefault(); + await likePost(post.id); }; + return (
@@ -41,11 +48,9 @@ export const BigPost = ({ post }) => { {post.created_at.slice(0, 10)}
- -
+
{post.content}
-
{post.tags && post.tags.map((tag) => ( @@ -54,13 +59,13 @@ export const BigPost = ({ post }) => { ))}
- -
- {post.like_users.length > 0 && `❤️ ${post.like_users.length}`} -
+ ❤️ {post.like_users.length} +
); -}; +}; \ No newline at end of file diff --git a/src/routes/PostCreatePage.jsx b/src/routes/PostCreatePage.jsx index cc06ef46..e9c9bb47 100644 --- a/src/routes/PostCreatePage.jsx +++ b/src/routes/PostCreatePage.jsx @@ -5,7 +5,6 @@ import { getTags, createPost } from "../apis/api"; import { useNavigate } from "react-router-dom"; const PostCreatePage = () => { - const [isSubmitted, setIsSubmitted] = useState(false); const [post, setPost] = useState({ title: "", content: "",