diff --git a/src/components/Comment/CommentElement.jsx b/src/components/Comment/CommentElement.jsx new file mode 100644 index 00000000..c3e19c65 --- /dev/null +++ b/src/components/Comment/CommentElement.jsx @@ -0,0 +1,87 @@ +import { useState, useEffect } from "react"; + +const CommentElement = ({ comment, handleCommentDelete, handleCommentEdit }) => { + + /* TODO: props 받기 + Hint: src/components/Comment/index.jsx에서 어떠한 props를 넘겨주는지 확인해보세요! */ + + /* TODO: 댓글을 수정하는 input의 value를 관리하기 위한 state 작성 + Hint: 댓글의 내용을 저장하는 state와 수정 중인지 여부를 저장하는 state를 따로 만드는 게 좋겠죠? */ + const [isEditing, setIsEditing] = useState(false); + const [editedComment, setEditedComment] = useState(comment.content); + + // comment created_at 전처리 + const date = new Date(comment.created_at); + const year = date.getFullYear(); + let month = date.getMonth() + 1; + month = month < 10 ? `0${month}` : month; + let day = date.getDate(); + day = day < 10 ? `0${day}` : day; + + useEffect(() => { + // add api call to check if user is the author of the comment + }, []); + + return ( +
+
+ {/* // TODO: 수정 중일 때와 아닐 때를 나눠서 보여줘야 해요! */} + + {isEditing ? ( + setEditedComment(e.target.value)} + value={editedComment} + > + ) : ( +

{comment.content}

+ )} + {/* // 날짜 */} + + {year}.{month}.{day} + +
+ +
+ {isEditing ? ( + <> + + + + ) : ( + <> + + + + )} +
+
+ ); +}; +export default CommentElement; diff --git a/src/components/Comment/index.jsx b/src/components/Comment/index.jsx new file mode 100644 index 00000000..d7a35509 --- /dev/null +++ b/src/components/Comment/index.jsx @@ -0,0 +1,68 @@ +import { useState } from "react"; +import comments from "../../data/comments"; // dummy data +import CommentElement from "./CommentElement"; + +const Comment = ({ postId }) => { + // TODO: comments를 저장하기 위한 state를 만들어주세요 + const [commentList, setCommentList] = useState(comments); + // TODO: 새로운 댓글을 추가하기 위한 state를 만들어주세요 + const [newComment, setNewComment] = useState([]); + + const handleCommentSubmit = (e) => { + e.preventDefault(); + const newCommentObject = { + id: commentList.length + 1, + content: newComment, + created_at: Date(), + }; + setCommentList([...commentList, newCommentObject]); + setNewComment(""); + alert("댓글 작성"); // add api call for creating comment + }; + + const handleCommentDelete = (commentId) => { + setCommentList(commentList.filter((comment) => comment.id !== commentId)); + alert("댓글 삭제"); // add api call for deleting comment + }; + + const handleCommentEdit = (commentId, editedComment) => { + setCommentList((commentList) => { + return commentList.map((comment) => { + if (comment.id === commentId) { + return { ...comment, content: editedComment }; + } + return comment; + }); + }); + alert("댓글 수정"); + }; + + return ( +
+

Comments

