Skip to content

Commit

Permalink
[FE] Feat #133: 댓글 수정 기능 추가
Browse files Browse the repository at this point in the history
Change-Id: Ie650386e786e8a30a8a7904f5ce89dc7d02a977d
  • Loading branch information
leewooseong committed Feb 8, 2024
1 parent 1c73906 commit f6f4d6f
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 14 deletions.
49 changes: 46 additions & 3 deletions frontend/src/pages/Bucket/BucketDetail/Comment/Comment.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { ChangeEvent, MouseEvent, useState } from 'react'
import UserProfile from '../../../../components/UserProfile'
import { ICommentItem, TimeUnitType } from '../../../../interfaces'
import ActiveLikeButton from './ActiveLikeButton'
import ShowMoreButton from './ShowMoreButton'
import UnActiveLikeButton from './UnActiveLikeButton'
import { useDetailPageTypeStore } from '../../../../store/detailStore'

const getTime = (time: number, timeUnit: TimeUnitType): string => {
switch (timeUnit) {
Expand All @@ -23,15 +25,56 @@ const getTime = (time: number, timeUnit: TimeUnitType): string => {

interface ICommentProps {
commentInfo: ICommentItem
type: 'read' | 'edit'
setSelectedId: React.Dispatch<React.SetStateAction<number | null>>
}

const Comment = ({ commentInfo }: ICommentProps) => {
const Comment = ({ commentInfo, type, setSelectedId }: ICommentProps) => {
const { setPageType } = useDetailPageTypeStore()
const [editText, setEditText] = useState('')

// handler about Comment
// Todo: handleChangeCommit으로 함수명 변경, edit 관련 함수가 너무 많아서 이름을 명시적으로 변경
const handleEditComment = (event: ChangeEvent<HTMLTextAreaElement>) => {
const inputText = event.currentTarget.value
setEditText(inputText)
}
// 이벤트 버블링을 이용한 이벤트 동작 수행
const handleClickComment = (event: MouseEvent<HTMLDivElement>) => {
const { id } = event.currentTarget.dataset
id && setSelectedId(parseInt(id))
}

// handler about ShowMoreButton
const handleCancelEdit = () => {
setEditText('')
setPageType('read')
}
const handleCompleteEdit = () => {
// Todo: 댓글 수정 Api 적용 예정
setPageType('read')
}
return (
<div className="relative flex flex-col">
<div onClick={handleClickComment} data-id={commentInfo.id} className="relative flex flex-col">
{/* //Todo: comment 유저로 정보 변경 필요 */}
<UserProfile type="comment" userInfo={commentInfo.writer} />
<p className="text-[10px] ml-11">{getTime(commentInfo.time, commentInfo.timeUnit)}</p>
<p className="text-xs ml-11">{commentInfo.context}</p>
{type === 'read' ? (
<p className="text-xs ml-11">{commentInfo.context}</p>
) : (
<div className="border-[1px] rounded-md border-gray ml-11 mr-7 mt-1 p-2">
<textarea
placeholder={commentInfo.context}
value={editText}
onChange={handleEditComment}
className="w-full text-sm resize-none focus:outline-none"
/>
<div className="flex justify-end gap-3 text-point1">
<button onClick={handleCancelEdit}>취소</button>
<button onClick={handleCompleteEdit}>완료</button>
</div>
</div>
)}

<ActiveLikeButton />
<UnActiveLikeButton />
Expand Down
18 changes: 12 additions & 6 deletions frontend/src/pages/Bucket/BucketDetail/Comment/CommentList.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import Comment from './Comment'
import { ICommentItem } from '../../../../interfaces'
import { useEffect, useRef } from 'react'
import { useCommentStore } from '../../../../store/detailStore'
import { useEffect, useRef, useState } from 'react'
import { useCommentStore, useDetailPageTypeStore } from '../../../../store/detailStore'

const commentInfo = {
totalPages: 0,
Expand All @@ -28,7 +28,7 @@ const commentInfo = {
updatedDate: '2023-12-29 10:34',
},
{
id: 1,
id: 2,
context: '10만이 엊그제 같은데... 벌써 20만이라니...',
writer: {
userId: 1,
Expand All @@ -47,7 +47,7 @@ const commentInfo = {
updatedDate: '2023-12-29 10:34',
},
{
id: 1,
id: 3,
context: '10만이 엊그제 같은데... 벌써 20만이라니...',
writer: {
userId: 1,
Expand Down Expand Up @@ -97,6 +97,8 @@ interface ICommentListProps {
// Todo : Api 데이터 타입 지정 후 as 삭제 예정
const CommentList = ({ isInputFocused, setIsInputShown }: ICommentListProps) => {
const { commentText } = useCommentStore()
const { pageType } = useDetailPageTypeStore()
const [selectedId, setSelectedId] = useState<null | number>(null)
const targetRef = useRef<HTMLUListElement>(null)

// 전역 이벤트 핸들러에서 closure 때문에 최신 state 값을 못 가져오는 문제 해결을 위한 useEffect
Expand Down Expand Up @@ -129,8 +131,12 @@ const CommentList = ({ isInputFocused, setIsInputShown }: ICommentListProps) =>
return (
<ul ref={targetRef}>
{commentInfo.content.map((comment, index) => (
<li key={index}>
<Comment commentInfo={comment as ICommentItem} />
<li key={`comment-${index}`}>
<Comment
commentInfo={comment as ICommentItem}
type={comment.id === selectedId && pageType === 'editComment' ? 'edit' : 'read'}
setSelectedId={setSelectedId}
/>
</li>
))}
</ul>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import { Menu, Transition } from '@headlessui/react'
import { AiOutlineMore } from 'react-icons/ai'
import { useDetailPageTypeStore } from '../../../../store/detailStore'

const ShowMoreButton = () => {
const { setPageType } = useDetailPageTypeStore()

const handleClickModifyButton = () => {
// Todo : 수정 모드로 변경
setPageType('editComment')
}
const handleClickDeleteButton = () => {
// Todo : 삭제 요청 Api 적용
Expand Down
8 changes: 4 additions & 4 deletions frontend/src/pages/Bucket/BucketDetail/Reaction.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,11 @@ const Reaction = () => {
const getReactionIcon = (reactionType: ReactionType) => {
switch (reactionType) {
case '멋져요':
return <Cool className="mb-1 w-8 h-8" />
return <Cool className="w-8 h-8 mb-1" />
case '나도할래':
return <WantToDo className="mb-1 w-8 h-8" />
return <WantToDo className="w-8 h-8 mb-1" />
case '응원해요':
return <Underpin className="mb-1 w-8 h-8" />
return <Underpin className="w-8 h-8 mb-1" />
}
}

Expand Down Expand Up @@ -74,7 +74,7 @@ const Reaction = () => {
className={`${activeReaction === reaction && textColorClass[activeColor]} inline-flex flex-col items-center`}
>
{getReactionIcon(reaction as ReactionType)}
<p className="text-xs font-bold mb-2">{reaction}</p>
<p className="mb-2 text-xs font-bold">{reaction}</p>
<p className="text-sm font-bold">{reactionInfo[reaction as ReactionType] ?? 0}</p>
</li>
))}
Expand Down
17 changes: 17 additions & 0 deletions frontend/src/store/detailStore.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,20 @@ export const useCommentStore = create<ICommentStore>()(
resetCommentText: () => set(() => ({ commentText: '' })),
}))
)

// 페이지가 현재 어떤 상태인지 나타내는 state
// - 한 페이지(컴포넌트)에서 다양한 분기 처리(글 보기, 수정)을 처리하기 위해 사용
// - 리뷰는 별도의 페이지로 이동하기 때문에 pageType에 넣어주지 않음
interface IDetailPageTypeStore {
pageType: 'read' | 'editComment' | 'editBucket'
setPageType: (type: 'read' | 'editComment' | 'editBucket') => void
resetPageType: () => void
}

export const useDetailPageTypeStore = create<IDetailPageTypeStore>()(
devtools((set) => ({
pageType: 'read',
setPageType: (type: 'read' | 'editComment' | 'editBucket') => set(() => ({ pageType: type })),
resetPageType: () => set(() => ({ pageType: 'read' })),
}))
)

0 comments on commit f6f4d6f

Please sign in to comment.