'use client'; import './style.scss'; import '../../board/_component/style.scss'; import Link from 'next/link'; import { useSearchParams } from 'next/navigation'; import Image, { ImageProps } from 'next/image'; import { useState, useEffect } from 'react'; import { clsx } from 'clsx'; import { BoardListMeta } from '@/types/forum/boardMeta'; import { fetchLatestPosts } from '@/lib/api/forum/board'; import LatestPostsRequest from '@/dtos/request/forum/board/latestPostsRequest' import LatestPostsResponse from '@/dtos/response/forum/board/latestPostsResponse' import { throwError, isNewPost, isHotPost, formatDate } from '@/lib/utils/client'; import Loading from '@/app/component/Loading'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { faComment, faThumbsUp, faEye, faClock } from '@fortawesome/free-regular-svg-icons'; import { BoardLayout } from '@/constants/forum'; type Props = { boardListMeta: BoardListMeta; boardID: number; boardCode: string; postID?: number|null; } function ImageWithFallback({ src, fallbackSrc = '/resources/no-image.png', alt, ...option }: ImageProps & { fallbackSrc?: string }) { const [imgSrc, setImgSrc] = useState(src); return ( {alt} setImgSrc(fallbackSrc)} /> ); } export default function LatestPosts(params : Props) { const searchParams = useSearchParams(); const [error, setError] = useState(''); const [loading, setLoading] = useState(false); const [latestPosts, setLatestPosts] = useState({ list: [] }); const query = Object.fromEntries(searchParams.entries()); useEffect(() => { if (error) { alert(error); setError(''); } }, [error]); useEffect(() => { (async () => { setLoading(true); const page = searchParams.get('page'); const perPage = searchParams.get('perPage'); const boardPrefixID = searchParams.get('boardPrefixID'); fetchLatestPosts({ boardID: params.boardID, boardCode: params.boardCode, postID: params.postID, page: page ? Number(page) : null, perPage: perPage ? Number(perPage) : null, boardPrefixID: boardPrefixID ? Number(boardPrefixID) : null, sort: searchParams.get('sort'), search: searchParams.get('search'), keyword: searchParams.get('keyword'), } as LatestPostsRequest).then((res) => { throwError(res); setLatestPosts(res.data as LatestPostsResponse); }).catch((err) => { setError(err.message); }).finally(() => { setLoading(false); }); })(); }, []); const handleClick = (boardPrefixID: number|null) => { const querys = new URLSearchParams(searchParams.toString()); if (boardPrefixID) { querys.set('prefix', String(boardPrefixID)); } window.location.href = `/board/${params.boardCode}?${querys.toString()}`; } if (latestPosts.list.length <= 0) { return; } return ( <>
{loading && }
{params.boardListMeta.layout == BoardLayout.Default && (
  • 번호
  • 제목
  • 작성자
  • 작성일
  • 조회수
  • 좋아요
{/* 일반 글 */} {(latestPosts.list.map((row) => { const query = Object.fromEntries(searchParams.entries()); const isNew = isNewPost(params.boardListMeta.isNewIcon, row); const isHot = isHotPost(params.boardListMeta.isHotIcon, row); const createdAt = formatDate(row.createdAt); return (
{/* PC */}
  1. {row.no}
  2. {row.boardPrefixID && ( )} {row.subject} {isNew && NEW} {isHot && HOT}
  3. {row.name || row.sid}
  4. {createdAt}
  5. {row.views}
  6. {row.likes}
{/* Mobile */}
); }) )}
)} {/* 1:1문의 */} {params.boardListMeta.layout == BoardLayout.QnA && (
  • 번호
  • 제목
  • 작성자
  • 답변 여부
  • 작성일
{(latestPosts.list.map((row) => { const query = Object.fromEntries(searchParams.entries()); const isNew = isNewPost(params.boardListMeta.isNewIcon, row); const createdAt = formatDate(row.createdAt); return (
{/* PC */}
  1. {row.no}
  2. {row.boardPrefixID && ( )} {row.subject} {row.comments > 0 && ([{row.comments}])} {isNew && NEW}
  3. {row.name || row.sid}
  4. {!row.isReply ? ( 대기 ) : ( 완료 )}
  5. {createdAt}
{/* Mobile */}
); }) )}
)} {/* 사진/동영상 글 */} {params.boardListMeta.layout == BoardLayout.Media && (
{(latestPosts.list.map((row) => { const query = Object.fromEntries(searchParams.entries()); const isNew = isNewPost(params.boardListMeta.isNewIcon, row); const isHot = isHotPost(params.boardListMeta.isHotIcon, row); const createdAt = formatDate(row.createdAt); // 사진/동영상 게시판 const href = `/post/${row.id}${window.location.search}`; return (
{row.thumbnail ? ( ) : ( {row.subject} )}
{row.boardPrefixID && ( )} {row.subject} {row.comments > 0 && ([{row.comments}])} {isNew && NEW} {isHot && HOT}
{row.name}
  • {row.likes}
  • {row.views}
  • {createdAt}
); }) )}
)}
목록으로
); }