From 36dd60ca6fce7712b35e6d7c1b9602710f442ada Mon Sep 17 00:00:00 2001
From: dujinkim <dujin.kim@dtsolution.co.kr>
Date: Wed, 28 May 2025 12:26:28 +0000
Subject: (최겸) 기술영업 해양 rfq 개발v1
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 lib/rfqs-tech/tbe-table/file-dialog.tsx | 139 ++++++++++++++++++++++++++++++++
 1 file changed, 139 insertions(+)
 create mode 100644 lib/rfqs-tech/tbe-table/file-dialog.tsx

(limited to 'lib/rfqs-tech/tbe-table/file-dialog.tsx')

diff --git a/lib/rfqs-tech/tbe-table/file-dialog.tsx b/lib/rfqs-tech/tbe-table/file-dialog.tsx
new file mode 100644
index 00000000..712f7ff6
--- /dev/null
+++ b/lib/rfqs-tech/tbe-table/file-dialog.tsx
@@ -0,0 +1,139 @@
+"use client"
+
+import * as React from "react"
+import { Download, X } from "lucide-react"
+import { toast } from "sonner"
+
+import { getErrorMessage } from "@/lib/handle-error"
+import { formatDateTime } from "@/lib/utils"
+import { Button } from "@/components/ui/button"
+import {
+  Dialog,
+  DialogContent,
+  DialogDescription,
+  DialogHeader,
+  DialogTitle,
+} from "@/components/ui/dialog"
+
+import {
+  FileList,
+  FileListItem,
+  FileListIcon,
+  FileListInfo,
+  FileListName,
+  FileListDescription,
+  FileListAction,
+} from "@/components/ui/file-list"
+import { getTbeFilesForVendor, getTbeSubmittedFiles } from "../service"
+
+interface TBEFileDialogProps {
+  isOpen: boolean
+  onOpenChange: (open: boolean) => void
+  tbeId: number
+  vendorId: number
+  rfqId: number
+  onRefresh?: () => void
+}
+
+export function TBEFileDialog({
+  isOpen,
+  onOpenChange,
+  vendorId,
+  rfqId,
+  onRefresh,
+}: TBEFileDialogProps) {
+  const [submittedFiles, setSubmittedFiles] = React.useState<any[]>([])
+  const [isFetchingFiles, setIsFetchingFiles] = React.useState(false)
+
+
+  // Fetch submitted files when dialog opens
+  React.useEffect(() => {
+    if (isOpen && rfqId && vendorId) {
+      fetchSubmittedFiles()
+    }
+  }, [isOpen, rfqId, vendorId])
+
+  // Fetch submitted files using the service function
+  const fetchSubmittedFiles = async () => {
+    if (!rfqId || !vendorId) return
+
+    setIsFetchingFiles(true)
+    try {
+      const { files, error } = await getTbeFilesForVendor(rfqId, vendorId)
+      
+      if (error) {
+        throw new Error(error)
+      }
+      
+      setSubmittedFiles(files)
+    } catch (error) {
+      toast.error("Failed to load files: " + getErrorMessage(error))
+    } finally {
+      setIsFetchingFiles(false)
+    }
+  }
+
+  // Download submitted file
+  const downloadSubmittedFile = async (file: any) => {
+    try {
+      const response = await fetch(`/api/tbe-download?path=${encodeURIComponent(file.filePath)}`)
+      if (!response.ok) {
+        throw new Error("Failed to download file")
+      }
+
+      const blob = await response.blob()
+      const url = window.URL.createObjectURL(blob)
+      const a = document.createElement("a")
+      a.href = url
+      a.download = file.fileName
+      document.body.appendChild(a)
+      a.click()
+      window.URL.revokeObjectURL(url)
+      document.body.removeChild(a)
+    } catch (error) {
+      toast.error("Failed to download file: " + getErrorMessage(error))
+    }
+  }
+
+  return (
+    <Dialog open={isOpen} onOpenChange={onOpenChange}>
+      <DialogContent className="sm:max-w-lg">
+        <DialogHeader>
+          <DialogTitle>TBE 응답 파일</DialogTitle>
+          <DialogDescription>제출된 파일 목록을 확인하고 다운로드하세요.</DialogDescription>
+        </DialogHeader>
+
+        {/* 제출된 파일 목록 */}
+        {isFetchingFiles ? (
+          <div className="flex justify-center items-center py-8">
+            <div className="animate-spin rounded-full h-8 w-8 border-b-2 border-primary"></div>
+          </div>
+        ) : submittedFiles.length > 0 ? (
+          <div className="grid gap-2">
+            <FileList>
+              {submittedFiles.map((file) => (
+                <FileListItem key={file.id} className="flex items-center justify-between gap-3">
+                  <div className="flex items-center gap-3 flex-1">
+                    <FileListIcon className="flex-shrink-0" />
+                    <FileListInfo className="flex-1 min-w-0">
+                      <FileListName className="text-sm font-medium truncate">{file.fileName}</FileListName>
+                      <FileListDescription className="text-xs text-muted-foreground">
+                        {file.uploadedAt ? formatDateTime(file.uploadedAt) : ""}
+                      </FileListDescription>
+                    </FileListInfo>
+                  </div>
+                  <FileListAction className="flex-shrink-0 ml-2" onClick={() => downloadSubmittedFile(file)}>
+                    <Download className="h-4 w-4" />
+                    <span className="sr-only">파일 다운로드</span>
+                  </FileListAction>
+                </FileListItem>
+              ))}
+            </FileList>
+          </div>
+        ) : (
+          <div className="text-center py-8 text-muted-foreground">제출된 파일이 없습니다.</div>
+        )}
+      </DialogContent>
+    </Dialog>
+  )
+}
\ No newline at end of file
-- 
cgit v1.2.3

