"use client"; import { useState, useCallback } from "react"; import { useDropzone } from "react-dropzone"; 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, uploadFilesToDetailDrawing } from "../actions"; import { v4 as uuidv4 } from "uuid"; 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 [files, setFiles] = useState([]); const [isSubmitting, setIsSubmitting] = useState(false); // 파일 드롭 핸들러 const onDrop = useCallback((acceptedFiles: File[]) => { setFiles((prev) => [...prev, ...acceptedFiles]); }, []); const { getRootProps, getInputProps, isDragActive } = useDropzone({ onDrop, multiple: true, }); // 파일 제거 const removeFile = (index: number) => { setFiles((prev) => prev.filter((_, i) => i !== index)); }; // 폼 초기화 const resetForm = () => { setDrawingUsage(""); setRegisterKind(""); setRevision(""); setFiles([]); }; // 제출 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}개 파일 업로드를 진행합니다...`); const formData = new FormData(); formData.append("uploadId", uploadId); formData.append("userId", userId); formData.append("fileCount", String(files.length)); files.forEach((file, index) => { formData.append(`file_${index}`, file); }); const uploadResult = await uploadFilesToDetailDrawing(formData); if (uploadResult.success) { toast.success(`상세도면 추가 및 ${uploadResult.uploadedCount}개 파일 업로드 완료`); } else { toast.warning(`상세도면은 추가되었으나 파일 업로드 실패: ${uploadResult.error}`); } } else { toast.success("상세도면이 추가되었습니다"); } resetForm(); onComplete(); } 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 ? (

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

여러 파일을 한 번에 업로드할 수 있습니다

) : (

{files.length}개 파일 선택됨

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

)}
{/* 선택된 파일 목록 */} {files.length > 0 && (
{files.map((file, index) => (
{file.name} {(file.size / 1024).toFixed(2)} KB
))}
)}
); }