From 4614210aa9878922cfa1e424ce677ef893a1b6b2 Mon Sep 17 00:00:00 2001
From: dujinkim <dujin.kim@dtsolution.co.kr>
Date: Mon, 29 Sep 2025 13:31:40 +0000
Subject: (대표님) 구매 권한설정, data room 등
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 components/file-manager/FileManager.tsx | 1215 ++++++++++++++++++++-----------
 1 file changed, 779 insertions(+), 436 deletions(-)

(limited to 'components/file-manager/FileManager.tsx')

diff --git a/components/file-manager/FileManager.tsx b/components/file-manager/FileManager.tsx
index 483ef773..587beb22 100644
--- a/components/file-manager/FileManager.tsx
+++ b/components/file-manager/FileManager.tsx
@@ -1,12 +1,12 @@
 'use client';
 
 import React, { useState, useEffect, useCallback } from 'react';
-import { 
-  Folder, 
-  File, 
-  FolderPlus, 
-  Upload, 
-  Trash2, 
+import {
+  Folder,
+  File,
+  FolderPlus,
+  Upload,
+  Trash2,
   Edit2,
   Download,
   Share2,
@@ -93,6 +93,8 @@ import {
 } from "@/components/ui/file-list";
 import { decryptWithServerAction } from '@/components/drm/drmUtils';
 import { Progress } from '@/components/ui/progress';
+// Import the secure viewer component
+import { SecurePDFViewer } from './SecurePDFViewer';
 
 interface FileItem {
   id: string;
@@ -126,12 +128,12 @@ interface FileManagerProps {
   projectId: string;
 }
 
-// 카테고리별 아이콘과 색상
+// Category configuration with icons and colors
 const categoryConfig = {
-  public: { icon: Globe, color: 'text-green-500', label: '공개' },
-  restricted: { icon: Eye, color: 'text-yellow-500', label: '제한' },
-  confidential: { icon: Lock, color: 'text-red-500', label: '기밀' },
-  internal: { icon: Shield, color: 'text-blue-500', label: '내부' },
+  public: { icon: Globe, color: 'text-green-500', label: 'Public' },
+  restricted: { icon: Eye, color: 'text-yellow-500', label: 'Restricted' },
+  confidential: { icon: Lock, color: 'text-red-500', label: 'Confidential' },
+  internal: { icon: Shield, color: 'text-blue-500', label: 'Internal' },
 };
 
 // Tree Item Component
@@ -143,172 +145,183 @@ const TreeItem: React.FC<{
   onToggleExpand: (id: string) => void;
   onSelectItem: (id: string) => void;
   onDoubleClick: (item: FileItem) => void;
+  onView: (item: FileItem) => void;
   onDownload: (item: FileItem) => void;
   onDownloadFolder: (item: FileItem) => void;
   onDelete: (ids: string[]) => void;
   onShare: (item: FileItem) => void;
   onRename: (item: FileItem) => void;
   isInternalUser: boolean;
-}> = ({ 
-  item, 
-  level, 
-  expandedFolders, 
-  selectedItems, 
-  onToggleExpand, 
+}> = ({
+  item,
+  level,
+  expandedFolders,
+  selectedItems,
+  onToggleExpand,
   onSelectItem,
   onDoubleClick,
+  onView,
   onDownload,
   onDownloadFolder,
   onDelete,
   onShare,
   onRename,
-  isInternalUser 
+  isInternalUser
 }) => {
-  const hasChildren = item.type === 'folder' && item.children && item.children.length > 0;
-  const isExpanded = expandedFolders.has(item.id);
-  const isSelected = selectedItems.has(item.id);
-  const CategoryIcon = categoryConfig[item.category].icon;
-  const categoryColor = categoryConfig[item.category].color;
-  const categoryLabel = categoryConfig[item.category].label;
+    const hasChildren = item.type === 'folder' && item.children && item.children.length > 0;
+    const isExpanded = expandedFolders.has(item.id);
+    const isSelected = selectedItems.has(item.id);
+    const CategoryIcon = categoryConfig[item.category].icon;
+    const categoryColor = categoryConfig[item.category].color;
+    const categoryLabel = categoryConfig[item.category].label;
 
-  const formatFileSize = (bytes?: number) => {
-    if (!bytes) return '-';
-    const sizes = ['B', 'KB', 'MB', 'GB'];
-    const i = Math.floor(Math.log(bytes) / Math.log(1024));
-    return `${(bytes / Math.pow(1024, i)).toFixed(1)} ${sizes[i]}`;
-  };
+    const formatFileSize = (bytes?: number) => {
+      if (!bytes) return '-';
+      const sizes = ['B', 'KB', 'MB', 'GB'];
+      const i = Math.floor(Math.log(bytes) / Math.log(1024));
+      return `${(bytes / Math.pow(1024, i)).toFixed(1)} ${sizes[i]}`;
+    };
 
-  return (
-    <>
-      <div
-        className={cn(
-          "flex items-center p-2 rounded-lg cursor-pointer transition-colors",
-          "hover:bg-accent",
-          isSelected && "bg-accent"
-        )}
-        style={{ paddingLeft: `${level * 24 + 8}px` }}
-        onClick={() => onSelectItem(item.id)}
-        onDoubleClick={() => onDoubleClick(item)}
-      >
-        <div className="flex items-center mr-2">
-          {item.type === 'folder' && (
-            <button
-              onClick={(e) => {
-                e.stopPropagation();
-                onToggleExpand(item.id);
-              }}
-              className="p-0.5 hover:bg-gray-200 rounded"
-            >
-              {isExpanded ? (
-                <ChevronDown className="h-4 w-4" />
-              ) : (
-                <ChevronRight className="h-4 w-4" />
-              )}
-            </button>
+    return (
+      <>
+        <div
+          className={cn(
+            "flex items-center p-2 rounded-lg cursor-pointer transition-colors",
+            "hover:bg-accent",
+            isSelected && "bg-accent"
           )}
-          {item.type === 'file' && (
-            <div className="w-5" />
-          )}
-        </div>
-        
-        {item.type === 'folder' ? (
-          <Folder className="h-5 w-5 text-blue-500 mr-2" />
-        ) : (
-          <File className="h-5 w-5 text-gray-500 mr-2" />
-        )}
-        
-        <span className="flex-1">{item.name}</span>
-        
-        <Badge variant="outline" className="mr-2">
-          <CategoryIcon className={cn("h-3 w-3 mr-1", categoryColor)} />
-          {categoryLabel}
-        </Badge>
-        
-        <span className="text-sm text-muted-foreground mr-4">
-          {formatFileSize(item.size)}
-        </span>
-        <span className="text-sm text-muted-foreground mr-2">
-          {new Date(item.updatedAt).toLocaleDateString()}
-        </span>
-        
-        <DropdownMenu>
-          <DropdownMenuTrigger asChild>
-            <Button variant="ghost" size="sm">
-              <MoreVertical className="h-4 w-4" />
-            </Button>
-          </DropdownMenuTrigger>
-          <DropdownMenuContent>
-            {item.type === 'file' && item.permissions?.canDownload && (
-              <DropdownMenuItem onClick={() => onDownload(item)}>
-                <Download className="h-4 w-4 mr-2" />
-                다운로드
-              </DropdownMenuItem>
-            )}
-            
+          style={{ paddingLeft: `${level * 24 + 8}px` }}
+          onClick={() => onSelectItem(item.id)}
+          onDoubleClick={() => onDoubleClick(item)}
+        >
+          <div className="flex items-center mr-2">
             {item.type === 'folder' && (
-              <DropdownMenuItem onClick={() => onDownloadFolder(item)}>
-                <Download className="h-4 w-4 mr-2" />
-                폴더 전체 다운로드
-              </DropdownMenuItem>
-            )}
-            
-            {isInternalUser && (
-              <>
-                <DropdownMenuItem onClick={() => onShare(item)}>
-                  <Share2 className="h-4 w-4 mr-2" />
-                  공유
-                </DropdownMenuItem>
-                
-                {item.permissions?.canEdit && (
-                  <DropdownMenuItem onClick={() => onRename(item)}>
-                    <Edit2 className="h-4 w-4 mr-2" />
-                    이름 변경
-                  </DropdownMenuItem>
+              <button
+                onClick={(e) => {
+                  e.stopPropagation();
+                  onToggleExpand(item.id);
+                }}
+                className="p-0.5 hover:bg-gray-200 rounded"
+              >
+                {isExpanded ? (
+                  <ChevronDown className="h-4 w-4" />
+                ) : (
+                  <ChevronRight className="h-4 w-4" />
                 )}
-              </>
+              </button>
             )}
-            
-            {item.permissions?.canDelete && (
-              <>
-                <DropdownMenuSeparator />
-                <DropdownMenuItem
-                  className="text-destructive"
-                  onClick={() => onDelete([item.id])}
-                >
-                  <Trash2 className="h-4 w-4 mr-2" />
-                  삭제
-                </DropdownMenuItem>
-              </>
+            {item.type === 'file' && (
+              <div className="w-5" />
             )}
-          </DropdownMenuContent>
-        </DropdownMenu>
-      </div>
-      
-      {item.type === 'folder' && isExpanded && item.children && (
-        <div>
-          {item.children.map((child) => (
-            <TreeItem
-              key={child.id}
-              item={child}
-              level={level + 1}
-              expandedFolders={expandedFolders}
-              selectedItems={selectedItems}
-              onToggleExpand={onToggleExpand}
-              onSelectItem={onSelectItem}
-              onDoubleClick={onDoubleClick}
-              onDownload={onDownload}
-              onDownloadFolder={onDownloadFolder}
-              onDelete={onDelete}
-              onShare={onShare}
-              onRename={onRename}
-              isInternalUser={isInternalUser}
-            />
-          ))}
+          </div>
+
+          {item.type === 'folder' ? (
+            <Folder className="h-5 w-5 text-blue-500 mr-2" />
+          ) : (
+            <File className="h-5 w-5 text-gray-500 mr-2" />
+          )}
+
+          <span className="flex-1">{item.name}</span>
+
+          <Badge variant="outline" className="mr-2">
+            <CategoryIcon className={cn("h-3 w-3 mr-1", categoryColor)} />
+            {categoryLabel}
+          </Badge>
+
+          <span className="text-sm text-muted-foreground mr-4">
+            {formatFileSize(item.size)}
+          </span>
+          <span className="text-sm text-muted-foreground mr-2">
+            {new Date(item.updatedAt).toLocaleDateString()}
+          </span>
+
+          <DropdownMenu>
+            <DropdownMenuTrigger asChild>
+              <Button variant="ghost" size="sm">
+                <MoreVertical className="h-4 w-4" />
+              </Button>
+            </DropdownMenuTrigger>
+            <DropdownMenuContent>
+              {item.type === 'file' && (
+                <>
+                  <DropdownMenuItem onClick={() => onView(item)}>
+                    <Eye className="h-4 w-4 mr-2" />
+                    View
+                  </DropdownMenuItem>
+                  {item.permissions?.canDownload && (
+                    <DropdownMenuItem onClick={() => onDownload(item)}>
+                      <Download className="h-4 w-4 mr-2" />
+                      Download
+                    </DropdownMenuItem>
+                  )}
+                </>
+              )}
+
+              {item.type === 'folder' && (
+                <DropdownMenuItem onClick={() => onDownloadFolder(item)}>
+                  <Download className="h-4 w-4 mr-2" />
+                  Download Folder
+                </DropdownMenuItem>
+              )}
+
+              {isInternalUser && (
+                <>
+                  <DropdownMenuItem onClick={() => onShare(item)}>
+                    <Share2 className="h-4 w-4 mr-2" />
+                    Share
+                  </DropdownMenuItem>
+
+                  {item.permissions?.canEdit && (
+                    <DropdownMenuItem onClick={() => onRename(item)}>
+                      <Edit2 className="h-4 w-4 mr-2" />
+                      Rename
+                    </DropdownMenuItem>
+                  )}
+                </>
+              )}
+
+              {item.permissions?.canDelete && (
+                <>
+                  <DropdownMenuSeparator />
+                  <DropdownMenuItem
+                    className="text-destructive"
+                    onClick={() => onDelete([item.id])}
+                  >
+                    <Trash2 className="h-4 w-4 mr-2" />
+                    Delete
+                  </DropdownMenuItem>
+                </>
+              )}
+            </DropdownMenuContent>
+          </DropdownMenu>
         </div>
-      )}
-    </>
-  );
-};
+
+        {item.type === 'folder' && isExpanded && item.children && (
+          <div>
+            {item.children.map((child) => (
+              <TreeItem
+                key={child.id}
+                item={child}
+                level={level + 1}
+                expandedFolders={expandedFolders}
+                selectedItems={selectedItems}
+                onToggleExpand={onToggleExpand}
+                onSelectItem={onSelectItem}
+                onDoubleClick={onDoubleClick}
+                onView={onView}
+                onDownload={onDownload}
+                onDownloadFolder={onDownloadFolder}
+                onDelete={onDelete}
+                onShare={onShare}
+                onRename={onRename}
+                isInternalUser={isInternalUser}
+              />
+            ))}
+          </div>
+        )}
+      </>
+    );
+  };
 
 export function FileManager({ projectId }: FileManagerProps) {
   const { data: session } = useSession();
@@ -321,19 +334,23 @@ export function FileManager({ projectId }: FileManagerProps) {
   const [viewMode, setViewMode] = useState<'grid' | 'list'>('list');
   const [searchQuery, setSearchQuery] = useState('');
   const [loading, setLoading] = useState(false);
-  
-  // 업로드 상태
+
+  console.log(items,"items")
+
+  // Upload states
   const [uploadDialogOpen, setUploadDialogOpen] = useState(false);
   const [uploadingFiles, setUploadingFiles] = useState<UploadingFile[]>([]);
   const [uploadCategory, setUploadCategory] = useState<string>('confidential');
-  
-  // 다이얼로그 상태
+
+  // Dialog states
   const [folderDialogOpen, setFolderDialogOpen] = useState(false);
   const [shareDialogOpen, setShareDialogOpen] = useState(false);
   const [permissionDialogOpen, setPermissionDialogOpen] = useState(false);
   const [renameDialogOpen, setRenameDialogOpen] = useState(false);
-  
-  // 다이얼로그 데이터
+  const [viewerDialogOpen, setViewerDialogOpen] = useState(false);
+  const [viewerFileUrl, setViewerFileUrl] = useState<string | null>(null);
+
+  // Dialog data
   const [dialogValue, setDialogValue] = useState('');
   const [selectedCategory, setSelectedCategory] = useState<string>('confidential');
   const [selectedFile, setSelectedFile] = useState<FileItem | null>(null);
@@ -343,76 +360,76 @@ export function FileManager({ projectId }: FileManagerProps) {
     expiresAt: '',
     maxDownloads: '',
   });
-  
+
   const { toast } = useToast();
 
-  // 사용자가 내부 사용자인지 확인
+  // Check if user is internal
   const isInternalUser = session?.user?.domain !== 'partners';
 
-  // 트리 구조 생성 함수
+  // Build tree structure function
   const buildTree = (flatItems: FileItem[]): FileItem[] => {
     const itemMap = new Map<string, FileItem>();
     const rootItems: FileItem[] = [];
-    
-    // 모든 아이템을 맵에 저장 (children 초기화)
+
+    // Store all items in map (initialize children)
     flatItems.forEach(item => {
       itemMap.set(item.id, { ...item, children: [] });
     });
-    
-    // 부모-자식 관계 설정
+
+    // Set parent-child relationships
     flatItems.forEach(item => {
       const mappedItem = itemMap.get(item.id)!;
-      
+
       if (!item.parentId) {
-        // parentId가 없으면 루트 아이템
+        // No parentId means root item
         rootItems.push(mappedItem);
       } else {
-        // parentId가 있으면 부모의 children에 추가
+        // Has parentId, add to parent's children
         const parent = itemMap.get(item.parentId);
         if (parent) {
           if (!parent.children) parent.children = [];
           parent.children.push(mappedItem);
         } else {
-          // 부모를 찾을 수 없으면 루트로 처리
+          // Can't find parent, treat as root
           rootItems.push(mappedItem);
         }
       }
     });
-    
+
     return rootItems;
   };
 
-  // 파일 목록 가져오기
+  // Fetch file list
   const fetchItems = useCallback(async () => {
     setLoading(true);
     try {
       const params = new URLSearchParams();
-      
-      // 트리 뷰일 때는 전체 목록을 가져옴
+
+      // For tree view, get entire list
       if (viewMode === 'list') {
         params.append('viewMode', 'tree');
-        // 트리 뷰에서도 현재 경로 정보는 유지 (하이라이팅 등에 사용)
+        // Keep current path info for tree view (used for highlighting, etc.)
         if (currentParentId) params.append('currentParentId', currentParentId);
       } else {
-        // 그리드 뷰일 때는 현재 폴더의 내용만 가져옴
+        // For grid view, only get current folder contents
         if (currentParentId) params.append('parentId', currentParentId);
       }
-      
+
       const response = await fetch(`/api/data-room/${projectId}?${params}`);
       if (!response.ok) throw new Error('Failed to fetch files');
-      
+
       const data = await response.json();
       setItems(data);
-      
-      // 트리 구조 생성
+
+      // Build tree structure
       if (viewMode === 'list') {
         const tree = buildTree(data);
         setTreeItems(tree);
       }
     } catch (error) {
       toast({
-        title: '오류',
-        description: '파일을 불러오는데 실패했습니다.',
+        title: 'Error',
+        description: 'Failed to load files.',
         variant: 'destructive',
       });
     } finally {
@@ -424,7 +441,7 @@ export function FileManager({ projectId }: FileManagerProps) {
     fetchItems();
   }, [fetchItems]);
 
-  // 폴더 생성
+  // Create folder
   const createFolder = async () => {
     try {
       const response = await fetch(`/api/data-room/${projectId}`, {
@@ -446,66 +463,66 @@ export function FileManager({ projectId }: FileManagerProps) {
       await fetchItems();
       setFolderDialogOpen(false);
       setDialogValue('');
-      
+
       toast({
-        title: '성공',
-        description: '폴더가 생성되었습니다.',
+        title: 'Success',
+        description: 'Folder created successfully.',
       });
     } catch (error: any) {
       toast({
-        title: '오류',
-        description: error.message || '폴더 생성에 실패했습니다.',
+        title: 'Error',
+        description: error.message || 'Failed to create folder.',
         variant: 'destructive',
       });
     }
   };
 
-  // 파일 업로드 처리
+  // Handle file upload
   const handleFileUpload = async (files: FileList | File[]) => {
     const fileArray = Array.from(files);
-    
-    // 업로드 파일 목록 초기화
+
+    // Initialize uploading file list
     const newUploadingFiles: UploadingFile[] = fileArray.map(file => ({
       file,
       progress: 0,
       status: 'pending' as const
     }));
-    
+
     setUploadingFiles(newUploadingFiles);
-    
-    // 각 파일 업로드 처리
+
+    // Process each file upload
     for (let i = 0; i < fileArray.length; i++) {
       const file = fileArray[i];
-      
+
       try {
-        // 상태 업데이트: 업로드 중
-        setUploadingFiles(prev => prev.map((f, idx) => 
+        // Update status: uploading
+        setUploadingFiles(prev => prev.map((f, idx) =>
           idx === i ? { ...f, status: 'uploading', progress: 20 } : f
         ));
 
-        // DRM 복호화
-        setUploadingFiles(prev => prev.map((f, idx) => 
+        // DRM decryption
+        setUploadingFiles(prev => prev.map((f, idx) =>
           idx === i ? { ...f, status: 'processing', progress: 40 } : f
         ));
-        
+
         const decryptedData = await decryptWithServerAction(file);
-        
-        // FormData 생성
+
+        // Create FormData
         const formData = new FormData();
         const blob = new Blob([decryptedData], { type: file.type });
         formData.append('file', blob, file.name);
         formData.append('category', uploadCategory);
-        formData.append('fileSize', file.size.toString()); // 파일 크기 전달
+        formData.append('fileSize', file.size.toString()); // Pass file size
         if (currentParentId) {
           formData.append('parentId', currentParentId);
         }
-        
-        // 업로드 진행률 업데이트
-        setUploadingFiles(prev => prev.map((f, idx) => 
+
+        // Update upload progress
+        setUploadingFiles(prev => prev.map((f, idx) =>
           idx === i ? { ...f, progress: 60 } : f
         ));
 
-        // API 호출
+        // API call
         const response = await fetch(`/api/data-room/${projectId}/upload`, {
           method: 'POST',
           body: formData,
@@ -515,99 +532,99 @@ export function FileManager({ projectId }: FileManagerProps) {
           const error = await response.json();
           throw new Error(error.error || 'Upload failed');
         }
-        
-        // 성공
-        setUploadingFiles(prev => prev.map((f, idx) => 
+
+        // Success
+        setUploadingFiles(prev => prev.map((f, idx) =>
           idx === i ? { ...f, status: 'completed', progress: 100 } : f
         ));
-        
+
       } catch (error: any) {
-        // 실패
-        setUploadingFiles(prev => prev.map((f, idx) => 
-          idx === i ? { 
-            ...f, 
-            status: 'error', 
-            error: error.message || '업로드 실패'
+        // Failure
+        setUploadingFiles(prev => prev.map((f, idx) =>
+          idx === i ? {
+            ...f,
+            status: 'error',
+            error: error.message || 'Upload failed'
           } : f
         ));
       }
     }
-    
-    // 모든 업로드 완료 후 목록 새로고침
+
+    // Refresh list after all uploads complete
     await fetchItems();
-    
-    // 성공한 파일이 있으면 토스트 표시
+
+    // Show toast if any files succeeded
     const successCount = newUploadingFiles.filter(f => f.status === 'completed').length;
     if (successCount > 0) {
       toast({
-        title: '업로드 완료',
-        description: `${successCount}개 파일이 업로드되었습니다.`,
+        title: 'Upload Complete',
+        description: `${successCount} file(s) uploaded successfully.`,
       });
     }
   };
 
-  // 폴더 다운로드
+  // Download folder
   const downloadFolder = async (folder: FileItem) => {
     if (folder.type !== 'folder') return;
-    
+
     try {
       toast({
-        title: '권한 확인 중',
-        description: '폴더 내 파일들의 다운로드 권한을 확인하고 있습니다...',
+        title: 'Checking Permissions',
+        description: 'Verifying download permissions for folder contents...',
       });
 
-      // 폴더 다운로드 API 호출
+      // Call folder download API
       const response = await fetch(`/api/data-room/${projectId}/download-folder/${folder.id}`, {
         method: 'GET',
       });
-      
+
       if (!response.ok) {
         const error = await response.json();
-        
-        // 권한이 없는 파일이 있는 경우 상세 정보 제공
+
+        // If there are files without permission, provide details
         if (error.unauthorizedFiles) {
           toast({
-            title: '다운로드 권한 부족',
-            description: `${error.unauthorizedFiles.length}개 파일에 대한 권한이 없습니다: ${error.unauthorizedFiles.join(', ')}`,
+            title: 'Insufficient Permissions',
+            description: `No permission for ${error.unauthorizedFiles.length} file(s): ${error.unauthorizedFiles.join(', ')}`,
             variant: 'destructive',
           });
           return;
         }
-        
-        throw new Error(error.error || '폴더 다운로드 실패');
+
+        throw new Error(error.error || 'Folder download failed');
       }
 
       const blob = await response.blob();
       const url = window.URL.createObjectURL(blob);
-      
-      // 폴더명을 파일명에 포함
+
+      // Include folder name in filename
       const timestamp = new Date().toISOString().replace(/[:.]/g, '-').slice(0, 19);
       const fileName = `${folder.name}_${timestamp}.zip`;
-      
+
       const a = document.createElement('a');
       a.href = url;
       a.download = fileName;
       document.body.appendChild(a);
       a.click();
-      
+
       window.URL.revokeObjectURL(url);
       document.body.removeChild(a);
 
       toast({
-        title: '다운로드 완료',
-        description: `${folder.name} 폴더가 다운로드되었습니다.`,
+        title: 'Download Complete',
+        description: `${folder.name} folder downloaded successfully.`,
       });
 
     } catch (error: any) {
       toast({
-        title: '오류',
-        description: error.message || '폴더 다운로드에 실패했습니다.',
+        title: 'Error',
+        description: error.message || 'Failed to download folder.',
         variant: 'destructive',
       });
     }
   };
 
-  // 파일 공유
+  // Share file
   const shareFile = async () => {
     if (!selectedFile) return;
 
@@ -626,45 +643,45 @@ export function FileManager({ projectId }: FileManagerProps) {
       }
 
       const data = await response.json();
-      
-      // 공유 링크 복사
+
+      // Copy share link to clipboard
       await navigator.clipboard.writeText(data.shareUrl);
-      
+
       toast({
-        title: '공유 링크 생성됨',
-        description: '링크가 클립보드에 복사되었습니다.',
+        title: 'Share Link Created',
+        description: 'Link copied to clipboard.',
       });
-      
+
       setShareDialogOpen(false);
       setSelectedFile(null);
     } catch (error) {
       toast({
-        title: '오류',
-        description: '공유 링크 생성에 실패했습니다.',
+        title: 'Error',
+        description: 'Failed to create share link.',
         variant: 'destructive',
       });
     }
   };
 
-  // 다중 파일 다운로드
+  // Download multiple files
   const downloadMultipleFiles = async (itemIds: string[]) => {
-    // 선택된 파일들 중 실제 파일만 필터링 (폴더 제외)
-    const filesToDownload = items.filter(item => 
-      itemIds.includes(item.id) && 
-      item.type === 'file' && 
-      item.permissions?.canDownload
+    // Filter only actual files (exclude folders) that can be downloaded
+    const filesToDownload = items.filter(item =>
+      itemIds.includes(item.id) &&
+      item.type === 'file' &&
+      item.permissions?.canDownload === 'true'
     );
 
     if (filesToDownload.length === 0) {
       toast({
-        title: '알림',
-        description: '다운로드 가능한 파일이 없습니다.',
+        title: 'Notice',
+        description: 'No downloadable files selected.',
         variant: 'default',
       });
       return;
     }
 
-    // 단일 파일인 경우 일반 다운로드 사용
+    // Use regular download for single file
     if (filesToDownload.length === 1) {
       await downloadFile(filesToDownload[0]);
       return;
@@ -672,98 +689,119 @@ export function FileManager({ projectId }: FileManagerProps) {
 
     try {
       toast({
-        title: '다운로드 준비 중',
-        description: `${filesToDownload.length}개 파일을 압축하고 있습니다...`,
+        title: 'Preparing Download',
+        description: `Compressing ${filesToDownload.length} files...`,
       });
 
-      // 여러 파일 다운로드 API 호출
+      // Call multiple files download API
       const response = await fetch(`/api/data-room/${projectId}/download-multiple`, {
         method: 'POST',
         headers: { 'Content-Type': 'application/json' },
         body: JSON.stringify({ fileIds: filesToDownload.map(f => f.id) })
       });
-      
+
       if (!response.ok) {
-        throw new Error('다운로드 실패');
+        throw new Error('Download failed');
       }
 
       const blob = await response.blob();
       const url = window.URL.createObjectURL(blob);
-      
-      // 현재 날짜시간을 파일명에 포함
+
+      // Include timestamp in filename
       const timestamp = new Date().toISOString().replace(/[:.]/g, '-').slice(0, 19);
       const fileName = `files_${timestamp}.zip`;
-      
+
       const a = document.createElement('a');
       a.href = url;
       a.download = fileName;
       document.body.appendChild(a);
       a.click();
-      
+
       window.URL.revokeObjectURL(url);
       document.body.removeChild(a);
 
       toast({
-        title: '다운로드 완료',
-        description: `${filesToDownload.length}개 파일이 다운로드되었습니다.`,
+        title: 'Download Complete',
+        description: `${filesToDownload.length} files downloaded successfully.`,
       });
 
     } catch (error) {
-      console.error('다중 다운로드 오류:', error);
-      
-      // 실패 시 개별 다운로드 옵션 제공
+      console.error('Multiple download error:', error);
+
+      // Offer individual downloads on failure
       toast({
-        title: '압축 다운로드 실패',
-        description: '개별 다운로드를 시도하시겠습니까?',
+        title: 'Batch Download Failed',
+        description: 'Would you like to try individual downloads?',
         action: (
           <Button
             size="sm"
             variant="outline"
             onClick={() => {
-              // 개별 다운로드 실행
+              // Execute individual downloads
               filesToDownload.forEach(async (file, index) => {
-                // 다운로드 간격을 두어 브라우저 부하 감소
+                // Add delay between downloads to reduce browser load
                 setTimeout(() => downloadFile(file), index * 500);
               });
             }}
           >
-            개별 다운로드
+            Download Individually
           </Button>
         ),
       });
     }
   };
 
-  // 파일 다운로드
+  // View file with PDFTron
+  const viewFile = async (file: FileItem) => {
+    try {
+ 
+
+      
+      setViewerFileUrl(file.filePath);
+      setSelectedFile(file);
+      setViewerDialogOpen(true);
+
+
+
+    } catch (error) {
+      toast({
+        title: 'Error',
+        description: 'Failed to open file for viewing.',
+        variant: 'destructive',
+      });
+    }
+  };
+
+  // Download file
   const downloadFile = async (file: FileItem) => {
     try {
       const response = await fetch(`/api/data-room/${projectId}/${file.id}/download`);
-      
+
       if (!response.ok) {
         throw new Error('Download failed');
       }
 
       const blob = await response.blob();
       const url = window.URL.createObjectURL(blob);
-      
+
       const a = document.createElement('a');
       a.href = url;
       a.download = file.name;
       document.body.appendChild(a);
       a.click();
-      
+
       window.URL.revokeObjectURL(url);
       document.body.removeChild(a);
     } catch (error) {
       toast({
-        title: '오류',
-        description: '다운로드에 실패했습니다.',
+        title: 'Error',
+        description: 'Download failed.',
         variant: 'destructive',
       });
     }
   };
 
-  // 파일 삭제
+  // Delete files
   const deleteItems = async (itemIds: string[]) => {
     try {
       await Promise.all(
@@ -774,27 +812,106 @@ export function FileManager({ projectId }: FileManagerProps) {
 
       await fetchItems();
       setSelectedItems(new Set());
-      
+
+      toast({
+        title: 'Success',
+        description: 'Selected items deleted successfully.',
+      });
+    } catch (error) {
+      toast({
+        title: 'Error',
+        description: 'Failed to delete items.',
+        variant: 'destructive',
+      });
+    }
+  };
+
+  // Rename item
+  const renameItem = async () => {
+    if (!selectedFile) return;
+
+    try {
+      const response = await fetch(
+        `/api/data-room/${projectId}/${selectedFile.id}`,
+        {
+          method: 'PATCH',
+          headers: { 'Content-Type': 'application/json' },
+          body: JSON.stringify({ name: dialogValue }),
+        }
+      );
+
+      if (!response.ok) {
+        throw new Error('Failed to rename');
+      }
+
+      await fetchItems();
+      setRenameDialogOpen(false);
+      setSelectedFile(null);
+      setDialogValue('');
+
+      toast({
+        title: 'Success',
+        description: 'Item renamed successfully.',
+      });
+    } catch (error) {
+      toast({
+        title: 'Error',
+        description: 'Failed to rename item.',
+        variant: 'destructive',
+      });
+    }
+  };
+
+  // Change category
+  const changeCategory = async (
+    itemId: string,
+    newCategory: string,
+    applyToChildren: boolean = false
+  ) => {
+    try {
+      const response = await fetch(
+        `/api/data-room/${projectId}/${itemId}`,
+        {
+          method: 'PATCH',
+          headers: { 'Content-Type': 'application/json' },
+          body: JSON.stringify({
+            category: newCategory,
+            applyToChildren
+          }),
+        }
+      );
+
+      if (!response.ok) {
+        throw new Error('Failed to change category');
+      }
+
+      await fetchItems();
+
       toast({
-        title: '성공',
-        description: '선택한 항목이 삭제되었습니다.',
+        title: 'Success',
+        description: 'Category updated successfully.',
       });
     } catch (error) {
       toast({
-        title: '오류',
-        description: '삭제에 실패했습니다.',
+        title: 'Error',
+        description: 'Failed to change category.',
         variant: 'destructive',
       });
     }
   };
 
-  // 폴더 더블클릭 처리
+  // Category change dialog states
+  const [categoryDialogOpen, setCategoryDialogOpen] = useState(false);
+  const [applyToChildren, setApplyToChildren] = useState(false);
+  const [newCategory, setNewCategory] = useState('confidential');
+
+  // Handle folder double click
   const handleFolderOpen = (folder: FileItem) => {
     if (viewMode === 'grid') {
       setCurrentPath([...currentPath, folder.name]);
       setCurrentParentId(folder.id);
     } else {
-      // 트리 뷰에서는 expand/collapse
+      // In tree view, expand/collapse
       const newExpanded = new Set(expandedFolders);
       if (newExpanded.has(folder.id)) {
         newExpanded.delete(folder.id);
@@ -806,7 +923,7 @@ export function FileManager({ projectId }: FileManagerProps) {
     setSelectedItems(new Set());
   };
 
-  // 폴더 확장 토글
+  // Toggle folder expansion
   const toggleFolderExpand = (folderId: string) => {
     const newExpanded = new Set(expandedFolders);
     if (newExpanded.has(folderId)) {
@@ -817,7 +934,7 @@ export function FileManager({ projectId }: FileManagerProps) {
     setExpandedFolders(newExpanded);
   };
 
-  // 아이템 선택
+  // Toggle item selection
   const toggleItemSelection = (itemId: string) => {
     const newSelected = new Set(selectedItems);
     if (newSelected.has(itemId)) {
@@ -828,18 +945,18 @@ export function FileManager({ projectId }: FileManagerProps) {
     setSelectedItems(newSelected);
   };
 
-  // 경로 탐색
+  // Navigate to path
   const navigateToPath = (index: number) => {
     if (index === -1) {
       setCurrentPath([]);
       setCurrentParentId(null);
     } else {
       setCurrentPath(currentPath.slice(0, index + 1));
-      // parentId 업데이트 로직 필요
+      // Need to update parentId logic
     }
   };
 
-  // 필터링된 아이템
+  // Filtered items
   const filteredItems = items.filter(item =>
     item.name.toLowerCase().includes(searchQuery.toLowerCase())
   );
@@ -848,7 +965,7 @@ export function FileManager({ projectId }: FileManagerProps) {
     item.name.toLowerCase().includes(searchQuery.toLowerCase())
   );
 
-  // 파일 크기 포맷
+  // Format file size
   const formatFileSize = (bytes?: number) => {
     if (!bytes) return '-';
     const sizes = ['B', 'KB', 'MB', 'GB'];
@@ -858,7 +975,7 @@ export function FileManager({ projectId }: FileManagerProps) {
 
   return (
     <div className="flex flex-col h-full">
-      {/* 툴바 */}
+      {/* Toolbar */}
       <div className="border-b p-4">
         <div className="flex items-center justify-between mb-3">
           <div className="flex items-center gap-2">
@@ -869,40 +986,40 @@ export function FileManager({ projectId }: FileManagerProps) {
                   onClick={() => setFolderDialogOpen(true)}
                 >
                   <FolderPlus className="h-4 w-4 mr-1" />
-                  새 폴더
+                  New Folder
                 </Button>
-                <Button 
-                  size="sm" 
+                <Button
+                  size="sm"
                   variant="outline"
                   onClick={() => setUploadDialogOpen(true)}
                 >
                   <Upload className="h-4 w-4 mr-1" />
-                  업로드
+                  Upload
                 </Button>
               </>
             )}
-            
+
             {selectedItems.size > 0 && (
               <>
-                {/* 다중 다운로드 버튼 */}
-                {items.filter(item => 
-                  selectedItems.has(item.id) && 
-                  item.type === 'file' && 
-                  item.permissions?.canDownload
+                {/* Multiple download button */}
+                {items.filter(item =>
+                  selectedItems.has(item.id) &&
+                  item.type === 'file' &&
+                  item.permissions?.canDownload ==='true'
                 ).length > 0 && (
-                  <Button
-                    size="sm"
-                    variant="outline"
-                    onClick={() => downloadMultipleFiles(Array.from(selectedItems))}
-                  >
-                    <Download className="h-4 w-4 mr-1" />
-                    다운로드 ({items.filter(item => 
-                      selectedItems.has(item.id) && item.type === 'file'
-                    ).length})
-                  </Button>
-                )}
-                
-                {/* 삭제 버튼 */}
+                    <Button
+                      size="sm"
+                      variant="outline"
+                      onClick={() => downloadMultipleFiles(Array.from(selectedItems))}
+                    >
+                      <Download className="h-4 w-4 mr-1" />
+                      Download ({items.filter(item =>
+                        selectedItems.has(item.id) && item.type === 'file'
+                      ).length})
+                    </Button>
+                  )}
+
+                {/* Delete button */}
                 {items.find(item => selectedItems.has(item.id))?.permissions?.canDelete && (
                   <Button
                     size="sm"
@@ -910,31 +1027,31 @@ export function FileManager({ projectId }: FileManagerProps) {
                     onClick={() => deleteItems(Array.from(selectedItems))}
                   >
                     <Trash2 className="h-4 w-4 mr-1" />
-                    삭제 ({selectedItems.size})
+                    Delete ({selectedItems.size})
                   </Button>
                 )}
               </>
             )}
-            
+
             {!isInternalUser && (
               <Badge variant="secondary" className="ml-2">
                 <Shield className="h-3 w-3 mr-1" />
-                외부 사용자
+                External User
               </Badge>
             )}
           </div>
-          
+
           <div className="flex items-center gap-2">
             <div className="relative">
               <Search className="absolute left-2 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground" />
               <Input
-                placeholder="검색..."
+                placeholder="Search..."
                 className="pl-8 w-64"
                 value={searchQuery}
                 onChange={(e) => setSearchQuery(e.target.value)}
               />
             </div>
-            
+
             <Button
               size="sm"
               variant="ghost"
@@ -947,41 +1064,41 @@ export function FileManager({ projectId }: FileManagerProps) {
 
         {/* Breadcrumb */}
         <Breadcrumb>
-         <BreadcrumbList>
-          <BreadcrumbItem>
-            <BreadcrumbLink onClick={() => navigateToPath(-1)}>
-              Home
-            </BreadcrumbLink>
-          </BreadcrumbItem>
-          {currentPath.map((path, index) => (
-            <BreadcrumbItem key={index}>
-              <ChevronRight className="h-4 w-4" />
-              <BreadcrumbLink onClick={() => navigateToPath(index)}>
-                {path}
+          <BreadcrumbList>
+            <BreadcrumbItem>
+              <BreadcrumbLink onClick={() => navigateToPath(-1)}>
+                Home
               </BreadcrumbLink>
             </BreadcrumbItem>
-          ))}
+            {currentPath.map((path, index) => (
+              <BreadcrumbItem key={index}>
+                <ChevronRight className="h-4 w-4" />
+                <BreadcrumbLink onClick={() => navigateToPath(index)}>
+                  {path}
+                </BreadcrumbLink>
+              </BreadcrumbItem>
+            ))}
           </BreadcrumbList>
         </Breadcrumb>
       </div>
 
-      {/* 파일 목록 */}
+      {/* File List */}
       <ScrollArea className="flex-1 p-4">
         {loading ? (
           <div className="flex justify-center items-center h-64">
-            <div className="text-muted-foreground">로딩 중...</div>
+            <div className="text-muted-foreground">Loading...</div>
           </div>
         ) : filteredItems.length === 0 ? (
           <div className="flex flex-col items-center justify-center h-64">
             <Folder className="h-12 w-12 text-muted-foreground mb-2" />
-            <p className="text-muted-foreground">비어있음</p>
+            <p className="text-muted-foreground">Empty</p>
           </div>
         ) : viewMode === 'grid' ? (
           <div className="grid grid-cols-6 gap-4">
             {filteredItems.map((item) => {
               const CategoryIcon = categoryConfig[item.category].icon;
               const categoryColor = categoryConfig[item.category].color;
-              
+
               return (
                 <ContextMenu key={item.id}>
                   <ContextMenuTrigger>
@@ -1006,11 +1123,11 @@ export function FileManager({ projectId }: FileManagerProps) {
                         )}
                         <CategoryIcon className={cn("h-4 w-4 absolute -bottom-1 -right-1", categoryColor)} />
                       </div>
-                      
+
                       <span className="mt-2 text-sm text-center truncate w-full">
                         {item.name}
                       </span>
-                      
+
                       {item.viewCount !== undefined && (
                         <div className="flex items-center gap-2 mt-1">
                           <span className="text-xs text-muted-foreground flex items-center">
@@ -1027,45 +1144,66 @@ export function FileManager({ projectId }: FileManagerProps) {
                       )}
                     </div>
                   </ContextMenuTrigger>
-                  
+
                   <ContextMenuContent>
                     {item.type === 'folder' && (
                       <>
                         <ContextMenuItem onClick={() => handleFolderOpen(item)}>
-                          열기
+                          Open
                         </ContextMenuItem>
                         <ContextMenuItem onClick={() => downloadFolder(item)}>
                           <Download className="h-4 w-4 mr-2" />
-                          폴더 전체 다운로드
+                          Download Folder
                         </ContextMenuItem>
                       </>
                     )}
-                    
-                    {item.type === 'file' && item.permissions?.canDownload && (
-                      <ContextMenuItem onClick={() => downloadFile(item)}>
-                        <Download className="h-4 w-4 mr-2" />
-                        다운로드
-                      </ContextMenuItem>
+
+                    {item.type === 'file' && (
+                      <>
+                        <ContextMenuItem onClick={() => viewFile(item)}>
+                          <Eye className="h-4 w-4 mr-2" />
+                          View
+                        </ContextMenuItem>
+                        {item.permissions?.canDownload === 'true' && (
+                          <ContextMenuItem onClick={() => downloadFile(item)}>
+                            <Download className="h-4 w-4 mr-2" />
+                            Download
+                          </ContextMenuItem>
+                        )}
+                      </>
                     )}
-                    
+
                     {isInternalUser && (
                       <>
                         <ContextMenuSeparator />
                         <ContextMenuSub>
                           <ContextMenuSubTrigger>
                             <Shield className="h-4 w-4 mr-2" />
-                            카테고리 변경
+                            Change Category
                           </ContextMenuSubTrigger>
                           <ContextMenuSubContent>
                             {Object.entries(categoryConfig).map(([key, config]) => (
-                              <ContextMenuItem key={key}>
+                              <ContextMenuItem
+                                key={key}
+                                onClick={() => {
+                                  if (item.type === 'folder') {
+                                    // Show dialog for folders
+                                    setSelectedFile(item);
+                                    setNewCategory(key);
+                                    setCategoryDialogOpen(true);
+                                  } else {
+                                    // Change immediately for files
+                                    changeCategory(item.id, key, false);
+                                  }
+                                }}
+                              >
                                 <config.icon className={cn("h-4 w-4 mr-2", config.color)} />
                                 {config.label}
                               </ContextMenuItem>
                             ))}
                           </ContextMenuSubContent>
                         </ContextMenuSub>
-                        
+
                         <ContextMenuItem
                           onClick={() => {
                             setSelectedFile(item);
@@ -1073,9 +1211,9 @@ export function FileManager({ projectId }: FileManagerProps) {
                           }}
                         >
                           <Share2 className="h-4 w-4 mr-2" />
-                          공유
+                          Share
                         </ContextMenuItem>
-                        
+
                         {item.permissions?.canEdit && (
                           <ContextMenuItem onClick={() => {
                             setSelectedFile(item);
@@ -1083,12 +1221,12 @@ export function FileManager({ projectId }: FileManagerProps) {
                             setRenameDialogOpen(true);
                           }}>
                             <Edit2 className="h-4 w-4 mr-2" />
-                            이름 변경
+                            Rename
                           </ContextMenuItem>
                         )}
                       </>
                     )}
-                    
+
                     {item.permissions?.canDelete && (
                       <>
                         <ContextMenuSeparator />
@@ -1097,7 +1235,7 @@ export function FileManager({ projectId }: FileManagerProps) {
                           onClick={() => deleteItems([item.id])}
                         >
                           <Trash2 className="h-4 w-4 mr-2" />
-                          삭제
+                          Delete
                         </ContextMenuItem>
                       </>
                     )}
@@ -1119,6 +1257,7 @@ export function FileManager({ projectId }: FileManagerProps) {
                 onToggleExpand={toggleFolderExpand}
                 onSelectItem={toggleItemSelection}
                 onDoubleClick={handleFolderOpen}
+                onView={viewFile}
                 onDownload={downloadFile}
                 onDownloadFolder={downloadFolder}
                 onDelete={deleteItems}
@@ -1138,20 +1277,20 @@ export function FileManager({ projectId }: FileManagerProps) {
         )}
       </ScrollArea>
 
-      {/* 업로드 다이얼로그 */}
+      {/* Upload Dialog */}
       <Dialog open={uploadDialogOpen} onOpenChange={setUploadDialogOpen}>
         <DialogContent className="max-w-2xl">
           <DialogHeader>
-            <DialogTitle>파일 업로드</DialogTitle>
+            <DialogTitle>Upload Files</DialogTitle>
             <DialogDescription>
-              파일을 드래그 앤 드롭하거나 클릭하여 선택하세요.
+              Drag and drop files or click to select.
             </DialogDescription>
           </DialogHeader>
-          
+
           <div className="space-y-4">
-            {/* 카테고리 선택 */}
+            {/* Category Selection */}
             <div>
-              <Label htmlFor="upload-category">카테고리</Label>
+              <Label htmlFor="upload-category">Category</Label>
               <Select value={uploadCategory} onValueChange={setUploadCategory}>
                 <SelectTrigger>
                   <SelectValue />
@@ -1170,7 +1309,7 @@ export function FileManager({ projectId }: FileManagerProps) {
             </div>
 
             {/* Dropzone */}
-            <Dropzone 
+            <Dropzone
               onDrop={(acceptedFiles: File[]) => {
                 handleFileUpload(acceptedFiles);
               }}
@@ -1198,16 +1337,16 @@ export function FileManager({ projectId }: FileManagerProps) {
                 <DropzoneInput />
                 <div className="flex flex-col items-center justify-center h-full">
                   <DropzoneUploadIcon className="h-12 w-12 text-muted-foreground mb-4" />
-                  <DropzoneTitle>파일을 드래그하거나 클릭하여 업로드</DropzoneTitle>
-                  <DropzoneDescription>여러 파일을 동시에 업로드할 수 있습니다</DropzoneDescription>
+                  <DropzoneTitle>Drag files or click to upload</DropzoneTitle>
+                  <DropzoneDescription>Multiple files can be uploaded simultaneously</DropzoneDescription>
                 </div>
               </DropzoneZone>
             </Dropzone>
 
-            {/* 업로드 중인 파일 목록 */}
+            {/* Uploading File List */}
             {uploadingFiles.length > 0 && (
               <FileList>
-                <FileListHeader>업로드 중인 파일</FileListHeader>
+                <FileListHeader>Uploading Files</FileListHeader>
                 {uploadingFiles.map((uploadFile, index) => (
                   <FileListItem key={index}>
                     <FileListIcon>
@@ -1218,10 +1357,10 @@ export function FileManager({ projectId }: FileManagerProps) {
                       <FileListDescription>
                         <div className="flex items-center gap-2">
                           <FileListSize>{uploadFile.file.size}</FileListSize>
-                          {uploadFile.status === 'uploading' && <span>업로드 중...</span>}
-                          {uploadFile.status === 'processing' && <span>처리 중...</span>}
+                          {uploadFile.status === 'uploading' && <span>Uploading...</span>}
+                          {uploadFile.status === 'processing' && <span>Processing...</span>}
                           {uploadFile.status === 'completed' && (
-                            <span className="text-green-600">완료</span>
+                            <span className="text-green-600">Complete</span>
                           )}
                           {uploadFile.status === 'error' && (
                             <span className="text-red-600">{uploadFile.error}</span>
@@ -1238,7 +1377,7 @@ export function FileManager({ projectId }: FileManagerProps) {
                           size="sm"
                           variant="ghost"
                           onClick={() => {
-                            setUploadingFiles(prev => 
+                            setUploadingFiles(prev =>
                               prev.filter((_, i) => i !== index)
                             );
                           }}
@@ -1252,44 +1391,44 @@ export function FileManager({ projectId }: FileManagerProps) {
               </FileList>
             )}
           </div>
-          
+
           <DialogFooter>
-            <Button 
-              variant="outline" 
+            <Button
+              variant="outline"
               onClick={() => {
                 setUploadDialogOpen(false);
                 setUploadingFiles([]);
               }}
             >
-              닫기
+              Close
             </Button>
           </DialogFooter>
         </DialogContent>
       </Dialog>
 
-      {/* 폴더 생성 다이얼로그 */}
+      {/* Create Folder Dialog */}
       <Dialog open={folderDialogOpen} onOpenChange={setFolderDialogOpen}>
         <DialogContent>
           <DialogHeader>
-            <DialogTitle>새 폴더 만들기</DialogTitle>
+            <DialogTitle>Create New Folder</DialogTitle>
             <DialogDescription>
-              폴더 이름과 접근 권한 카테고리를 설정하세요.
+              Set the folder name and access permission category.
             </DialogDescription>
           </DialogHeader>
-          
+
           <div className="space-y-4">
             <div>
-              <Label htmlFor="folder-name">폴더 이름</Label>
+              <Label htmlFor="folder-name">Folder Name</Label>
               <Input
                 id="folder-name"
                 value={dialogValue}
                 onChange={(e) => setDialogValue(e.target.value)}
-                placeholder="폴더 이름 입력"
+                placeholder="Enter folder name"
               />
             </div>
-            
+
             <div>
-              <Label htmlFor="folder-category">카테고리</Label>
+              <Label htmlFor="folder-category">Category</Label>
               <Select value={selectedCategory} onValueChange={setSelectedCategory}>
                 <SelectTrigger>
                   <SelectValue />
@@ -1307,38 +1446,38 @@ export function FileManager({ projectId }: FileManagerProps) {
               </Select>
             </div>
           </div>
-          
+
           <DialogFooter>
             <Button variant="outline" onClick={() => setFolderDialogOpen(false)}>
-              취소
+              Cancel
             </Button>
-            <Button onClick={createFolder}>생성</Button>
+            <Button onClick={createFolder}>Create</Button>
           </DialogFooter>
         </DialogContent>
       </Dialog>
 
-      {/* 파일 공유 다이얼로그 */}
+      {/* File Share Dialog */}
       <Dialog open={shareDialogOpen} onOpenChange={setShareDialogOpen}>
         <DialogContent className="max-w-md">
           <DialogHeader>
-            <DialogTitle>파일 공유</DialogTitle>
+            <DialogTitle>Share File</DialogTitle>
             <DialogDescription>
-              {selectedFile?.name}을(를) 공유합니다.
+              Sharing {selectedFile?.name}.
             </DialogDescription>
           </DialogHeader>
-          
+
           <Tabs defaultValue="link" className="w-full">
             <TabsList className="grid w-full grid-cols-2">
-              <TabsTrigger value="link">링크 공유</TabsTrigger>
-              <TabsTrigger value="permission">권한 설정</TabsTrigger>
+              <TabsTrigger value="link">Link Sharing</TabsTrigger>
+              <TabsTrigger value="permission">Permission Settings</TabsTrigger>
             </TabsList>
-            
+
             <TabsContent value="link" className="space-y-4">
               <div>
-                <Label htmlFor="access-level">접근 레벨</Label>
-                <Select 
-                  value={shareSettings.accessLevel} 
-                  onValueChange={(value) => setShareSettings({...shareSettings, accessLevel: value})}
+                <Label htmlFor="access-level">Access Level</Label>
+                <Select
+                  value={shareSettings.accessLevel}
+                  onValueChange={(value) => setShareSettings({ ...shareSettings, accessLevel: value })}
                 >
                   <SelectTrigger>
                     <SelectValue />
@@ -1347,101 +1486,305 @@ export function FileManager({ projectId }: FileManagerProps) {
                     <SelectItem value="view_only">
                       <div className="flex items-center">
                         <Eye className="h-4 w-4 mr-2" />
-                        보기만 가능
+                        View Only
                       </div>
                     </SelectItem>
                     <SelectItem value="view_download">
                       <div className="flex items-center">
                         <Download className="h-4 w-4 mr-2" />
-                        보기 + 다운로드
+                        View + Download
                       </div>
                     </SelectItem>
                   </SelectContent>
                 </Select>
               </div>
-              
+
               <div>
-                <Label htmlFor="password">비밀번호 (선택)</Label>
+                <Label htmlFor="password">Password (Optional)</Label>
                 <Input
                   id="password"
                   type="password"
                   value={shareSettings.password}
-                  onChange={(e) => setShareSettings({...shareSettings, password: e.target.value})}
-                  placeholder="비밀번호 입력"
+                  onChange={(e) => setShareSettings({ ...shareSettings, password: e.target.value })}
+                  placeholder="Enter password"
                 />
               </div>
-              
+
               <div>
-                <Label htmlFor="expires">만료일 (선택)</Label>
+                <Label htmlFor="expires">Expiry Date (Optional)</Label>
                 <Input
                   id="expires"
                   type="datetime-local"
                   value={shareSettings.expiresAt}
-                  onChange={(e) => setShareSettings({...shareSettings, expiresAt: e.target.value})}
+                  onChange={(e) => setShareSettings({ ...shareSettings, expiresAt: e.target.value })}
                 />
               </div>
-              
+
               <div>
-                <Label htmlFor="max-downloads">최대 다운로드 횟수 (선택)</Label>
+                <Label htmlFor="max-downloads">Max Downloads (Optional)</Label>
                 <Input
                   id="max-downloads"
                   type="number"
                   value={shareSettings.maxDownloads}
-                  onChange={(e) => setShareSettings({...shareSettings, maxDownloads: e.target.value})}
-                  placeholder="무제한"
+                  onChange={(e) => setShareSettings({ ...shareSettings, maxDownloads: e.target.value })}
+                  placeholder="Unlimited"
                 />
               </div>
             </TabsContent>
-            
+
             <TabsContent value="permission" className="space-y-4">
               <div>
-                <Label htmlFor="target-domain">대상 도메인</Label>
+                <Label htmlFor="target-domain">Target Domain</Label>
                 <Select>
                   <SelectTrigger>
-                    <SelectValue placeholder="도메인 선택" />
+                    <SelectValue placeholder="Select domain" />
                   </SelectTrigger>
                   <SelectContent>
-                    <SelectItem value="partners">파트너</SelectItem>
-                    <SelectItem value="internal">내부</SelectItem>
+                    <SelectItem value="partners">Partners</SelectItem>
+                    <SelectItem value="internal">Internal</SelectItem>
                   </SelectContent>
                 </Select>
               </div>
-              
+
               <div className="space-y-2">
-                <Label>권한</Label>
+                <Label>Permissions</Label>
                 <div className="space-y-2">
                   <div className="flex items-center justify-between">
-                    <Label htmlFor="can-view" className="text-sm font-normal">보기</Label>
+                    <Label htmlFor="can-view" className="text-sm font-normal">View</Label>
                     <Switch id="can-view" defaultChecked />
                   </div>
                   <div className="flex items-center justify-between">
-                    <Label htmlFor="can-download" className="text-sm font-normal">다운로드</Label>
+                    <Label htmlFor="can-download" className="text-sm font-normal">Download</Label>
                     <Switch id="can-download" />
                   </div>
                   <div className="flex items-center justify-between">
-                    <Label htmlFor="can-edit" className="text-sm font-normal">수정</Label>
+                    <Label htmlFor="can-edit" className="text-sm font-normal">Edit</Label>
                     <Switch id="can-edit" />
                   </div>
                   <div className="flex items-center justify-between">
-                    <Label htmlFor="can-share" className="text-sm font-normal">공유</Label>
+                    <Label htmlFor="can-share" className="text-sm font-normal">Share</Label>
                     <Switch id="can-share" />
                   </div>
                 </div>
               </div>
             </TabsContent>
           </Tabs>
-          
+
           <DialogFooter>
             <Button variant="outline" onClick={() => setShareDialogOpen(false)}>
-              취소
+              Cancel
             </Button>
             <Button onClick={shareFile}>
               <Share2 className="h-4 w-4 mr-2" />
-              공유 링크 생성
+              Create Share Link
+            </Button>
+          </DialogFooter>
+        </DialogContent>
+      </Dialog>
+
+      {/* Rename Dialog */}
+      <Dialog open={renameDialogOpen} onOpenChange={setRenameDialogOpen}>
+        <DialogContent>
+          <DialogHeader>
+            <DialogTitle>Rename</DialogTitle>
+            <DialogDescription>
+              {selectedFile?.type === 'file'
+                ? 'Enter the file name. (Extension will be preserved automatically)'
+                : 'Enter the folder name.'
+              }
+            </DialogDescription>
+          </DialogHeader>
+
+          <div>
+            <Label htmlFor="item-name">New Name</Label>
+            <Input
+              id="item-name"
+              value={dialogValue}
+              onChange={(e) => setDialogValue(e.target.value)}
+              placeholder={
+                selectedFile?.type === 'file'
+                  ? selectedFile.name.substring(0, selectedFile.name.lastIndexOf('.'))
+                  : selectedFile?.name
+              }
+              onKeyDown={(e) => {
+                if (e.key === 'Enter') {
+                  renameItem();
+                }
+              }}
+            />
+            {selectedFile?.type === 'file' && (
+              <p className="text-sm text-muted-foreground mt-1">
+                Extension: {selectedFile.name.substring(selectedFile.name.lastIndexOf('.'))}
+              </p>
+            )}
+          </div>
+
+          <DialogFooter>
+            <Button
+              variant="outline"
+              onClick={() => {
+                setRenameDialogOpen(false);
+                setSelectedFile(null);
+                setDialogValue('');
+              }}
+            >
+              Cancel
+            </Button>
+            <Button onClick={renameItem}>Rename</Button>
+          </DialogFooter>
+        </DialogContent>
+      </Dialog>
+
+      {/* Category Change Dialog (for folders) */}
+      <Dialog open={categoryDialogOpen} onOpenChange={setCategoryDialogOpen}>
+        <DialogContent>
+          <DialogHeader>
+            <DialogTitle>Change Category</DialogTitle>
+            <DialogDescription>
+              Changing category for {selectedFile?.name} folder.
+            </DialogDescription>
+          </DialogHeader>
+          
+          <div className="space-y-4">
+            <div>
+              <Label>New Category</Label>
+              <div className="mt-2 space-y-2">
+                {Object.entries(categoryConfig).map(([key, config]) => (
+                  <div 
+                    key={key}
+                    className={cn(
+                      "flex items-center p-3 rounded-lg border cursor-pointer transition-colors",
+                      newCategory === key && "bg-accent border-primary"
+                    )}
+                    onClick={() => setNewCategory(key)}
+                  >
+                    <config.icon className={cn("h-5 w-5 mr-3", config.color)} />
+                    <div className="flex-1">
+                      <div className="font-medium">{config.label}</div>
+                      <div className="text-sm text-muted-foreground">
+                        {key === 'public' && 'External users can access freely'}
+                        {key === 'restricted' && 'External users can only view'}
+                        {key === 'confidential' && 'External users cannot access'}
+                        {key === 'internal' && 'Internal use only'}
+                      </div>
+                    </div>
+                  </div>
+                ))}
+              </div>
+            </div>
+            
+            {selectedFile?.type === 'folder' && (
+              <div className="flex items-center space-x-2">
+                <Switch
+                  id="apply-to-children"
+                  checked={applyToChildren}
+                  onCheckedChange={setApplyToChildren}
+                />
+                <Label htmlFor="apply-to-children">
+                  Apply to all files and subfolders
+                </Label>
+              </div>
+            )}
+          </div>
+          
+          <DialogFooter>
+            <Button 
+              variant="outline" 
+              onClick={() => {
+                setCategoryDialogOpen(false);
+                setSelectedFile(null);
+                setApplyToChildren(false);
+              }}
+            >
+              Cancel
+            </Button>
+            <Button 
+              onClick={() => {
+                if (selectedFile) {
+                  changeCategory(selectedFile.id, newCategory, applyToChildren);
+                  setCategoryDialogOpen(false);
+                  setSelectedFile(null);
+                  setApplyToChildren(false);
+                }
+              }}
+            >
+              Change
             </Button>
           </DialogFooter>
         </DialogContent>
       </Dialog>
+
+      {/* Secure Document Viewer Dialog */}
+      <Dialog 
+        open={viewerDialogOpen} 
+        onOpenChange={(open) => {
+          if (!open) {
+            setViewerDialogOpen(false);
+            setViewerFileUrl(null);
+            setSelectedFile(null);
+          }
+        }}
+      >
+        <DialogContent className="max-w-[90vw] max-h-[90vh] w-full h-full p-0">
+          <DialogHeader className="px-6 py-4 border-b">
+            <DialogTitle className="flex items-center justify-between">
+              <div className="flex items-center gap-2">
+                <Eye className="h-5 w-5" />
+                Secure Document Viewer
+              </div>
+              <div className="flex items-center gap-2 text-sm text-muted-foreground">
+                <Lock className="h-4 w-4" />
+                View Only Mode
+              </div>
+            </DialogTitle>
+            <DialogDescription>
+              <div className="flex items-center justify-between mt-2">
+                <span>Viewing: {selectedFile?.name}</span>
+                <Badge variant="destructive" className="text-xs">
+                  <AlertCircle className="h-3 w-3 mr-1" />
+                  Protected Document - No Download/Copy/Print
+                </Badge>
+              </div>
+            </DialogDescription>
+          </DialogHeader>
+          
+          <div className="relative flex-1 h-[calc(90vh-120px)]">
+            {viewerFileUrl && selectedFile && (
+              <SecurePDFViewer
+                documentUrl={viewerFileUrl}
+                fileName={selectedFile.name}
+                onClose={() => {
+                  setViewerDialogOpen(false);
+                  setViewerFileUrl(null);
+                  setSelectedFile(null);
+                }}
+              />
+            )}
+          </div>
+          
+          <div className="px-6 py-3 border-t bg-muted/50">
+            <div className="flex items-center justify-between text-xs text-muted-foreground">
+              <div className="flex items-center gap-4">
+                <span>Viewer: {session?.user?.email}</span>
+                <span>Time: {new Date().toLocaleString()}</span>
+                <span>IP logged for security</span>
+              </div>
+              <Button
+                size="sm"
+                variant="outline"
+                onClick={() => {
+                  setViewerDialogOpen(false);
+                  setViewerFileUrl(null);
+                  setSelectedFile(null);
+                }}
+              >
+                <X className="h-4 w-4 mr-1" />
+                Close Viewer
+              </Button>
+            </div>
+          </div>
+        </DialogContent>
+      </Dialog>
     </div>
   );
 }
\ No newline at end of file
-- 
cgit v1.2.3

