'use client'; import './style.scss'; import '../../board/_component/style.scss'; import Link from 'next/link'; import { useSearchParams } from 'next/navigation'; import { useState, useEffect, useMemo, useCallback } from 'react'; import useErrorAlert from '@/hooks/useErrorAlert'; import { BoardListMeta } from '@/types/forum/boardMeta'; import Post from '@/types/forum/post'; import PostLatest from '@/types/forum/latestPost'; import { LatestPostsResponse } from '@/types/response/forum/board' import { fetchApi } from '@/lib/utils/client'; import Loading from '@/app/component/Loading'; import DefaultListLayout from '@/app/(main)/(forum)/board/_component/DefaultListLayout'; import QnAListLayout from '@/app/(main)/(forum)/board/_component/QnAListLayout'; import AlbumListLayout from '@/app/(main)/(forum)/board/_component/AlbumListLayout'; import { BoardLayout } from '@/constants/forum'; type Props = { boardListMeta: BoardListMeta; boardID: number; boardCode: string; postID?: number|null; } function toPost(item: PostLatest): Post { return { ...item, num: item.no, boardName: '', boardPrefix: item.boardPrefixName ? { id: item.boardPrefixID!, boardID: item.boardID, name: item.boardPrefixName, color: null, posts: 0 } : null, content: '', blames: 0, }; } export default function LatestPosts(params : Props) { const searchParams = useSearchParams(); const { setError } = useErrorAlert(); const [loading, setLoading] = useState(false); const [latestPosts, setLatestPosts] = useState({ list: [] }); useEffect(() => { setLoading(true); const queryParams = new URLSearchParams(); queryParams.set('boardID', String(params.boardID)); const page = searchParams.get('page'); const perPage = searchParams.get('perPage'); const boardPrefixID = searchParams.get('boardPrefixID'); const sortParam = searchParams.get('sort'); const searchParam = searchParams.get('search'); const keywordParam = searchParams.get('keyword'); if (page) queryParams.set('page', page); if (perPage) queryParams.set('perPage', perPage); if (boardPrefixID) queryParams.set('boardPrefixID', boardPrefixID); if (sortParam) queryParams.set('sort', sortParam); if (searchParam) queryParams.set('search', searchParam); if (keywordParam) queryParams.set('keyword', keywordParam); fetchApi(`/api/forum/posts?${queryParams.toString()}`).then((res) => { setLatestPosts(res.data as LatestPostsResponse); }).catch((err) => { setError(err.message); }).finally(() => { setLoading(false); }); }, [params.boardID, searchParams]); const posts = useMemo(() => latestPosts.list.map(toPost) , [latestPosts.list]); const query = useMemo(() => Object.fromEntries(searchParams.entries()) , [searchParams]); const startIndex = latestPosts.list[0]?.no ?? posts.length; const renderLayout = useCallback(() => { switch (params.boardListMeta.layout) { case BoardLayout.Media: return ; case BoardLayout.QnA: return ; default: return ; } }, [params.boardListMeta, posts, startIndex]); if (latestPosts.list.length <= 0) { return null; } return ( <>
{loading && }
{renderLayout()}
목록으로
); }