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
36 changes: 28 additions & 8 deletions src/apis/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -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들
Expand All @@ -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);
}
};

Expand All @@ -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");
}
};
3 changes: 2 additions & 1 deletion src/apis/axios.js
Original file line number Diff line number Diff line change
Expand Up @@ -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}`;
Expand Down
49 changes: 30 additions & 19 deletions src/components/Comment/CommentElement.jsx
Original file line number Diff line number Diff line change
@@ -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

Expand All @@ -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 (
Expand All @@ -41,17 +47,22 @@ const CommentElement = (props) => {
</div>

<div className="flex flex-row items-center gap-3">
{isEdit ? (
<>
<button onClick={() => { setIsEdit(!isEdit); setOnChangeValue(content); }}>취소</button>
<button onClick={handleEditComment}>완료</button>
</>
) : (
<>
<button onClick={() => handleCommentDelete(comment.id)}>삭제</button>
<button onClick={() => setIsEdit(!isEdit)}>수정</button>
</>
)}
{
user?.id === comment.author.id ? (
isEdit ? (
<>
<button onClick={() => { setIsEdit(!isEdit); setOnChangeValue(content); }}>취소</button>
<button onClick={handleEditComment}>완료</button>
</>
) : (
<>
<button onClick={() => handleCommentDelete(comment.id)}>삭제</button>
<button onClick={() => setIsEdit(!isEdit)}>수정</button>
</>
)
) : null
}
{}
</div>
</div>
);
Expand Down
50 changes: 26 additions & 24 deletions src/components/Comment/index.jsx
Original file line number Diff line number Diff line change
@@ -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 (
Expand Down
41 changes: 23 additions & 18 deletions src/components/Posts/index.jsx
Original file line number Diff line number Diff line change
@@ -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 (
<Link
to={`/${post.id}`}
Expand All @@ -19,18 +21,23 @@ export const SmallPost = ({ post }) => {
</span>
))}
</div>
<div className="cursor-pointer" onClick={onClickLike}>
{post.like_users.length > 0 && `❤️ ${post.like_users.length}`}
</div>
<button
type="button"
className="bg-transparent border-none cursor-pointer"
onClick={onClickLike}
>
❤️ {post.like_users.length}
</button>
</Link>
);
};

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 (
<div className="flex flex-col px-8 py-5 w-full bg-orange-400 ring-4 ring-orange-300 rounded-xl gap-5">
<div className="flex flex-row items-center justify-between gap-3">
Expand All @@ -41,11 +48,9 @@ export const BigPost = ({ post }) => {
{post.created_at.slice(0, 10)}
</span>
</div>

<div className=" rounded-xl p-2 text-black font-medium text-lg border-2 border-black">
<div className="rounded-xl p-2 text-black font-medium text-lg border-2 border-black">
{post.content}
</div>

<div className="flex flex-row gap-2">
{post.tags &&
post.tags.map((tag) => (
Expand All @@ -54,13 +59,13 @@ export const BigPost = ({ post }) => {
</span>
))}
</div>

<div
className="flex flex-row text-black cursor-pointer"
<button
type="button"
className="self-start text-black bg-transparent border-none cursor-pointer mt-2"
onClick={onClickLike}
>
{post.like_users.length > 0 && `❤️ ${post.like_users.length}`}
</div>
❤️ {post.like_users.length}
</button>
</div>
);
};
};
1 change: 0 additions & 1 deletion src/routes/PostCreatePage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -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: "",
Expand Down