Skip to content

Commit

Permalink
FE-54✨ 댓글 수정 로직 변경 (#163)
Browse files Browse the repository at this point in the history
* FE-54✨ 댓글 수정 로직 변경

* FE-54✨ CommentTextarea Enter key로 폼 제출 함수 추가

* FE-54💄 CommentItem height수정

* FE-54💄댓글 height 조정

---------

Co-authored-by: 우지석 <[email protected]>
  • Loading branch information
jisurk and 우지석 authored Aug 2, 2024
1 parent 1a69b6e commit 735a7c1
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 34 deletions.
23 changes: 15 additions & 8 deletions src/components/epigram/Comment/CommentItem.tsx
Original file line number Diff line number Diff line change
@@ -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 <CommentTextarea epigramId={epigramId} editingComment={comment} onEditComplete={() => onEditComment(0)} />;
}

const handleDeleteComment = async () => {
try {
await deleteCommentMutation.mutateAsync(comment.id);
Expand All @@ -42,9 +49,9 @@ function CommentItem({ comment, status, onEditComment }: CommentItemProps) {

return (
<div
className={`bg-slate-100 border-t border-slate-300 flex-col justify-start items-start gap-2.5 inline-flex ${sizeStyles.sm} ${sizeStyles.md} ${sizeStyles.lg} ${paddingStyles.sm} ${paddingStyles.md} ${paddingStyles.lg}`}
className={`h-auto bg-slate-100 border-t border-slate-300 flex-col justify-start items-start gap-2.5 inline-flex w-[360px] md:w-[384px] lg:w-[640px] ${paddingStyles.sm} ${paddingStyles.md} ${paddingStyles.lg}`}
>
<div className='justify-start items-start gap-4 inline-flex'>
<div className='h-full justify-start items-start gap-4 inline-flex'>
<div className='w-12 h-12 relative'>
<div className='w-12 h-12 bg-zinc-300 rounded-full overflow-hidden flex items-center justify-center'>
<Image src={comment.writer.image || '/ProfileTestImage.jpg'} alt='프로필 이미지' layout='fill' objectFit='cover' className='rounded-full' />
Expand Down Expand Up @@ -79,7 +86,7 @@ function CommentItem({ comment, status, onEditComment }: CommentItemProps) {
)}
</div>
<div
className={`w-full text-zinc-800 font-normal font-pretendard ${textSizeStyles.sm.content} ${textSizeStyles.md.content} ${textSizeStyles.lg.content} ${contentWidthStyles.sm} ${contentWidthStyles.md} ${contentWidthStyles.lg}`}
className={`w-full text-zinc-800 font-normal font-pretendard whitespace-pre ${textSizeStyles.sm.content} ${textSizeStyles.md.content} ${textSizeStyles.lg.content} ${contentWidthStyles.sm} ${contentWidthStyles.md} ${contentWidthStyles.lg}`}
>
{comment.content}
</div>
Expand Down
16 changes: 11 additions & 5 deletions src/components/epigram/Comment/CommentList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,16 @@ import NoComment from './NoComment';
import CommentItem from './CommentItem';

interface CommentListProps extends Omit<EpigramCommentProps, 'userImage'> {
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<IntersectionObserver | null>(null);
const lastCommentRef = useRef<HTMLDivElement | null>(null);

// NOTE: Observer 콜백: 마지막 요소가 화면에 보이면 다음 페이지(댓글 최대3개를 묶어 1페이지 취급) 로드
const handleObserver = useCallback(
(entries: IntersectionObserverEntry[]) => {
const [target] = entries;
Expand All @@ -39,7 +39,6 @@ function CommentList({ epigramId, currentUserId, onEditComment }: CommentListPro
}

return () => {
// NOTE: effect가 실행되기전에 호출해서 메모리 누수를 방지해줌
if (observerRef.current) {
observerRef.current.disconnect();
}
Expand All @@ -58,7 +57,14 @@ function CommentList({ epigramId, currentUserId, onEditComment }: CommentListPro
{allComments.length > 0 ? (
<>
{allComments.map((comment) => (
<CommentItem key={comment.id} comment={comment} status={comment.writer.id === currentUserId ? 'edit' : 'view'} onEditComment={onEditComment} />
<CommentItem
key={comment.id}
comment={comment}
status={comment.writer.id === currentUserId ? 'edit' : 'view'}
onEditComment={onEditComment}
isEditing={editingCommentId === comment.id}
epigramId={epigramId}
/>
))}
<div ref={lastCommentRef}>{isFetchingNextPage && <div>더 많은 댓글을 불러오는 중...</div>}</div>
</>
Expand Down
18 changes: 11 additions & 7 deletions src/components/epigram/Comment/CommentTextarea.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand All @@ -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,
Expand All @@ -46,7 +45,6 @@ function CommentTextarea({ epigramId, editingComment, onEditComplete }: CommentT

const onSubmit = (values: CommentFormValues) => {
if (editingComment) {
// NOTE: 댓글 수정 시
patchCommentMutation.mutate(
{ commentId: editingComment.id, ...values },
{
Expand All @@ -57,7 +55,6 @@ function CommentTextarea({ epigramId, editingComment, onEditComplete }: CommentT
},
);
} else {
// NOTE: 새 댓글 작성 시
const commentData = {
epigramId,
...values,
Expand All @@ -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();
Expand All @@ -91,6 +94,7 @@ function CommentTextarea({ epigramId, editingComment, onEditComplete }: CommentT
editingComment ? 'border-black' : 'border-line-200'
}`}
placeholder='100자 이내로 입력해 주세요.'
onKeyDown={handleKeyDown}
{...field}
/>
{editingComment && (
Expand Down
20 changes: 6 additions & 14 deletions src/pageLayout/Epigram/EpigramComment.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,11 @@ import { EpigramCommentProps } from '@/types/epigram.types';
import Image from 'next/image';

function EpigramComment({ epigramId, currentUserId, userImage }: EpigramCommentProps) {
// NOTE: 현재 수정 중인 댓글 상태, null이면 댓글 수정이 아닌 새 댓글 작성 취급
const [editingComment, setEditingComment] = useState<{ id: number; content: string; isPrivate: boolean } | null>(null);

const handleEditComment = (id: number, content: string, isPrivate: boolean) => {
setEditingComment({ id, content, isPrivate });
};

const handleEditComplete = () => {
setEditingComment(null);
};
// NOTE: 수정상태를 수정중인 댓글의 ID로 변경
const [editingCommentId, setEditingCommentId] = useState<number | null>(null);

return (
// NOTE: 댓글부분 height 수정
<div className='bg-slate-100 flex justify-center min-h-screen'>
<div className='bg-slate-100 flex justify-center'>
<div className='w-80 md:w-96 lg:w-[640px] pt-6 lg:pt-12'>
<h3 className='text-base lg:text-xl font-semibold'>댓글 작성</h3>
<div className={`flex flex-col gap-4 lg:gap-6 ${paddingStyles.sm} ${paddingStyles.md} ${paddingStyles.lg}`}>
Expand All @@ -31,10 +22,11 @@ function EpigramComment({ epigramId, currentUserId, userImage }: EpigramCommentP
<Image src='/profile.svg' alt='기본 프로필 사진' width={48} height={48} />
)}
</div>
<CommentTextarea epigramId={epigramId} editingComment={editingComment} onEditComplete={handleEditComplete} />
{/* NOTE: editingCommentId을 null로 바꿈으로써 수정중인 상태가 아니라는걸 알림 */}
<CommentTextarea epigramId={epigramId} onEditComplete={() => setEditingCommentId(null)} />
</div>
</div>
<CommentList epigramId={epigramId} currentUserId={currentUserId} onEditComment={handleEditComment} />
<CommentList epigramId={epigramId} currentUserId={currentUserId} editingCommentId={editingCommentId} onEditComment={setEditingCommentId} />
</div>
</div>
);
Expand Down

0 comments on commit 735a7c1

Please sign in to comment.