From 795b4915069c44f500a91638e16ded67b9e16618 Mon Sep 17 00:00:00 2001 From: dujinkim Date: Tue, 1 Jul 2025 11:46:33 +0000 Subject: (최겸) 정보시스템 공지사항 개발 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/information/information-button.tsx | 306 +++++++++++++------------- 1 file changed, 153 insertions(+), 153 deletions(-) (limited to 'components/information/information-button.tsx') diff --git a/components/information/information-button.tsx b/components/information/information-button.tsx index da0de548..38e8cb12 100644 --- a/components/information/information-button.tsx +++ b/components/information/information-button.tsx @@ -1,137 +1,129 @@ "use client" -import React, { useState, useEffect } from "react" -import { Info, Download, Edit } from "lucide-react" +import * as React from "react" +import { useState } from "react" import { Button } from "@/components/ui/button" + import { Dialog, DialogContent, - DialogDescription, DialogHeader, DialogTitle, DialogTrigger, } from "@/components/ui/dialog" +import { Info, Download, Edit } from "lucide-react" import { getCachedPageInformation, getCachedEditPermission } from "@/lib/information/service" +import { getCachedPageNotices } from "@/lib/notice/service" import { UpdateInformationDialog } from "@/lib/information/table/update-information-dialog" +import { NoticeViewDialog } from "@/components/notice/notice-view-dialog" import type { PageInformation } from "@/db/schema/information" +import type { Notice } from "@/db/schema/notice" import { useSession } from "next-auth/react" +import { formatDate } from "@/lib/utils" interface InformationButtonProps { - pageCode: string + pagePath: string className?: string variant?: "default" | "outline" | "ghost" | "secondary" size?: "default" | "sm" | "lg" | "icon" } +type NoticeWithAuthor = Notice & { + authorName: string | null + authorEmail: string | null +} + export function InformationButton({ - pageCode, + pagePath, className, variant = "ghost", size = "icon" }: InformationButtonProps) { const { data: session } = useSession() - const [information, setInformation] = useState(null) - const [isLoading, setIsLoading] = useState(false) const [isOpen, setIsOpen] = useState(false) + const [information, setInformation] = useState(null) + const [notices, setNotices] = useState([]) const [hasEditPermission, setHasEditPermission] = useState(false) const [isEditDialogOpen, setIsEditDialogOpen] = useState(false) + const [selectedNotice, setSelectedNotice] = useState(null) + const [isNoticeViewDialogOpen, setIsNoticeViewDialogOpen] = useState(false) + const [dataLoaded, setDataLoaded] = useState(false) - useEffect(() => { - if (isOpen && !information) { - loadInformation() - } - }, [isOpen, information]) - - // 편집 권한 확인 - useEffect(() => { - const checkEditPermission = async () => { - if (session?.user?.id) { - try { - const permission = await getCachedEditPermission(pageCode, session.user.id) - setHasEditPermission(permission) - } catch (error) { - console.error("Failed to check edit permission:", error) - setHasEditPermission(false) - } - } - } + // 데이터 로드 함수 (단순화) + const loadData = React.useCallback(async () => { + if (dataLoaded) return // 이미 로드되었으면 중복 방지 - checkEditPermission() - }, [pageCode, session?.user?.id]) - - const loadInformation = async () => { - setIsLoading(true) try { - const data = await getCachedPageInformation(pageCode) - setInformation(data) + // pagePath 정규화 (앞의 / 제거) + const normalizedPath = pagePath.startsWith('/') ? pagePath.slice(1) : pagePath + + // 병렬로 데이터 조회 + const [infoResult, noticesResult] = await Promise.all([ + getCachedPageInformation(normalizedPath), + getCachedPageNotices(normalizedPath) + ]) + + setInformation(infoResult) + setNotices(noticesResult) + setDataLoaded(true) + + // 권한 확인 + if (session?.user?.id) { + const hasPermission = await getCachedEditPermission(normalizedPath, session.user.id) + setHasEditPermission(hasPermission) + } } catch (error) { - console.error("Failed to load information:", error) - } finally { - setIsLoading(false) + console.error("데이터 로딩 중 오류:", error) } - } + }, [pagePath, session?.user?.id, dataLoaded]) - const handleDownload = () => { - if (information?.attachmentFilePath && information?.attachmentFileName) { - const link = document.createElement('a') - link.href = information.attachmentFilePath - link.download = information.attachmentFileName - document.body.appendChild(link) - link.click() - document.body.removeChild(link) + // 다이얼로그 열기 + const handleDialogOpen = (open: boolean) => { + setIsOpen(open) + + if (open && !dataLoaded) { + loadData() } } + // 편집 관련 핸들러 const handleEditClick = () => { setIsEditDialogOpen(true) } - const handleEditClose = () => { + const handleEditSuccess = () => { setIsEditDialogOpen(false) - refreshInformation() + // 편집 후 데이터 다시 로드 + setDataLoaded(false) + loadData() + } + + // 공지사항 클릭 핸들러 + const handleNoticeClick = (notice: NoticeWithAuthor) => { + setSelectedNotice(notice) + setIsNoticeViewDialogOpen(true) } - const refreshInformation = () => { - // 편집 후 정보 다시 로드 - setInformation(null) - if (isOpen) { - loadInformation() + // 파일 다운로드 핸들러 + const handleDownload = () => { + if (information?.attachmentFilePath) { + window.open(information.attachmentFilePath, '_blank') } - // 캐시 무효화를 위해 다시 확인 - setTimeout(() => { - loadInformation() - }, 500) } - // 인포메이션이 없으면 버튼을 숨김 - const [hasInformation, setHasInformation] = useState(null) - useEffect(() => { - const checkInformation = async () => { - try { - const data = await getCachedPageInformation(pageCode) - setHasInformation(!!data) - } catch { - setHasInformation(false) - } - } - checkInformation() - }, [pageCode]) - // 인포메이션이 없으면 버튼을 숨김 - if (hasInformation === false) { - return null - } + return ( <> - + + {/* 첨부파일 */} + {information?.attachmentFileName && ( +
+

첨부파일

+
+
+
+
+ {information.attachmentFileName}
+ {information.attachmentFileSize && ( +
+ {information.attachmentFileSize} +
+ )}
- ) : ( -
- -

첨부된 파일이 없습니다.

-
- )} + +
- - ) : ( +
+ )} + + {!information && notices.length === 0 && (
- 이 페이지에 대한 정보가 없습니다. +

이 페이지에 대한 정보가 없습니다.

)}
+ {/* 공지사항 보기 다이얼로그 */} + + {/* 편집 다이얼로그 */} {information && ( )} -- cgit v1.2.3