From 26884395c8af3ecba2087a511eb9aa60d087ef73 Mon Sep 17 00:00:00 2001 From: Jiseok Woo <115205098+jisurk@users.noreply.github.com> Date: Sun, 4 Aug 2024 13:05:44 +0900 Subject: [PATCH 1/2] =?UTF-8?q?FE-54=F0=9F=94=80=20=EC=83=81=EC=84=B8?= =?UTF-8?q?=ED=8E=98=EC=9D=B4=EC=A7=80=20=EB=A6=AC=ED=8C=A9=ED=86=A0?= =?UTF-8?q?=EB=A7=81=20main=EB=A8=B8=EC=A7=80=20(#172)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * FE-31 상세페이지 UI 제작 (#12) * FE-31💄상세페이지 기본 UI 제작 * FE-31♻️ textarea태그 Textarea컴포넌트로 변경 * FE-31💄 반응형 디자인 추가 --------- Co-authored-by: Woojiseok * FE-43 ✨ 상세페이지 에피그램 조회 (#18) * FE-43✨ 상세페이지 Epigram API연동 * FE-43⚡ ️axios 에러 핸들링 추가 * FE-43🏗️ 상세페이지 Layout 구조개선 * FE-43📝 주석 추가 * FE-43🔥 사용안하는 파일 삭제 * FE-43✏️ 오타 수정 * FE-43 🐛 id없을때 useQuery실행되는 문제 해결 * FE-43♻️ interface->zod 변경 --------- Co-authored-by: 우지석 * FE-43✨ 사용자 ID에 따른 미트볼아이콘 표시 (#22) * FE-43✨ 사용자 ID에 따른 미트볼아이콘 표시 * FE-43✨ 에피그램 상세페이지 더보기 드롭다운 추가 * FE-43💄 MoreOptionMenu 스타일 수정 * FE-31 상세페이지 UI 제작 (#12) * FE-31💄상세페이지 기본 UI 제작 * FE-31♻️ textarea태그 Textarea컴포넌트로 변경 * FE-31💄 반응형 디자인 추가 --------- Co-authored-by: Woojiseok * FE-43 ✨ 상세페이지 에피그램 조회 (#18) * FE-43✨ 상세페이지 Epigram API연동 * FE-43⚡ ️axios 에러 핸들링 추가 * FE-43🏗️ 상세페이지 Layout 구조개선 * FE-43📝 주석 추가 * FE-43🔥 사용안하는 파일 삭제 * FE-43✏️ 오타 수정 * FE-43 🐛 id없을때 useQuery실행되는 문제 해결 * FE-43♻️ interface->zod 변경 --------- Co-authored-by: 우지석 * FE-43✨ 사용자 ID에 따른 미트볼아이콘 표시 (#22) * FE-43✨ 사용자 ID에 따른 미트볼아이콘 표시 * FE-43✨ 에피그램 상세페이지 더보기 드롭다운 추가 * FE-43💄 MoreOptionMenu 스타일 수정 * ✨ 상세페이지 댓글 조회 api연동 (#38) * FE-42💄 EpigramComment안에 CommentCard 추가 * FE-42✨ 상세페이지 댓글 조회 api연동 * FE-42✨ dateUtil함수 추가, 적용 * FE-42✨ 댓글작성자가 본인인지 판별해 수정,삭제 표시 * FE-42🔥 안쓰는 함수 삭제 * FE-42💄 EpigramComment 배경색 수정 * FE-42♻️ CommetCard 구조 개선 * FE-42💄작성된 댓글 없을때 UI 추가 * FE-42🐛 댓글수를 length->totalCount로 변경 * FE-42♻️ useEpigramCommentHook 분리 * FE-42✨ 댓글 목록에 무한스크롤 적용 * FE-42💡 주석 추가 --------- Co-authored-by: 우지석 * FE-76✨ 댓글 작성 api 연동 (#78) * FE-76♻️ 댓글 textarea 컴포넌트 분리 * FE-76💄 switch 컴포넌트 스타일 수정 * FE-76✨ textarea focus out 버튼 추가 * FE-76✨ postComment schema,interface 추가, 수정 * FE-76✨ 댓글 작성 api 연동 * FE-76🐛 import error 해결 * FE-76✨ switch로 댓글 공개,비공개 설정 기능 추가 * FE-76✨ 댓글 작성 시 image를 유저가 등록한 image로 변경 * FE-76🐛 build error 해결 --------- Co-authored-by: 우지석 * FE-45✨ 에피그램 삭제 api 연동 (#80) * FE-45✨ 에피그램 삭제 api 연동 * FE-45💄 에피그램 삭제 모달 추가 * FE-45💄 반응형 디자인 수정 * FE-45♻️ DeleteAlertModal 컴포넌트 분리 * FE-45🐛 build error 해결 --------- Co-authored-by: 우지석 * FE-78✨댓글 수정,삭제 기능 추가 (#91) * FE-78💄 미트볼아이콘 ui수정 * FE-78✨ 댓글 삭제 함수 추가 * FE-78✨댓글 삭제 버튼 기능 추가 * FE-78✨ 댓글 수정 api함수 추가 * FE-78✨ 댓글 수정 기능 추가 * FE-78📝 주석 추가 * FE-78💄 EpigramComment height수정 * FE-78🐛 build error 해결 --------- Co-authored-by: 우지석 * FE-44✨ 에피그램 수정 기능 추가 (#97) * FE-44🚚 상세페이지 페이지 구조 변경 * FE-44✨ 에피그램 수정 api 함수 추가 * FE-44✨ 에피그램 수정 기능 추가 * FE-44♻️ 저자선택관련 함수 useAuthorSelection훅으로 분리 * FE-44💄 EditEpigram,AddEpigram UI수정 * FE-44🐛 출처 유효성검사 버그 수정 * FE-44✨ 작성자 본인이 아닐때 수정페이지 접근 시 리다이렉트 기능 구현 * FE-44🐛 유효성 검사 버그 수정 --------- Co-authored-by: 우지석 * FE-41✨좋아요 기능 추가 (#103) * FE-41♻️ httpClien에t interceoptor 추가 * FE-41✨ 좋아요 api 함수 추가 * FE-41✨ 좋아요 기능 Layout에 적용 * FE-41✨ Url Link버튼 생성 * FE-41💄좋아요,link버튼 스타일 수정 * FE-41🐛 import 에러 해결 * FE-41♻️ 기존header-> Header컴포넌트로 변경 --------- Co-authored-by: 우지석 * FE-54🐛 오타 수정 * build error 해결 * FE-54🐛 build error해결 * Fe-54♻️상세페이지 리팩토링 (#131) * FE-54🚚 상세페이지,수정페이지 페이지 폴더 변경 * FE-54♻️ 상세페이지로 이동하는 url 수정 * FE-54🚚 작성페이지 페이지 폴더 생성 * FE-54♻️상세페이지 개선사항 적용 (#146) * FE-54🚚 상세페이지,수정페이지 페이지 폴더 변경 * FE-54♻️ 상세페이지로 이동하는 url 수정 * FE-54🚚 작성페이지 페이지 폴더 생성 * FE-54💄 Switch컴포넌트 배경색 변경 * FE-54💄 댓글 없을때 스타일 수정 * FE-54🚚 useAddEpigram 이름 변경 * FE-54💄 댓글 공개,비공개 아이콘 추가 * FE-54🐛 build error 해결 * FE-54✨ 댓글 수정 로직 변경 (#163) * FE-54✨ 댓글 수정 로직 변경 * FE-54✨ CommentTextarea Enter key로 폼 제출 함수 추가 * FE-54💄 CommentItem height수정 * FE-54💄댓글 height 조정 --------- Co-authored-by: 우지석 * FE-54♻️ 좋아요 기능 리팩토링, Query Key 분리 (#169) * FE-54🚚 상세페이지,수정페이지 페이지 폴더 변경 * FE-54♻️ 상세페이지로 이동하는 url 수정 * FE-54🚚 작성페이지 페이지 폴더 생성 * FE-54💄 Switch컴포넌트 배경색 변경 * FE-54💄 댓글 없을때 스타일 수정 * FE-54🚚 useAddEpigram 이름 변경 * FE-54💄 댓글 공개,비공개 아이콘 추가 * FE-54🐛 build error 해결 * FE-54♻️ 좋아요기능 Optimistic Update적용 * FE-54💄 좋아요 상태에 따른 이미지 변경 * FE-54💄댓글 수정시 스타일 변경 * FE-54♻️ 댓글조회 query Key 분리 --------- Co-authored-by: Woojiseok --- public/icon/privateIcon.png | Bin 0 -> 5843 bytes public/icon/publicIcon.png | Bin 0 -> 6009 bytes public/noComment.svg | 6 ++ public/unlikeIcon.svg | 3 + src/apis/queries.ts | 10 ++- .../epigram/Comment/CommentItem.tsx | 24 +++++--- .../epigram/Comment/CommentList.tsx | 16 +++-- .../epigram/Comment/CommentTextarea.tsx | 24 +++++--- src/components/epigram/Comment/NoComment.tsx | 10 ++- src/components/epigram/EditEpigram.tsx | 4 +- src/components/ui/switch.tsx | 2 +- ...igramQueryHook.ts => useAddEpigramHook.ts} | 2 - src/hooks/useEpigramCommentsQueryHook.ts | 19 +++--- src/hooks/useEpigramLike.ts | 58 +++++++++++------- src/hooks/usePostCommentHook.ts | 2 + src/pageLayout/Epigram/AddEpigram.tsx | 2 +- src/pageLayout/Epigram/EpigramComment.tsx | 19 ++---- src/pageLayout/Epigram/EpigramFigure.tsx | 17 +++-- src/pages/epigrams/[id]/index.tsx | 6 +- 19 files changed, 142 insertions(+), 82 deletions(-) create mode 100644 public/icon/privateIcon.png create mode 100644 public/icon/publicIcon.png create mode 100644 public/noComment.svg create mode 100644 public/unlikeIcon.svg rename src/hooks/{epigramQueryHook.ts => useAddEpigramHook.ts} (90%) diff --git a/public/icon/privateIcon.png b/public/icon/privateIcon.png new file mode 100644 index 0000000000000000000000000000000000000000..3f6c8a22ffeb9d1a83ff0e64505ce02924800369 GIT binary patch literal 5843 zcmeHL_ct6|^IyFSPqgS!qDw^YqDCirC&B6~R*SN`1PLCI=v}l$5FttsE$S-463gnn z_g;4Q^_=e?@Sg8)?>X;#%b7cOK4;F%+%xx{JF!LvT2$oBd zCAcG9aGw4mmyB17`0lFyCoCGSV~Ez~OLr`2V&4Mc}_A0y&?eBJW(i_J3hu z0>Hy3AS5CtAtfWHproR{M??G9eL8vuMy3bMEUawo9GnlixOsRV@$m}?3JHsdK7Jzh zR9r$*T1Hk*UO`bwS>>6kn!1LjmbQ+rp1y&hk?{)?Q!{f5ODk&|TRVFP$Ct01U0i`~ z?jD|A-aa7T*M9y1fkDAT!rms0HGRoMr%nlr9lzj~pWLb`l1qE7Eb8SB z-JqasoIh{9EE%5*LS)iA*=Dj<)U&E}$e~ZW`fJNg7%(sM3gdc?!M2A%7Dhtz@A!ow zCQX+jNczlvsPk^OJD5?_re#INX(@uuGhHM{-g|jUYrmyRH=F=pS8qm%8)?BVCA4}t za7r7F?tN0__$m0JSYx^bo`KxeNZvPa_KEmxjH}Cqiv+^YK;5@t`g=+y(%DWmZ#?qR zLu2Wtdq=lfFUIk7Pzno0f+wdBHVmhLa{X;&8{#G$;d}RNKytsYomgouBY$A?Q!>69 z9c$xc)+?kxA-*5$Ga~X+SrI8`iu)|z5dOLP1TtI`$(x};8F}AU=H1{`Y?3kiQi`uG zMw#_&g?>Lrh$-^&tx>|iQq}jZXXYhKrt)hp094s*<%3SP`9G=mR!$U zfJt512YNdqRqrb0K=Ad&hL8!k?Tec3{+RIKL|&!q=_-0@fqk50cgbj!S9DN3{Mo#V z{~9rhK0~QsQ4Z~w7tsR;@v}d7Fi2k3H0JYb0FB5l_2Oisds%s3CV}Tzajw5JAc$PF zg#LRujB=um8yarn*DeNblii7|WNlfa`M&q*#f;_WOu;HSLta#8nM)aP?4Zwe!)Q(?XBU%6ZRuBFV9g z5UbR%cRucM*4RKMX_e~~*6v%WELDsaTMG(jP%I~NvtAxJ!r<~cKt_1Et)WQ`9NBfT zE1Ba6=GaE<(vXpaHbU4#(b4TKa)vYV>^W-j=S?G%{Tq^jeEKVI8kT3Z5(C{q8`(iS zsry9DeigYzpUx%R6N6buV0@YuLEe3TAFcefdjR3~EvH)G$ZlMom*k8qH9_TZ zOb;zbbLXJHG;1x>0Tpw7uN?!)t&2G5MDhmtvZG~l0_ooPcCuHVcVH*V*rbwIpc@UoYXijs;kCQ{;En@LHqj z)j_mM?NK*T1IyG)3x@Z?(?`{QM9I6gP(F3;%C0zJULTnJ_-qDR9J^}|D@yRUSLdGg zi9tR(#gN31EJrr`%6Iu*V+m@L0nMOtS|7LTv^MBSbggpk>*nfLIbLjx$jgI|ir}SS z#W|F*;rZkzgap>6&`%wF(&;JV{8$zcH-K2&uyg`5diijvjyXrfH3ytb%~p zzw9UWm@3m{tUMT*`m5|ytpB{~PW!0kX~9-@sc-;;NU2yWZU}(rXt)9@&hYF!P&rUe zW`OO$+BN<4Ka!AOe;FV;tgnHJBD_1(+6QUtsavJ=F2qA_=@0lHpn{dF+{@IV|x%)hcR{M9NfTI=e>eMGDPs&g3L?=XpS=u+H z85~1<;G~2PC+;}9__uHPN>(ALo;py!)X1gpj=I-jgKSfGNGA&y=7(tK4G(I(?ID^r zW1}x%twzX5(`WNp_(5MlI7f(GQyrANQ!Q2M`n4Sk(Y@9}j0q`q+T`VHJ5NH2qHsb0 zp~`>TfawUR+!A4Wi`%gKNoH2l?HW%?e|d4d;J2JQz$RCk>CT5M2I#d@AK~p_zicSY zyow|W1peLrRFr1TV(Ss+ttU5wB+EtuD2DJML6BI z0^y+kpZz3feZ^_W6q^)-50kApbI)?bpL-E$As5gaF*(0n`$h}(ba*N z&Gz;L^cOMnQC77iT8!a)j?z!y>l7(`y;3UrpPzMc1e>Z<(wk$rrW~AwdLDx^(M!~L zl%V;RZ-7iHyWp9V3g0=Dzqt7AF$U`C_Kep-Q;@-tl&x%yy&fYiqetW+YiUys5O-6N zEEl{18SCMF5%4NDfa+4ICN zdq3!(HpP{*8SBf<%LIS;<6!>IZ0|324}tah^rQ;onkWy%kV4Gj$m5l{ft+w67$IB zI`L@qvUj&1Bfatwg(52l$~hx2 zms$a6@#4DyGUM9ZGdD5T?LE4LtBeaEsyRNAo_EYCm57&$-SSnXRBqoMPKFlu*=m7(1BC>h%WmGNR!xk<#(J z`+Dg^=$&`k7oVb<(~ff%tr3;gM=~j^3XVz^u-vQWVbr1RqWUxVmH!6i2~iiev@er~ zubcxe2Mo6C5*Gy%WnRC?6+fk?3~lJkWFUVUP#_1~^Zx*rg_CUG(|u$^ z{0EWKK@+Ml9X^%nzn2}77=WjD3~xt|F76OrA5Z%kNlGKzR{3LvoA$FGDGd%X{bnIi z3pT*1k}!0P51dqiEmF{kRo`}>aM5rc;{RRFf6PQk+6<`D6^ye*GT`BhcF5BM?cW1B z89u)%8=a%&9K|0Zr4PZwC$xeIlBh;2vA+f2F)SiS%R?Wkz=(pm{I_FCX&mw3(FUz| zzeVAW!qIYzeI zV8$o3gxMFE+*5}EC}@&71pT!Y|8byTp3OUJkcyDB7J!N&4`;+Dv_VvG0R%Eu8Zzuz`m#r`g)G3#ad(#3wX&C+Mg?mw&cXHiM(B0$UUMz6Em(PnkPr z5zQ#+${L=OkuEZmkwKov0#aH3lO8JAc;$WPxDr|5b2`e<*1k-0(x>%zX?0oQI3=X; z`?QABgz*bF1`_E6-F*#jB+T?Fxy#MxPj(v>e@obX+#i9wh9_ zy94$SWq#-x&AmS%L`xZ3*H_>}@BB2>IPX4X(ol1CUqKR20sM{&*7sT00%Y+sQK18Dq9Bz#<8O#b4g0aE&vQ0I8e5gwK%*ie3O6Fx0L4(4DfL8U|^z z)Swvmcgb&zs5Kghv%cz0ne#s4FI}|_;IIOTLC%KEE^|}6FaM0&uNe=L3^_mX!#w?ZN^iI3Y^9&B7A9)k zXx3s{knEIZb*peXYw7*RvXIz<2Z|JKJ@Vus+l~2qwF)6eacb$?KZ7rI^4sl>UTZ1J*5wq9Y&tVE*p8p^M1;Q;O{6=8yWGEi#LB-x7VP~+3EST1ffR% PloGWy4Aj4>I!68r-<$i) literal 0 HcmV?d00001 diff --git a/public/icon/publicIcon.png b/public/icon/publicIcon.png new file mode 100644 index 0000000000000000000000000000000000000000..05e342c37ea68dbead75b434fcd1743664c89358 GIT binary patch literal 6009 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 literal 0 HcmV?d00001 diff --git a/public/noComment.svg b/public/noComment.svg new file mode 100644 index 00000000..ebf2cf2c --- /dev/null +++ b/public/noComment.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/public/unlikeIcon.svg b/public/unlikeIcon.svg new file mode 100644 index 00000000..9b841d94 --- /dev/null +++ b/public/unlikeIcon.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/src/apis/queries.ts b/src/apis/queries.ts index 4bcb6463..817fe12b 100644 --- a/src/apis/queries.ts +++ b/src/apis/queries.ts @@ -5,7 +5,7 @@ import { CommentRequestType } from '@/schema/comment'; import { GetMonthlyEmotionLogsRequestType } from '@/schema/emotion'; import { GetEpigramsParamsType } from '@/schema/epigrams'; import { getMe, getUser, getMyContentCount } from './user'; -import { getEpigram } from './epigram'; +import { getEpigram, toggleEpigramLike } from './epigram'; import { getEpigramComments, getMyEpigramComments } from './epigramComment'; import getMonthlyEmotionLogs from './emotion'; import getEpigrams from './getEpigrams'; @@ -37,12 +37,20 @@ const queries = createQueryKeyStore({ }, enabled: request.id !== undefined, }), + toggleLike: (request: EpigramRequestType) => ({ + queryKey: ['toggleEpigramLike', request.id], + mutationFn: (variables: EpigramRequestType) => toggleEpigramLike(variables), + }), }, epigramComment: { getComments: (request: CommentRequestType) => ({ queryKey: ['epigramComments', request], queryFn: () => getEpigramComments(request), }), + getCommentList: (request: CommentRequestType) => ({ + queryKey: ['epigramComments', request] as const, + queryFn: ({ pageParam }: { pageParam: number | undefined }) => getEpigramComments({ ...request, cursor: pageParam }), + }), getMyComments: (request: CommentRequestType) => ({ queryKey: ['myEpigramComments', request], queryFn: () => getMyEpigramComments(request), diff --git a/src/components/epigram/Comment/CommentItem.tsx b/src/components/epigram/Comment/CommentItem.tsx index 8d26f189..3b1b4501 100644 --- a/src/components/epigram/Comment/CommentItem.tsx +++ b/src/components/epigram/Comment/CommentItem.tsx @@ -1,29 +1,36 @@ import React, { useState } from 'react'; import Image from 'next/image'; import { CommentType } from '@/schema/comment'; -import { sizeStyles, textSizeStyles, gapStyles, paddingStyles, contentWidthStyles } from '@/styles/CommentCardStyles'; +import { textSizeStyles, gapStyles, paddingStyles, contentWidthStyles } from '@/styles/CommentCardStyles'; import getCustomRelativeTime from '@/lib/dateUtils'; import useDeleteCommentMutation from '@/hooks/useDeleteCommentHook'; import { useToast } from '@/components/ui/use-toast'; import { Button } from '@/components/ui/button'; import DeleteAlertModal from '../DeleteAlertModal'; +import CommentTextarea from './CommentTextarea'; interface CommentItemProps { comment: CommentType; status?: 'view' | 'edit'; - onEditComment: (id: number, content: string, isPrivate: boolean) => void; + onEditComment: (id: number) => void; + isEditing: boolean; + epigramId: number; } -function CommentItem({ comment, status, onEditComment }: CommentItemProps) { +function CommentItem({ comment, status, onEditComment, isEditing, epigramId }: CommentItemProps) { const deleteCommentMutation = useDeleteCommentMutation(); const { toast } = useToast(); const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false); const handleEditClick = () => { - onEditComment(comment.id, comment.content, comment.isPrivate); + onEditComment(comment.id); }; - // NOTE: 댓글 삭제 + // NOTE: 수정 중일 때(isEditing===true) CommentTextarea를 수정모드로 렌더링 + if (isEditing) { + return onEditComment(0)} />; + } + const handleDeleteComment = async () => { try { await deleteCommentMutation.mutateAsync(comment.id); @@ -42,9 +49,9 @@ function CommentItem({ comment, status, onEditComment }: CommentItemProps) { return (
-
+
프로필 이미지 @@ -57,6 +64,7 @@ function CommentItem({ comment, status, onEditComment }: CommentItemProps) {
{getCustomRelativeTime(comment.createdAt)}
+ {comment.isPrivate
{status === 'edit' && (
@@ -78,7 +86,7 @@ function CommentItem({ comment, status, onEditComment }: CommentItemProps) { )}
{comment.content}
diff --git a/src/components/epigram/Comment/CommentList.tsx b/src/components/epigram/Comment/CommentList.tsx index f1cccdc9..d1a33e15 100644 --- a/src/components/epigram/Comment/CommentList.tsx +++ b/src/components/epigram/Comment/CommentList.tsx @@ -5,16 +5,16 @@ import NoComment from './NoComment'; import CommentItem from './CommentItem'; interface CommentListProps extends Omit { - onEditComment: (id: number, content: string, isPrivate: boolean) => void; + onEditComment: (id: number) => void; + editingCommentId: number | null; } -function CommentList({ epigramId, currentUserId, onEditComment }: CommentListProps) { +function CommentList({ epigramId, currentUserId, onEditComment, editingCommentId }: CommentListProps) { const { data, fetchNextPage, hasNextPage, isFetchingNextPage, status } = useEpigramCommentsQuery(epigramId); const observerRef = useRef(null); const lastCommentRef = useRef(null); - // NOTE: Observer 콜백: 마지막 요소가 화면에 보이면 다음 페이지(댓글 최대3개를 묶어 1페이지 취급) 로드 const handleObserver = useCallback( (entries: IntersectionObserverEntry[]) => { const [target] = entries; @@ -39,7 +39,6 @@ function CommentList({ epigramId, currentUserId, onEditComment }: CommentListPro } return () => { - // NOTE: effect가 실행되기전에 호출해서 메모리 누수를 방지해줌 if (observerRef.current) { observerRef.current.disconnect(); } @@ -58,7 +57,14 @@ function CommentList({ epigramId, currentUserId, onEditComment }: CommentListPro {allComments.length > 0 ? ( <> {allComments.map((comment) => ( - + ))}
{isFetchingNextPage &&
더 많은 댓글을 불러오는 중...
}
diff --git a/src/components/epigram/Comment/CommentTextarea.tsx b/src/components/epigram/Comment/CommentTextarea.tsx index 707ee760..c63a30c1 100644 --- a/src/components/epigram/Comment/CommentTextarea.tsx +++ b/src/components/epigram/Comment/CommentTextarea.tsx @@ -7,13 +7,13 @@ import { Textarea } from '@/components/ui/textarea'; import { zodResolver } from '@hookform/resolvers/zod'; import { useForm } from 'react-hook-form'; import Image from 'next/image'; -import { CommentFormSchema, CommentFormValues } from '@/schema/comment'; +import { CommentFormSchema, CommentFormValues, CommentType } from '@/schema/comment'; import usePostCommentMutation from '@/hooks/usePostCommentHook'; import usePatchCommentMutation from '@/hooks/usePatchCommentHook'; interface CommentTextareaProps { epigramId: number; - editingComment: { id: number; content: string; isPrivate: boolean } | null; + editingComment?: CommentType; onEditComplete: () => void; } @@ -29,9 +29,8 @@ function CommentTextarea({ epigramId, editingComment, onEditComplete }: CommentT }, }); - // NOTE: 수정중인지 새댓글작성중인지의 상태가 변활때 폼 초기화 useEffect(() => { - if (editingComment !== null) { + if (editingComment) { form.reset({ content: editingComment.content, isPrivate: editingComment.isPrivate, @@ -46,7 +45,6 @@ function CommentTextarea({ epigramId, editingComment, onEditComplete }: CommentT const onSubmit = (values: CommentFormValues) => { if (editingComment) { - // NOTE: 댓글 수정 시 patchCommentMutation.mutate( { commentId: editingComment.id, ...values }, { @@ -57,7 +55,6 @@ function CommentTextarea({ epigramId, editingComment, onEditComplete }: CommentT }, ); } else { - // NOTE: 새 댓글 작성 시 const commentData = { epigramId, ...values, @@ -70,7 +67,13 @@ function CommentTextarea({ epigramId, editingComment, onEditComplete }: CommentT } }; - // NOTE: 수정 취소 + const handleKeyDown = (event: React.KeyboardEvent) => { + if (event.key === 'Enter' && !event.shiftKey) { + event.preventDefault(); + form.handleSubmit(onSubmit)(); + } + }; + const handleCancel = () => { form.reset(); onEditComplete(); @@ -78,7 +81,7 @@ function CommentTextarea({ epigramId, editingComment, onEditComplete }: CommentT return (
- +