| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153 |
- 'use client';
- import '../style.scss';
- import Image from 'next/image';
- import { useState, useEffect } from 'react';
- import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
- import { faThumbsUp as nThumbsUp, faThumbsDown as nThumbsDown, faFlag as nFlag, faPenToSquare, faTrashCan } from '@fortawesome/free-regular-svg-icons';
- import { faThumbsUp as yThumbsUp, faFlag as yFlag, faArrowRotateRight, faEllipsisVertical } from '@fortawesome/free-solid-svg-icons';
- import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "@/components/ui/dropdown-menu"
- import { throwError, loginCheck, formatDate } from '@/lib/utils/client';
- import { type CommentItem } from '@/types/forum/comment';
- import BoardResponse from '@/dtos/response/forum/board/boardResponse';
- import PostResponse from '@/dtos/response/forum/post/postResponse';
- import CommentDeleteRequest from '@/dtos/request/forum/comment/commentDeleteRequest';
- import EditForm from './EditForm';
- import { fetchCommentDelete } from '@/lib/api/forum/comment';
- type Props = {
- board: BoardResponse; // 게시판 정보
- post: PostResponse; // 게시글 정보
- comment: CommentItem; // 댓글 정보
- isReplying?: boolean; // 답글 버튼 클릭 여부
- onReply: () => void; // 답글 버튼 클릭 시
- onDelete: () => void; // 삭제 후
- onSuccess: () => void; // 수정/삭제 후
- }
- export default function Item({ comment, isReplying, board, post, onReply, onSuccess, onDelete } : Props)
- {
- const [error, setError] = useState<string|null>(null);
- const [loading, setLoading] = useState<boolean>(false);
- const [isEditing, setIsEditing] = useState<boolean>(false);
- useEffect(() => {
- if (!comment) {
- setIsEditing(false);
- }
- }, [comment]);
- const handleStartEdit = () => {
- if (!loginCheck()) {
- return;
- }
- setIsEditing(true);
- };
- const handleCancelEdit = () => {
- setIsEditing(false);
- };
- const handleEditSuccess = () => {
- setIsEditing(false);
- if (typeof onSuccess === 'function') {
- onSuccess();
- }
- };
- const handleDelete = () => {
- setIsEditing(false);
- if (confirm("댓글을 삭제하시겠습니까?")) {
- setLoading(true);
- // 댓글 삭제 호출
- fetchCommentDelete({ commentID: comment.id } as CommentDeleteRequest).then((res) => {
- throwError(res);
- // 삭제 성공 시 해당 댓글 영역 삭제
- onDelete();
- }).catch(err => {
- setError(err.message);
- }).finally(() => {
- setLoading(false);
- });
- }
- };
- const writerThumb = (comment.writer.thumbnail ?? '/resources/thumb.gif');
- const writerName = (comment.writer.name || comment.writer.sid);
- const createdAt = formatDate(comment.createdAt);
- return (
- <li className={comment.isSecret ? 'is-secret' : ''}>
- <div>
- <Image src={writerThumb} alt={writerName} width={72} height={0} />
- </div>
- <div>
- <ul>
- <li>{writerName}</li>
- <li>{createdAt}</li>
- </ul>
- </div>
- <div>
- <DropdownMenu>
- <DropdownMenuTrigger>
- <FontAwesomeIcon icon={faEllipsisVertical}/>
- </DropdownMenuTrigger>
- <DropdownMenuContent>
- {/*
- <DropdownMenuItem><FontAwesomeIcon icon={nFlag} className="mr-2"/> 신고</DropdownMenuItem>
- */}
- <DropdownMenuItem onClick={handleStartEdit}>
- <FontAwesomeIcon icon={faPenToSquare} className="mr-2"/> 수정
- </DropdownMenuItem>
- <DropdownMenuItem onClick={handleDelete}>
- <FontAwesomeIcon icon={faTrashCan} className="mr-2"/> 삭제
- </DropdownMenuItem>
- </DropdownMenuContent>
- </DropdownMenu>
- </div>
- <div>
- <ul>
- <li>
- {isEditing ? (
- <EditForm
- board={board}
- post={post}
- comment={comment}
- onSuccess={handleEditSuccess}
- onCancel={handleCancelEdit}
- />
- ) : (
- <ul>
- <li>
- {comment.mention && (
- <span className="mention">@{comment.mention.rawHandle} </span>
- )}
- {comment.content}
- </li>
- </ul>
- )}
- </li>
- </ul>
- </div>
- {!isEditing && (
- <div>
- {/*
- <button type="button" title="좋아요"><FontAwesomeIcon icon={nThumbsUp} /></button>
- <button type="button" title="싫어요"><FontAwesomeIcon icon={nThumbsDown} /></button>
- */}
- <button
- type="button"
- title="답글"
- onClick={onReply}
- >
- {isReplying ? '답글 접기' : '답글'}
- </button>
- </div>
- )}
- </li>
- );
- }
|