first commit
This commit is contained in:
141
app/usr/4_noticeboard/page.tsx
Normal file
141
app/usr/4_noticeboard/page.tsx
Normal file
@@ -0,0 +1,141 @@
|
||||
'use client'
|
||||
import { useEffect, useState } from "react";
|
||||
import NoticeModal from "@/app/components/ModelNotice";
|
||||
import { MilkdownViewer } from "@/app/components/MilkdownViewer";
|
||||
import { MilkdownProvider } from "@milkdown/react";
|
||||
import { Crepe } from "@milkdown/crepe";
|
||||
import { useRef } from "react";
|
||||
|
||||
export default function Page() {
|
||||
const crepeRef = useRef<Crepe>(null!);
|
||||
const [noticeList, setNoticeList] = useState<{
|
||||
id: string;
|
||||
title: string;
|
||||
pubDate: Date;
|
||||
content: string;
|
||||
tag: string;
|
||||
}[]>([]);
|
||||
|
||||
const [currentNotice, setCurrentNotice] = useState<{
|
||||
id: string;
|
||||
title: string;
|
||||
content: string;
|
||||
tag:string
|
||||
pubDate: Date;
|
||||
}>({
|
||||
id: "",
|
||||
tag: "",
|
||||
title: "",
|
||||
content: "",
|
||||
pubDate: new Date("0"),
|
||||
});
|
||||
|
||||
|
||||
const [isNoticeModalOpen, setIsNoticeModalOpen] = useState(false);
|
||||
|
||||
const openHandler = (id: string) => {
|
||||
const notice = noticeList.find((notice) => notice.id === id);
|
||||
if (notice) {
|
||||
setCurrentNotice({
|
||||
id: notice.id,
|
||||
title: notice.title,
|
||||
content: notice.content,
|
||||
tag: notice.tag,
|
||||
pubDate: notice.pubDate,
|
||||
});
|
||||
}
|
||||
setIsNoticeModalOpen(true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
const fetchNotices = async () => {
|
||||
const response = await fetch('/api/notice');
|
||||
const data = await response.json();
|
||||
setNoticeList(data);
|
||||
console.log(data);
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
fetchNotices();
|
||||
}, []);
|
||||
return (
|
||||
<div className="bg-white h-full w-[100vw] lg:w-[calc(100vw-360px)]">
|
||||
|
||||
<div className="h-[calc(100%-80px)] max-w-[800px] mx-auto overflow-y-auto p-4 flex flex-col">
|
||||
{noticeList.length === 0 ? (
|
||||
<div className="text-center text-gray-500">게시글이 없습니다.</div>
|
||||
) : (
|
||||
noticeList.map((notice) => (
|
||||
<div
|
||||
key={notice.id}
|
||||
className="h-[75px] border-[#d5d5d5] border-1 rounded-lg p-4 my-2 flex flex-row justify-between hover:border-[#F94B37] cursor-pointer min-w-[100px] shrink-0 basis-0 grow-0"
|
||||
onClick={() => openHandler(notice.id)}
|
||||
>
|
||||
|
||||
{/* 여기 min-w-0 추가해서 자식을 제한함 부모와 이 위치 관계 다시 확인 */}
|
||||
<div className="flex flex-col justify-between min-w-0">
|
||||
<div className="flex flex-row justify-start">
|
||||
|
||||
{
|
||||
notice.tag === "중요" && (
|
||||
<div className="mr-2 flex items-center justify-center">
|
||||
<div className="w-[33px] h-[20px] bg-[#FEDBD7] text-[#F94B37] font-semibold text-xs rounded-lg text-center flex items-center justify-center">중요</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
<div className="text-normal font-semibold truncate">
|
||||
{notice.title}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="text-xs text-[#848484]">
|
||||
{notice.pubDate.toLocaleString('ko-KR', { year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', hour12: false })}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center justify-center">
|
||||
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M7.5 15L12.5 10L7.5 5" stroke="#848484" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
))
|
||||
)}
|
||||
</div>
|
||||
|
||||
<NoticeModal isOpen={isNoticeModalOpen} onClose={() => setIsNoticeModalOpen(false)}>
|
||||
<div className="flex flex-col h-full bg-white rounded-lg p-6">
|
||||
<div className="flex justify-end mb-4">
|
||||
<button
|
||||
className="bg-gray-500 text-white px-4 py-2 rounded hover:bg-gray-600"
|
||||
onClick={() => setIsNoticeModalOpen(false)}
|
||||
>
|
||||
닫기
|
||||
</button>
|
||||
</div>
|
||||
<div className="flex flex-col border-b border-gray-200 pb-4 mb-4">
|
||||
<h1 className="text-2xl font-bold text-gray-800">{currentNotice.title}</h1>
|
||||
<p className="text-sm text-gray-400 mt-1">
|
||||
{currentNotice.pubDate.toLocaleString('ko-KR', {
|
||||
year: 'numeric',
|
||||
month: '2-digit',
|
||||
day: '2-digit',
|
||||
hour: '2-digit',
|
||||
minute: '2-digit',
|
||||
hour12: false,
|
||||
})}
|
||||
</p>
|
||||
</div>
|
||||
<div className="flex-1 overflow-y-auto">
|
||||
<MilkdownProvider>
|
||||
<MilkdownViewer value={currentNotice.content} editorRef={crepeRef} />
|
||||
</MilkdownProvider>
|
||||
</div>
|
||||
</div>
|
||||
</NoticeModal>
|
||||
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user