"use client"; import { useState } from "react"; import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter, } from "@/components/ui/dialog"; import { Button } from "@/components/ui/button"; import { Label } from "@/components/ui/label"; import { Input } from "@/components/ui/input"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select"; import { Alert, AlertDescription } from "@/components/ui/alert"; import { Upload, X, FileIcon, Info } from "lucide-react"; import { toast } from "sonner"; import { UnifiedDwgReceiptItem, editDetailDwgReceipt } from "../actions"; import { v4 as uuidv4 } from "uuid"; import { useFileUploadWithProgress } from "../hooks/use-file-upload-with-progress"; import { uploadFilesWithProgress } from "../utils/upload-with-progress"; import { FileUploadProgressList } from "../components/file-upload-progress-list"; interface AddDetailDrawingDialogProps { open: boolean; onOpenChange: (open: boolean) => void; drawing: UnifiedDwgReceiptItem | null; vendorCode: string; userId: string; userName: string; userEmail: string; onComplete: () => void; drawingKind: "B3" | "B4"; // 추가 } // B3 벤더의 선택 옵션 const B3_DRAWING_USAGE_OPTIONS = [ { value: "APP", label: "APPROVAL (승인용)" }, { value: "WOR", label: "WORKING (작업용)" }, ]; const B3_REGISTER_KIND_OPTIONS: Record> = { APP: [ { value: "APPR", label: "승인용 도면 (Full)", revisionRule: "예: A, B, C 또는 R00, R01, R02" }, { value: "APPR-P", label: "승인용 도면 (Partial)", revisionRule: "예: A, B, C 또는 R00, R01, R02" }, ], WOR: [ { value: "WORK", label: "작업용 입수도면 (Full)", revisionRule: "예: A, B, C 또는 R00, R01, R02" }, { value: "WORK-P", label: "작업용 입수도면 (Partial)", revisionRule: "예: A, B, C 또는 R00, R01, R02" }, ], }; // B4 벤더(GTT)의 선택 옵션 const B4_DRAWING_USAGE_OPTIONS = [ { value: "REC", label: "RECEIVE (입수용)" }, ]; const B4_REGISTER_KIND_OPTIONS: Record> = { REC: [ { value: "RECP", label: "Pre. 도면입수", revisionRule: "예: R00, R01, R02, R03" }, { value: "RECW", label: "Working 도면입수", revisionRule: "예: R00, R01, R02, R03" }, ], }; export function AddDetailDrawingDialog({ open, onOpenChange, drawing, vendorCode, userId, userName, userEmail, onComplete, drawingKind, }: AddDetailDrawingDialogProps) { const [drawingUsage, setDrawingUsage] = useState(""); const [registerKind, setRegisterKind] = useState(""); const [revision, setRevision] = useState(""); const [isSubmitting, setIsSubmitting] = useState(false); // 파일 업로드 훅 사용 (진행도 추적) const { fileProgresses, files, removeFile, clearFiles, updateFileProgress, getRootProps, getInputProps, isDragActive, } = useFileUploadWithProgress(); // 폼 초기화 const resetForm = () => { setDrawingUsage(""); setRegisterKind(""); setRevision(""); clearFiles(); }; // 제출 const handleSubmit = async () => { if (!drawing) return; // 유효성 검사 if (!drawingUsage) { toast.error("도면용도를 선택하세요"); return; } if (!registerKind) { toast.error("등록종류를 선택하세요"); return; } if (!revision.trim()) { toast.error("Revision을 입력하세요"); return; } if (files.length === 0) { toast.error("최소 1개 이상의 파일을 첨부해야 합니다"); return; } try { setIsSubmitting(true); // 파일 업로드 ID 생성 const uploadId = uuidv4(); // 상세도면 추가 const result = await editDetailDwgReceipt({ dwgList: [ { Mode: "ADD", Status: "Draft", RegisterId: 0, ProjectNo: drawing.ProjectNo, Discipline: drawing.Discipline, DrawingKind: drawing.DrawingKind, DrawingNo: drawing.DrawingNo, DrawingName: drawing.DrawingName, RegisterGroupId: drawing.RegisterGroupId, RegisterSerialNo: 0, // 자동 증가 RegisterKind: registerKind, DrawingRevNo: revision, Category: "TS", // To SHI (벤더가 SHI에게 제출) Receiver: null, Manager: "", RegisterDesc: "", UploadId: uploadId, RegCompanyCode: vendorCode, }, ], userId, userNm: userName, vendorCode, email: userEmail, }); if (result > 0) { // 파일 업로드 처리 (상세도면 추가 후) if (files.length > 0) { toast.info(`${files.length}개 파일 업로드를 진행합니다...`); // 모든 파일 상태를 uploading으로 변경 files.forEach((_, index) => { updateFileProgress(index, 0, "uploading"); }); const uploadResult = await uploadFilesWithProgress({ uploadId, userId, files, callbacks: { onProgress: (fileIndex, progress) => { updateFileProgress(fileIndex, progress, "uploading"); }, onFileComplete: (fileIndex) => { updateFileProgress(fileIndex, 100, "completed"); }, onFileError: (fileIndex, error) => { updateFileProgress(fileIndex, 0, "error", error); }, }, }); if (uploadResult.success) { toast.success(`상세도면 추가 및 ${uploadResult.uploadedCount}개 파일 업로드 완료`); } else { toast.warning(`상세도면은 추가되었으나 파일 업로드 실패: ${uploadResult.error}`); } } else { toast.success("상세도면이 추가되었습니다"); } // API 호출 성공 시 무조건 다이얼로그 닫기 (파일 업로드 성공 여부와 무관) resetForm(); onComplete(); onOpenChange(false); } else { toast.error("상세도면 추가에 실패했습니다"); } } catch (error) { console.error("상세도면 추가 실패:", error); toast.error("상세도면 추가 중 오류가 발생했습니다"); } finally { setIsSubmitting(false); } }; const handleCancel = () => { resetForm(); onOpenChange(false); }; // DrawingUsage가 변경되면 RegisterKind 초기화 const handleDrawingUsageChange = (value: string) => { setDrawingUsage(value); setRegisterKind(""); }; // 현재 선택 가능한 DrawingUsage 및 RegisterKind 옵션 const drawingUsageOptions = drawingKind === "B4" ? B4_DRAWING_USAGE_OPTIONS : B3_DRAWING_USAGE_OPTIONS; const registerKindOptionsMap = drawingKind === "B4" ? B4_REGISTER_KIND_OPTIONS : B3_REGISTER_KIND_OPTIONS; const registerKindOptions = drawingUsage ? registerKindOptionsMap[drawingUsage] || [] : []; // 선택된 RegisterKind의 Revision Rule const revisionRule = registerKindOptions.find((opt) => opt.value === registerKind)?.revisionRule || ""; return ( 상세도면 추가
{/* 도면 정보 표시 */} {drawing && (
{drawing.DrawingNo}
{drawing.DrawingName}
)} {/* 도면용도 선택 */}
{/* 등록종류 선택 */}
{revisionRule && (

Revision 입력 형식: {revisionRule}

)}
{/* Revision 입력 */}
setRevision(e.target.value)} placeholder="예: A, B, R00, R01" disabled={!registerKind} />
{/* 파일 업로드 */}
0 ? "py-4" : ""} `} > {files.length === 0 ? (

파일을 드래그하거나 클릭하여 선택

여러 파일을 한 번에 업로드할 수 있습니다 (최대 1GB/파일)

) : (

{files.length}개 파일 선택됨

추가로 파일을 드래그하거나 클릭하여 더 추가할 수 있습니다

)}
{/* 선택된 파일 목록 */} {files.length > 0 && (
{isSubmitting ? ( // 업로드 중: 진행도 표시 ) : ( // 대기 중: 삭제 버튼 표시 <>

선택된 파일 ({files.length}개)

{files.map((file, index) => (

{file.name}

{(file.size / 1024 / 1024).toFixed(2)} MB

))}
)}
)}
); }