From b43b1d92ef3d7e57b5df5cd72f75dc3a1c3f1c7a Mon Sep 17 00:00:00 2001
From: joonhoekim <26rote@gmail.com>
Date: Thu, 27 Nov 2025 13:48:44 +0900
Subject: (김준회) swp 파일 개수 컬럼 삭제 (API에서 주지 않는 데이터), dolce
 rebuild 에서 상태값 수정, bulk upload MatchBatchFileDwg API 사용해 Edit 으로
 보내도록 수정 (Category, status 하드코딩 값 넣어주도록 처리), 상세도면, 파일
 추가시 확인 다이얼로그 추가
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../add-and-modify-detail-drawing-dialog.tsx       | 415 ++++++++++++---------
 1 file changed, 244 insertions(+), 171 deletions(-)

(limited to 'lib/dolce/dialogs/add-and-modify-detail-drawing-dialog.tsx')

diff --git a/lib/dolce/dialogs/add-and-modify-detail-drawing-dialog.tsx b/lib/dolce/dialogs/add-and-modify-detail-drawing-dialog.tsx
index 673d48d6..0253228b 100644
--- a/lib/dolce/dialogs/add-and-modify-detail-drawing-dialog.tsx
+++ b/lib/dolce/dialogs/add-and-modify-detail-drawing-dialog.tsx
@@ -72,6 +72,8 @@ export function AddAndModifyDetailDrawingDialog({
   const [comment, setComment] = useState<string>("");
   const [isSubmitting, setIsSubmitting] = useState(false);
 
+  const [showConfirmation, setShowConfirmation] = useState(false);
+
   // Edit 모드일 때 초기값 설정
   useEffect(() => {
     if (mode === "edit" && detailDrawing && open) {
@@ -155,9 +157,10 @@ export function AddAndModifyDetailDrawingDialog({
     setRevisionError("");
     setComment("");
     clearFiles();
+    setShowConfirmation(false);
   };
 
-  // 제출
+  // 제출 (확인 단계 포함)
   const handleSubmit = async () => {
     // 유효성 검사
     if (!registerKind) {
@@ -200,6 +203,12 @@ export function AddAndModifyDetailDrawingDialog({
       return;
     }
 
+    // 확인 단계가 아니면 확인 단계로 이동
+    if (!showConfirmation) {
+      setShowConfirmation(true);
+      return;
+    }
+
     try {
       setIsSubmitting(true);
 
@@ -212,7 +221,7 @@ export function AddAndModifyDetailDrawingDialog({
           dwgList: [
             {
               Mode: "ADD",
-              Status: "Submitted",
+              Status: "Standby",
               RegisterId: 0,
               ProjectNo: drawing.ProjectNo,
               Discipline: drawing.Discipline,
@@ -329,8 +338,12 @@ export function AddAndModifyDetailDrawingDialog({
   };
 
   const handleCancel = () => {
-    resetForm();
-    onOpenChange(false);
+    if (showConfirmation) {
+      setShowConfirmation(false);
+    } else {
+      resetForm();
+      onOpenChange(false);
+    }
   };
 
   // DrawingUsage가 변경되면 RegisterKind 초기화
@@ -355,219 +368,279 @@ export function AddAndModifyDetailDrawingDialog({
 
   return (
     <Dialog open={open} onOpenChange={onOpenChange}>
-      <DialogContent className="max-w-2xl">
+      <DialogContent className="max-w-2xl max-h-[85vh] overflow-y-auto">
         <DialogHeader>
           <DialogTitle>
-            {mode === "edit" ? t("editDetailDialog.title") : t("addDetailDialog.title")}
+            {showConfirmation 
+              ? t("addDetailDialog.confirmTitle", "확인") 
+              : (mode === "edit" ? t("editDetailDialog.title") : t("addDetailDialog.title"))
+            }
           </DialogTitle>
         </DialogHeader>
 
-        <div className="space-y-6">
-          {/* 도면 정보 표시 */}
-          {mode === "add" && drawing && (
+        {showConfirmation ? (
+          <div className="space-y-6">
             <Alert>
               <Info className="h-4 w-4" />
               <AlertDescription>
-                <div className="font-medium">{drawing.DrawingNo}</div>
-                <div className="text-sm text-muted-foreground">{drawing.DrawingName}</div>
+                {t("addDetailDialog.confirmMessage", "아래 내용으로 제출하시겠습니까?")}
               </AlertDescription>
             </Alert>
-          )}
 
-          {mode === "edit" && detailDrawing && (
-            <Alert>
-              <Info className="h-4 w-4" />
-              <AlertDescription>
-                <div className="font-medium">{detailDrawing.DrawingNo} - Rev. {detailDrawing.DrawingRevNo}</div>
-                <div className="text-sm text-muted-foreground">{detailDrawing.DrawingName}</div>
-              </AlertDescription>
-            </Alert>
-          )}
+            <div className="grid grid-cols-2 gap-4 border rounded-lg p-4 bg-muted/20">
+              <div className="space-y-1">
+                <Label className="text-xs text-muted-foreground">{t("addDetailDialog.drawingUsageLabel")}</Label>
+                <p className="text-sm font-medium">
+                  {drawingUsageOptions.find(opt => opt.value === drawingUsage)?.label || drawingUsage}
+                </p>
+              </div>
+              <div className="space-y-1">
+                <Label className="text-xs text-muted-foreground">{t("addDetailDialog.registerKindLabel")}</Label>
+                <p className="text-sm font-medium">
+                  {registerKindOptions.find(opt => opt.value === registerKind)?.label || registerKind}
+                </p>
+              </div>
+              {drawingUsage !== "CMT" && (
+                <div className="space-y-1">
+                  <Label className="text-xs text-muted-foreground">{t("addDetailDialog.revisionLabel")}</Label>
+                  <p className="text-sm font-medium">{revision}</p>
+                </div>
+              )}
+              <div className="space-y-1 col-span-2">
+                <Label className="text-xs text-muted-foreground">{t("addDetailDialog.commentLabel")}</Label>
+                <p className="text-sm">{comment || "-"}</p>
+              </div>
+            </div>
+
+            {files.length > 0 && (
+              <div className="space-y-2">
+                <Label>{t("addDetailDialog.selectedFiles", { count: files.length })}</Label>
+                <div className="max-h-60 overflow-y-auto space-y-2 border rounded-lg p-2">
+                  {isSubmitting ? (
+                    <FileUploadProgressList fileProgresses={fileProgresses} />
+                  ) : (
+                    files.map((file, index) => (
+                      <div key={index} className="flex items-center gap-2 p-2 rounded bg-muted/50 text-sm">
+                        <FileIcon className="h-4 w-4 text-muted-foreground shrink-0" />
+                        <span className="truncate flex-1">{file.name}</span>
+                        <span className="text-xs text-muted-foreground whitespace-nowrap">
+                          {(file.size / 1024 / 1024).toFixed(2)} MB
+                        </span>
+                      </div>
+                    ))
+                  )}
+                </div>
+              </div>
+            )}
+          </div>
+        ) : (
+          <div className="space-y-6">
+            {/* 도면 정보 표시 */}
+            {mode === "add" && drawing && (
+              <Alert>
+                <Info className="h-4 w-4" />
+                <AlertDescription>
+                  <div className="font-medium">{drawing.DrawingNo}</div>
+                  <div className="text-sm text-muted-foreground">{drawing.DrawingName}</div>
+                </AlertDescription>
+              </Alert>
+            )}
+
+            {mode === "edit" && detailDrawing && (
+              <Alert>
+                <Info className="h-4 w-4" />
+                <AlertDescription>
+                  <div className="font-medium">{detailDrawing.DrawingNo} - Rev. {detailDrawing.DrawingRevNo}</div>
+                  <div className="text-sm text-muted-foreground">{detailDrawing.DrawingName}</div>
+                </AlertDescription>
+              </Alert>
+            )}
 
-          {/* 도면용도 선택 (Add 모드에서만 표시) */}
-          {mode === "add" && (
+            {/* 도면용도 선택 (Add 모드에서만 표시) */}
+            {mode === "add" && (
+              <div className="space-y-2">
+                <Label>{t("addDetailDialog.drawingUsageLabel")}</Label>
+                <Select value={drawingUsage} onValueChange={handleDrawingUsageChange}>
+                  <SelectTrigger>
+                    <SelectValue placeholder={t("addDetailDialog.drawingUsagePlaceholder")} />
+                  </SelectTrigger>
+                  <SelectContent>
+                    {drawingUsageOptions.map((option) => (
+                      <SelectItem key={option.value} value={option.value}>
+                        {option.label}
+                      </SelectItem>
+                    ))}
+                  </SelectContent>
+                </Select>
+              </div>
+            )}
+
+            {/* 등록종류 선택 */}
             <div className="space-y-2">
-              <Label>{t("addDetailDialog.drawingUsageLabel")}</Label>
-              <Select value={drawingUsage} onValueChange={handleDrawingUsageChange}>
+              <Label>{t("addDetailDialog.registerKindLabel")}</Label>
+              <Select
+                value={registerKind}
+                onValueChange={setRegisterKind}
+                disabled={mode === "add" && !drawingUsage}
+              >
                 <SelectTrigger>
-                  <SelectValue placeholder={t("addDetailDialog.drawingUsagePlaceholder")} />
+                  <SelectValue placeholder={t("addDetailDialog.registerKindPlaceholder")} />
                 </SelectTrigger>
                 <SelectContent>
-                  {drawingUsageOptions.map((option) => (
+                  {registerKindOptions.map((option) => (
                     <SelectItem key={option.value} value={option.value}>
                       {option.label}
                     </SelectItem>
                   ))}
                 </SelectContent>
               </Select>
+              {revisionRule && (
+                <p className="text-sm text-muted-foreground">
+                  {t("addDetailDialog.revisionFormatPrefix")}{revisionRule}
+                </p>
+              )}
             </div>
-          )}
-
-          {/* 등록종류 선택 */}
-          <div className="space-y-2">
-            <Label>{t("addDetailDialog.registerKindLabel")}</Label>
-            <Select
-              value={registerKind}
-              onValueChange={setRegisterKind}
-              disabled={mode === "add" && !drawingUsage}
-            >
-              <SelectTrigger>
-                <SelectValue placeholder={t("addDetailDialog.registerKindPlaceholder")} />
-              </SelectTrigger>
-              <SelectContent>
-                {registerKindOptions.map((option) => (
-                  <SelectItem key={option.value} value={option.value}>
-                    {option.label}
-                  </SelectItem>
-                ))}
-              </SelectContent>
-            </Select>
-            {revisionRule && (
-              <p className="text-sm text-muted-foreground">
-                {t("addDetailDialog.revisionFormatPrefix")}{revisionRule}
-              </p>
+
+            {/* Revision 입력 */}
+            {drawingUsage !== "CMT" && (
+              <div className="space-y-2">
+                <Label>{t("addDetailDialog.revisionLabel")}</Label>
+                <Input
+                  value={revision}
+                  onChange={(e) => handleRevisionChange(e.target.value)}
+                  placeholder={t("addDetailDialog.revisionPlaceholder")}
+                  disabled={!registerKind}
+                  className={revisionError ? "border-red-500 focus-visible:ring-red-500" : ""}
+                />
+                {revisionError && (
+                  <p className="text-sm text-red-500 flex items-center gap-1">
+                    {revisionError}
+                  </p>
+                )}
+                {!revisionError && revision && (
+                  <p className="text-sm text-green-600 flex items-center gap-1">
+                    {t("addDetailDialog.revisionValid")}
+                  </p>
+                )}
+              </div>
             )}
-          </div>
 
-          {/* Revision 입력 */}
-          {drawingUsage !== "CMT" && (
+            {/* Comment 입력 */}
             <div className="space-y-2">
-              <Label>{t("addDetailDialog.revisionLabel")}</Label>
-              <Input
-                value={revision}
-                onChange={(e) => handleRevisionChange(e.target.value)}
-                placeholder={t("addDetailDialog.revisionPlaceholder")}
-                disabled={!registerKind}
-                className={revisionError ? "border-red-500 focus-visible:ring-red-500" : ""}
+              <Label>{t("addDetailDialog.commentLabel")}</Label>
+              <Textarea
+                value={comment}
+                onChange={(e) => setComment(e.target.value)}
+                placeholder={t("addDetailDialog.commentPlaceholder")}
+                rows={3}
+                className="resize-none"
               />
-              {revisionError && (
-                <p className="text-sm text-red-500 flex items-center gap-1">
-                  {revisionError}
-                </p>
-              )}
-              {!revisionError && revision && (
-                <p className="text-sm text-green-600 flex items-center gap-1">
-                  {t("addDetailDialog.revisionValid")}
-                </p>
-              )}
+              <p className="text-xs text-muted-foreground">
+                {t("addDetailDialog.commentMaxLength")}
+              </p>
             </div>
-          )}
-
-          {/* Comment 입력 */}
-          <div className="space-y-2">
-            <Label>{t("addDetailDialog.commentLabel")}</Label>
-            <Textarea
-              value={comment}
-              onChange={(e) => setComment(e.target.value)}
-              placeholder={t("addDetailDialog.commentPlaceholder")}
-              rows={3}
-              className="resize-none"
-            />
-            <p className="text-xs text-muted-foreground">
-              {t("addDetailDialog.commentMaxLength")}
-            </p>
-          </div>
 
-          {/* 파일 업로드 (Add 모드에서만 표시) */}
-          {mode === "add" && (
-            <div className="space-y-2">
-              <Label>{t("addDetailDialog.attachmentLabel")}</Label>
-            <div
-              {...getRootProps()}
-              className={`
-                border-2 border-dashed rounded-lg p-8 text-center cursor-pointer
-                transition-colors
-                ${isDragActive ? "border-primary bg-primary/5" : "border-muted-foreground/25"}
-                ${files.length > 0 ? "py-4" : ""}
-              `}
-            >
-              <input {...getInputProps()} />
-              {files.length === 0 ? (
-                <div className="space-y-2">
-                  <Upload className="h-8 w-8 mx-auto text-muted-foreground" />
-                  <div>
+            {/* 파일 업로드 (Add 모드에서만 표시) */}
+            {mode === "add" && (
+              <div className="space-y-2">
+                <Label>{t("addDetailDialog.attachmentLabel")}</Label>
+              <div
+                {...getRootProps()}
+                className={`
+                  border-2 border-dashed rounded-lg p-8 text-center cursor-pointer
+                  transition-colors
+                  ${isDragActive ? "border-primary bg-primary/5" : "border-muted-foreground/25"}
+                  ${files.length > 0 ? "py-4" : ""}
+                `}
+              >
+                <input {...getInputProps()} />
+                {files.length === 0 ? (
+                  <div className="space-y-2">
+                    <Upload className="h-8 w-8 mx-auto text-muted-foreground" />
+                    <div>
+                      <p className="text-sm font-medium">
+                        {t("addDetailDialog.dragDropText")}
+                      </p>
+                      <p className="text-xs text-muted-foreground">
+                        {t("addDetailDialog.fileInfo")}
+                      </p>
+                    </div>
+                  </div>
+                ) : (
+                  <div className="space-y-2">
                     <p className="text-sm font-medium">
-                      {t("addDetailDialog.dragDropText")}
+                      {t("addDetailDialog.filesSelected", { count: files.length })}
                     </p>
                     <p className="text-xs text-muted-foreground">
-                      {t("addDetailDialog.fileInfo")}
+                      {t("addDetailDialog.addMoreFiles")}
                     </p>
                   </div>
-                </div>
-              ) : (
-                <div className="space-y-2">
-                  <p className="text-sm font-medium">
-                    {t("addDetailDialog.filesSelected", { count: files.length })}
-                  </p>
-                  <p className="text-xs text-muted-foreground">
-                    {t("addDetailDialog.addMoreFiles")}
-                  </p>
-                </div>
-              )}
-            </div>
+                )}
+              </div>
 
-            {/* 선택된 파일 목록 */}
-            {files.length > 0 && (
-              <div className="space-y-2 mt-4">
-                {isSubmitting ? (
-                  // 업로드 중: 진행도 표시
-                  <FileUploadProgressList fileProgresses={fileProgresses} />
-                ) : (
-                  // 대기 중: 삭제 버튼 표시
-                  <>
-                    <div className="flex items-center justify-between mb-2">
-                      <h4 className="text-sm font-medium">
-                        {t("addDetailDialog.selectedFiles", { count: files.length })}
-                      </h4>
-                      <Button
-                        variant="ghost"
-                        size="sm"
-                        onClick={clearFiles}
-                      >
-                        {t("addDetailDialog.removeAll")}
-                      </Button>
-                    </div>
-                    <div className="max-h-60 overflow-y-auto space-y-2">
-                      {files.map((file, index) => (
-                        <div
-                          key={index}
-                          className="flex items-center gap-2 p-2 border rounded-lg bg-muted/50"
+              {/* 선택된 파일 목록 */}
+              {files.length > 0 && (
+                <div className="space-y-2 mt-4">
+                  {isSubmitting ? (
+                    // 업로드 중: 진행도 표시
+                    <FileUploadProgressList fileProgresses={fileProgresses} />
+                  ) : (
+                    // 대기 중: 삭제 버튼 표시
+                    <>
+                      <div className="flex items-center justify-between mb-2">
+                        <h4 className="text-sm font-medium">
+                          {t("addDetailDialog.selectedFiles", { count: files.length })}
+                        </h4>
+                        <Button
+                          variant="ghost"
+                          size="sm"
+                          onClick={clearFiles}
                         >
-                          <FileIcon className="h-4 w-4 text-muted-foreground shrink-0" />
-                          <div className="flex-1 min-w-0">
-                            <p className="text-sm truncate">{file.name}</p>
-                            <p className="text-xs text-muted-foreground">
-                              {(file.size / 1024 / 1024).toFixed(2)} MB
-                            </p>
-                          </div>
-                          <Button
-                            variant="ghost"
-                            size="sm"
-                            onClick={() => removeFile(index)}
+                          {t("addDetailDialog.removeAll")}
+                        </Button>
+                      </div>
+                      <div className="max-h-60 overflow-y-auto space-y-2">
+                        {files.map((file, index) => (
+                          <div
+                            key={index}
+                            className="flex items-center gap-2 p-2 border rounded-lg bg-muted/50"
                           >
-                            <X className="h-4 w-4" />
-                          </Button>
-                        </div>
-                      ))}
-                    </div>
-                  </>
-                )}
+                            <FileIcon className="h-4 w-4 text-muted-foreground shrink-0" />
+                            <div className="flex-1 min-w-0">
+                              <p className="text-sm truncate">{file.name}</p>
+                              <p className="text-xs text-muted-foreground">
+                                {(file.size / 1024 / 1024).toFixed(2)} MB
+                              </p>
+                            </div>
+                            <Button
+                              variant="ghost"
+                              size="sm"
+                              onClick={() => removeFile(index)}
+                            >
+                              <X className="h-4 w-4" />
+                            </Button>
+                          </div>
+                        ))}
+                      </div>
+                    </>
+                  )}
+                </div>
+              )}
               </div>
             )}
-            </div>
-          )}
-        </div>
+          </div>
+        )}
 
         <DialogFooter>
           <Button variant="outline" onClick={handleCancel} disabled={isSubmitting}>
-            {t("addDetailDialog.cancelButton")}
+            {showConfirmation ? t("addDetailDialog.backButton", "뒤로") : t("addDetailDialog.cancelButton")}
           </Button>
           <Button onClick={handleSubmit} disabled={isSubmitting || !isFormValid}>
             {isSubmitting 
               ? t("addDetailDialog.processingButton") 
-              : mode === "edit" 
-                ? t("editDetailDialog.updateButton") 
-                : t("addDetailDialog.addButton")
+              : showConfirmation
+                ? t("addDetailDialog.confirmSubmit", "제출")
+                : t("addDetailDialog.nextButton", "다음")
             }
           </Button>
         </DialogFooter>
-- 
cgit v1.2.3

