diff options
| author | joonhoekim <26rote@gmail.com> | 2025-12-01 19:52:06 +0900 |
|---|---|---|
| committer | joonhoekim <26rote@gmail.com> | 2025-12-01 19:52:06 +0900 |
| commit | 44b74ff4170090673b6eeacd8c528e0abf47b7aa (patch) | |
| tree | 3f3824b4e2cb24536c1677188b4cae5b8909d3da /lib/b-rfq/vendor-response/response-detail-sheet.tsx | |
| parent | 4953e770929b82ef77da074f77071ebd0f428529 (diff) | |
(김준회) deprecated code 정리
Diffstat (limited to 'lib/b-rfq/vendor-response/response-detail-sheet.tsx')
| -rw-r--r-- | lib/b-rfq/vendor-response/response-detail-sheet.tsx | 358 |
1 files changed, 0 insertions, 358 deletions
diff --git a/lib/b-rfq/vendor-response/response-detail-sheet.tsx b/lib/b-rfq/vendor-response/response-detail-sheet.tsx deleted file mode 100644 index da7f9b01..00000000 --- a/lib/b-rfq/vendor-response/response-detail-sheet.tsx +++ /dev/null @@ -1,358 +0,0 @@ -// components/rfq/response-detail-sheet.tsx -"use client"; - -import { Button } from "@/components/ui/button"; -import { Badge } from "@/components/ui/badge"; -import { - Sheet, - SheetContent, - SheetDescription, - SheetHeader, - SheetTitle, - SheetTrigger, -} from "@/components/ui/sheet"; -import { - FileText, - Upload, - Download, - AlertCircle, - MessageSquare, - FileCheck, - Eye -} from "lucide-react"; -import { formatDateTime, formatFileSize } from "@/lib/utils"; -import { cn } from "@/lib/utils"; -import type { EnhancedVendorResponse } from "@/lib/b-rfq/service"; - -// 파일 다운로드 핸들러 (API 사용) -async function handleFileDownload( - filePath: string, - fileName: string, - type: "client" | "vendor" = "client", - id?: number -) { - try { - const params = new URLSearchParams({ - path: filePath, - type: type, - }); - - // ID가 있으면 추가 - if (id) { - if (type === "client") { - params.append("revisionId", id.toString()); - } else { - params.append("responseFileId", id.toString()); - } - } - - const response = await fetch(`/api/rfq-attachments/download?${params.toString()}`); - - if (!response.ok) { - const errorData = await response.json(); - throw new Error(errorData.error || `Download failed: ${response.status}`); - } - - // Blob으로 파일 데이터 받기 - const blob = await response.blob(); - - // 임시 URL 생성하여 다운로드 - const url = window.URL.createObjectURL(blob); - const link = document.createElement('a'); - link.href = url; - link.download = fileName; - document.body.appendChild(link); - link.click(); - - // 정리 - document.body.removeChild(link); - window.URL.revokeObjectURL(url); - - console.log("✅ 파일 다운로드 성공:", fileName); - - } catch (error) { - console.error("❌ 파일 다운로드 실패:", error); - - // 사용자에게 에러 알림 (토스트나 알럿으로 대체 가능) - alert(`파일 다운로드에 실패했습니다: ${error instanceof Error ? error.message : '알 수 없는 오류'}`); - } -} - -// 효과적인 상태별 아이콘 및 색상 -function getEffectiveStatusInfo(effectiveStatus: string) { - switch (effectiveStatus) { - case "NOT_RESPONDED": - return { - label: "미응답", - variant: "outline" as const - }; - case "UP_TO_DATE": - return { - label: "최신", - variant: "default" as const - }; - case "VERSION_MISMATCH": - return { - label: "업데이트 필요", - variant: "secondary" as const - }; - case "REVISION_REQUESTED": - return { - label: "수정요청", - variant: "secondary" as const - }; - case "WAIVED": - return { - label: "포기", - variant: "outline" as const - }; - default: - return { - label: effectiveStatus, - variant: "outline" as const - }; - } -} - -interface ResponseDetailSheetProps { - response: EnhancedVendorResponse; - trigger?: React.ReactNode; -} - -export function ResponseDetailSheet({ response, trigger }: ResponseDetailSheetProps) { - const hasMultipleRevisions = response.attachment?.revisions && response.attachment.revisions.length > 1; - const hasResponseFiles = response.responseAttachments && response.responseAttachments.length > 0; - - return ( - <Sheet> - <SheetTrigger asChild> - {trigger || ( - <Button size="sm" variant="ghost"> - <Eye className="h-3 w-3 mr-1" /> - 상세 - </Button> - )} - </SheetTrigger> - <SheetContent side="right" className="w-[600px] sm:w-[800px] overflow-y-auto"> - <SheetHeader> - <SheetTitle className="flex items-center gap-2"> - <FileText className="h-5 w-5" /> - 상세 정보 - {response.serialNo} - </SheetTitle> - <SheetDescription> - {response.attachmentType} • {response.attachment?.revisions?.[0]?.originalFileName} - </SheetDescription> - </SheetHeader> - - <div className="space-y-6 mt-6"> - {/* 기본 정보 */} - <div className="space-y-4"> - <h3 className="text-lg font-semibold flex items-center gap-2"> - <AlertCircle className="h-4 w-4" /> - 기본 정보 - </h3> - <div className="grid grid-cols-2 gap-4 p-4 bg-muted/30 rounded-lg"> - <div> - <div className="text-sm text-muted-foreground">상태</div> - <div className="font-medium">{getEffectiveStatusInfo(response.effectiveStatus).label}</div> - </div> - <div> - <div className="text-sm text-muted-foreground">현재 리비전</div> - <div className="font-medium">{response.currentRevision}</div> - </div> - <div> - <div className="text-sm text-muted-foreground">응답 리비전</div> - <div className="font-medium">{response.respondedRevision || "-"}</div> - </div> - <div> - <div className="text-sm text-muted-foreground">응답일</div> - <div className="font-medium"> - {response.respondedAt ? formatDateTime(new Date(response.respondedAt)) : "-"} - </div> - </div> - <div> - <div className="text-sm text-muted-foreground">요청일</div> - <div className="font-medium"> - {formatDateTime(new Date(response.requestedAt))} - </div> - </div> - <div> - <div className="text-sm text-muted-foreground">응답 파일 수</div> - <div className="font-medium">{response.totalResponseFiles}개</div> - </div> - </div> - </div> - - {/* 코멘트 정보 */} - <div className="space-y-4"> - <h3 className="text-lg font-semibold flex items-center gap-2"> - <MessageSquare className="h-4 w-4" /> - 코멘트 - </h3> - <div className="space-y-3"> - {response.responseComment && ( - <div className="p-3 border-l-4 border-blue-500 bg-blue-50"> - <div className="text-sm font-medium text-blue-700 mb-1">발주처 응답 코멘트</div> - <div className="text-sm">{response.responseComment}</div> - </div> - )} - {response.vendorComment && ( - <div className="p-3 border-l-4 border-green-500 bg-green-50"> - <div className="text-sm font-medium text-green-700 mb-1">내부 메모</div> - <div className="text-sm">{response.vendorComment}</div> - </div> - )} - {response.attachment?.revisions?.find(r => r.revisionComment) && ( - <div className="p-3 border-l-4 border-orange-500 bg-orange-50"> - <div className="text-sm font-medium text-orange-700 mb-1">발주처 요청 사항</div> - <div className="text-sm"> - {response.attachment.revisions.find(r => r.revisionComment)?.revisionComment} - </div> - </div> - )} - {!response.responseComment && !response.vendorComment && !response.attachment?.revisions?.find(r => r.revisionComment) && ( - <div className="text-center text-muted-foreground py-4 bg-muted/20 rounded-lg"> - 코멘트가 없습니다. - </div> - )} - </div> - </div> - - {/* 발주처 리비전 히스토리 */} - {hasMultipleRevisions && ( - <div className="space-y-4"> - <h3 className="text-lg font-semibold flex items-center gap-2"> - <FileCheck className="h-4 w-4" /> - 발주처 리비전 히스토리 ({response.attachment!.revisions.length}개) - </h3> - <div className="space-y-3"> - {response.attachment!.revisions - .sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime()) - .map((revision) => ( - <div - key={revision.id} - className={cn( - "flex items-center justify-between p-4 rounded-lg border", - revision.isLatest ? "bg-blue-50 border-blue-200" : "bg-white" - )} - > - <div className="flex items-center gap-3 flex-1"> - <Badge variant={revision.isLatest ? "default" : "outline"}> - {revision.revisionNo} - </Badge> - <div className="flex-1"> - <div className="font-medium text-sm">{revision.originalFileName}</div> - <div className="text-xs text-muted-foreground"> - {formatFileSize(revision.fileSize)} • {formatDateTime(new Date(revision.createdAt))} - </div> - {revision.revisionComment && ( - <div className="text-xs text-muted-foreground mt-1 italic"> - "{revision.revisionComment}" - </div> - )} - </div> - </div> - - <div className="flex items-center gap-2"> - {revision.isLatest && ( - <Badge variant="secondary" className="text-xs">최신</Badge> - )} - {revision.revisionNo === response.respondedRevision && ( - <Badge variant="outline" className="text-xs text-green-600 border-green-300"> - 응답됨 - </Badge> - )} - <Button - size="sm" - variant="ghost" - onClick={() => { - if (revision.filePath) { - handleFileDownload( - revision.filePath, - revision.originalFileName, - "client", - revision.id - ); - } - }} - disabled={!revision.filePath} - title="파일 다운로드" - > - <Download className="h-4 w-4" /> - </Button> - </div> - </div> - ))} - </div> - </div> - )} - - {/* 벤더 응답 파일들 */} - {hasResponseFiles && ( - <div className="space-y-4"> - <h3 className="text-lg font-semibold flex items-center gap-2"> - <Upload className="h-4 w-4" /> - 벤더 응답 파일들 ({response.totalResponseFiles}개) - </h3> - <div className="space-y-3"> - {response.responseAttachments! - .sort((a, b) => new Date(b.uploadedAt).getTime() - new Date(a.uploadedAt).getTime()) - .map((file) => ( - <div key={file.id} className="flex items-center justify-between p-4 rounded-lg border bg-green-50 border-green-200"> - <div className="flex items-center gap-3 flex-1"> - <Badge variant="outline" className="bg-green-100"> - 파일 #{file.fileSequence} - </Badge> - <div className="flex-1"> - <div className="font-medium text-sm">{file.originalFileName}</div> - <div className="text-xs text-muted-foreground"> - {formatFileSize(file.fileSize)} • {formatDateTime(new Date(file.uploadedAt))} - </div> - {file.description && ( - <div className="text-xs text-muted-foreground mt-1 italic"> - "{file.description}" - </div> - )} - </div> - </div> - - <div className="flex items-center gap-2"> - {file.isLatestResponseFile && ( - <Badge variant="secondary" className="text-xs">최신</Badge> - )} - <Button - size="sm" - variant="ghost" - onClick={() => { - if (file.filePath) { - handleFileDownload( - file.filePath, - file.originalFileName, - "vendor", - file.id - ); - } - }} - disabled={!file.filePath} - title="파일 다운로드" - > - <Download className="h-4 w-4" /> - </Button> - </div> - </div> - ))} - </div> - </div> - )} - - {!hasMultipleRevisions && !hasResponseFiles && ( - <div className="text-center text-muted-foreground py-8 bg-muted/20 rounded-lg"> - <FileText className="h-8 w-8 mx-auto mb-2 opacity-50" /> - <p>추가 파일이나 리비전 정보가 없습니다.</p> - </div> - )} - </div> - </SheetContent> - </Sheet> - ); -}
\ No newline at end of file |
