From 02ed197f3c5314d58d126eb3353f7de17cb2fd4e Mon Sep 17 00:00:00 2001 From: Yoobin Seo <135022491+alwubin@users.noreply.github.com> Date: Mon, 17 Feb 2025 19:33:36 +0900 Subject: [PATCH 01/30] =?UTF-8?q?chore:=20=EB=AA=A8=EB=B0=94=EC=9D=BC=20?= =?UTF-8?q?=ED=86=A1=ED=94=BD=20=EC=83=81=EC=84=B8=20=ED=8E=98=EC=9D=B4?= =?UTF-8?q?=EC=A7=80=EC=97=90=20=ED=95=84=EC=9A=94=ED=95=9C=20=EC=95=84?= =?UTF-8?q?=EC=9D=B4=EC=BD=98=20=EC=A0=95=EC=9D=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/assets/index.ts | 2 ++ src/assets/svg/cry-emoji.svg | 13 +++++++++++++ src/assets/svg/mobile-comment.svg | 12 ++++++++++++ 3 files changed, 27 insertions(+) create mode 100644 src/assets/svg/cry-emoji.svg create mode 100644 src/assets/svg/mobile-comment.svg diff --git a/src/assets/index.ts b/src/assets/index.ts index 4ca00b96..ddec7837 100644 --- a/src/assets/index.ts +++ b/src/assets/index.ts @@ -151,6 +151,8 @@ export { default as LogoMedium } from './svg/logo-medium.svg'; export { default as DefaultPerson } from './svg/default-person.svg'; export { default as MobileDefaultPerson } from './svg/mobile-default-person.svg'; export { default as MobilePlus } from './svg/mobile-plus.svg'; +export { default as MobileComment } from './svg/mobile-comment.svg'; +export { default as CryEmoji } from './svg/cry-emoji.svg'; // TODO: 이전 SVG export { default as Email } from './svg/email.svg'; diff --git a/src/assets/svg/cry-emoji.svg b/src/assets/svg/cry-emoji.svg new file mode 100644 index 00000000..02ce4df4 --- /dev/null +++ b/src/assets/svg/cry-emoji.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/src/assets/svg/mobile-comment.svg b/src/assets/svg/mobile-comment.svg new file mode 100644 index 00000000..996a2da7 --- /dev/null +++ b/src/assets/svg/mobile-comment.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + From 3c7ac07f0b636f89456870633ad9be9da95a1f00 Mon Sep 17 00:00:00 2001 From: Yoobin Seo <135022491+alwubin@users.noreply.github.com> Date: Mon, 17 Feb 2025 19:34:41 +0900 Subject: [PATCH 02/30] =?UTF-8?q?refactor:=20CategoryBarChip=EC=9D=98=20si?= =?UTF-8?q?ze=20extraSmall=20=EC=82=AC=EC=9D=B4=EC=A6=88=20=EC=8A=A4?= =?UTF-8?q?=ED=83=80=EC=9D=BC=20=EC=A0=95=EC=9D=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../atoms/CategoryBarChip/CategoryBarChip.style.ts | 12 +++++++++++- .../atoms/CategoryBarChip/CategoryBarChip.tsx | 2 +- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/components/atoms/CategoryBarChip/CategoryBarChip.style.ts b/src/components/atoms/CategoryBarChip/CategoryBarChip.style.ts index 691a01e7..93395f4e 100644 --- a/src/components/atoms/CategoryBarChip/CategoryBarChip.style.ts +++ b/src/components/atoms/CategoryBarChip/CategoryBarChip.style.ts @@ -15,15 +15,25 @@ export const getStylingBySize = ( borderRadius: '25px', padding: '0 12px', }), + extraSmall: css({ + borderRadius: '3px', + padding: '3px 6px', + }), }; return style[size]; }; -export const categoryBarChipStyling = css(typo.Comment.SemiBold, { +export const categoryBarChipStyling = css({ + ...typo.Comment.SemiBold, display: 'flex', justifyContent: 'center', alignItems: 'center', backgroundColor: color.MAIN, color: color.WT, + '@media (max-width: 430px)': { + ...typo.Mobile.Text.SemiBold_10, + backgroundColor: color.WT_VIOLET, + color: color.MAIN, + }, }); diff --git a/src/components/atoms/CategoryBarChip/CategoryBarChip.tsx b/src/components/atoms/CategoryBarChip/CategoryBarChip.tsx index 1bad38c6..5e0b9603 100644 --- a/src/components/atoms/CategoryBarChip/CategoryBarChip.tsx +++ b/src/components/atoms/CategoryBarChip/CategoryBarChip.tsx @@ -2,7 +2,7 @@ import React, { ReactNode } from 'react'; import * as S from './CategoryBarChip.style'; export interface CategoryBarChipProps { - size?: 'large' | 'small'; + size?: 'large' | 'small' | 'extraSmall'; children?: ReactNode; } From d0004452dace5fca27ec9372c868bf80600247c8 Mon Sep 17 00:00:00 2001 From: Yoobin Seo <135022491+alwubin@users.noreply.github.com> Date: Mon, 17 Feb 2025 19:35:12 +0900 Subject: [PATCH 03/30] =?UTF-8?q?refactor:=20GY[4]=20=EC=83=89=EC=83=81=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/styles/color.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/styles/color.ts b/src/styles/color.ts index 13800520..d293beb0 100644 --- a/src/styles/color.ts +++ b/src/styles/color.ts @@ -5,7 +5,7 @@ const color = { 1: '#8C8C8C', 2: '#D9D9D9', 3: '#F1F1F1', - 4: '#E6E9EF', + 4: '#555555', 5: '#F6F7F9', }, WT: '#FFFFFF', From 21f2b435c0afd71aefb6a8a3248c467ee28a2dc5 Mon Sep 17 00:00:00 2001 From: Yoobin Seo <135022491+alwubin@users.noreply.github.com> Date: Mon, 17 Feb 2025 19:35:33 +0900 Subject: [PATCH 04/30] =?UTF-8?q?feat:=20=EB=8C=93=EA=B8=80=20=EC=97=86?= =?UTF-8?q?=EB=8A=94=20=EC=83=81=ED=99=A9=EC=97=90=20=EB=8C=80=ED=95=9C=20?= =?UTF-8?q?=EC=83=81=EC=88=98=20=EB=A9=94=EC=84=B8=EC=A7=80=20=EC=A0=95?= =?UTF-8?q?=EC=9D=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/constants/message.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/constants/message.ts b/src/constants/message.ts index c6b9ae53..c3e2f55f 100644 --- a/src/constants/message.ts +++ b/src/constants/message.ts @@ -217,3 +217,8 @@ export const PROFILE = { SIZE_LIMIT: '3MB 이하의 사진만 가능합니다.', }, }; + +export const COMMENT = { + NO_COMMENTS_YET: '아직 댓글이 없어요', + FIRST_COMMENT_SUGGESTION: '첫 댓글을 달아보는건 어때요?', +}; From 22f0dad365bf30bc5634dc281723aeb688394eb5 Mon Sep 17 00:00:00 2001 From: Yoobin Seo <135022491+alwubin@users.noreply.github.com> Date: Mon, 17 Feb 2025 19:37:17 +0900 Subject: [PATCH 05/30] =?UTF-8?q?refactor:=20=EB=AF=B8=EB=94=94=EC=96=B4?= =?UTF-8?q?=20=EC=BF=BC=EB=A6=AC=20=EC=A0=81=EC=9A=A9=20=EB=B0=8F=20?= =?UTF-8?q?=EA=B0=9D=EC=B2=B4=20=EB=A6=AC=ED=84=B0=EB=9F=B4=20=ED=98=95?= =?UTF-8?q?=EC=8B=9D=EC=9C=BC=EB=A1=9C=20=EC=BB=B4=ED=8F=AC=EB=84=8C?= =?UTF-8?q?=ED=8A=B8=20=EB=AA=A8=EB=B0=94=EC=9D=BC=20=EC=8A=A4=ED=83=80?= =?UTF-8?q?=EC=9D=BC=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CommentProfile/CommentProfile.style.ts | 22 +- src/components/atoms/MenuTap/MenuTap.style.ts | 15 +- .../atoms/ToastModal/ToastModal.style.ts | 7 +- .../CommentItem/CommentItem.style.ts | 204 +++++++++--------- .../CommentsSection/CommentsSection.style.ts | 120 +++++------ 5 files changed, 197 insertions(+), 171 deletions(-) diff --git a/src/components/atoms/CommentProfile/CommentProfile.style.ts b/src/components/atoms/CommentProfile/CommentProfile.style.ts index 46be8172..eb950635 100644 --- a/src/components/atoms/CommentProfile/CommentProfile.style.ts +++ b/src/components/atoms/CommentProfile/CommentProfile.style.ts @@ -1,13 +1,17 @@ import { css } from '@emotion/react'; import color from '@/styles/color'; -export const containerStyle = css` - display: inline-flex; - padding: 5px; - align-items: center; - gap: 10px; - border-radius: 50px 50px 0 50px; -`; +export const containerStyle = css({ + display: 'inline-flex', + padding: '5px', + alignItems: 'center', + gap: '10px', + borderRadius: '50px 50px 0 50px', + '@media (max-width: 430px)': { + padding: '2.7px', + borderRadius: '27.3px 27.3px 0 27.3px', + }, +}); export const getProfileColor = (option: 'A' | 'B' | null) => { const backgroundColors = { @@ -29,6 +33,10 @@ export const profileWrapper = css({ backgroundSize: 'cover', backgroundPosition: 'center', cursor: 'pointer', + '@media (max-width: 430px)': { + width: '24.5px', + height: '24.5px', + }, }); export const profileImage = css({ diff --git a/src/components/atoms/MenuTap/MenuTap.style.ts b/src/components/atoms/MenuTap/MenuTap.style.ts index 9746b063..97f8c122 100644 --- a/src/components/atoms/MenuTap/MenuTap.style.ts +++ b/src/components/atoms/MenuTap/MenuTap.style.ts @@ -24,9 +24,16 @@ export const menuStlying = css({ borderRadius: '10px', overflow: 'hidden', boxShadow: '1px 2px 10px rgba(0, 0, 0, 0.07)', + '@media (max-width: 430px)': { + width: '58px', + backgroundColor: color.WT, + border: `1px solid ${color.GY[1]}`, + borderRadius: '6px', + }, }); -export const menuItemStyling = css(typo.Comment.SemiBold, { +export const menuItemStyling = css({ + ...typo.Comment.SemiBold, width: '100%', padding: '10px', cursor: 'pointer', @@ -35,4 +42,10 @@ export const menuItemStyling = css(typo.Comment.SemiBold, { ':last-child': { borderBottom: 'none', }, + '@media (max-width: 430px)': { + ...typo.Mobile.Text.Medium_12, + padding: '7px', + color: color.GY[1], + borderBottom: `1px solid ${color.GY[1]}`, + }, }); diff --git a/src/components/atoms/ToastModal/ToastModal.style.ts b/src/components/atoms/ToastModal/ToastModal.style.ts index 2c362f26..dbc4d15e 100644 --- a/src/components/atoms/ToastModal/ToastModal.style.ts +++ b/src/components/atoms/ToastModal/ToastModal.style.ts @@ -20,7 +20,8 @@ export const getToastModalColor = ( return style[bgColor]; }; -export const toastModalStyling = css(typo.Main.SemiBold, { +export const toastModalStyling = css({ + ...typo.Main.SemiBold, display: 'flex', justifyContent: 'center', alignItems: 'center', @@ -29,6 +30,10 @@ export const toastModalStyling = css(typo.Main.SemiBold, { padding: '20px 30px', borderRadius: '35px', boxShadow: '1px 1px 10px rgba(0, 0, 0, 0.07)', + '@media (max-width: 430px)': { + ...typo.Mobile.Text.SemiBold_12, + padding: '14px 24px', + }, }); export const toastContainer = css({ diff --git a/src/components/molecules/CommentItem/CommentItem.style.ts b/src/components/molecules/CommentItem/CommentItem.style.ts index 79defdcc..5d1c0309 100644 --- a/src/components/molecules/CommentItem/CommentItem.style.ts +++ b/src/components/molecules/CommentItem/CommentItem.style.ts @@ -2,106 +2,106 @@ import { css } from '@emotion/react'; import color from '@/styles/color'; import typo from '@/styles/typo'; -export const MainContainer = css` - display: flex; - flex-direction: column; - width: 1175px; -`; - -export const myCommentColor = css` - background-color: ${color.WT_VIOLET}; -`; - -export const commentContainer = css` - display: flex; - align-items: flex-start; - width: 100%; - padding: 30px 10px 30px 27px; - gap: 20px; - border-top: 1px solid #f4f4f4; -`; - -export const profileWrapper = css` - display: flex; -`; - -export const commentInfoWrapper = css` - display: flex; - flex-direction: column; - width: 100%; - gap: 10px; -`; - -export const commentTopWrapper = css` - display: flex; - justify-content: space-between; -`; - -export const writerInfoWrapper = css` - display: flex; - gap: 10px; -`; - -export const nickname = css` - ${typo.Comment.SemiBold} - color: ${color.BK}; -`; - -export const createdTime = css` - ${typo.Comment.SemiBold} - color: #67727E; - margin-left: 10px; -`; - -export const editedText = css` - ${typo.Comment.Regular} - color: ${color.MAIN}; -`; - -export const commentTextWrapper = css` - display: flex; - width: 100%; - padding-right: 20px; - ${typo.Comment.Regular} - color: #505050; -`; - -export const commentBottomWrapper = css` - display: flex; - justify-content: space-between; - padding-right: 15px; -`; - -export const replyButton = css` - display: flex; - gap: 10px; - ${typo.Comment.SemiBold} - background: none; - padding-top: 10px; - color: ${color.GY[1]}; - cursor: pointer; -`; - -export const repliesWrapper = css` - display: flex; - flex-direction: column; -`; - -export const replyContainer = css` - display: flex; - width: 100%; - height: 210px; - justify-content: center; - align-items: flex-start; - flex-direction: column; - border-top: 1px solid #f4f4f4; - padding-left: 105px; -`; - -export const nicknameInput = css` - margin-bottom: 12px; - ${typo.Comment.SemiBold} -`; +export const MainContainer = css({ + display: 'flex', + flexDirection: 'column', + width: '1175px', +}); + +export const myCommentColor = css({ + backgroundColor: color.WT_VIOLET, +}); + +export const commentContainer = css({ + display: 'flex', + alignItems: 'flex-start', + width: '100%', + padding: '30px 10px 30px 27px', + gap: '20px', + borderTop: '1px solid #f4f4f4', +}); + +export const profileWrapper = css({ + display: 'flex', +}); + +export const commentInfoWrapper = css({ + display: 'flex', + flexDirection: 'column', + width: '100%', + gap: '10px', +}); + +export const commentTopWrapper = css({ + display: 'flex', + justifyContent: 'space-between', +}); + +export const writerInfoWrapper = css({ + display: 'flex', + gap: '10px', +}); + +export const nickname = css({ + ...typo.Comment.SemiBold, + color: color.BK, +}); + +export const createdTime = css({ + ...typo.Comment.SemiBold, + color: '#67727E', + marginLeft: '10px', +}); + +export const editedText = css({ + ...typo.Comment.Regular, + color: color.MAIN, +}); + +export const commentTextWrapper = css({ + display: 'flex', + width: '100%', + paddingRight: '20px', + ...typo.Comment.Regular, + color: '#505050', +}); + +export const commentBottomWrapper = css({ + display: 'flex', + justifyContent: 'space-between', + paddingRight: '15px', +}); + +export const replyButton = css({ + display: 'flex', + gap: '10px', + ...typo.Comment.SemiBold, + background: 'none', + paddingTop: '10px', + color: color.GY[1], + cursor: 'pointer', +}); + +export const repliesWrapper = css({ + display: 'flex', + flexDirection: 'column', +}); + +export const replyContainer = css({ + display: 'flex', + width: '100%', + height: '210px', + justifyContent: 'center', + alignItems: 'flex-start', + flexDirection: 'column', + borderTop: '1px solid #f4f4f4', + paddingLeft: '105px', +}); + +export const nicknameInput = css({ + marginBottom: '12px', + ...typo.Comment.SemiBold, +}); export const moreButtonStyling = css({ display: 'flex', @@ -118,7 +118,7 @@ export const toastModalStyling = css({ top: '110px', left: '50%', transform: 'translate(-50%)', - zIndex: '1000', + zIndex: 1000, }); export const centerStyling = css({ @@ -126,5 +126,5 @@ export const centerStyling = css({ top: '50%', left: '50%', transform: 'translate(-50%, -50%)', - zIndex: '1000', + zIndex: 1000, }); diff --git a/src/components/organisms/CommentsSection/CommentsSection.style.ts b/src/components/organisms/CommentsSection/CommentsSection.style.ts index a43b8275..e61f0e8c 100644 --- a/src/components/organisms/CommentsSection/CommentsSection.style.ts +++ b/src/components/organisms/CommentsSection/CommentsSection.style.ts @@ -1,69 +1,69 @@ import { css } from '@emotion/react'; import color from '@/styles/color'; -export const commentsSectionContainer = css` - display: flex; - flex-direction: column; - padding-top: 5px; - padding-bottom: 100px; - margin: 0 auto; - background-color: ${color.WT}; - overflow-y: auto; - gap: 23px; -`; +export const commentsSectionContainer = css({ + display: 'flex', + flexDirection: 'column', + paddingTop: '5px', + paddingBottom: '100px', + margin: '0 auto', + backgroundColor: color.WT, + overflowY: 'auto', + gap: '23px', +}); -export const commentTopWrapper = css` - display: flex; - justify-content: space-between; - padding: 0 5px; -`; +export const commentTopWrapper = css({ + display: 'flex', + justifyContent: 'space-between', + padding: '0 5px', +}); -export const loggedInBackground = css` - width: 100%; - height: auto; - flex-shrink: 0; - display: flex; - flex-direction: column; - gap: 29px; - position: relative; -`; +export const loggedInBackground = css({ + width: '100%', + height: 'auto', + flexShrink: 0, + display: 'flex', + flexDirection: 'column', + gap: '29px', + position: 'relative', +}); -export const loggedOutBackground = css` - width: 100%; - height: 100%; - background-color: rgba(255, 255, 255, 0.01); - backdrop-filter: blur(11px); - position: absolute; - top: 0; - left: 0; - z-index: 1; - display: flex; - flex-direction: column; - gap: 29px; -`; +export const loggedOutBackground = css({ + width: '100%', + height: '100%', + backgroundColor: 'rgba(255, 255, 255, 0.01)', + backdropFilter: 'blur(11px)', + position: 'absolute', + top: 0, + left: 0, + zIndex: 1, + display: 'flex', + flexDirection: 'column', + gap: '29px', +}); -export const commentsWrapper = css` - display: flex; - flex-direction: column; - justify-content: flex-start; - padding: 0; - margin: 0; - height: auto; -`; +export const commentsWrapper = css({ + display: 'flex', + flexDirection: 'column', + justifyContent: 'flex-start', + padding: 0, + margin: 0, + height: 'auto', +}); -export const paginationWrapper = css` - display: flex; - justify-content: center; - margin-top: 17px; - width: 100%; - height: 40px; - flex-shrink: 0; -`; +export const paginationWrapper = css({ + display: 'flex', + justifyContent: 'center', + marginTop: '17px', + width: '100%', + height: '40px', + flexShrink: 0, +}); -export const toastModalWrapper = css` - position: absolute; - top: 76px; - left: 50%; - transform: translateX(-50%); - z-index: 10; -`; +export const toastModalWrapper = css({ + position: 'absolute', + top: '76px', + left: '50%', + transform: 'translateX(-50%)', + zIndex: 10, +}); From 8c3ba0d447b0832b36a2b79fe96508f31cca8ad7 Mon Sep 17 00:00:00 2001 From: Yoobin Seo <135022491+alwubin@users.noreply.github.com> Date: Mon, 17 Feb 2025 19:38:02 +0900 Subject: [PATCH 06/30] =?UTF-8?q?feat:=20TalkPickMobilePage=20=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=A7=80=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../TalkPickMobilePage.style.ts | 14 +++++ .../TalkPickMobilePage/TalkPickMobilePage.tsx | 56 +++++++++++++++++++ 2 files changed, 70 insertions(+) create mode 100644 src/pages/mobile/TalkPickMobilePage/TalkPickMobilePage.style.ts create mode 100644 src/pages/mobile/TalkPickMobilePage/TalkPickMobilePage.tsx diff --git a/src/pages/mobile/TalkPickMobilePage/TalkPickMobilePage.style.ts b/src/pages/mobile/TalkPickMobilePage/TalkPickMobilePage.style.ts new file mode 100644 index 00000000..b360295a --- /dev/null +++ b/src/pages/mobile/TalkPickMobilePage/TalkPickMobilePage.style.ts @@ -0,0 +1,14 @@ +import color from '@/styles/color'; +import { css } from '@emotion/react'; + +export const contentWrapStyle = css({ + display: 'flex', + flexDirection: 'column', + alignItems: 'center', +}); + +export const commentsWrapStyle = css({ + marginTop: '444px', + borderTop: `10px solid ${color.GY[5]}`, + width: '100%', +}); diff --git a/src/pages/mobile/TalkPickMobilePage/TalkPickMobilePage.tsx b/src/pages/mobile/TalkPickMobilePage/TalkPickMobilePage.tsx new file mode 100644 index 00000000..04d27ae3 --- /dev/null +++ b/src/pages/mobile/TalkPickMobilePage/TalkPickMobilePage.tsx @@ -0,0 +1,56 @@ +/* eslint-disable @typescript-eslint/no-unused-vars */ +import React, { useState } from 'react'; +import { useLocation, useParams } from 'react-router-dom'; +import MobileCommentsSection from '@/components/mobile/organisms/MobileCommentsSection/MobileCommentsSection'; +// import { useMemberQuery } from '@/hooks/api/member/useMemberQuery'; +import { useTalkPickDetailQuery } from '@/hooks/api/talk-pick/useTalkPickDetailQuery'; +// import { ToggleGroupItem } from '@/types/toggle'; +import { useCommentsQuery } from '@/hooks/api/comment/useCommentsQuery'; +import * as S from './TalkPickMobilePage.style'; + +interface State { + talkPickId: number; + isTodayTalkPick: boolean; +} + +const TalkPickMobilePage = () => { + const [currentPage, setCurrentPage] = useState(1); + // const { member } = useMemberQuery(); + + const { talkPickId } = useParams(); + const location = useLocation(); + const state = location.state as State; + + const id = state?.talkPickId ?? Number(talkPickId); + // const isTodayTalkPick = state?.isTodayTalkPick; + + const { talkPick } = useTalkPickDetailQuery(id); + + const handleCommentPageChange = (newPage: number) => { + setCurrentPage(newPage); + }; + + const { comments } = useCommentsQuery( + id, + { + page: currentPage - 1, + size: 7, + }, + 'comments', + ); + + return ( +
+
+ +
+
+ ); +}; +export default TalkPickMobilePage; From 4dfe1e5bb7416eecde751c16eafa86ee1c6a1bad Mon Sep 17 00:00:00 2001 From: Yoobin Seo <135022491+alwubin@users.noreply.github.com> Date: Mon, 17 Feb 2025 19:38:17 +0900 Subject: [PATCH 07/30] =?UTF-8?q?feat:=20MobileCommentItem=20=EC=BB=B4?= =?UTF-8?q?=ED=8F=AC=EB=84=8C=ED=8A=B8=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MobileCommentItem.style.ts | 77 +++++++ .../MobileCommentItem/MobileCommentItem.tsx | 196 ++++++++++++++++++ 2 files changed, 273 insertions(+) create mode 100644 src/components/mobile/molecules/MobileCommentItem/MobileCommentItem.style.ts create mode 100644 src/components/mobile/molecules/MobileCommentItem/MobileCommentItem.tsx diff --git a/src/components/mobile/molecules/MobileCommentItem/MobileCommentItem.style.ts b/src/components/mobile/molecules/MobileCommentItem/MobileCommentItem.style.ts new file mode 100644 index 00000000..fe796674 --- /dev/null +++ b/src/components/mobile/molecules/MobileCommentItem/MobileCommentItem.style.ts @@ -0,0 +1,77 @@ +import { css } from '@emotion/react'; +import color from '@/styles/color'; +import typo from '@/styles/typo'; + +export const MainContainer = css({ + display: 'flex', + flexDirection: 'column', + width: '344px', +}); + +export const myCommentColor = css({ + backgroundColor: color.WT_VIOLET, +}); + +export const commentContainer = css({ + display: 'flex', + alignItems: 'flex-start', + width: '100%', + padding: '30px 10px 30px 27px', + gap: '20px', + borderTop: '1px solid #f4f4f4', +}); + +export const profileWrapper = css({ + display: 'flex', +}); + +export const commentInfoWrapper = css({ + display: 'flex', + flexDirection: 'column', + width: '100%', + gap: '10px', +}); + +export const commentTopWrapper = css({ + display: 'flex', + justifyContent: 'space-between', +}); + +export const writerInfoWrapper = css({ + display: 'flex', + gap: '6px', +}); + +export const nickname = css({ + ...typo.Mobile.Text.SemiBold_12, + color: color.GY[1], +}); + +export const createdTime = css({ + ...typo.Mobile.Main.Regular_12, + color: color.GY[1], + marginLeft: '8px', +}); + +export const commentTextWrapper = css({ + ...typo.Text.Regular, + display: 'flex', + width: '100%', + paddingRight: '20px', + color: color.BK, +}); + +export const commentBottomWrapper = css({ + display: 'flex', + paddingRight: '15px', + gap: '18px', +}); + +export const replyButton = css({ + ...typo.Mobile.Text.Medium_12, + display: 'flex', + gap: '5px', + background: 'none', + color: color.GY[1], + cursor: 'pointer', +}); diff --git a/src/components/mobile/molecules/MobileCommentItem/MobileCommentItem.tsx b/src/components/mobile/molecules/MobileCommentItem/MobileCommentItem.tsx new file mode 100644 index 00000000..a5cf1ec7 --- /dev/null +++ b/src/components/mobile/molecules/MobileCommentItem/MobileCommentItem.tsx @@ -0,0 +1,196 @@ +/* eslint-disable @typescript-eslint/no-unused-vars */ +import React, { useEffect, useMemo, useRef, useState } from 'react'; +import { Comment } from '@/types/comment'; +import { MobileComment } from '@/assets'; +import { useMemberQuery } from '@/hooks/api/member/useMemberQuery'; +import { formatDateFromISOWithTime } from '@/utils/formatData'; +import { useCommentActions } from '@/hooks/comment/useCommentActions'; +import { useCreateReplyMutation } from '@/hooks/api/comment/useCreateReplyMutation'; +import { useRepliesQuery } from '@/hooks/api/comment/useRepliesQuery'; +import MenuTap, { MenuItem } from '@/components/atoms/MenuTap/MenuTap'; +import CategoryBarChip from '@/components/atoms/CategoryBarChip/CategoryBarChip'; +import LikeButton from '@/components/atoms/LikeButton/LikeButton'; +import TextArea from '@/components/molecules/TextArea/TextArea'; +import CommentProfile from '@/components/atoms/CommentProfile/CommentProfile'; +import useToastModal from '@/hooks/modal/useToastModal'; +import useOutsideClick from '@/hooks/common/useOutsideClick'; +import * as S from './MobileCommentItem.style'; + +export interface CommentItemProps { + comment: Comment; + selectedPage: number; + talkPickWriter: string; +} + +const MobileCommentItem = ({ + comment, + selectedPage, + talkPickWriter, +}: CommentItemProps) => { + const { member } = useMemberQuery(); + + const isMyComment = useMemo(() => { + return comment?.nickname === member?.nickname; + }, [comment?.nickname, member?.nickname]); + + const isTalkPickWriter = useMemo(() => { + return comment?.nickname === talkPickWriter; + }, [comment?.nickname, talkPickWriter]); + + const commentRef = useRef(null); + const { isVisible, modalText, showToastModal } = useToastModal(); + + const [editCommentClicked, setEditCommentClicked] = useState(false); + const [editCommentText, setEditCommentText] = useState( + comment.content, + ); + + const [activeModal, setActiveModal] = useState< + 'reportComment' | 'reportText' | 'deleteText' | 'none' + >('none'); + + const onCloseModal = () => { + setActiveModal('none'); + }; + + const [visibleReply, setVisibleReply] = useState(10); + + const { handleEditSubmit, handleDelete, handleLikeToggle, handleReport } = + useCommentActions( + comment, + editCommentText, + selectedPage, + setEditCommentClicked, + showToastModal, + ); + + useEffect(() => { + setEditCommentText(comment.content); + }, [comment.content]); + + useOutsideClick(commentRef, () => setEditCommentClicked(false)); + + const [showReply, setShowReply] = useState(false); + const [replyValue, setReplyValue] = useState(''); + + const handleReplyToggle = () => { + setShowReply(!showReply); + setVisibleReply(10); + }; + + const { mutate: createReply } = useCreateReplyMutation( + comment.talkPickId, + comment.id, + selectedPage, + ); + + const handleReplyButton = () => { + createReply({ content: replyValue }); + setReplyValue(''); + }; + + const { replies } = useRepliesQuery(comment.talkPickId, comment.id); + + // const handleDeleteCommentButton = () => { + // onCloseModal(); + // handleDelete(); + // }; + + const myComment: MenuItem[] = [ + { + label: '수정', + onClick: () => { + setEditCommentClicked(true); + }, + }, + { + label: '삭제', + onClick: () => { + setActiveModal('deleteText'); + }, + }, + ]; + + const reportComment: MenuItem[] = [ + { + label: '신고', + onClick: () => { + setActiveModal('reportText'); + }, + }, + ]; + + // const handleReportCommentButton = (reason: string) => { + // handleReport(reason); + // onCloseModal(); + // }; + + // const handleMoreButton = () => { + // setVisibleReply((reply) => reply + 10); + // }; + + return ( +
+
+
+ +
+
+
+
+ {comment?.nickname} + + {formatDateFromISOWithTime(comment?.createdAt ?? '')} + + {isTalkPickWriter && ( + 작성자 + )} + {/* {comment.edited && 수정됨} */} +
+ {!editCommentClicked && ( + + )} +
+ {editCommentClicked ? ( +