From d38877eef87917087a4a217bea32ae84d6738a7d Mon Sep 17 00:00:00 2001
From: dujinkim <dujin.kim@dtsolution.co.kr>
Date: Fri, 22 Aug 2025 08:20:45 +0000
Subject: (최겸) 인포메이션 첨부파일 뷰어 추가
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 components/information/information-button.tsx | 61 +++++++++++++++++++++++++--
 1 file changed, 57 insertions(+), 4 deletions(-)

(limited to 'components/information/information-button.tsx')

diff --git a/components/information/information-button.tsx b/components/information/information-button.tsx
index 69cbb106..015894c1 100644
--- a/components/information/information-button.tsx
+++ b/components/information/information-button.tsx
@@ -11,15 +11,17 @@ import {
   DialogTitle,
   DialogTrigger,
 } from "@/components/ui/dialog"
-import { Info, Download, Edit, Loader2 } from "lucide-react"
+import { Info, Download, Edit, Loader2,Eye, EyeIcon } from "lucide-react"
 import { getPageInformationDirect, getEditPermissionDirect } from "@/lib/information/service"
 import { getPageNotices } from "@/lib/notice/service"
 import { UpdateInformationDialog } from "@/lib/information/table/update-information-dialog"
 import { NoticeViewDialog } from "@/components/notice/notice-view-dialog"
+import { PDFTronViewerDialog } from "@/components/document-viewer/pdftron-viewer-dialog"
 import type { PageInformation, InformationAttachment } from "@/db/schema/information"
 import type { Notice } from "@/db/schema/notice"
 import { useSession } from "next-auth/react"
 import { formatDate } from "@/lib/utils"
+import prettyBytes from "pretty-bytes"
 // downloadFile은 동적으로 import
 
 interface InformationButtonProps {
@@ -51,6 +53,8 @@ export function InformationButton({
   const [dataLoaded, setDataLoaded] = useState(false)
   const [isLoading, setIsLoading] = useState(false)
   const [retryCount, setRetryCount] = useState(0)
+  const [viewerDialogOpen, setViewerDialogOpen] = useState(false)
+  const [selectedFile, setSelectedFile] = useState<InformationAttachment | null>(null)
 
   // 데이터 로드 함수
   const loadData = React.useCallback(async () => {
@@ -151,6 +155,29 @@ export function InformationButton({
     setIsNoticeViewDialogOpen(true)
   }
 
+  // 파일 확장자 확인 함수
+  const getFileExtension = (fileName: string): string => {
+    return fileName.split('.').pop()?.toLowerCase() || ''
+  }
+
+  // 뷰어 지원 파일 형식 확인
+  const isViewerSupported = (fileName: string): boolean => {
+    const extension = getFileExtension(fileName)
+    return ['pdf', 'docx', 'doc'].includes(extension)
+  }
+
+  // 파일 클릭 핸들러 (뷰어 또는 다운로드)
+  const handleFileClick = async (attachment: InformationAttachment) => {
+    if (isViewerSupported(attachment.fileName)) {
+      // PDF/DOCX 파일은 뷰어로 열기
+      setSelectedFile(attachment)
+      setViewerDialogOpen(true)
+    } else {
+      // 기타 파일은 다운로드
+      await handleDownload(attachment)
+    }
+  }
+
   // 파일 다운로드 핸들러
   const handleDownload = async (attachment: InformationAttachment) => {
     try {
@@ -294,25 +321,43 @@ export function InformationButton({
                             key={attachment.id} 
                             className="flex items-center justify-between p-3 bg-white rounded border"
                           >
-                            <div className="flex-1">
-                              <div className="text-sm font-medium">
+                            <div 
+                              className="flex-1"
+                            >
+                              <div className="text-sm font-medium flex items-center gap-2">
                                 {attachment.fileName}
+                              
                               </div>
                               {attachment.fileSize && (
                                 <div className="text-xs text-gray-500 mt-1">
-                                  {attachment.fileSize}
+                                  {prettyBytes(Number(attachment.fileSize))}
                                 </div>
                               )}
                             </div>
+                            <div className="flex gap-2">
+                              {isViewerSupported(attachment.fileName) &&
                             <Button
                               size="sm"
                               variant="outline"
+                              disabled={!isViewerSupported(attachment.fileName)}
+                              onClick={() => isViewerSupported(attachment.fileName) && handleFileClick(attachment)}
+                              className="flex items-center gap-1"
+                            >
+                              <EyeIcon className="h-3 w-3" />
+                            미리보기
+                            </Button>
+                            }
+                            <Button
+                              size="sm"
+                              variant="outline"
+                              
                               onClick={() => handleDownload(attachment)}
                               className="flex items-center gap-1"
                             >
                               <Download className="h-3 w-3" />
                               다운로드
                             </Button>
+                            </div>
                           </div>
                         ))}
                       </div>
@@ -345,6 +390,14 @@ export function InformationButton({
           onSuccess={handleEditSuccess}
         />
       )}
+
+      {/* PDFTron 뷰어 다이얼로그 */}
+      <PDFTronViewerDialog
+        open={viewerDialogOpen}
+        onOpenChange={setViewerDialogOpen}
+        fileUrl={selectedFile?.filePath}
+        fileName={selectedFile?.fileName}
+      />
     </>
   )
 } 
\ No newline at end of file
-- 
cgit v1.2.3

