diff --git a/src/components/Common/Feed/Feed.jsx b/src/components/Common/Feed/Feed.jsx index 0b843b7ef..22ab281f0 100644 --- a/src/components/Common/Feed/Feed.jsx +++ b/src/components/Common/Feed/Feed.jsx @@ -1,5 +1,6 @@ import React, { useState, useRef } from "react"; import { useDispatch, useSelector } from "react-redux"; +import { useNavigate } from "react-router-dom"; import FeedOption from "@/components/Common/Feed/FeedOption"; import { @@ -12,6 +13,7 @@ import { cancelLikeGroupPost, likeGroupPost, } from "@/features/post/post-service"; +import { openFeedDetailModal } from "@/features/ui/ui-slice"; import useOutsideClick from "@/hooks/useOutsideClick"; import { useTimeStamp } from "@/hooks/useTimeStamp"; @@ -20,11 +22,12 @@ import { TopDiv, InfoDiv, BottomDiv, + ContentDiv, IconDiv, IconItemButton, } from "./Feed.styles"; -const Feed = ({ post, groupId, leaderName }) => { +const Feed = ({ post, groupId, leaderId, isGroupPage }) => { const dispatch = useDispatch(); const { user } = useSelector((state) => state.auth); @@ -35,6 +38,8 @@ const Feed = ({ post, groupId, leaderName }) => { const optionMenuRef = useRef(); + const navigate = useNavigate(); + useOutsideClick(optionMenuRef, () => setIsOptionOpen(false)); const likeClick = async () => { @@ -59,7 +64,9 @@ const Feed = ({ post, groupId, leaderName }) => { } }; - const handleLikeClick = () => { + const handleLikeClick = (e) => { + e.stopPropagation(); + if (!isPostLiked) { setIsPostLiked(true); setPostLikesCount((prev) => prev + 1); @@ -72,14 +79,23 @@ const Feed = ({ post, groupId, leaderName }) => { }; return ( - + + isGroupPage + ? dispatch(openFeedDetailModal(post.postId)) + : navigate(`/group/${groupId}`) + } + > {user.nickname === post.author && ( setIsOptionOpen((prev) => !prev)} + handleOptionClick={(e) => { + e.stopPropagation(); + setIsOptionOpen((prev) => !prev); + }} /> )} @@ -87,13 +103,18 @@ const Feed = ({ post, groupId, leaderName }) => {

{post.author} - {post.author === leaderName && } + + {/* 게시글 작성자 id 비교 필요 */} + {post.author === leaderId && }

{useTimeStamp(post.createdAt)}

-

{post.content}

+ +

{post.content}

+
+ {isPostLiked ? : } diff --git a/src/components/Common/Feed/Feed.styles.js b/src/components/Common/Feed/Feed.styles.js index fdf89e464..feb103c9e 100644 --- a/src/components/Common/Feed/Feed.styles.js +++ b/src/components/Common/Feed/Feed.styles.js @@ -7,6 +7,7 @@ export const FeedArticle = styled.article` border: 1px solid ${({ theme: { colors } }) => colors.btn_02}; padding: 24px 18px; position: relative; + cursor: pointer; `; export const OptionDiv = styled.div` @@ -19,6 +20,7 @@ export const OptionDiv = styled.div` export const OptionMenuDiv = styled.div` position: absolute; z-index: 2; + right: 0; & > ul > li { width: 60px; @@ -35,6 +37,12 @@ export const OptionMenuDiv = styled.div` border-bottom: none; color: ${({ theme: { colors } }) => colors.text_01}; } + + & > button { + width: 100%; + height: 100%; + text-align: center; + } } `; @@ -78,7 +86,9 @@ export const BottomDiv = styled.div` display: flex; flex-direction: column; gap: 12px; +`; +export const ContentDiv = styled.div` & > p { color: ${({ theme: { colors } }) => colors.text_03}; font-size: ${({ theme: { typography } }) => typography.size.s1}; diff --git a/src/components/Common/Feed/FeedComment/FeedComment.jsx b/src/components/Common/Feed/FeedComment/FeedComment.jsx new file mode 100644 index 000000000..55b2eef67 --- /dev/null +++ b/src/components/Common/Feed/FeedComment/FeedComment.jsx @@ -0,0 +1,110 @@ +import React, { useState, useRef } from "react"; +import { useDispatch, useSelector } from "react-redux"; + +import { + CommentDiv, + CommentContentDiv, + EditContentDiv, + ButtonDiv, +} from "@/components/Common/Feed/FeedComment/FeedComment.style"; +import FeedOption from "@/components/Common/Feed/FeedOption"; +import { putComment } from "@/features/comment/comment-service"; +import useOutsideClick from "@/hooks/useOutsideClick"; +import { useTimeStamp } from "@/hooks/useTimeStamp"; + +const FeedComment = ({ + commentId, + postId, + groupId, + author, + authorImage, + updatedAt, + content, +}) => { + const dispatch = useDispatch(); + + const { user } = useSelector((state) => state.auth); + + const [isOptionOpen, setIsOptionOpen] = useState(false); + const [newContent, setNewContent] = useState(content); + const [isEdit, setIsEdit] = useState(false); + + const optionMenuRef = useRef(); + const commentBoxRef = useRef(null); + + useOutsideClick(optionMenuRef, () => setIsOptionOpen(false)); + + const handleEditCommentMenuClick = () => { + commentBoxRef.current.scrollIntoView({ + behavior: "smooth", + block: "center", + }); + + setIsOptionOpen(false); + setIsEdit(true); + }; + + const handleEditComment = () => { + dispatch( + putComment({ + groupId, + postId, + commentId, + content: newContent, + }), + setIsEdit(false), + ); + }; + + return ( + + profileImg + +

{author}

+

{useTimeStamp(updatedAt)}

+ + {isEdit ? ( + +