From 95984e67b8d57fbe1431fcfedf3bb682f28416b3 Mon Sep 17 00:00:00 2001
From: joonhoekim <26rote@gmail.com>
Date: Thu, 27 Nov 2025 17:48:28 +0900
Subject: (김준회) swp 영문 처리
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 lib/swp/table/swp-inbox-document-detail-dialog.tsx | 80 +++++++++++-----------
 1 file changed, 40 insertions(+), 40 deletions(-)

(limited to 'lib/swp/table/swp-inbox-document-detail-dialog.tsx')

diff --git a/lib/swp/table/swp-inbox-document-detail-dialog.tsx b/lib/swp/table/swp-inbox-document-detail-dialog.tsx
index ca7fcf1b..7f814267 100644
--- a/lib/swp/table/swp-inbox-document-detail-dialog.tsx
+++ b/lib/swp/table/swp-inbox-document-detail-dialog.tsx
@@ -35,7 +35,7 @@ interface SwpInboxDocumentDetailDialogProps {
   userId: string;
 }
 
-// 리비전별 그룹 타입
+// Group type by revision
 interface RevisionGroup {
   revNo: string;
   stage: string;
@@ -43,7 +43,7 @@ interface RevisionGroup {
   totalFiles: number;
 }
 
-// Activity별 그룹 타입 (activity가 null일 수 있음)
+// Group type by Activity (activity can be null)
 interface ActivityGroup {
   actvNo: string | null;
   files: SwpFileApiResponse[];
@@ -59,7 +59,7 @@ export function SwpInboxDocumentDetailDialog({
   const [expandedActivities, setExpandedActivities] = useState<Set<string>>(new Set());
   const [isAllExpanded, setIsAllExpanded] = useState(true);
 
-  // 파일들을 리비전 > Activity 구조로 그룹핑
+  // Group files into Revision > Activity structure
   const revisionGroups = useMemo(() => {
     if (!document) return [];
 
@@ -78,7 +78,7 @@ export function SwpInboxDocumentDetailDialog({
     revMap.forEach((revFiles, revKey) => {
       const [revNo, stage] = revKey.split("|");
 
-      // Activity별로 그룹핑 (null 가능)
+      // Group by Activity (nullable)
       const actMap = new Map<string | null, SwpFileApiResponse[]>();
       
       revFiles.forEach((file) => {
@@ -94,7 +94,7 @@ export function SwpInboxDocumentDetailDialog({
         activities.push({ actvNo, files });
       });
 
-      // Activity가 없는 것을 먼저, 있는 것을 나중에 정렬
+      // Sort: No Activity first, then with Activity
       activities.sort((a, b) => {
         if (a.actvNo === null && b.actvNo !== null) return -1;
         if (a.actvNo !== null && b.actvNo === null) return 1;
@@ -110,11 +110,11 @@ export function SwpInboxDocumentDetailDialog({
       });
     });
 
-    // 리비전 번호로 정렬 (최신이 위로)
+    // Sort by revision number (newest first)
     return result.sort((a, b) => b.revNo.localeCompare(a.revNo));
   }, [document]);
 
-  // Dialog가 열릴 때 모두 펼치기
+  // Expand all when dialog opens
   React.useEffect(() => {
     if (open && revisionGroups.length > 0) {
       const allRevKeys = new Set<string>();
@@ -160,15 +160,15 @@ export function SwpInboxDocumentDetailDialog({
     });
   };
 
-  // 일괄 열기/닫기
+  // Toggle all
   const handleToggleAll = () => {
     if (isAllExpanded) {
-      // 모두 닫기
+      // Collapse all
       setExpandedRevisions(new Set());
       setExpandedActivities(new Set());
       setIsAllExpanded(false);
     } else {
-      // 모두 열기
+      // Expand all
       const allRevKeys = new Set<string>();
       const allActKeys = new Set<string>();
       
@@ -191,27 +191,27 @@ export function SwpInboxDocumentDetailDialog({
   const handleCancelFile = async (boxSeq: string, actvSeq: string, fileName: string) => {
     try {
       await cancelVendorFile(boxSeq, actvSeq);
-      toast.success(`파일 취소 완료: ${fileName}`);
+      toast.success(`File cancelled: ${fileName}`);
       
-      // Dialog를 닫고 부모 컴포넌트가 새로고침하도록 함
+      // Close dialog and trigger parent refresh
       onOpenChange(false);
     } catch (error) {
-      console.error("파일 취소 실패:", error);
-      toast.error("파일 취소에 실패했습니다");
+      console.error("Failed to cancel file:", error);
+      toast.error("Failed to cancel file");
     }
   };
 
   const handleDownloadFile = async (fileName: string, ownDocNo: string) => {
     try {
-      toast.info("파일 다운로드 중...");
+      toast.info("Downloading file...");
       const result = await downloadVendorFile(projNo, ownDocNo, fileName);
       
       if (!result.success || !result.data) {
-        toast.error(result.error || "파일 다운로드 실패");
+        toast.error(result.error || "File download failed");
         return;
       }
 
-      // Blob 생성 및 다운로드
+      // Create Blob and download
       const blob = new Blob([Buffer.from(result.data)], { type: result.mimeType });
       const url = URL.createObjectURL(blob);
       const link = window.document.createElement("a");
@@ -222,10 +222,10 @@ export function SwpInboxDocumentDetailDialog({
       window.document.body.removeChild(link);
       URL.revokeObjectURL(url);
 
-      toast.success(`파일 다운로드 완료: ${fileName}`);
+      toast.success(`File downloaded: ${fileName}`);
     } catch (error) {
-      console.error("파일 다운로드 실패:", error);
-      toast.error("파일 다운로드에 실패했습니다");
+      console.error("File download failed:", error);
+      toast.error("Failed to download file");
     }
   };
 
@@ -233,7 +233,7 @@ export function SwpInboxDocumentDetailDialog({
     <Dialog open={open} onOpenChange={onOpenChange}>
       <DialogContent className="max-w-6xl max-h-[90vh] overflow-y-auto">
         <DialogHeader>
-          <DialogTitle>업로드 파일 상세</DialogTitle>
+          <DialogTitle>Uploaded File Details</DialogTitle>
           {document && (
             <DialogDescription>
               {document.ownDocNo}
@@ -243,30 +243,30 @@ export function SwpInboxDocumentDetailDialog({
 
         {document && (
           <div className="space-y-4">
-            {/* 문서 정보 */}
+            {/* Document Info */}
             <div className="grid grid-cols-1 md:grid-cols-4 gap-4 p-4 bg-muted/30 rounded-lg">
               <div>
                 <span className="text-sm font-semibold">OWN_DOC_NO:</span>
                 <div className="text-sm font-mono">{document.ownDocNo}</div>
               </div>
               <div>
-                <span className="text-sm font-semibold">최신 스테이지:</span>
+                <span className="text-sm font-semibold">Latest Stage:</span>
                 <div className="text-sm">{document.latestStage || "-"}</div>
               </div>
               <div>
-                <span className="text-sm font-semibold">최신 리비전:</span>
+                <span className="text-sm font-semibold">Latest Revision:</span>
                 <div className="text-sm">{document.latestRevNo || "-"}</div>
               </div>
               <div>
-                <span className="text-sm font-semibold">최신 REV 파일:</span>
-                <div className="text-sm">{document.latestRevFileCount}개</div>
+                <span className="text-sm font-semibold">Latest REV Files:</span>
+                <div className="text-sm">{document.latestRevFileCount}</div>
               </div>
             </div>
 
-            {/* 리비전 및 액티비티 트리 */}
+            {/* Revision and Activity Tree */}
             {revisionGroups.length > 0 ? (
               <div className="space-y-2">
-                {/* 일괄 열기/닫기 버튼 */}
+                {/* Toggle All Button */}
                 <div className="flex justify-end">
                   <Button
                     variant="outline"
@@ -276,12 +276,12 @@ export function SwpInboxDocumentDetailDialog({
                     {isAllExpanded ? (
                       <>
                         <ChevronDown className="h-4 w-4 mr-2" />
-                        일괄 닫기
+                        Collapse All
                       </>
                     ) : (
                       <>
                         <ChevronRight className="h-4 w-4 mr-2" />
-                        일괄 열기
+                        Expand All
                       </>
                     )}
                   </Button>
@@ -292,7 +292,7 @@ export function SwpInboxDocumentDetailDialog({
 
                   return (
                     <div key={revKey} className="border rounded-lg">
-                      {/* 리비전 헤더 */}
+                      {/* Revision Header */}
                       <div
                         className="flex items-center justify-between p-3 bg-muted/50 cursor-pointer hover:bg-muted"
                         onClick={() => toggleRevision(revKey)}
@@ -314,12 +314,12 @@ export function SwpInboxDocumentDetailDialog({
                             {revision.stage}
                           </Badge>
                           <span className="text-sm text-muted-foreground">
-                            {revision.activities.length}개 그룹 / {revision.totalFiles}개 파일
+                            {revision.activities.length} Groups / {revision.totalFiles} Files
                           </span>
                         </div>
                       </div>
 
-                      {/* 액티비티 목록 (또는 Activity 없는 파일들) */}
+                      {/* Activity List (or files without Activity) */}
                       {isRevExpanded && (
                         <div className="p-2 space-y-2">
                           {revision.activities.map((activity) => {
@@ -328,7 +328,7 @@ export function SwpInboxDocumentDetailDialog({
 
                             return (
                               <div key={actKey} className="border rounded-md">
-                                {/* 액티비티 헤더 */}
+                                {/* Activity Header */}
                                 <div
                                   className="flex items-center justify-between p-2 bg-muted/30 cursor-pointer hover:bg-muted/50"
                                   onClick={() => toggleActivity(actKey)}
@@ -350,16 +350,16 @@ export function SwpInboxDocumentDetailDialog({
                                       </>
                                     ) : (
                                       <Badge variant="outline" className="bg-gray-100 text-gray-800">
-                                        Activity 없음
+                                        No Activity
                                       </Badge>
                                     )}
                                     <span className="text-xs text-muted-foreground">
-                                      {activity.files.length}개 파일
+                                      {activity.files.length} Files
                                     </span>
                                   </div>
                                 </div>
 
-                                {/* 파일 목록 */}
+                                {/* File List */}
                                 {isActExpanded && (
                                   <div className="p-2 space-y-1">
                                     {activity.files.map((file, idx) => (
@@ -398,7 +398,7 @@ export function SwpInboxDocumentDetailDialog({
                                               onClick={() => handleCancelFile(file.BOX_SEQ!, file.ACTV_SEQ!, file.FILE_NM)}
                                             >
                                               <XCircle className="h-4 w-4 mr-1" />
-                                              취소
+                                              Cancel
                                             </Button>
                                           )}
                                           {file.FLD_PATH && (
@@ -408,7 +408,7 @@ export function SwpInboxDocumentDetailDialog({
                                               onClick={() => handleDownloadFile(file.FILE_NM, document.ownDocNo)}
                                             >
                                               <Download className="h-4 w-4 mr-1" />
-                                              다운로드
+                                              Download
                                             </Button>
                                           )}
                                         </div>
@@ -428,7 +428,7 @@ export function SwpInboxDocumentDetailDialog({
             ) : (
               <div className="p-8 text-center text-muted-foreground">
                 <AlertCircle className="h-12 w-12 mx-auto mb-2 opacity-50" />
-                <p>파일 정보가 없습니다</p>
+                <p>No file information available</p>
               </div>
             )}
           </div>
-- 
cgit v1.2.3

