From 290590778e4aa833545fae20d5612a198b51663a Mon Sep 17 00:00:00 2001 From: heeyongKim <166043860+heeeeyong@users.noreply.github.com> Date: Sat, 19 Jul 2025 16:18:11 +0900 Subject: [PATCH 01/13] =?UTF-8?q?fix:=20TitleHeader=20=EA=B8=B0=EB=8A=A5?= =?UTF-8?q?=20=ED=99=95=EC=9E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/common/TitleHeader.tsx | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/components/common/TitleHeader.tsx b/src/components/common/TitleHeader.tsx index 255cf953..3fe75717 100644 --- a/src/components/common/TitleHeader.tsx +++ b/src/components/common/TitleHeader.tsx @@ -50,6 +50,7 @@ const InnerHeader = styled.div` type HeaderProps = { title?: string; leftIcon?: React.ReactNode; + rightIcon?: React.ReactNode; rightButton?: React.ReactNode; isNextActive?: boolean; onLeftClick?: (e: React.MouseEvent) => void; @@ -58,6 +59,7 @@ type HeaderProps = { const TitleHeader = ({ leftIcon, + rightIcon, title, rightButton, isNextActive = false, @@ -70,7 +72,11 @@ const TitleHeader = ({ {leftIcon}
{title}
- {rightButton ? ( + {rightIcon ? ( +
+ {rightIcon} +
+ ) : rightButton ? ( {rightButton} From f57fa9b8b20686b4e706b45a54c4dc1785beb55d Mon Sep 17 00:00:00 2001 From: heeyongKim <166043860+heeeeyong@users.noreply.github.com> Date: Sat, 19 Jul 2025 16:18:30 +0900 Subject: [PATCH 02/13] feat: add FeedDetailPage --- src/assets/feed/activeLike.svg | 2 +- src/assets/feed/like.svg | 4 +- src/assets/feed/replyIcon.svg | 4 + .../{feed => common/Post}/PostBody.tsx | 2 +- .../{feed => common/Post}/PostFooter.tsx | 12 +- .../{feed => common/Post}/PostHeader.tsx | 0 src/components/common/Post/Reply.tsx | 97 +++++++++++++++ src/components/common/Post/ReplyList.tsx | 31 +++++ src/components/common/Post/SubReply.tsx | 117 ++++++++++++++++++ src/components/feed/FeedPost.tsx | 8 +- src/components/feed/TotalBar.tsx | 1 - src/data/postData.ts | 66 ++++++++++ src/pages/feed/FeedDetailPage.tsx | 45 +++++++ src/pages/index.tsx | 4 +- src/types/post.ts | 34 ++++- 15 files changed, 409 insertions(+), 18 deletions(-) create mode 100644 src/assets/feed/replyIcon.svg rename src/components/{feed => common/Post}/PostBody.tsx (98%) rename src/components/{feed => common/Post}/PostFooter.tsx (86%) rename src/components/{feed => common/Post}/PostHeader.tsx (100%) create mode 100644 src/components/common/Post/Reply.tsx create mode 100644 src/components/common/Post/ReplyList.tsx create mode 100644 src/components/common/Post/SubReply.tsx create mode 100644 src/data/postData.ts create mode 100644 src/pages/feed/FeedDetailPage.tsx diff --git a/src/assets/feed/activeLike.svg b/src/assets/feed/activeLike.svg index 2d5e6607..b9a76ce3 100644 --- a/src/assets/feed/activeLike.svg +++ b/src/assets/feed/activeLike.svg @@ -1,3 +1,3 @@ - + diff --git a/src/assets/feed/like.svg b/src/assets/feed/like.svg index fc38f0c0..0562cd42 100644 --- a/src/assets/feed/like.svg +++ b/src/assets/feed/like.svg @@ -1,3 +1,3 @@ - - + + diff --git a/src/assets/feed/replyIcon.svg b/src/assets/feed/replyIcon.svg new file mode 100644 index 00000000..26bdeff3 --- /dev/null +++ b/src/assets/feed/replyIcon.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/components/feed/PostBody.tsx b/src/components/common/Post/PostBody.tsx similarity index 98% rename from src/components/feed/PostBody.tsx rename to src/components/common/Post/PostBody.tsx index b7a3da11..15bd9405 100644 --- a/src/components/feed/PostBody.tsx +++ b/src/components/common/Post/PostBody.tsx @@ -1,6 +1,6 @@ import styled from '@emotion/styled'; import { useNavigate } from 'react-router-dom'; -import BookInfoCard from './BookInfoCard'; +import BookInfoCard from '../../feed/BookInfoCard'; const Container = styled.div` display: flex; diff --git a/src/components/feed/PostFooter.tsx b/src/components/common/Post/PostFooter.tsx similarity index 86% rename from src/components/feed/PostFooter.tsx rename to src/components/common/Post/PostFooter.tsx index 4d30709b..37612a2e 100644 --- a/src/components/feed/PostFooter.tsx +++ b/src/components/common/Post/PostFooter.tsx @@ -1,12 +1,12 @@ import { useState } from 'react'; import { useNavigate } from 'react-router-dom'; import styled from '@emotion/styled'; -import like from '../../assets/feed/like.svg'; -import activeLike from '../../assets/feed/activeLike.svg'; -import comment from '../../assets/feed/comment.svg'; -import save from '../../assets/feed/save.svg'; -import activeSave from '../../assets/feed/activeSave.svg'; -import lockIcon from '../../assets/feed/lockIcon.svg'; +import like from '../../../assets/feed/like.svg'; +import activeLike from '../../../assets/feed/activeLike.svg'; +import comment from '../../../assets/feed/comment.svg'; +import save from '../../../assets/feed/save.svg'; +import activeSave from '../../../assets/feed/activeSave.svg'; +import lockIcon from '../../../assets/feed/lockIcon.svg'; const Container = styled.div` width: 100%; diff --git a/src/components/feed/PostHeader.tsx b/src/components/common/Post/PostHeader.tsx similarity index 100% rename from src/components/feed/PostHeader.tsx rename to src/components/common/Post/PostHeader.tsx diff --git a/src/components/common/Post/Reply.tsx b/src/components/common/Post/Reply.tsx new file mode 100644 index 00000000..8d0f3341 --- /dev/null +++ b/src/components/common/Post/Reply.tsx @@ -0,0 +1,97 @@ +import { useState } from 'react'; +import styled from '@emotion/styled'; +import { typography, colors } from '@/styles/global/global'; +import PostHeader from './PostHeader'; +import type { ReplyDataProps } from '@/types/post'; +import like from '../../../assets/feed/like.svg'; +import activeLike from '../../../assets/feed/activeLike.svg'; + +const Reply = ({ + profileImgUrl, + userName, + userTitle, + titleColor, + createdAt, + initialLikeCount, + replyContent, +}: ReplyDataProps) => { + const [liked, setLiked] = useState(false); + const [likeCount, setLikeCount] = useState(initialLikeCount); + const handleLike = () => { + setLiked(!liked); + setLikeCount(prev => (liked ? prev - 1 : prev + 1)); + }; + + return ( + + + +
+
{replyContent}
+
답글작성
+
+
+ +
{likeCount}
+
+ + + ); +}; + +const Container = styled.div` + display: flex; + flex-direction: column; + width: 100%; + margin-bottom: 24px; + gap: 12px; +`; + +const ReplySection = styled.div` + display: flex; + flex-direction: row; + justify-content: space-between; + gap: 20px; + + .left { + display: flex; + flex-direction: column; + gap: 12px; + + .reply { + color: ${colors.grey[100]}; + font-size: ${typography.fontSize.sm}; + font-weight: ${typography.fontWeight.regular}; + line-height: 20px; + } + .sub-reply { + color: ${colors.grey[300]}; + font-size: ${typography.fontSize.xs}; + font-weight: ${typography.fontWeight.semibold}; + line-height: normal; + cursor: pointer; + } + } + + .right { + display: flex; + flex-direction: column; + cursor: pointer; + + .count { + text-align: center; + color: ${colors.grey[100]}; + font-size: 10px; + font-weight: ${typography.fontWeight.medium}; + line-height: normal; + } + } +`; + +export default Reply; diff --git a/src/components/common/Post/ReplyList.tsx b/src/components/common/Post/ReplyList.tsx new file mode 100644 index 00000000..26bf24f9 --- /dev/null +++ b/src/components/common/Post/ReplyList.tsx @@ -0,0 +1,31 @@ +import styled from '@emotion/styled'; +import Reply from './Reply'; +import SubReply from './SubReply'; +import type { ReplyListProps } from '@/types/post'; + +const ReplyList = ({ commentList }: ReplyListProps) => { + return ( + + {commentList.map(comment => ( +
+ + {comment.replyCommentList.map(sub => ( + + ))} +
+ ))} +
+ ); +}; + +const Container = styled.div` + display: flex; + flex-direction: column; + width: 100%; + min-width: 360px; + max-width: 540px; + padding: 40px 20px; + margin: 0 auto; +`; + +export default ReplyList; diff --git a/src/components/common/Post/SubReply.tsx b/src/components/common/Post/SubReply.tsx new file mode 100644 index 00000000..6333057f --- /dev/null +++ b/src/components/common/Post/SubReply.tsx @@ -0,0 +1,117 @@ +import { useState } from 'react'; +import styled from '@emotion/styled'; +import { typography, colors } from '@/styles/global/global'; +import PostHeader from './PostHeader'; +import type { SubReplyDataProps } from '@/types/post'; +import like from '../../../assets/feed/like.svg'; +import activeLike from '../../../assets/feed/activeLike.svg'; +import replyIcon from '../../../assets/feed/replyIcon.svg'; + +const SubReply = ({ + profileImgUrl, + userName, + userTitle, + titleColor, + createdAt, + initialLikeCount, + subreplyContent, +}: SubReplyDataProps) => { + const [liked, setLiked] = useState(false); + const [likeCount, setLikeCount] = useState(initialLikeCount); + const handleLike = () => { + setLiked(!liked); + setLikeCount(prev => (liked ? prev - 1 : prev + 1)); + }; + + return ( + + + 대댓글 + + + + +
+
{subreplyContent}
+
답글작성
+
+
+ +
{likeCount}
+
+
+
+
+ ); +}; + +const Container = styled.div` + display: flex; + flex-direction: row; + margin-bottom: 24px; + width: 100%; + gap: 8px; +`; + +const ReplyIcon = styled.div` + img { + width: 24px; + height: 24px; + } +`; + +const Content = styled.div` + display: flex; + flex-direction: column; + width: 100%; + gap: 12px; +`; + +const ReplySection = styled.div` + display: flex; + flex-direction: row; + justify-content: space-between; + gap: 20px; + + .left { + display: flex; + flex-direction: column; + gap: 12px; + + .reply { + color: ${colors.grey[100]}; + font-size: ${typography.fontSize.sm}; + font-weight: ${typography.fontWeight.regular}; + line-height: 20px; + } + .sub-reply { + color: ${colors.grey[300]}; + font-size: ${typography.fontSize.xs}; + font-weight: ${typography.fontWeight.semibold}; + line-height: normal; + cursor: pointer; + } + } + + .right { + display: flex; + flex-direction: column; + cursor: pointer; + + .count { + text-align: center; + color: ${colors.grey[100]}; + font-size: 10px; + font-weight: ${typography.fontWeight.medium}; + line-height: normal; + } + } +`; + +export default SubReply; diff --git a/src/components/feed/FeedPost.tsx b/src/components/feed/FeedPost.tsx index 22e8a717..a1d61689 100644 --- a/src/components/feed/FeedPost.tsx +++ b/src/components/feed/FeedPost.tsx @@ -1,7 +1,7 @@ import styled from '@emotion/styled'; -import PostBody from './PostBody'; -import PostFooter from './PostFooter'; -import PostHeader from './PostHeader'; +import PostBody from '../common/Post/PostBody'; +import PostFooter from '../common/Post/PostFooter'; +import PostHeader from '../common/Post/PostHeader'; import type { FeedPostProps } from '../../types/post'; const Container = styled.div` @@ -28,7 +28,7 @@ const FeedPost = ({ showHeader, isMyFeed, ...postData }: FeedPostProps) => { {showHeader && } - + {/* 페이징 처리에서 마지막 게시글인 경우 BorderBottom 안보이게 처리해야함 */} diff --git a/src/components/feed/TotalBar.tsx b/src/components/feed/TotalBar.tsx index e1638f0e..9e939148 100644 --- a/src/components/feed/TotalBar.tsx +++ b/src/components/feed/TotalBar.tsx @@ -32,7 +32,6 @@ const TotalBar = ({ count }: TotalBarProps) => {
전체
{count}
- {/* 피드 글 개수에 맞춰서 count 세야할듯 */}
); }; diff --git a/src/data/postData.ts b/src/data/postData.ts new file mode 100644 index 00000000..5acbcef5 --- /dev/null +++ b/src/data/postData.ts @@ -0,0 +1,66 @@ +// data/postData.ts +import type { FeedPostProps, ReplyDataProps } from '@/types/post'; + +// 📌 게시글(Mock) +export const mockFeedPost: FeedPostProps = { + profileImgUrl: 'https://placehold.co/54x54', + userName: '문학하는 고래', + userTitle: '문학가', + titleColor: '#a1d5ff', + createdAt: '2025.01.12', + bookTitle: '채식주의자', + bookAuthor: '한강', + postContent: '정말 인상 깊게 읽은 책이에요.', + postId: '1', + initialLikeCount: 15, + commentCount: 2, + showHeader: true, + tags: ['소설', '베스트셀러', '한강'], +}; + +// 📌 댓글/대댓글(Mock) +export const mockCommentList: ReplyDataProps[] = [ + { + commentId: 23, + profileImgUrl: 'https://placehold.co/36x36', + userName: 'User31', + userTitle: '독서가', + titleColor: '#FF8BAC', + createdAt: '2025.01.12', + replyContent: '이 책 정말 좋죠!', + initialLikeCount: 1, + replyCommentList: [ + { + replyCommentId: 1, + profileImgUrl: 'https://placehold.co/36x36', + userName: 'SubUser1', + userTitle: '북러버', + titleColor: '#A0F8E8', + createdAt: '2025.01.13', + subreplyContent: '맞아요, 저도 너무 좋았어요!', + initialLikeCount: 2, + }, + { + replyCommentId: 2, + profileImgUrl: 'https://placehold.co/36x36', + userName: 'SubUser2', + userTitle: '소설가', + titleColor: '#A1D5FF', + createdAt: '2025.01.14', + subreplyContent: '추천 감사합니다!', + initialLikeCount: 0, + }, + ], + }, + { + commentId: 30, + profileImgUrl: 'https://placehold.co/36x36', + userName: 'User45', + userTitle: '작가', + titleColor: '#A1D5FF', + createdAt: '12시간 전', + replyContent: '저도 읽어보고 싶네요!', + initialLikeCount: 3, + replyCommentList: [], + }, +]; diff --git a/src/pages/feed/FeedDetailPage.tsx b/src/pages/feed/FeedDetailPage.tsx new file mode 100644 index 00000000..d912615b --- /dev/null +++ b/src/pages/feed/FeedDetailPage.tsx @@ -0,0 +1,45 @@ +import { useNavigate } from 'react-router-dom'; +import styled from '@emotion/styled'; +import TitleHeader from '@/components/common/TitleHeader'; +import FeedPost from '@/components/feed/FeedPost'; +import leftArrow from '../../assets/common/leftArrow.svg'; +import moreIcon from '../../assets/common/more.svg'; +import ReplyList from '@/components/common/Post/ReplyList'; +import { mockFeedPost, mockCommentList } from '@/data/postData'; + +const FeedDetailPage = () => { + const navigate = useNavigate(); + const handleBackClick = () => { + navigate(-1); + }; + const handleMoreClick = () => {}; + + return ( + + } + onLeftClick={handleBackClick} + rightIcon={더보기} + onRightClick={handleMoreClick} + /> + + + + ); +}; + +const Wrapper = styled.div` + display: flex; + position: relative; + flex-direction: column; + align-items: center; + justify-content: center; + min-width: 320px; + max-width: 767px; + min-height: 100vh; + padding-top: 56px; + margin: 0 auto; + background-color: #121212; +`; + +export default FeedDetailPage; diff --git a/src/pages/index.tsx b/src/pages/index.tsx index b5d2ff5a..2135bb76 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -16,6 +16,7 @@ import OtherFeedPage from './feed/OtherFeedPage'; import FollowerListPage from './feed/FollowerListPage'; import GroupSearch from './groupSearch/GroupSearch'; import TodayWords from './today-words/TodayWords'; +import FeedDetailPage from './feed/FeedDetailPage'; const Router = () => { const router = createBrowserRouter( @@ -31,8 +32,9 @@ const Router = () => { } /> } /> } /> + } /> } /> - } /> + } /> } /> , ), diff --git a/src/types/post.ts b/src/types/post.ts index 2a8fcdea..593644cb 100644 --- a/src/types/post.ts +++ b/src/types/post.ts @@ -18,10 +18,40 @@ export interface PostData { export interface FeedListProps { showHeader: boolean; posts: PostData[]; - isMyFeed: boolean; + isMyFeed?: boolean; } export interface FeedPostProps extends PostData { showHeader: boolean; - isMyFeed: boolean; + isMyFeed?: boolean; +} + +// 대댓글(SubReply) +export interface SubReplyDataProps { + replyCommentId: number; + profileImgUrl: string; + userName: string; + userTitle: string; + titleColor: string; + createdAt: string; + subreplyContent: string; + initialLikeCount: number; +} + +// 댓글(Reply) +export interface ReplyDataProps { + commentId: number; + profileImgUrl: string; + userName: string; + userTitle: string; + titleColor: string; + createdAt: string; + replyContent: string; + initialLikeCount: number; + replyCommentList: SubReplyDataProps[]; +} + +// ReplyList Props +export interface ReplyListProps { + commentList: ReplyDataProps[]; } From d8e8090c4c26c544009ecf24877b91bf6057af19 Mon Sep 17 00:00:00 2001 From: heeyongKim <166043860+heeeeyong@users.noreply.github.com> Date: Sat, 19 Jul 2025 16:25:27 +0900 Subject: [PATCH 03/13] =?UTF-8?q?fix:=20=EB=8C=93=EA=B8=80&=EB=8B=B5?= =?UTF-8?q?=EA=B8=80=20=EA=B0=84=EA=B2=A9=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/common/Post/Reply.tsx | 1 - src/components/common/Post/ReplyList.tsx | 9 ++++++++- src/components/common/Post/SubReply.tsx | 1 - src/data/postData.ts | 9 ++++++--- 4 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/components/common/Post/Reply.tsx b/src/components/common/Post/Reply.tsx index 8d0f3341..e18964f1 100644 --- a/src/components/common/Post/Reply.tsx +++ b/src/components/common/Post/Reply.tsx @@ -49,7 +49,6 @@ const Container = styled.div` display: flex; flex-direction: column; width: 100%; - margin-bottom: 24px; gap: 12px; `; diff --git a/src/components/common/Post/ReplyList.tsx b/src/components/common/Post/ReplyList.tsx index 26bf24f9..8bfc9006 100644 --- a/src/components/common/Post/ReplyList.tsx +++ b/src/components/common/Post/ReplyList.tsx @@ -7,7 +7,7 @@ const ReplyList = ({ commentList }: ReplyListProps) => { return ( {commentList.map(comment => ( -
+
{comment.replyCommentList.map(sub => ( @@ -26,6 +26,13 @@ const Container = styled.div` max-width: 540px; padding: 40px 20px; margin: 0 auto; + gap: 24px; + + .comment-group { + display: flex; + flex-direction: column; + gap: 24px; + } `; export default ReplyList; diff --git a/src/components/common/Post/SubReply.tsx b/src/components/common/Post/SubReply.tsx index 6333057f..f5573850 100644 --- a/src/components/common/Post/SubReply.tsx +++ b/src/components/common/Post/SubReply.tsx @@ -54,7 +54,6 @@ const SubReply = ({ const Container = styled.div` display: flex; flex-direction: row; - margin-bottom: 24px; width: 100%; gap: 8px; `; diff --git a/src/data/postData.ts b/src/data/postData.ts index 5acbcef5..e45900e6 100644 --- a/src/data/postData.ts +++ b/src/data/postData.ts @@ -10,7 +10,8 @@ export const mockFeedPost: FeedPostProps = { createdAt: '2025.01.12', bookTitle: '채식주의자', bookAuthor: '한강', - postContent: '정말 인상 깊게 읽은 책이에요.', + postContent: + '정말 인상 깊게 읽은 책이에요.정말 인상 깊게 읽은 책이에요.정말 인상 깊게 읽은 책이에요.정말 인상 깊게 읽은 책이에요.정말 인상 깊게 읽은 책이에요.정말 인상 깊게 읽은 책이에요.정말 인상 깊게 읽은 책이에요.정말 인상 깊게 읽은 책이에요.정말 인상 깊게 읽은 책이에요.정말 인상 깊게 읽은 책이에요.정말 인상 깊게 읽은 책이에요.정말 인상 깊게 읽은 책이에요.정말 인상 깊게 읽은 책이에요.', postId: '1', initialLikeCount: 15, commentCount: 2, @@ -27,7 +28,8 @@ export const mockCommentList: ReplyDataProps[] = [ userTitle: '독서가', titleColor: '#FF8BAC', createdAt: '2025.01.12', - replyContent: '이 책 정말 좋죠!', + replyContent: + '이 책 정말 좋죠!이 책 정말 좋죠!이 책 정말 좋죠!이 책 정말 좋죠!이 책 정말 좋죠!이 책 정말 좋죠!이 책 정말 좋죠!이 책 정말 좋죠!이 책 정말 좋죠!이 책 정말 좋죠!이 책 정말 좋죠!이 책 정말 좋죠!이 책 정말 좋죠!이 책 정말 좋죠!이 책 정말 좋죠!이 책 정말 좋죠!', initialLikeCount: 1, replyCommentList: [ { @@ -37,7 +39,8 @@ export const mockCommentList: ReplyDataProps[] = [ userTitle: '북러버', titleColor: '#A0F8E8', createdAt: '2025.01.13', - subreplyContent: '맞아요, 저도 너무 좋았어요!', + subreplyContent: + '맞아요, 저도 너무 좋았어요!맞아요, 저도 너무 좋았어요!맞아요, 저도 너무 좋았어요!맞아요, 저도 너무 좋았어요!', initialLikeCount: 2, }, { From c46ef3c7c9b0857f97c48ef553ca6a594dea21e9 Mon Sep 17 00:00:00 2001 From: heeyongKim <166043860+heeeeyong@users.noreply.github.com> Date: Sat, 19 Jul 2025 16:40:25 +0900 Subject: [PATCH 04/13] =?UTF-8?q?fix:=20=EB=8C=93=EA=B8=80=20=EC=97=86?= =?UTF-8?q?=EC=9D=84=20=EC=8B=9C,=20=EC=98=88=EC=99=B8=EC=B2=98=EB=A6=AC?= =?UTF-8?q?=20=ED=99=94=EB=A9=B4=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/common/Post/ReplyList.tsx | 57 ++++++++++++--- src/data/postData.ts | 90 ++++++++++++------------ src/pages/feed/FeedDetailPage.tsx | 1 - 3 files changed, 94 insertions(+), 54 deletions(-) diff --git a/src/components/common/Post/ReplyList.tsx b/src/components/common/Post/ReplyList.tsx index 8bfc9006..768f4eaf 100644 --- a/src/components/common/Post/ReplyList.tsx +++ b/src/components/common/Post/ReplyList.tsx @@ -1,19 +1,29 @@ import styled from '@emotion/styled'; +import { typography, colors } from '@/styles/global/global'; import Reply from './Reply'; import SubReply from './SubReply'; import type { ReplyListProps } from '@/types/post'; const ReplyList = ({ commentList }: ReplyListProps) => { + const hasComments = commentList.length > 0; + return ( - {commentList.map(comment => ( -
- - {comment.replyCommentList.map(sub => ( - - ))} -
- ))} + {hasComments ? ( + commentList.map(comment => ( +
+ + {comment.replyCommentList.map(sub => ( + + ))} +
+ )) + ) : ( + +
아직 댓글이 없어요
+
첫번째 댓글을 남겨보세요
+
+ )}
); }; @@ -27,6 +37,7 @@ const Container = styled.div` padding: 40px 20px; margin: 0 auto; gap: 24px; + flex: 1; .comment-group { display: flex; @@ -35,4 +46,34 @@ const Container = styled.div` } `; +const EmptyState = styled.div` + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + width: 100%; + min-width: 360px; + max-width: 540px; + padding: 40px 20px; + margin: 0 auto; + gap: 8px; + flex: 1; + + .title { + color: ${colors.white}; + text-align: center; + font-size: ${typography.fontSize.lg}; + font-weight: ${typography.fontWeight.semibold}; + line-height: 24px; + } + + .sub-title { + color: ${colors.grey[100]}; + text-align: center; + font-size: ${typography.fontSize.sm}; + font-weight: ${typography.fontWeight.regular}; + line-height: normal; + } +`; + export default ReplyList; diff --git a/src/data/postData.ts b/src/data/postData.ts index e45900e6..08b5da60 100644 --- a/src/data/postData.ts +++ b/src/data/postData.ts @@ -21,49 +21,49 @@ export const mockFeedPost: FeedPostProps = { // 📌 댓글/대댓글(Mock) export const mockCommentList: ReplyDataProps[] = [ - { - commentId: 23, - profileImgUrl: 'https://placehold.co/36x36', - userName: 'User31', - userTitle: '독서가', - titleColor: '#FF8BAC', - createdAt: '2025.01.12', - replyContent: - '이 책 정말 좋죠!이 책 정말 좋죠!이 책 정말 좋죠!이 책 정말 좋죠!이 책 정말 좋죠!이 책 정말 좋죠!이 책 정말 좋죠!이 책 정말 좋죠!이 책 정말 좋죠!이 책 정말 좋죠!이 책 정말 좋죠!이 책 정말 좋죠!이 책 정말 좋죠!이 책 정말 좋죠!이 책 정말 좋죠!이 책 정말 좋죠!', - initialLikeCount: 1, - replyCommentList: [ - { - replyCommentId: 1, - profileImgUrl: 'https://placehold.co/36x36', - userName: 'SubUser1', - userTitle: '북러버', - titleColor: '#A0F8E8', - createdAt: '2025.01.13', - subreplyContent: - '맞아요, 저도 너무 좋았어요!맞아요, 저도 너무 좋았어요!맞아요, 저도 너무 좋았어요!맞아요, 저도 너무 좋았어요!', - initialLikeCount: 2, - }, - { - replyCommentId: 2, - profileImgUrl: 'https://placehold.co/36x36', - userName: 'SubUser2', - userTitle: '소설가', - titleColor: '#A1D5FF', - createdAt: '2025.01.14', - subreplyContent: '추천 감사합니다!', - initialLikeCount: 0, - }, - ], - }, - { - commentId: 30, - profileImgUrl: 'https://placehold.co/36x36', - userName: 'User45', - userTitle: '작가', - titleColor: '#A1D5FF', - createdAt: '12시간 전', - replyContent: '저도 읽어보고 싶네요!', - initialLikeCount: 3, - replyCommentList: [], - }, + // { + // commentId: 23, + // profileImgUrl: 'https://placehold.co/36x36', + // userName: 'User31', + // userTitle: '독서가', + // titleColor: '#FF8BAC', + // createdAt: '2025.01.12', + // replyContent: + // '이 책 정말 좋죠!이 책 정말 좋죠!이 책 정말 좋죠!이 책 정말 좋죠!이 책 정말 좋죠!이 책 정말 좋죠!이 책 정말 좋죠!이 책 정말 좋죠!이 책 정말 좋죠!이 책 정말 좋죠!이 책 정말 좋죠!이 책 정말 좋죠!이 책 정말 좋죠!이 책 정말 좋죠!이 책 정말 좋죠!이 책 정말 좋죠!', + // initialLikeCount: 1, + // replyCommentList: [ + // { + // replyCommentId: 1, + // profileImgUrl: 'https://placehold.co/36x36', + // userName: 'SubUser1', + // userTitle: '북러버', + // titleColor: '#A0F8E8', + // createdAt: '2025.01.13', + // subreplyContent: + // '맞아요, 저도 너무 좋았어요!맞아요, 저도 너무 좋았어요!맞아요, 저도 너무 좋았어요!맞아요, 저도 너무 좋았어요!', + // initialLikeCount: 2, + // }, + // { + // replyCommentId: 2, + // profileImgUrl: 'https://placehold.co/36x36', + // userName: 'SubUser2', + // userTitle: '소설가', + // titleColor: '#A1D5FF', + // createdAt: '2025.01.14', + // subreplyContent: '추천 감사합니다!', + // initialLikeCount: 0, + // }, + // ], + // }, + // { + // commentId: 30, + // profileImgUrl: 'https://placehold.co/36x36', + // userName: 'User45', + // userTitle: '작가', + // titleColor: '#A1D5FF', + // createdAt: '12시간 전', + // replyContent: '저도 읽어보고 싶네요!', + // initialLikeCount: 3, + // replyCommentList: [], + // }, ]; diff --git a/src/pages/feed/FeedDetailPage.tsx b/src/pages/feed/FeedDetailPage.tsx index d912615b..38803bdd 100644 --- a/src/pages/feed/FeedDetailPage.tsx +++ b/src/pages/feed/FeedDetailPage.tsx @@ -33,7 +33,6 @@ const Wrapper = styled.div` position: relative; flex-direction: column; align-items: center; - justify-content: center; min-width: 320px; max-width: 767px; min-height: 100vh; From 9b685ea469a0196f3d162b188532fe6647913105 Mon Sep 17 00:00:00 2001 From: heeyongKim <166043860+heeeeyong@users.noreply.github.com> Date: Sat, 19 Jul 2025 17:03:48 +0900 Subject: [PATCH 05/13] feat: add MessageInputBox to FeedDetailPage --- src/pages/feed/FeedDetailPage.tsx | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/pages/feed/FeedDetailPage.tsx b/src/pages/feed/FeedDetailPage.tsx index 38803bdd..0dbef68a 100644 --- a/src/pages/feed/FeedDetailPage.tsx +++ b/src/pages/feed/FeedDetailPage.tsx @@ -1,4 +1,5 @@ import { useNavigate } from 'react-router-dom'; +import { useState } from 'react'; import styled from '@emotion/styled'; import TitleHeader from '@/components/common/TitleHeader'; import FeedPost from '@/components/feed/FeedPost'; @@ -6,14 +7,23 @@ import leftArrow from '../../assets/common/leftArrow.svg'; import moreIcon from '../../assets/common/more.svg'; import ReplyList from '@/components/common/Post/ReplyList'; import { mockFeedPost, mockCommentList } from '@/data/postData'; +import MessageInput from '@/components/today-words/MessageInput'; const FeedDetailPage = () => { + const [message, setMessage] = useState(''); const navigate = useNavigate(); const handleBackClick = () => { navigate(-1); }; const handleMoreClick = () => {}; + const handleSend = () => { + if (!message.trim()) return; + console.log('작성한 댓글 내용:', message); + // 댓글 등록 API 호출 추가 + setMessage(''); + }; + return ( { /> + ); }; From edfe7864544e0666d5f93478ed3499d869b1757c Mon Sep 17 00:00:00 2001 From: heeyongKim <166043860+heeeeyong@users.noreply.github.com> Date: Sat, 19 Jul 2025 17:04:43 +0900 Subject: [PATCH 06/13] =?UTF-8?q?fix:=20MessageInput=20=EB=A1=9C=EC=A7=81?= =?UTF-8?q?=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/today-words/MessageInput.tsx | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/components/today-words/MessageInput.tsx b/src/components/today-words/MessageInput.tsx index e9af4968..c8a505b2 100644 --- a/src/components/today-words/MessageInput.tsx +++ b/src/components/today-words/MessageInput.tsx @@ -11,9 +11,10 @@ interface MessageInputProps { value: string; onChange: (value: string) => void; onSend: () => void; + placeholder: string; } -const MessageInput = ({ value, onChange, onSend }: MessageInputProps) => { +const MessageInput = ({ value, onChange, onSend, placeholder }: MessageInputProps) => { const inputRef = useRef(null); const [isComposing, setIsComposing] = useState(false); // IME 조합 상태 @@ -43,14 +44,23 @@ const MessageInput = ({ value, onChange, onSend }: MessageInputProps) => { if (isComposing) { return; } - + if (value.trim() === '') return; // 공백 메세지 전송 방지 e.preventDefault(); onSend(); + // 전송 후 채팅창 높이 초기화 + if (inputRef.current) { + inputRef.current.style.height = 'auto'; + } } }; const handleSendClick = () => { + if (value.trim() === '') return; // 공백 메세지 전송 방지 onSend(); + // 전송 후 채팅창 높이 초기화 + if (inputRef.current) { + inputRef.current.style.height = 'auto'; + } }; return ( @@ -58,7 +68,7 @@ const MessageInput = ({ value, onChange, onSend }: MessageInputProps) => { Date: Sun, 20 Jul 2025 16:01:15 +0900 Subject: [PATCH 07/13] =?UTF-8?q?fix:=20MessageInput=20placeholder=20props?= =?UTF-8?q?=20=EB=88=84=EB=9D=BD=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/today-words/TodayWords.tsx | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/pages/today-words/TodayWords.tsx b/src/pages/today-words/TodayWords.tsx index 05907844..86c91761 100644 --- a/src/pages/today-words/TodayWords.tsx +++ b/src/pages/today-words/TodayWords.tsx @@ -94,7 +94,12 @@ const TodayWords = () => { )} - + {/* 개발용 토글 버튼 */}