+ {commentList.map((comment) => ( + + ))} +
+ setNewComment(e.target.value)} + > + +
+
+ ); +}; + +export default Comment; diff --git a/src/data/comments.js b/src/data/comments.js new file mode 100644 index 00000000..bfab2a4d --- /dev/null +++ b/src/data/comments.js @@ -0,0 +1,35 @@ +// dummy data +const comments = [ + { + "id": 1, + "content": "새해 복 많이 받으세요^^", + "created_at": "2024-01-01T15:09:43Z", + "post": 1, + "author": { + "id": 2, + "username": "user2" + } + }, + { + "id": 2, + "content": "축구 2대 0;;;", + "created_at": "2024-02-07T15:09:43Z", + "post": 1, + "author": { + "id": 3, + "username": "user3" + } + }, + { + "id": 3, + "content": "망할 개강이야...", + "created_at": "2024-03-02T15:09:43Z", + "post": 1, + "author": { + "id": 4, + "username": "user4" + } + }, +] + +export default comments; \ No newline at end of file diff --git a/src/routes/PostDetailPage.jsx b/src/routes/PostDetailPage.jsx index 1c759335..764b8b14 100644 --- a/src/routes/PostDetailPage.jsx +++ b/src/routes/PostDetailPage.jsx @@ -1,6 +1,7 @@ import { useState, useEffect } from "react"; import { useParams, Link, useNavigate } from "react-router-dom"; import { BigPost } from "../components/Posts"; +import Comment from "../components/Comment"; import posts from "../data/posts"; const PostDetailPage = () => { @@ -21,6 +22,7 @@ const PostDetailPage = () => { post && (
+
diff --git a/src/routes/PostEditPage.jsx b/src/routes/PostEditPage.jsx index ff86e811..233bde6e 100644 --- a/src/routes/PostEditPage.jsx +++ b/src/routes/PostEditPage.jsx @@ -1,10 +1,34 @@ import { useEffect, useState } from "react"; import { useParams } from "react-router-dom"; import posts from "../data/posts"; +import { BigPost } from "../components/Posts"; const PostEditPage = () => { const { postId } = useParams(); - const [post, setPost] = useState({}); + const [isSubmitted, setIsSubmitted] = useState(false); + const [tagInputValue, setTagInputValue] = useState(""); + const [autoCompletes, setAutoCompletes] = useState([]); + const [tags, setTags] = useState([]); + const [post, setPost] = useState({ + id: posts.length, + title: "", + content: "", + author: { id: posts.length, username: "아기사자" }, + tags: [], + like_users: [], + created_at: "2024-02-04T07:42:50.658501Z", + }); + + useEffect(() => { + const duplicatedTagList = posts.reduce((acc, post) => { + for (let tag of post.tags) { + acc.add(tag.content); + } + return acc; + }, new Set()); + const tagList = [...duplicatedTagList]; + setTags([...tagList]); + }, []); // 기존 게시글 불러오기 useEffect(() => { @@ -13,12 +37,69 @@ const PostEditPage = () => { setPost(originalPost); }, [postId]); + const handleChange = (e) => { + setPost({ ...post, [e.target.id]: e.target.value }); + }; + + const handleTag = (e) => { + setTagInputValue(e.target.value); + if (e.target.value) { + const autoCompleteData = tags.filter((tag) => + tag.includes(e.target.value) + ); + setAutoCompletes(autoCompleteData); + } + }; + + const handleAutoCompletes = (autoComplete) => { + const selectedTag = tags.find((tag) => tag === autoComplete); + if (post.tags.includes(selectedTag)) return; + setPost({ + ...post, + tags: [...post.tags, selectedTag], + }); + setTagInputValue(""); + setAutoCompletes([]); + }; + + const addTag = (e) => { + e.preventDefault(); + if (post.tags.find((tag) => tag === tagInputValue)) return; + setPost({ + ...post, + tags: [...post.tags, tagInputValue], + }); + setTagInputValue(""); + setAutoCompletes([]); + }; + + const deleteTag = (tag) => { + setPost({ + ...post, + tags: post.tags.filter((t) => t !== tag), + }); + }; + const onSubmit = (e) => { + e.preventDefault(); + const editedPost = { + ...post, + like_users: [], + tags: post.tags.map((tag, idx) => { + return { id: idx + 1, content: tag }; + }), + }; + setPost(editedPost); + setIsSubmitted(true); alert("게시글을 수정합니다."); // TODO : api connect(edit post) }; - return ( + return isSubmitted ? ( +
+ +
+ ) : (

게시글 수정