summaryrefslogtreecommitdiff
path: root/lib/rfq-last
diff options
context:
space:
mode:
authorjoonhoekim <26rote@gmail.com>2025-09-22 19:33:16 +0900
committerjoonhoekim <26rote@gmail.com>2025-09-22 19:33:16 +0900
commit480ac58010604140d1a52fa2b839aedb6ac15941 (patch)
tree4cc45c96ea174991d59c1a058ed9da05a2a3ac8c /lib/rfq-last
parentba35e67845f935c8ce0151c9ef1fefa0b0510faf (diff)
(김준회) POS I/F 로직 및 UI 처리 구현
Diffstat (limited to 'lib/rfq-last')
-rw-r--r--lib/rfq-last/table/rfq-attachments-dialog.tsx80
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">