summaryrefslogtreecommitdiff
path: root/lib/bidding/pre-quote/table/bidding-pre-quote-attachments-dialog.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'lib/bidding/pre-quote/table/bidding-pre-quote-attachments-dialog.tsx')
-rw-r--r--lib/bidding/pre-quote/table/bidding-pre-quote-attachments-dialog.tsx224
1 files changed, 0 insertions, 224 deletions
diff --git a/lib/bidding/pre-quote/table/bidding-pre-quote-attachments-dialog.tsx b/lib/bidding/pre-quote/table/bidding-pre-quote-attachments-dialog.tsx
deleted file mode 100644
index cfa629e3..00000000
--- a/lib/bidding/pre-quote/table/bidding-pre-quote-attachments-dialog.tsx
+++ /dev/null
@@ -1,224 +0,0 @@
-'use client'
-
-import * as React from 'react'
-import {
- Dialog,
- DialogContent,
- DialogDescription,
- DialogHeader,
- DialogTitle,
-} from '@/components/ui/dialog'
-import { Button } from '@/components/ui/button'
-import { Badge } from '@/components/ui/badge'
-import {
- Table,
- TableBody,
- TableCell,
- TableHead,
- TableHeader,
- TableRow,
-} from '@/components/ui/table'
-import {
- FileText,
- Download,
- User,
- Calendar
-} from 'lucide-react'
-import { useToast } from '@/hooks/use-toast'
-import { useTransition } from 'react'
-import { getPreQuoteDocuments, getPreQuoteDocumentForDownload } from '../service'
-import { downloadFile } from '@/lib/file-download'
-
-interface UploadedDocument {
- id: number
- fileName: string
- originalFileName: string
- fileSize: number | null
- filePath: string
- title: string | null
- description: string | null
- uploadedAt: string
- uploadedBy: string
-}
-
-interface BiddingPreQuoteAttachmentsDialogProps {
- open: boolean
- onOpenChange: (open: boolean) => void
- biddingId: number
- companyId: number
- companyName: string
-}
-
-export function BiddingPreQuoteAttachmentsDialog({
- open,
- onOpenChange,
- biddingId,
- companyId,
- companyName
-}: BiddingPreQuoteAttachmentsDialogProps) {
- const { toast } = useToast()
- const [isPending, startTransition] = useTransition()
- const [documents, setDocuments] = React.useState<UploadedDocument[]>([])
- const [isLoading, setIsLoading] = React.useState(false)
-
- // 다이얼로그가 열릴 때 첨부파일 목록 로드
- React.useEffect(() => {
- if (open) {
- loadDocuments()
- }
- }, [open, biddingId, companyId])
-
- const loadDocuments = async () => {
- setIsLoading(true)
- try {
- const docs = await getPreQuoteDocuments(biddingId, companyId)
- // Date를 string으로 변환
- const mappedDocs = docs.map(doc => ({
- ...doc,
- uploadedAt: doc.uploadedAt.toString(),
- uploadedBy: doc.uploadedBy || ''
- }))
- setDocuments(mappedDocs)
- } catch (error) {
- console.error('Failed to load documents:', error)
- toast({
- title: '오류',
- description: '첨부파일 목록을 불러오는데 실패했습니다.',
- variant: 'destructive',
- })
- } finally {
- setIsLoading(false)
- }
- }
-
- // 파일 다운로드
- const handleDownload = (document: UploadedDocument) => {
- startTransition(async () => {
- const result = await getPreQuoteDocumentForDownload(document.id, biddingId, companyId)
-
- if (result.success) {
- try {
- await downloadFile(result.document?.filePath, result.document?.originalFileName, {
- showToast: true
- })
- } catch (error) {
- toast({
- title: '다운로드 실패',
- description: '파일 다운로드에 실패했습니다.',
- variant: 'destructive',
- })
- }
- } else {
- toast({
- title: '다운로드 실패',
- description: result.error,
- variant: 'destructive',
- })
- }
- })
- }
-
- // 파일 크기 포맷팅
- const formatFileSize = (bytes: number | null) => {
- if (!bytes) return '-'
- if (bytes === 0) return '0 Bytes'
- const k = 1024
- const sizes = ['Bytes', 'KB', 'MB', 'GB']
- const i = Math.floor(Math.log(bytes) / Math.log(k))
- return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
- }
-
- return (
- <Dialog open={open} onOpenChange={onOpenChange}>
- <DialogContent className="max-w-4xl max-h-[80vh] overflow-y-auto">
- <DialogHeader>
- <DialogTitle className="flex items-center gap-2">
- <FileText className="w-5 h-5" />
- <span>협력업체 첨부파일</span>
- <span className="text-sm font-normal text-muted-foreground">
- - {companyName}
- </span>
- </DialogTitle>
- <DialogDescription>
- 협력업체가 제출한 견적 관련 첨부파일 목록입니다.
- </DialogDescription>
- </DialogHeader>
-
- {isLoading ? (
- <div className="flex items-center justify-center py-12">
- <div className="text-center">
- <div className="animate-spin rounded-full h-8 w-8 border-b-2 border-primary mx-auto mb-4"></div>
- <p className="text-muted-foreground">첨부파일 목록을 불러오는 중...</p>
- </div>
- </div>
- ) : documents.length > 0 ? (
- <div className="space-y-4">
- <div className="flex items-center justify-between">
- <Badge variant="secondary" className="text-sm">
- 총 {documents.length}개 파일
- </Badge>
- </div>
-
- <Table>
- <TableHeader>
- <TableRow>
- <TableHead>파일명</TableHead>
- <TableHead>크기</TableHead>
- <TableHead>업로드일</TableHead>
- <TableHead>작성자</TableHead>
- <TableHead className="w-24">작업</TableHead>
- </TableRow>
- </TableHeader>
- <TableBody>
- {documents.map((doc) => (
- <TableRow key={doc.id}>
- <TableCell>
- <div className="flex items-center gap-2">
- <FileText className="w-4 h-4 text-gray-500" />
- <span className="truncate max-w-48" title={doc.originalFileName}>
- {doc.originalFileName}
- </span>
- </div>
- </TableCell>
- <TableCell className="text-sm text-gray-500">
- {formatFileSize(doc.fileSize)}
- </TableCell>
- <TableCell className="text-sm text-gray-500">
- <div className="flex items-center gap-1">
- <Calendar className="w-3 h-3" />
- {new Date(doc.uploadedAt).toLocaleDateString('ko-KR')}
- </div>
- </TableCell>
- <TableCell className="text-sm text-gray-500">
- <div className="flex items-center gap-1">
- <User className="w-3 h-3" />
- {doc.uploadedBy}
- </div>
- </TableCell>
- <TableCell>
- <Button
- variant="outline"
- size="sm"
- onClick={() => handleDownload(doc)}
- disabled={isPending}
- title="다운로드"
- >
- <Download className="w-3 h-3" />
- </Button>
- </TableCell>
- </TableRow>
- ))}
- </TableBody>
- </Table>
- </div>
- ) : (
- <div className="text-center py-12 text-gray-500">
- <FileText className="w-12 h-12 mx-auto mb-4 opacity-50" />
- <p className="text-lg font-medium mb-2">첨부파일이 없습니다</p>
- <p className="text-sm">협력업체가 아직 첨부파일을 업로드하지 않았습니다.</p>
- </div>
- )}
- </DialogContent>
- </Dialog>
- )
-}