LatestListLayout.tsx 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. 'use client';
  2. import './style.scss';
  3. import Link from 'next/link';
  4. import { useSearchParams } from 'next/navigation';
  5. import { useMemo } from 'react';
  6. import Post from '@/types/forum/post';
  7. import { formatDate } from '@/lib/utils/client';
  8. import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
  9. import { faComment, faThumbsUp, faEye } from '@fortawesome/free-regular-svg-icons';
  10. import { faFloppyDisk, faImage, faVideo } from '@fortawesome/free-solid-svg-icons';
  11. interface Props {
  12. list: Post[];
  13. startIndex?: number;
  14. }
  15. export default function LatestListLayout({list, startIndex}: Props)
  16. {
  17. const searchParams = useSearchParams();
  18. const query = useMemo(() => Object.fromEntries(searchParams.entries()), [searchParams]);
  19. return (
  20. <section className="latest-list-layout" aria-label='최근 게시글'>
  21. <article>
  22. <ul>
  23. <li>번호</li>
  24. <li>게시판</li>
  25. <li>제목</li>
  26. <li>작성자</li>
  27. <li>작성일</li>
  28. <li>조회수</li>
  29. <li>좋아요</li>
  30. </ul>
  31. </article>
  32. <article>
  33. {list.length > 0 && (
  34. list.map((row, i) => {
  35. const createdAt = formatDate(row.createdAt);
  36. const postViewUrl = {pathname: '/post/' + row.id, query};
  37. return (
  38. <section key={row.id}>
  39. {/* PC */}
  40. <ol>
  41. <li>
  42. <small>{startIndex !== undefined ? startIndex - i : i + 1}</small>
  43. </li>
  44. <li>{row.boardName}</li>
  45. <li>
  46. {row.boardPrefix && row.boardPrefixID && (
  47. <span className='prefix'>[{row.boardPrefix.name}]</span>
  48. )}
  49. <Link href={postViewUrl}>
  50. <em>{row.subject} {row.comments > 0 && <span>[{row.comments}]</span>}</em>
  51. {row.files > 0 && <FontAwesomeIcon icon={faFloppyDisk} />}
  52. {row.images > 0 && <FontAwesomeIcon icon={faImage} />}
  53. {row.videos > 0 && <FontAwesomeIcon icon={faVideo} />}
  54. </Link>
  55. </li>
  56. <li>{row.name || row.sid}</li>
  57. <li>{createdAt}</li>
  58. <li>{row.views}</li>
  59. <li>{row.likes}</li>
  60. </ol>
  61. {/* Mobile */}
  62. <dl hidden>
  63. <dt>
  64. <span className='board-name'>{row.boardName}</span>
  65. {row.boardPrefix && row.boardPrefixID && (
  66. <span className='prefix'>[{row.boardPrefix.name}]</span>
  67. )}
  68. <Link href={postViewUrl}>
  69. <em>{row.subject} {row.comments > 0 && <span>[{row.comments}]</span>}</em>
  70. {row.files > 0 && <FontAwesomeIcon icon={faFloppyDisk} />}
  71. {row.images > 0 && <FontAwesomeIcon icon={faImage} />}
  72. {row.videos > 0 && <FontAwesomeIcon icon={faVideo} />}
  73. </Link>
  74. </dt>
  75. <dd>
  76. <ul>
  77. <li>{row.name || row.sid}</li>
  78. <li><FontAwesomeIcon icon={faComment} /> {row.comments}</li>
  79. <li><FontAwesomeIcon icon={faEye} /> {row.views}</li>
  80. <li><FontAwesomeIcon icon={faThumbsUp} /> {row.likes}</li>
  81. <li>{createdAt}</li>
  82. </ul>
  83. </dd>
  84. </dl>
  85. </section>
  86. );
  87. })
  88. )}
  89. {list.length <= 0 && (
  90. <section>
  91. <p className="text-center p-10">
  92. 등록된 글이 없습니다.
  93. </p>
  94. </section>
  95. )}
  96. </article>
  97. </section>
  98. );
  99. }