| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116 |
- 'use client';
- import './style.scss';
- import { useState, useEffect } from 'react';
- import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
- import { faArrowRotateRight } from '@fortawesome/free-solid-svg-icons';
- import BoardResponse from '@/dtos/response/forum/board/boardResponse';
- import PostResponse from '@/dtos/response/forum/post/postResponse';
- import CommentListRequest from '@/dtos/request/forum/comment/commentListRequest';
- import CommentListResponse from '@/dtos/response/forum/comment/commentListResponse';
- import { fetchCommentList } from '@/lib/api/forum/comment';
- import { throwError, loginCheck } from '@/lib/utils/client';
- import useAuth from '@/hooks/useAuth';
- import WriteForm from './_component/WriteForm';
- import List from './_component/List';
- import { type CommentSort, CommentConst } from '@/constants/forum';
- import Pagination from '@/app/component/Pagination';
- type Props = {
- board: BoardResponse;
- post: PostResponse;
- }
- export default function View({ board, post } : Props)
- {
- const { isAuthenticated } = useAuth();
- const [error, setError] = useState<string|null>(null);
- const [loading, setLoading] = useState<boolean>(false);
- const [page, setPage] = useState<number>(1);
- const [sort, setSort] = useState<CommentSort>(CommentConst.Sort.CreatedAt);
- const [data, setData] = useState<CommentListResponse>({ total: 0, list: [] });
- const [replyTargetID, setReplyTargetID] = useState<number|null>(null);
- useEffect(() => {
- if (error) {
- alert(error);
- setError(null);
- }
- }, [error]);
- useEffect(() => {
- loadComments();
- }, [page, sort]);
- const loadComments = async () => {
- setLoading(true);
- // 댓글 목록 호출
- fetchCommentList({
- postID: post.id,
- page: page,
- sort: sort,
- perPage: board.boardMeta.comment?.perPage ?? 20
- } as CommentListRequest).then((res) => {
- throwError(res);
- if (res.data != null) {
- setData(res.data);
- }
- }).catch(err => {
- setError(err.message);
- }).finally(() => {
- setLoading(false);
- });
- };
- const handleReply = (commentID: number) => {
- if (!loginCheck(isAuthenticated)) {
- return;
- }
- setReplyTargetID((prev) => (prev === commentID ? null : commentID)); // toggle
- };
- const handleSuccess = () => {
- setReplyTargetID(null);
- loadComments();
- };
- const handleDelete = () => {
- setReplyTargetID(null);
- loadComments();
- };
- return (
- <>
- {/* 댓글, 답글 */}
- <section id="comments">
- <div className='comment-header'>
- <article>댓글 <em>{data.total}개</em></article>
- <article>
- <select name="sort" title="정렬 기준" onChange={e => setSort(Number(e.target.value) as CommentSort)} value={sort}>
- <option value="0">최신순</option>
- <option value="1">인기순</option>
- </select>
- </article>
- <article>
- <button className="btn btn-default" title="새로고침" onClick={loadComments} disabled={loading}>
- <FontAwesomeIcon icon={faArrowRotateRight}/>
- </button>
- </article>
- </div>
- {/* 댓글 작성란 */}
- <WriteForm board={board} post={post} onSuccess={handleSuccess} />
- <hr />
- {/* 댓글 목록 */}
- <List board={board} post={post} data={data} loading={loading} replyTargetID={replyTargetID} onReply={handleReply} onSuccess={handleSuccess} onDelete={handleDelete} />
- {/* 페이징 */}
- <Pagination total={data.total} page={page} onChange={setPage} />
- </section>
- </>
- );
- }
|