diff options
| author | joonhoekim <26rote@gmail.com> | 2025-09-22 19:33:16 +0900 |
|---|---|---|
| committer | joonhoekim <26rote@gmail.com> | 2025-09-22 19:33:16 +0900 |
| commit | 480ac58010604140d1a52fa2b839aedb6ac15941 (patch) | |
| tree | 4cc45c96ea174991d59c1a058ed9da05a2a3ac8c /lib/rfq-last | |
| parent | ba35e67845f935c8ce0151c9ef1fefa0b0510faf (diff) | |
(김준회) POS I/F 로직 및 UI 처리 구현
Diffstat (limited to 'lib/rfq-last')
| -rw-r--r-- | lib/rfq-last/table/rfq-attachments-dialog.tsx | 80 |
1 files changed, 74 insertions, 6 deletions
diff --git a/lib/rfq-last/table/rfq-attachments-dialog.tsx b/lib/rfq-last/table/rfq-attachments-dialog.tsx index 05747c6c..4513b0b0 100644 --- a/lib/rfq-last/table/rfq-attachments-dialog.tsx +++ b/lib/rfq-last/table/rfq-attachments-dialog.tsx @@ -2,7 +2,7 @@ import * as React from "react" import { format } from "date-fns" -import { Download, FileText, Eye, ExternalLink, Loader2 } from "lucide-react" +import { Download, FileText, Eye, ExternalLink, Loader2, RefreshCw } from "lucide-react" import { Dialog, DialogContent, @@ -26,6 +26,8 @@ import { toast } from "sonner" import { RfqsLastView } from "@/db/schema" import { getRfqAttachmentsAction } from "../service" import { downloadFile, quickPreview, smartFileAction, formatFileSize, getFileInfo } from "@/lib/file-download" +import { syncRfqPosFiles } from "@/lib/pos" +import { useSession } from "next-auth/react" // 첨부파일 타입 interface RfqAttachment { @@ -55,6 +57,9 @@ export function RfqAttachmentsDialog({ isOpen, onClose, rfqData }: RfqAttachment const [attachments, setAttachments] = React.useState<RfqAttachment[]>([]) const [isLoading, setIsLoading] = React.useState(false) const [downloadingFiles, setDownloadingFiles] = React.useState<Set<number>>(new Set()) + const [isSyncing, setIsSyncing] = React.useState(false) + + const { data: session } = useSession() // 첨부파일 목록 로드 React.useEffect(() => { @@ -153,6 +158,49 @@ export function RfqAttachmentsDialog({ isOpen, onClose, rfqData }: RfqAttachment } } + // POS 파일 동기화 핸들러 + const handlePosSync = async () => { + if (!session?.user?.id || !rfqData.id) { + toast.error("로그인이 필요하거나 RFQ 정보가 없습니다") + return + } + + setIsSyncing(true) + + try { + const result = await syncRfqPosFiles(rfqData.id, parseInt(session.user.id)) + + if (result.success) { + toast.success( + `POS 파일 동기화 완료: 성공 ${result.successCount}건, 실패 ${result.failedCount}건` + ) + + // 성공한 경우 첨부파일 목록 새로고침 + if (result.successCount > 0) { + const refreshResult = await getRfqAttachmentsAction(rfqData.id) + if (refreshResult.success) { + setAttachments(refreshResult.data) + } + } + + // 상세 결과 표시 + if (result.details.length > 0) { + const failedItems = result.details.filter(d => d.status === 'failed') + if (failedItems.length > 0) { + console.warn("POS 동기화 실패 항목:", failedItems) + } + } + } else { + toast.error(`POS 파일 동기화 실패: ${result.errors.join(', ')}`) + } + } catch (error) { + console.error("POS 동기화 오류:", error) + toast.error("POS 파일 동기화 중 오류가 발생했습니다") + } finally { + setIsSyncing(false) + } + } + // 첨부파일 타입별 색상 const getAttachmentTypeBadgeVariant = (type: string) => { switch (type.toLowerCase()) { @@ -167,11 +215,31 @@ export function RfqAttachmentsDialog({ isOpen, onClose, rfqData }: RfqAttachment <Dialog open={isOpen} onOpenChange={onClose}> <DialogContent className="max-w-6xl h-[85vh] flex flex-col"> <DialogHeader> - <DialogTitle>견적 첨부파일</DialogTitle> - <DialogDescription> - {rfqData.rfqCode} - {rfqData.rfqTitle || rfqData.itemName || "견적"} - {attachments.length > 0 && ` (${attachments.length}개 파일)`} - </DialogDescription> + <div className="flex items-center justify-between"> + <div className="flex-1"> + <DialogTitle>견적 첨부파일</DialogTitle> + <DialogDescription> + {rfqData.rfqCode} - {rfqData.rfqTitle || rfqData.itemName || "견적"} + {attachments.length > 0 && ` (${attachments.length}개 파일)`} + </DialogDescription> + </div> + + {/* POS 동기화 버튼 */} + <Button + variant="outline" + size="sm" + onClick={handlePosSync} + disabled={isSyncing || isLoading} + className="flex items-center gap-2" + > + {isSyncing ? ( + <Loader2 className="h-4 w-4 animate-spin" /> + ) : ( + <RefreshCw className="h-4 w-4" /> + )} + {isSyncing ? "동기화 중..." : "POS 파일 동기화"} + </Button> + </div> </DialogHeader> <ScrollArea className="flex-1"> |
