From c54a2445b6285d06c0ce3afa1cd3aa6aecf6de94 Mon Sep 17 00:00:00 2001
From: joonhoekim <26rote@gmail.com>
Date: Mon, 24 Nov 2025 20:13:50 +0900
Subject: (김준회) dolce rebuild: i18n 지원
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 lib/dolce/dialogs/b4-bulk-upload-dialog.tsx | 109 +++++++++++++++-------------
 1 file changed, 57 insertions(+), 52 deletions(-)

(limited to 'lib/dolce/dialogs/b4-bulk-upload-dialog.tsx')

diff --git a/lib/dolce/dialogs/b4-bulk-upload-dialog.tsx b/lib/dolce/dialogs/b4-bulk-upload-dialog.tsx
index 75b221da..1be7f226 100644
--- a/lib/dolce/dialogs/b4-bulk-upload-dialog.tsx
+++ b/lib/dolce/dialogs/b4-bulk-upload-dialog.tsx
@@ -22,6 +22,7 @@ import {
 import { FolderOpen, Loader2, ChevronRight, ChevronLeft, CheckCircle2 } from "lucide-react";
 import { toast } from "sonner";
 import { Progress } from "@/components/ui/progress";
+import { useTranslation } from "@/i18n/client";
 import {
   validateB4FileName,
   B4UploadValidationDialog,
@@ -44,20 +45,9 @@ interface B4BulkUploadDialogProps {
   userEmail: string;
   vendorCode: string;
   onUploadComplete?: () => void;
+  lng: string;
 }
 
-// B4 GTT 옵션
-const B4_DRAWING_USAGE_OPTIONS = [
-  { value: "REC", label: "RECEIVE (입수용)" },
-];
-
-const B4_REGISTER_KIND_OPTIONS: Record<string, Array<{ value: string; label: string }>> = {
-  REC: [
-    { value: "RECP", label: "Pre. 도면입수" },
-    { value: "RECW", label: "Working 도면입수" },
-  ],
-};
-
 type UploadStep = "settings" | "files" | "validation" | "uploading" | "complete";
 
 export function B4BulkUploadDialog({
@@ -69,7 +59,9 @@ export function B4BulkUploadDialog({
   userEmail,
   vendorCode,
   onUploadComplete,
+  lng,
 }: B4BulkUploadDialogProps) {
+  const { t } = useTranslation(lng, "dolce");
   const [currentStep, setCurrentStep] = useState<UploadStep>("settings");
   const [drawingUsage, setDrawingUsage] = useState<string>("REC");
   const [registerKind, setRegisterKind] = useState<string>("");
@@ -81,6 +73,18 @@ export function B4BulkUploadDialog({
   const [uploadProgress, setUploadProgress] = useState(0);
   const [uploadResult, setUploadResult] = useState<B4BulkUploadResult | null>(null);
 
+  // B4 GTT 옵션 (코드 번역 유틸리티 사용)
+  const drawingUsageOptions = [
+    { value: "REC", label: t("bulkUpload.drawingUsageReceive") },
+  ];
+
+  const registerKindOptionsMap: Record<string, Array<{ value: string; label: string }>> = {
+    REC: [
+      { value: "RECP", label: t("bulkUpload.registerKindRecP") },
+      { value: "RECW", label: t("bulkUpload.registerKindRecW") },
+    ],
+  };
+
   // 다이얼로그 닫을 때 초기화
   React.useEffect(() => {
     if (!open) {
@@ -105,12 +109,12 @@ export function B4BulkUploadDialog({
     const newFiles = files.filter((f) => !existingNames.has(f.name));
 
     if (newFiles.length === 0) {
-      toast.error("이미 선택된 파일입니다");
+      toast.error(t("bulkUpload.duplicateFileError"));
       return;
     }
 
     setSelectedFiles((prev) => [...prev, ...newFiles]);
-    toast.success(`${newFiles.length}개 파일이 선택되었습니다`);
+    toast.success(t("bulkUpload.filesSelectedSuccess", { count: newFiles.length }));
   };
 
   // Drag & Drop 핸들러
@@ -153,7 +157,7 @@ export function B4BulkUploadDialog({
   // 1단계 완료 (설정)
   const handleSettingsNext = () => {
     if (!registerKind) {
-      toast.error("등록종류를 선택하세요");
+      toast.error(t("bulkUpload.selectRegisterKindError"));
       return;
     }
     setCurrentStep("files");
@@ -162,7 +166,7 @@ export function B4BulkUploadDialog({
   // 2단계 완료 (파일 선택)
   const handleFilesNext = () => {
     if (selectedFiles.length === 0) {
-      toast.error("파일을 선택해주세요");
+      toast.error(t("bulkUpload.selectFilesError"));
       return;
     }
     setCurrentStep("validation");
@@ -220,7 +224,7 @@ export function B4BulkUploadDialog({
           return {
             ...parseResult,
             mappingStatus: "not_found" as const,
-            error: "DOLCE 시스템에서 도면을 찾을 수 없습니다",
+            error: t("validation.notFound"),
           };
         }
 
@@ -229,7 +233,7 @@ export function B4BulkUploadDialog({
           return {
             ...parseResult,
             mappingStatus: "not_found" as const,
-            error: "해당 도면번호가 프로젝트에 등록되어 있지 않습니다",
+            error: t("validation.notRegistered"),
           };
         }
 
@@ -238,7 +242,7 @@ export function B4BulkUploadDialog({
           return {
             ...parseResult,
             mappingStatus: "not_found" as const,
-            error: "도면입수(GTT Deliverables)인 도면만 업로드 가능합니다",
+            error: t("validation.notGttDeliverables"),
           };
         }
 
@@ -256,7 +260,7 @@ export function B4BulkUploadDialog({
     } catch (error) {
       console.error("검증 실패:", error);
       toast.error(
-        error instanceof Error ? error.message : "검증 중 오류가 발생했습니다"
+        error instanceof Error ? error.message : t("bulkUpload.validationError")
       );
     }
   };
@@ -393,11 +397,11 @@ export function B4BulkUploadDialog({
 
       setUploadResult(result);
       setCurrentStep("complete");
-      toast.success(`${successCount}/${validFiles.length}개 파일 업로드 완료`);
+      toast.success(t("bulkUpload.uploadSuccessToast", { successCount, total: validFiles.length }));
     } catch (error) {
       console.error("[B4 일괄 업로드] 실패:", error);
       toast.error(
-        error instanceof Error ? error.message : "업로드 중 오류가 발생했습니다"
+        error instanceof Error ? error.message : t("bulkUpload.uploadError")
       );
       setCurrentStep("files");
     } finally {
@@ -406,7 +410,7 @@ export function B4BulkUploadDialog({
   };
 
   const registerKindOptions = drawingUsage
-    ? B4_REGISTER_KIND_OPTIONS[drawingUsage] || []
+    ? registerKindOptionsMap[drawingUsage] || []
     : [];
 
   const handleDrawingUsageChange = (value: string) => {
@@ -419,11 +423,11 @@ export function B4BulkUploadDialog({
       <Dialog open={open} onOpenChange={onOpenChange}>
         <DialogContent className="max-w-2xl">
           <DialogHeader>
-            <DialogTitle>B4 일괄 업로드</DialogTitle>
+            <DialogTitle>{t("bulkUpload.title")}</DialogTitle>
             <DialogDescription>
-              {currentStep === "settings" && "업로드 설정을 선택하세요"}
-              {currentStep === "files" && "파일명 형식: [버림] [DrawingNo] [RevNo].[확장자] (예: testfile GTT-DE-007 R01.pdf)"}
-              {currentStep === "validation" && "파일 검증 중..."}
+              {currentStep === "settings" && t("bulkUpload.stepSettings")}
+              {currentStep === "files" && t("bulkUpload.stepFiles")}
+              {currentStep === "validation" && t("bulkUpload.stepValidation")}
             </DialogDescription>
           </DialogHeader>
 
@@ -433,13 +437,13 @@ export function B4BulkUploadDialog({
               <>
                 {/* 도면용도 선택 */}
                 <div className="space-y-2">
-                  <Label>도면용도 (Drawing Usage) *</Label>
+                  <Label>{t("bulkUpload.drawingUsage")} *</Label>
                   <Select value={drawingUsage} onValueChange={handleDrawingUsageChange}>
                     <SelectTrigger>
-                      <SelectValue placeholder="도면용도를 선택하세요" />
+                      <SelectValue placeholder={t("bulkUpload.drawingUsagePlaceholder")} />
                     </SelectTrigger>
                     <SelectContent>
-                      {B4_DRAWING_USAGE_OPTIONS.map((option) => (
+                      {drawingUsageOptions.map((option) => (
                         <SelectItem key={option.value} value={option.value}>
                           {option.label}
                         </SelectItem>
@@ -450,14 +454,14 @@ export function B4BulkUploadDialog({
 
                 {/* 등록종류 선택 */}
                 <div className="space-y-2">
-                  <Label>등록종류 (Register Kind) *</Label>
+                  <Label>{t("bulkUpload.registerKind")} *</Label>
                   <Select
                     value={registerKind}
                     onValueChange={setRegisterKind}
                     disabled={!drawingUsage}
                   >
                     <SelectTrigger>
-                      <SelectValue placeholder="등록종류를 선택하세요" />
+                      <SelectValue placeholder={t("bulkUpload.registerKindPlaceholder")} />
                     </SelectTrigger>
                     <SelectContent>
                       {registerKindOptions.map((option) => (
@@ -468,7 +472,7 @@ export function B4BulkUploadDialog({
                     </SelectContent>
                   </Select>
                   <p className="text-sm text-muted-foreground">
-                    선택한 등록종류가 모든 파일에 적용됩니다
+                    {t("bulkUpload.registerKindNote")}
                   </p>
                 </div>
               </>
@@ -514,11 +518,11 @@ export function B4BulkUploadDialog({
                       }`}
                     >
                       {isDragging
-                        ? "파일을 여기에 놓으세요"
-                        : "클릭하거나 파일을 드래그하여 선택"}
+                        ? t("bulkUpload.fileDropHere")
+                        : t("bulkUpload.fileSelectArea")}
                     </p>
                     <p className="text-xs text-muted-foreground mt-1">
-                      PDF, DOC, DOCX, XLS, XLSX, DWG, DXF, ZIP
+                      {t("bulkUpload.fileTypes")}
                     </p>
                   </label>
                 </div>
@@ -528,14 +532,14 @@ export function B4BulkUploadDialog({
                   <div className="border rounded-lg p-4">
                     <div className="flex items-center justify-between mb-3">
                       <h4 className="text-sm font-medium">
-                        선택된 파일 ({selectedFiles.length}개)
+                        {t("bulkUpload.selectedFiles", { count: selectedFiles.length })}
                       </h4>
                       <Button
                         variant="ghost"
                         size="sm"
                         onClick={() => setSelectedFiles([])}
                       >
-                        전체 제거
+                        {t("bulkUpload.removeAll")}
                       </Button>
                     </div>
                     <div className="max-h-60 overflow-y-auto space-y-2">
@@ -555,7 +559,7 @@ export function B4BulkUploadDialog({
                             size="sm"
                             onClick={() => handleRemoveFile(index)}
                           >
-                            제거
+                            {t("bulkUpload.removeFile")}
                           </Button>
                         </div>
                       ))}
@@ -570,7 +574,7 @@ export function B4BulkUploadDialog({
               <div className="flex flex-col items-center justify-center py-12">
                 <Loader2 className="h-12 w-12 animate-spin text-primary mb-4" />
                 <p className="text-sm text-muted-foreground">
-                  파일 검증 중입니다...
+                  {t("bulkUpload.validating")}
                 </p>
               </div>
             )}
@@ -580,21 +584,21 @@ export function B4BulkUploadDialog({
               <div className="space-y-6 py-8">
                 <div className="flex flex-col items-center">
                   <Loader2 className="h-12 w-12 animate-spin text-primary mb-4" />
-                  <h3 className="text-lg font-semibold mb-2">파일 업로드 중...</h3>
+                  <h3 className="text-lg font-semibold mb-2">{t("bulkUpload.uploading")}</h3>
                   <p className="text-sm text-muted-foreground">
-                    잠시만 기다려주세요
+                    {t("bulkUpload.uploadingWait")}
                   </p>
                 </div>
                 <div className="space-y-2">
                   <div className="flex justify-between text-sm">
-                    <span>진행률</span>
+                    <span>{t("bulkUpload.uploadProgress")}</span>
                     <span>{uploadProgress}%</span>
                   </div>
                   <Progress value={uploadProgress} className="h-2" />
                   {/* 90% 이상일 때 추가 안내 메시지 */}
                   {uploadProgress >= 90 && uploadProgress < 100 && (
                     <p className="text-xs text-muted-foreground text-center pt-2">
-                      서버에서 DOLCE API로 전송 중입니다...
+                      {t("bulkUpload.uploadingToServer")}
                     </p>
                   )}
                 </div>
@@ -606,16 +610,16 @@ export function B4BulkUploadDialog({
               <div className="space-y-6 py-8">
                 <div className="flex flex-col items-center">
                   <CheckCircle2 className="h-16 w-16 text-green-500 mb-4" />
-                  <h3 className="text-lg font-semibold mb-2">업로드 완료!</h3>
+                  <h3 className="text-lg font-semibold mb-2">{t("bulkUpload.uploadComplete")}</h3>
                   <p className="text-sm text-muted-foreground">
-                    {uploadResult.successCount}개 파일이 성공적으로 업로드되었습니다
+                    {t("bulkUpload.uploadSuccessMessage", { count: uploadResult.successCount })}
                   </p>
                 </div>
                 
                 {uploadResult.failCount && uploadResult.failCount > 0 && (
                   <div className="bg-yellow-50 dark:bg-yellow-950/30 border border-yellow-200 dark:border-yellow-800 rounded-lg p-4">
                     <p className="text-sm text-yellow-800 dark:text-yellow-200">
-                      {uploadResult.failCount}개 파일 업로드 실패
+                      {t("bulkUpload.uploadFailMessage", { count: uploadResult.failCount })}
                     </p>
                   </div>
                 )}
@@ -627,7 +631,7 @@ export function B4BulkUploadDialog({
                       onUploadComplete?.();
                     }}
                   >
-                    확인
+                    {t("bulkUpload.confirmButton")}
                   </Button>
                 </div>
               </div>
@@ -643,13 +647,13 @@ export function B4BulkUploadDialog({
                   variant="outline"
                   onClick={() => onOpenChange(false)}
                 >
-                  취소
+                  {t("bulkUpload.cancelButton")}
                 </Button>
                 <Button
                   onClick={handleSettingsNext}
                   disabled={!registerKind}
                 >
-                  다음
+                  {t("bulkUpload.nextButton")}
                   <ChevronRight className="ml-2 h-4 w-4" />
                 </Button>
               </>
@@ -662,13 +666,13 @@ export function B4BulkUploadDialog({
                   onClick={() => setCurrentStep("settings")}
                 >
                   <ChevronLeft className="mr-2 h-4 w-4" />
-                  이전
+                  {t("bulkUpload.previousButton")}
                 </Button>
                 <Button
                   onClick={handleFilesNext}
                   disabled={selectedFiles.length === 0}
                 >
-                  검증 시작
+                  {t("bulkUpload.validateButton")}
                   <ChevronRight className="ml-2 h-4 w-4" />
                 </Button>
               </>
@@ -685,6 +689,7 @@ export function B4BulkUploadDialog({
         validationResults={validationResults}
         onConfirmUpload={handleConfirmUpload}
         isUploading={isUploading}
+        lng={lng}
       />
     </>
   );
-- 
cgit v1.2.3

