Content.tsx 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. 'use client';
  2. import './style.scss';
  3. import { useEffect, useRef } from 'react';
  4. import BoardMeta from '@/types/forum/boardMeta';
  5. import BoardManager from '@/types/forum/boardManager';
  6. import { checkPermission } from '@/lib/utils/permission';
  7. type Props = {
  8. boardMeta: BoardMeta;
  9. content: string;
  10. boardManagers?: BoardManager[];
  11. }
  12. export default function Content({ boardMeta, content, boardManagers }: Props)
  13. {
  14. const articleRef = useRef<HTMLElement>(null);
  15. const allowTargetBlank = boardMeta.view.allowContentLinkTargetBlank;
  16. useEffect(() => {
  17. const el = articleRef.current;
  18. if (!el) {
  19. return;
  20. }
  21. const handler = (e: MouseEvent) => {
  22. const target = e.target as HTMLElement;
  23. // 파일 다운로드
  24. const file = target.closest('section.file-embed') as HTMLElement;
  25. if (file && file.dataset.uuid) {
  26. // 파일 다운로드 권한 체크
  27. if (boardManagers) {
  28. const stored = localStorage.getItem('member');
  29. const member = stored ? JSON.parse(stored) : null;
  30. if (!checkPermission(boardMeta, boardManagers, member).canDownloadFile) {
  31. alert('파일을 다운로드할 수 있는 권한이 없습니다.');
  32. return;
  33. }
  34. }
  35. window.location.href = `/api/forum/post/file/${file.dataset.uuid}`;
  36. }
  37. // 링크 클릭
  38. const anchor = target.closest('a[data-uuid]') as HTMLAnchorElement;
  39. if (anchor && anchor.dataset.uuid) {
  40. e.preventDefault();
  41. window.open(`/api/forum/post/link/${anchor.dataset.uuid}`, allowTargetBlank ? '_blank' : '_self');
  42. }
  43. }
  44. el.addEventListener('click', handler);
  45. return () => {
  46. el.removeEventListener('click', handler);
  47. }
  48. }, [allowTargetBlank, boardMeta, boardManagers]);
  49. return (
  50. <article ref={articleRef} dangerouslySetInnerHTML={{ __html: content }} className='whitespace-normal break-words'></article>
  51. );
  52. }