summaryrefslogtreecommitdiff
path: root/components
diff options
context:
space:
mode:
authordujinkim <dujin.kim@dtsolution.co.kr>2025-08-22 02:12:15 +0000
committerdujinkim <dujin.kim@dtsolution.co.kr>2025-08-22 02:12:15 +0000
commit7dd2b9fc1856306652f311d19697d9880955bfab (patch)
tree3144f14e2b6e9d66c25f10686ca9e94d61d9154e /components
parent94082bfe915d3b0337f8929a2bb27828abb5d3c7 (diff)
(최겸) 공지사항, 인포메이션 기능 수정
Diffstat (limited to 'components')
-rw-r--r--components/additional-info/join-form.tsx12
-rw-r--r--components/information/information-button.tsx113
-rw-r--r--components/notice/notice-client.tsx116
-rw-r--r--components/notice/notice-create-dialog.tsx2
-rw-r--r--components/notice/notice-edit-sheet.tsx2
-rw-r--r--components/vendor-info/pq-simple-dialog.tsx5
-rw-r--r--components/vendor-regular-registrations/document-status-dialog.tsx203
7 files changed, 294 insertions, 159 deletions
diff --git a/components/additional-info/join-form.tsx b/components/additional-info/join-form.tsx
index ca0c60d5..90effddb 100644
--- a/components/additional-info/join-form.tsx
+++ b/components/additional-info/join-form.tsx
@@ -87,7 +87,6 @@ import { InformationButton } from "@/components/information/information-button"
// 보안 파일 다운로드 유틸리티 import
import {
- downloadFile,
quickDownload,
smartFileAction,
getFileInfo,
@@ -366,6 +365,7 @@ export function InfoForm() {
const downloadUrl = `/api/vendors/attachments/download?id=${fileId}&vendorId=${Number(companyId)}`;
// 보안 다운로드 유틸리티 사용
+ const { downloadFile } = await import('@/lib/file-download')
const result = await downloadFile(downloadUrl, fileName, {
action: 'download',
showToast: false, // 우리가 직접 토스트 관리
@@ -413,6 +413,8 @@ export function InfoForm() {
const fileName = `vendor-${companyId}-files.zip`;
// 보안 다운로드 유틸리티 사용
+
+ const { downloadFile } = await import('@/lib/file-download')
const result = await downloadFile(downloadUrl, fileName, {
action: 'download',
showToast: false, // 우리가 직접 토스트 관리
@@ -708,7 +710,7 @@ export function InfoForm() {
}
// 보안 정보 가져오기 (선택적으로 사용자에게 표시)
- const securityInfo = getSecurityInfo();
+ // const securityInfo = getSecurityInfo();
// Render
return (
@@ -746,9 +748,9 @@ export function InfoForm() {
)}
{/* 보안 정보 표시 (선택적) */}
- <div className="text-xs text-muted-foreground">
+ {/* <div className="text-xs text-muted-foreground">
<p>📁 허용 파일 크기: {securityInfo.maxFileSizeFormatted} | 남은 다운로드: {securityInfo.remainingDownloads}/분</p>
- </div>
+ </div> */}
</div>
<Separator />
@@ -1860,7 +1862,7 @@ export function InfoForm() {
domesticCredit: "not_submitted",
},
basicContracts: registrationData.basicContracts || [],
- documentFiles: {
+ documentFiles: registrationData.documentFiles || {
businessRegistration: [],
creditEvaluation: [],
bankCopy: [],
diff --git a/components/information/information-button.tsx b/components/information/information-button.tsx
index 52079767..17f10502 100644
--- a/components/information/information-button.tsx
+++ b/components/information/information-button.tsx
@@ -12,14 +12,15 @@ import {
DialogTrigger,
} from "@/components/ui/dialog"
import { Info, Download, Edit, Loader2 } from "lucide-react"
-import { getCachedPageInformation, getCachedEditPermission } from "@/lib/information/service"
-import { getCachedPageNotices } from "@/lib/notice/service"
+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 type { PageInformation } from "@/db/schema/information"
+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"
+// downloadFile은 동적으로 import
interface InformationButtonProps {
pagePath: string
@@ -41,7 +42,7 @@ export function InformationButton({
}: InformationButtonProps) {
const { data: session } = useSession()
const [isOpen, setIsOpen] = useState(false)
- const [information, setInformation] = useState<PageInformation | null>(null)
+ const [information, setInformation] = useState<(PageInformation & { attachments: InformationAttachment[] }) | null>(null)
const [notices, setNotices] = useState<NoticeWithAuthor[]>([])
const [hasEditPermission, setHasEditPermission] = useState(false)
const [isEditDialogOpen, setIsEditDialogOpen] = useState(false)
@@ -59,19 +60,35 @@ export function InformationButton({
// pagePath 정규화 (앞의 / 제거)
const normalizedPath = pagePath.startsWith('/') ? pagePath.slice(1) : pagePath
+ console.log('🔍 Information Button - 데이터 로딩:', {
+ originalPath: pagePath,
+ normalizedPath: normalizedPath,
+ sessionUserId: session?.user?.id
+ })
+
// 병렬로 데이터 조회
const [infoResult, noticesResult] = await Promise.all([
- getCachedPageInformation(normalizedPath),
- getCachedPageNotices(normalizedPath)
+ getPageInformationDirect(normalizedPath),
+ getPageNotices(normalizedPath)
])
+ console.log('📊 조회 결과:', {
+ infoResult: infoResult ? {
+ id: infoResult.id,
+ pagePath: infoResult.pagePath,
+ pageName: infoResult.pageName,
+ attachmentsCount: infoResult.attachments?.length || 0
+ } : null,
+ noticesCount: noticesResult.length
+ })
+
setInformation(infoResult)
setNotices(noticesResult)
setDataLoaded(true)
// 권한 확인
if (session?.user?.id) {
- const hasPermission = await getCachedEditPermission(normalizedPath, session.user.id)
+ const hasPermission = await getEditPermissionDirect(normalizedPath, session.user.id)
setHasEditPermission(hasPermission)
}
} catch (error) {
@@ -109,16 +126,22 @@ export function InformationButton({
}
// 파일 다운로드 핸들러
- const handleDownload = () => {
- if (information?.attachmentFilePath) {
- // window.open 대신 link 요소 사용
- const link = document.createElement('a')
- link.href = information.attachmentFilePath
- link.target = '_blank'
- link.rel = 'noopener noreferrer'
- document.body.appendChild(link)
- link.click()
- document.body.removeChild(link)
+ const handleDownload = async (attachment: InformationAttachment) => {
+ try {
+ // 동적으로 downloadFile 함수 import
+ const { downloadFile } = await import('@/lib/file-download')
+
+ await downloadFile(
+ attachment.filePath,
+ attachment.fileName,
+ {
+ action: 'download',
+ showToast: true,
+ showSuccessToast: true
+ }
+ )
+ } catch (error) {
+ console.error('파일 다운로드 실패:', error)
}
}
@@ -145,7 +168,7 @@ export function InformationButton({
<div className="flex items-center justify-between">
<div className="flex items-center gap-2">
<div>
- <DialogTitle>{information?.pageName}</DialogTitle>
+ <DialogTitle></DialogTitle>
</div>
</div>
</div>
@@ -231,29 +254,41 @@ export function InformationButton({
{/* 첨부파일 */}
<div className="space-y-3">
- <h4 className="font-semibold">첨부파일</h4>
+ <div className="flex items-center justify-between">
+ <h4 className="font-semibold">첨부파일</h4>
+ {information?.attachments && information.attachments.length > 0 && (
+ <span className="text-xs text-gray-500">{information.attachments.length}개</span>
+ )}
+ </div>
<div className="bg-gray-50 border rounded-lg p-4">
- {information?.attachmentFileName ? (
- <div className="flex items-center justify-between p-3 bg-white rounded border">
- <div className="flex-1">
- <div className="text-sm font-medium">
- {information.attachmentFileName}
- </div>
- {information.attachmentFileSize && (
- <div className="text-xs text-gray-500 mt-1">
- {information.attachmentFileSize}
+ {information?.attachments && information.attachments.length > 0 ? (
+ <div className="space-y-3">
+ {information.attachments.map((attachment) => (
+ <div
+ 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">
+ {attachment.fileName}
+ </div>
+ {attachment.fileSize && (
+ <div className="text-xs text-gray-500 mt-1">
+ {attachment.fileSize}
+ </div>
+ )}
</div>
- )}
- </div>
- <Button
- size="sm"
- variant="outline"
- onClick={handleDownload}
- className="flex items-center gap-1"
- >
- <Download 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 className="text-center text-gray-500">
diff --git a/components/notice/notice-client.tsx b/components/notice/notice-client.tsx
index e5c05d84..1eb6d75f 100644
--- a/components/notice/notice-client.tsx
+++ b/components/notice/notice-client.tsx
@@ -1,6 +1,6 @@
"use client"
-import { useState, useEffect, useTransition } from "react"
+import React, { useState, useEffect, useTransition } from "react"
import { useParams } from "next/navigation"
import { useTranslation } from "@/i18n/client"
import { Button } from "@/components/ui/button"
@@ -91,28 +91,12 @@ export function NoticeClient({ initialData = [], currentUserId }: NoticeClientPr
const fetchNotices = async () => {
try {
setLoading(true)
- const search = searchQuery || undefined
startTransition(async () => {
- const result = await getNoticeLists({
- page: 1,
- perPage: 50,
- search: search,
- sort: [{ id: sortField, desc: sortDirection === "desc" }],
- flags: [],
- filters: [],
- joinOperator: "and",
- pagePath: "",
- title: "",
- content: "",
- authorId: null,
- isActive: null,
- from: "",
- to: "",
- })
+ const result = await getNoticeLists()
if (result?.data) {
- setNotices(result.data)
+ setNotices(result.data as NoticeWithAuthor[])
} else {
toast.error("공지사항 목록을 가져오는데 실패했습니다.")
}
@@ -125,37 +109,12 @@ export function NoticeClient({ initialData = [], currentUserId }: NoticeClientPr
}
}
- // 검색 핸들러
+ // 검색 핸들러 (클라이언트 사이드에서 필터링하므로 별도 동작 불필요)
const handleSearch = () => {
- fetchNotices()
+ // 클라이언트 사이드 필터링이므로 별도 서버 요청 불필요
}
- // 정렬 함수
- const sortNotices = (notices: NoticeWithAuthor[]) => {
- return [...notices].sort((a, b) => {
- let aValue: string | Date
- let bValue: string | Date
- if (sortField === "title") {
- aValue = a.title
- bValue = b.title
- } else if (sortField === "pagePath") {
- aValue = a.pagePath
- bValue = b.pagePath
- } else {
- aValue = new Date(a.createdAt)
- bValue = new Date(b.createdAt)
- }
-
- if (aValue < bValue) {
- return sortDirection === "asc" ? -1 : 1
- }
- if (aValue > bValue) {
- return sortDirection === "asc" ? 1 : -1
- }
- return 0
- })
- }
// 정렬 핸들러
const handleSort = (field: SortField) => {
@@ -184,8 +143,49 @@ export function NoticeClient({ initialData = [], currentUserId }: NoticeClientPr
}
}
- // 정렬된 공지사항 목록
- const sortedNotices = sortNotices(notices)
+ // 클라이언트 사이드 필터링 및 정렬
+ const filteredAndSortedNotices = React.useMemo(() => {
+ let filtered = notices
+
+ // 검색 필터
+ if (searchQuery.trim()) {
+ const query = searchQuery.toLowerCase()
+ filtered = filtered.filter(notice =>
+ notice.title.toLowerCase().includes(query) ||
+ notice.pagePath.toLowerCase().includes(query) ||
+ notice.content.toLowerCase().includes(query)
+ )
+ }
+
+ // 정렬
+ filtered = filtered.sort((a, b) => {
+ let aValue: string | Date
+ let bValue: string | Date
+
+ switch (sortField) {
+ case "title":
+ aValue = a.title
+ bValue = b.title
+ break
+ case "pagePath":
+ aValue = a.pagePath
+ bValue = b.pagePath
+ break
+ case "createdAt":
+ aValue = new Date(a.createdAt)
+ bValue = new Date(b.createdAt)
+ break
+ default:
+ return 0
+ }
+
+ if (aValue < bValue) return sortDirection === "asc" ? -1 : 1
+ if (aValue > bValue) return sortDirection === "asc" ? 1 : -1
+ return 0
+ })
+
+ return filtered
+ }, [notices, searchQuery, sortField, sortDirection])
// 페이지 경로 옵션 로딩
const loadPagePathOptions = async () => {
@@ -227,13 +227,7 @@ export function NoticeClient({ initialData = [], currentUserId }: NoticeClientPr
loadPagePathOptions()
}, [])
- useEffect(() => {
- if (searchQuery !== "") {
- fetchNotices()
- } else if (initialData.length > 0) {
- setNotices(initialData)
- }
- }, [searchQuery])
+ // 검색은 클라이언트 사이드에서 실시간으로 처리됨
return (
<div className="space-y-6">
@@ -243,16 +237,12 @@ export function NoticeClient({ initialData = [], currentUserId }: NoticeClientPr
<div className="relative flex-1 max-w-md">
<Search className="absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-400 h-4 w-4" />
<Input
- placeholder="제목이나 페이지 경로로 검색..."
+ placeholder="제목, 페이지 경로, 내용으로 검색..."
value={searchQuery}
onChange={(e) => setSearchQuery(e.target.value)}
className="pl-10"
- onKeyPress={(e) => e.key === "Enter" && handleSearch()}
/>
</div>
- <Button onClick={handleSearch} variant="outline">
- 검색
- </Button>
<Button
variant="outline"
onClick={() => window.location.reload()}
@@ -328,14 +318,14 @@ export function NoticeClient({ initialData = [], currentUserId }: NoticeClientPr
로딩 중...
</TableCell>
</TableRow>
- ) : notices.length === 0 ? (
+ ) : filteredAndSortedNotices.length === 0 ? (
<TableRow>
<TableCell colSpan={6} className="text-center py-8 text-gray-500">
- 공지사항이 없습니다.
+ {searchQuery.trim() ? "검색 결과가 없습니다." : "공지사항이 없습니다."}
</TableCell>
</TableRow>
) : (
- sortedNotices.map((notice) => (
+ filteredAndSortedNotices.map((notice) => (
<TableRow key={notice.id}>
<TableCell className="font-medium">
<div className="flex items-center gap-2">
diff --git a/components/notice/notice-create-dialog.tsx b/components/notice/notice-create-dialog.tsx
index 21cd46f6..591b2bc7 100644
--- a/components/notice/notice-create-dialog.tsx
+++ b/components/notice/notice-create-dialog.tsx
@@ -147,7 +147,7 @@ export function NoticeCreateDialog({
<SelectContent>
{pagePathOptions.map((option) => (
<SelectItem key={option.value} value={option.value}>
- {safeTranslate(option.label)}
+ {safeTranslate(option.label)} - {option.value}
</SelectItem>
))}
</SelectContent>
diff --git a/components/notice/notice-edit-sheet.tsx b/components/notice/notice-edit-sheet.tsx
index dc83d23a..b87714b3 100644
--- a/components/notice/notice-edit-sheet.tsx
+++ b/components/notice/notice-edit-sheet.tsx
@@ -170,7 +170,7 @@ export function UpdateNoticeSheet({
<SelectContent>
{pagePathOptions.map((option) => (
<SelectItem key={option.value} value={option.value}>
- {safeTranslate(option.label)}
+ {safeTranslate(option.label)} - {option.value}
</SelectItem>
))}
</SelectContent>
diff --git a/components/vendor-info/pq-simple-dialog.tsx b/components/vendor-info/pq-simple-dialog.tsx
index bb26685d..fbff2a1c 100644
--- a/components/vendor-info/pq-simple-dialog.tsx
+++ b/components/vendor-info/pq-simple-dialog.tsx
@@ -29,7 +29,7 @@ import { Download, FileText, ChevronDown, ChevronUp, Search } from "lucide-react
import { Input } from "@/components/ui/input"
import { toast } from "sonner"
import { getPQProjectsByVendorId, ProjectPQ, getPQDataByVendorId, PQGroupData } from "@/lib/pq/service"
-import { downloadFile } from "@/lib/file-download"
+// downloadFile은 동적으로 import
interface PQSimpleDialogProps {
open: boolean
@@ -109,6 +109,9 @@ export function PQSimpleDialog({
const handleFileDownload = async (filePath: string, fileName: string) => {
try {
+ // 동적으로 downloadFile 함수 import
+ const { downloadFile } = await import('@/lib/file-download')
+
const result = await downloadFile(filePath, fileName)
if (result.success) {
toast.success(`${fileName} 파일이 다운로드되었습니다.`)
diff --git a/components/vendor-regular-registrations/document-status-dialog.tsx b/components/vendor-regular-registrations/document-status-dialog.tsx
index 1b10760a..848e4977 100644
--- a/components/vendor-regular-registrations/document-status-dialog.tsx
+++ b/components/vendor-regular-registrations/document-status-dialog.tsx
@@ -15,7 +15,6 @@ import type { VendorRegularRegistration } from "@/config/vendorRegularRegistrati
import {
documentStatusColumns,
} from "@/config/vendorRegularRegistrationsColumnsConfig";
-import { downloadFile } from "@/lib/file-download";
interface DocumentStatusDialogProps {
open: boolean;
@@ -73,51 +72,153 @@ export function DocumentStatusDialog({
if (!registration) return null;
// 파일 다운로드 핸들러
- // const handleFileDownload = async (docKey: string, fileIndex: number = 0) => {
- // try {
- // const files = registration.documentFiles[docKey as keyof typeof registration.documentFiles];
- // if (!files || files.length === 0) {
- // toast.error("다운로드할 파일이 없습니다.");
- // return;
- // }
-
- // const file = files[fileIndex];
- // if (!file) {
- // toast.error("파일을 찾을 수 없습니다.");
- // return;
- // }
-
- // // filePath와 fileName 추출
- // const filePath = file.filePath || file.path;
- // const fileName = file.originalFileName || file.fileName || file.name;
-
- // if (!filePath || !fileName) {
- // toast.error("파일 정보가 올바르지 않습니다.");
- // return;
- // }
-
- // console.log(`📥 파일 다운로드 시작:`, { filePath, fileName, docKey });
-
- // // downloadFile 함수를 사용하여 파일 다운로드
- // const result = await downloadFile(filePath, fileName, {
- // showToast: true,
- // onError: (error) => {
- // console.error("파일 다운로드 오류:", error);
- // toast.error(`파일 다운로드 실패: ${error}`);
- // },
- // onSuccess: (fileName, fileSize) => {
- // console.log(`✅ 파일 다운로드 성공:`, { fileName, fileSize });
- // }
- // });
-
- // if (!result.success) {
- // console.error("파일 다운로드 실패:", result.error);
- // }
- // } catch (error) {
- // console.error("파일 다운로드 중 오류 발생:", error);
- // toast.error("파일 다운로드 중 오류가 발생했습니다.");
- // }
- // };
+ const handleFileDownload = async (docKey: string, fileIndex: number = 0) => {
+ try {
+ console.log(`🔍 파일 다운로드 시도:`, {
+ docKey,
+ fileIndex,
+ allDocumentFiles: registration.documentFiles,
+ registrationId: registration.id,
+ registrationKeys: Object.keys(registration),
+ fullRegistration: registration
+ });
+
+ // documentFiles가 없는 경우 처리
+ if (!registration.documentFiles) {
+ console.error(`❌ documentFiles가 없음:`, {
+ registration,
+ hasDocumentFiles: !!registration.documentFiles,
+ registrationKeys: Object.keys(registration)
+ });
+ toast.error("문서 파일 정보를 찾을 수 없습니다. 페이지를 새로고침 해주세요.");
+ return;
+ }
+
+ const files = registration.documentFiles[docKey as keyof typeof registration.documentFiles];
+ console.log(`📂 ${docKey} 파일 목록:`, files);
+
+ if (!files || files.length === 0) {
+ console.warn(`❌ ${docKey}에 파일이 없음:`, { files, length: files?.length });
+ toast.error("다운로드할 파일이 없습니다.");
+ return;
+ }
+
+ const file = files[fileIndex];
+ console.log(`📄 선택된 파일 (index ${fileIndex}):`, file);
+
+ if (!file) {
+ console.warn(`❌ 파일 인덱스 ${fileIndex}에 파일이 없음`);
+ toast.error("파일을 찾을 수 없습니다.");
+ return;
+ }
+
+ // 파일 객체의 모든 속성 확인
+ console.log(`🔍 파일 객체 전체 속성:`, Object.keys(file));
+ console.log(`🔍 파일 상세 정보:`, {
+ filePath: file.filePath,
+ path: file.path,
+ originalFileName: file.originalFileName,
+ fileName: file.fileName,
+ name: file.name,
+ fullObject: file
+ });
+
+ // filePath와 fileName 추출
+ const filePath = file.filePath || file.path;
+ const fileName = file.originalFileName || file.fileName || file.name;
+
+ console.log(`📝 추출된 파일 정보:`, { filePath, fileName });
+
+ if (!filePath || !fileName) {
+ console.error(`❌ 파일 정보 누락:`, {
+ filePath,
+ fileName,
+ fileObject: file,
+ availableKeys: Object.keys(file)
+ });
+ toast.error("파일 정보가 올바르지 않습니다.");
+ return;
+ }
+
+ console.log(`📥 파일 다운로드 시작:`, { filePath, fileName, docKey });
+
+ // downloadFile 함수를 동적으로 import하여 파일 다운로드
+ const { downloadFile } = await import('@/lib/file-download');
+ const result = await downloadFile(filePath, fileName, {
+ showToast: true,
+ onError: (error: any) => {
+ console.error("파일 다운로드 오류:", error);
+ toast.error(`파일 다운로드 실패: ${error}`);
+ },
+ onSuccess: (fileName: string, fileSize?: number) => {
+ console.log(`✅ 파일 다운로드 성공:`, { fileName, fileSize });
+ }
+ });
+
+ if (!result.success) {
+ console.error("파일 다운로드 실패:", result.error);
+ }
+ } catch (error) {
+ console.error("파일 다운로드 중 오류 발생:", error);
+ toast.error("파일 다운로드 중 오류가 발생했습니다.");
+ }
+ };
+
+ // 기본계약 파일 다운로드 핸들러
+ const handleContractDownload = async (contractIndex: number) => {
+ try {
+ if (!registration.basicContracts || registration.basicContracts.length === 0) {
+ toast.error("다운로드할 계약이 없습니다.");
+ return;
+ }
+
+ const contract = registration.basicContracts[contractIndex];
+ if (!contract) {
+ toast.error("계약을 찾을 수 없습니다.");
+ return;
+ }
+
+ if (contract.status !== "COMPLETED") {
+ toast.error("완료된 계약서만 다운로드할 수 있습니다.");
+ return;
+ }
+
+ // 서명된 계약서 파일 정보 확인
+ const filePath = contract.filePath;
+ const fileName = contract.fileName || `${contract.templateName || '기본계약'}_${registration.companyName}.docx`;
+
+ if (!filePath) {
+ toast.error("계약서 파일을 찾을 수 없습니다.");
+ return;
+ }
+
+ console.log(`📥 기본계약 다운로드 시작:`, {
+ filePath,
+ fileName,
+ templateName: contract.templateName
+ });
+
+ // downloadFile 함수를 사용하여 서명된 계약서 다운로드
+ const { downloadFile } = await import('@/lib/file-download');
+ const result = await downloadFile(filePath, fileName, {
+ showToast: true,
+ onError: (error: any) => {
+ console.error("기본계약 다운로드 오류:", error);
+ toast.error(`기본계약 다운로드 실패: ${error}`);
+ },
+ onSuccess: (fileName: string, fileSize?: number) => {
+ console.log(`✅ 기본계약 다운로드 성공:`, { fileName, fileSize });
+ }
+ });
+
+ if (!result.success) {
+ console.error("기본계약 다운로드 실패:", result.error);
+ }
+ } catch (error) {
+ console.error("기본계약 다운로드 중 오류 발생:", error);
+ toast.error("기본계약 다운로드 중 오류가 발생했습니다.");
+ }
+ };
return (
<Dialog open={open} onOpenChange={onOpenChange}>
@@ -205,7 +306,7 @@ export function DocumentStatusDialog({
{isSubmitted ? "2024.01.01" : "-"}
</div>
<div>
- {/* {isSubmitted && (
+ {isSubmitted && (
<Button
size="sm"
variant="outline"
@@ -214,7 +315,7 @@ export function DocumentStatusDialog({
<Download className="w-4 h-4 mr-1" />
다운로드
</Button>
- )} */}
+ )}
</div>
</div>
);
@@ -262,7 +363,11 @@ export function DocumentStatusDialog({
</div>
<div>
{isCompleted && (
- <Button size="sm" variant="outline">
+ <Button
+ size="sm"
+ variant="outline"
+ onClick={() => handleContractDownload(index)}
+ >
<Download className="w-4 h-4 mr-1" />
다운로드
</Button>