diff options
Diffstat (limited to 'components/ship-vendor-document')
3 files changed, 89 insertions, 89 deletions
diff --git a/components/ship-vendor-document/add-attachment-dialog.tsx b/components/ship-vendor-document/add-attachment-dialog.tsx index 2f2467a3..a285b4de 100644 --- a/components/ship-vendor-document/add-attachment-dialog.tsx +++ b/components/ship-vendor-document/add-attachment-dialog.tsx @@ -55,15 +55,15 @@ const ACCEPTED_FILE_TYPES = [ const attachmentUploadSchema = z.object({ attachments: z .array(z.instanceof(File)) - .min(1, "최소 1개의 파일을 업로드해주세요") - .max(10, "최대 10개의 파일까지 업로드 가능합니다") + .min(1, "Please upload at least 1 file") + .max(10, "Maximum 10 files can be uploaded") .refine( (files) => files.every((file) => file.size <= MAX_FILE_SIZE), - "파일 크기는 50MB 이하여야 합니다" + "File size must be 50MB or less" ) .refine( (files) => files.every((file) => ACCEPTED_FILE_TYPES.includes(file.type)), - "지원하지 않는 파일 형식입니다" + "Unsupported file format" ), }) @@ -128,10 +128,10 @@ function FileUploadArea({ > <Paperclip className="mx-auto h-12 w-12 text-gray-400 mb-4" /> <p className="text-sm text-gray-600 mb-2"> - 추가할 파일을 드래그하여 놓거나 클릭하여 선택하세요 + Drag files to add here or click to select </p> <p className="text-xs text-gray-500"> - PDF, Word, Excel, 이미지, 텍스트, ZIP 파일 지원 (최대 50MB) + Supports PDF, Word, Excel, Image, Text, ZIP files (max 50MB) </p> <input ref={fileInputRef} @@ -145,7 +145,7 @@ function FileUploadArea({ {files.length > 0 && ( <div className="space-y-2 max-h-40 overflow-y-auto overscroll-contain pr-2"> - <p className="text-sm font-medium">선택된 파일 ({files.length}개)</p> + <p className="text-sm font-medium">Selected Files ({files.length})</p> <div className="max-h-40 overflow-y-auto space-y-2"> {files.map((file, index) => ( <div @@ -251,7 +251,7 @@ export function AddAttachmentDialog({ if (!response.ok) { const errorData = await response.json() - throw new Error(errorData.error || errorData.details || '첨부파일 업로드에 실패했습니다.') + throw new Error(errorData.error || errorData.details || 'Failed to upload attachments.') } const result = await response.json() @@ -259,10 +259,10 @@ export function AddAttachmentDialog({ toast.success( result.message || - `${result.data?.uploadedFiles?.length || 0}개 첨부파일이 추가되었습니다.` + `${result.data?.uploadedFiles?.length || 0} attachments added.` ) - console.log('✅ 첨부파일 업로드 성공:', result) + console.log('✅ Attachment upload successful:', result) setTimeout(() => { handleDialogClose() @@ -270,8 +270,8 @@ export function AddAttachmentDialog({ }, 1000) } catch (error) { - console.error('❌ 첨부파일 업로드 오류:', error) - toast.error(error instanceof Error ? error.message : "첨부파일 업로드 중 오류가 발생했습니다") + console.error('❌ Attachment upload error:', error) + toast.error(error instanceof Error ? error.message : "An error occurred while uploading attachments") } finally { setIsUploading(false) setTimeout(() => setUploadProgress(0), 2000) @@ -285,10 +285,10 @@ export function AddAttachmentDialog({ <DialogHeader className="flex-shrink-0 pb-4 border-b"> <DialogTitle className="flex items-center gap-2"> <Paperclip className="h-5 w-5" /> - 첨부파일 추가 + Add Attachments </DialogTitle> <DialogDescription className="text-sm"> - 리비전 {revisionName}에 추가 첨부파일을 업로드합니다 + Upload additional attachments to revision {revisionName} </DialogDescription> </DialogHeader> @@ -302,7 +302,7 @@ export function AddAttachmentDialog({ name="attachments" render={({ field }) => ( <FormItem> - <FormLabel className="required">첨부파일</FormLabel> + <FormLabel className="required">Attachments</FormLabel> <FormControl> <FileUploadArea files={watchedFiles || []} @@ -318,14 +318,14 @@ export function AddAttachmentDialog({ {isUploading && ( <div className="space-y-2"> <div className="flex items-center justify-between text-sm"> - <span>업로드 진행률</span> + <span>Upload Progress</span> <span>{uploadProgress.toFixed(0)}%</span> </div> <Progress value={uploadProgress} className="w-full" /> {uploadProgress === 100 && ( <div className="flex items-center gap-2 text-sm text-green-600"> <CheckCircle className="h-4 w-4" /> - <span>업로드 완료</span> + <span>Upload Complete</span> </div> )} </div> @@ -340,7 +340,7 @@ export function AddAttachmentDialog({ onClick={handleDialogClose} disabled={isUploading} > - 취소 + Cancel </Button> <Button type="submit" @@ -350,12 +350,12 @@ export function AddAttachmentDialog({ {isUploading ? ( <> <Loader2 className="mr-2 h-4 w-4 animate-spin" /> - 업로드 중... + Uploading... </> ) : ( <> <Upload className="mr-2 h-4 w-4" /> - 추가 + Add </> )} </Button> diff --git a/components/ship-vendor-document/new-revision-dialog.tsx b/components/ship-vendor-document/new-revision-dialog.tsx index 83c9c658..7adc0b3a 100644 --- a/components/ship-vendor-document/new-revision-dialog.tsx +++ b/components/ship-vendor-document/new-revision-dialog.tsx @@ -67,20 +67,20 @@ const ACCEPTED_FILE_TYPES = [ // drawingKind에 따른 동적 스키마 생성 const createRevisionUploadSchema = (drawingKind: string) => { const baseSchema = { - usage: z.string().min(1, "용도를 선택해주세요"), - revision: z.string().min(1, "리비전을 입력해주세요").max(50, "리비전은 50자 이내로 입력해주세요"), + usage: z.string().min(1, "Please select a usage"), + revision: z.string().min(1, "Please enter a revision").max(50, "Revision must be 50 characters or less"), comment: z.string().optional(), attachments: z .array(z.instanceof(File)) - .min(1, "최소 1개의 파일을 업로드해주세요") - .max(10, "최대 10개의 파일까지 업로드 가능합니다") + .min(1, "Please upload at least 1 file") + .max(10, "Maximum 10 files can be uploaded") .refine( (files) => files.every((file) => file.size <= MAX_FILE_SIZE), - "파일 크기는 50MB 이하여야 합니다" + "File size must be 50MB or less" ) .refine( (files) => files.every((file) => ACCEPTED_FILE_TYPES.includes(file.type)), - "지원하지 않는 파일 형식입니다" + "Unsupported file format" ), } @@ -88,7 +88,7 @@ const createRevisionUploadSchema = (drawingKind: string) => { if (drawingKind === 'B3') { return z.object({ ...baseSchema, - usageType: z.string().min(1, "용도 타입을 선택해주세요"), + usageType: z.string().min(1, "Please select a usage type"), }) } else { return z.object({ @@ -151,7 +151,7 @@ const getUsageTypeOptions = (usage: string) => { // 리비전 형식 가이드 생성 const getRevisionGuide = () => { - return "R01, R02, R03... 형식으로 입력하세요" + return "Enter in R01, R02, R03... format" } interface NewRevisionDialogProps { @@ -216,10 +216,10 @@ function FileUploadArea({ > <Upload className="mx-auto h-12 w-12 text-gray-400 mb-4" /> <p className="text-sm text-gray-600 mb-2"> - 파일을 드래그하여 놓거나 클릭하여 선택하세요 + Drag files here or click to select </p> <p className="text-xs text-gray-500"> - PDF, Word, Excel, 이미지, 텍스트, ZIP 파일 지원 (최대 50MB) + Supports PDF, Word, Excel, Image, Text, ZIP files (max 50MB) </p> <input ref={fileInputRef} @@ -233,7 +233,7 @@ function FileUploadArea({ {files.length > 0 && ( <div className="space-y-2 max-h-40 overflow-y-auto overscroll-contain pr-2"> - <p className="text-sm font-medium">선택된 파일 ({files.length}개)</p> + <p className="text-sm font-medium">Selected Files ({files.length})</p> <div className="max-h-40 overflow-y-auto space-y-2"> {files.map((file, index) => ( <div @@ -386,7 +386,7 @@ export function NewRevisionDialog({ if (!response.ok) { const errorData = await response.json() - throw new Error(errorData.error || errorData.details || '업로드에 실패했습니다.') + throw new Error(errorData.error || errorData.details || 'Upload failed.') } const result = await response.json() @@ -394,10 +394,10 @@ export function NewRevisionDialog({ toast.success( result.message || - `리비전 ${data.revision}이 성공적으로 업로드되었습니다. (${result.data?.uploadedFiles?.length || 0}개 파일)` + `Revision ${data.revision} uploaded successfully. (${result.data?.uploadedFiles?.length || 0} files)` ) - console.log('✅ 업로드 성공:', result) + console.log('✅ Upload successful:', result) setTimeout(() => { handleDialogClose() @@ -405,8 +405,8 @@ export function NewRevisionDialog({ }, 1000) } catch (error) { - console.error('❌ 업로드 오류:', error) - toast.error(error instanceof Error ? error.message : "업로드 중 오류가 발생했습니다") + console.error('❌ Upload error:', error) + toast.error(error instanceof Error ? error.message : "An error occurred during upload") } finally { setIsUploading(false) setTimeout(() => setUploadProgress(0), 2000) @@ -420,11 +420,11 @@ export function NewRevisionDialog({ <DialogHeader className="flex-shrink-0 pb-4 border-b"> <DialogTitle className="flex items-center gap-2"> <Upload className="h-5 w-5" /> - 새 리비전 업로드 + Upload New Revision </DialogTitle> {documentTitle && ( <DialogDescription className="text-sm space-y-1"> - <div>문서: {documentTitle}</div> + <div>Document: {documentTitle}</div> </DialogDescription> )} </DialogHeader> @@ -439,11 +439,11 @@ export function NewRevisionDialog({ name="usage" render={({ field }) => ( <FormItem> - <FormLabel className="required">용도</FormLabel> + <FormLabel className="required">Usage</FormLabel> <Select onValueChange={field.onChange} value={field.value}> <FormControl> <SelectTrigger> - <SelectValue placeholder="용도를 선택하세요" /> + <SelectValue placeholder="Select usage" /> </SelectTrigger> </FormControl> <SelectContent> @@ -466,11 +466,11 @@ export function NewRevisionDialog({ name="usageType" render={({ field }) => ( <FormItem> - <FormLabel className="required">용도 타입</FormLabel> + <FormLabel className="required">Usage Type</FormLabel> <Select onValueChange={field.onChange} value={field.value}> <FormControl> <SelectTrigger> - <SelectValue placeholder="용도 타입을 선택하세요" /> + <SelectValue placeholder="Select usage type" /> </SelectTrigger> </FormControl> <SelectContent> @@ -493,7 +493,7 @@ export function NewRevisionDialog({ name="revision" render={({ field }) => ( <FormItem> - <FormLabel className="required">리비전</FormLabel> + <FormLabel className="required">Revision</FormLabel> <FormControl> <Input placeholder={revisionGuide} @@ -514,10 +514,10 @@ export function NewRevisionDialog({ name="comment" render={({ field }) => ( <FormItem> - <FormLabel>코멘트</FormLabel> + <FormLabel>Comment</FormLabel> <FormControl> <Textarea - placeholder="리비전에 대한 설명이나 변경사항을 입력하세요 (선택사항)" + placeholder="Enter description or changes for this revision (optional)" className="resize-none" rows={3} {...field} @@ -534,7 +534,7 @@ export function NewRevisionDialog({ name="attachments" render={({ field }) => ( <FormItem> - <FormLabel className="required">첨부파일</FormLabel> + <FormLabel className="required">Attachments</FormLabel> <FormControl> <FileUploadArea files={watchedFiles || []} @@ -550,14 +550,14 @@ export function NewRevisionDialog({ {isUploading && ( <div className="space-y-2"> <div className="flex items-center justify-between text-sm"> - <span>업로드 진행률</span> + <span>Upload Progress</span> <span>{uploadProgress.toFixed(0)}%</span> </div> <Progress value={uploadProgress} className="w-full" /> {uploadProgress === 100 && ( <div className="flex items-center gap-2 text-sm text-green-600"> <CheckCircle className="h-4 w-4" /> - <span>업로드 완료</span> + <span>Upload Complete</span> </div> )} </div> @@ -572,7 +572,7 @@ export function NewRevisionDialog({ onClick={handleDialogClose} disabled={isUploading} > - 취소 + Cancel </Button> <Button type="submit" @@ -582,12 +582,12 @@ export function NewRevisionDialog({ {isUploading ? ( <> <Loader2 className="mr-2 h-4 w-4 animate-spin" /> - 업로드 중... + Uploading... </> ) : ( <> <Upload className="mr-2 h-4 w-4" /> - 업로드 + Upload </> )} </Button> diff --git a/components/ship-vendor-document/user-vendor-document-table-container.tsx b/components/ship-vendor-document/user-vendor-document-table-container.tsx index 17af5436..4e133696 100644 --- a/components/ship-vendor-document/user-vendor-document-table-container.tsx +++ b/components/ship-vendor-document/user-vendor-document-table-container.tsx @@ -168,7 +168,7 @@ function RevisionTable({ <CardHeader> <div className="flex items-center justify-between"> <div> - <CardTitle className="text-lg">리비전</CardTitle> + <CardTitle className="text-lg">Revisions</CardTitle> </div> <Button onClick={onNewRevision} @@ -176,7 +176,7 @@ function RevisionTable({ className="flex items-center gap-2" > <Plus className="h-4 w-4" /> - 새 리비전 + New Revision </Button> </div> </CardHeader> @@ -185,17 +185,17 @@ function RevisionTable({ <Table className="tbl-compact"> <TableHeader> <TableRow> - <TableHead className="w-12">선택</TableHead> - <TableHead>리비전</TableHead> - <TableHead>카테고리</TableHead> - <TableHead>용도</TableHead> - <TableHead>타입</TableHead> {/* ✅ usageType 컬럼 */} - <TableHead>상태</TableHead> - <TableHead>업로더</TableHead> - <TableHead>코멘트</TableHead> - <TableHead>업로드일</TableHead> - <TableHead className="text-center">파일 수</TableHead> - <TableHead>액션</TableHead> + <TableHead className="w-12">Select</TableHead> + <TableHead>Revision</TableHead> + <TableHead>Category</TableHead> + <TableHead>Usage</TableHead> + <TableHead>Type</TableHead> {/* ✅ usageType 컬럼 */} + <TableHead>Status</TableHead> + <TableHead>Uploader</TableHead> + <TableHead>Comment</TableHead> + <TableHead>Upload Date</TableHead> + <TableHead className="text-center">Files</TableHead> + <TableHead>Actions</TableHead> </TableRow> </TableHeader> <TableBody> @@ -331,7 +331,7 @@ function AttachmentTable({ // ✅ 첨부파일 업로드 성공 핸들러 const handleAttachmentUploadSuccess = React.useCallback((uploadResult?: any) => { if (!selectedRevisionId || !allData || !uploadResult?.data) { - console.log('🔄 전체 새로고침') + console.log('🔄 Full refresh') router.refresh() return } @@ -374,7 +374,7 @@ function AttachmentTable({ }) setAllData(updatedData) - console.log('✅ AttachmentTable 업데이트 완료') + console.log('✅ AttachmentTable update complete') // 메인 테이블도 업데이트 (약간의 지연 후) setTimeout(() => { @@ -382,7 +382,7 @@ function AttachmentTable({ }, 1500) } catch (error) { - console.error('❌ AttachmentTable 업데이트 실패:', error) + console.error('❌ AttachmentTable update failed:', error) router.refresh() } }, [selectedRevisionId, allData, setAllData, router]) @@ -392,7 +392,7 @@ function AttachmentTable({ <Card className="w-96 flex-shrink-0"> <CardHeader> <div className="flex items-center justify-between"> - <CardTitle className="text-lg">첨부파일</CardTitle> + <CardTitle className="text-lg">Attachments</CardTitle> {/* ✅ + 버튼 추가 */} {selectedRevisionId && selectedRevisionInfo && ( <Button @@ -402,7 +402,7 @@ function AttachmentTable({ className="flex items-center gap-2" > <Plus className="h-4 w-4" /> - 추가 + Add </Button> )} </div> @@ -411,8 +411,8 @@ function AttachmentTable({ <Table className="tbl-compact"> <TableHeader> <TableRow> - <TableHead>파일명</TableHead> - <TableHead>액션</TableHead> + <TableHead>File Name</TableHead> + <TableHead>Actions</TableHead> </TableRow> </TableHeader> <TableBody> @@ -423,8 +423,8 @@ function AttachmentTable({ <FileText className="h-8 w-8" /> <span> {!selectedRevisionId - ? '리비전을 선택해주세요' - : '첨부된 파일이 없습니다'} + ? 'Please select a revision' + : 'No attached files'} </span> {/* ✅ 리비전이 선택된 경우 추가 버튼 표시 */} {selectedRevisionId && selectedRevisionInfo && ( @@ -435,7 +435,7 @@ function AttachmentTable({ className="mt-2" > <Plus className="h-4 w-4 mr-2" /> - 첫 번째 파일 추가 + Add First File </Button> )} </div> @@ -599,10 +599,10 @@ function SubTables() { // State 업데이트 setAllData(updatedData) - console.log('✅ RevisionTable 데이터 업데이트 완료') + console.log('✅ RevisionTable data update complete') } catch (error) { - console.error('❌ RevisionTable 업데이트 실패:', error) + console.error('❌ RevisionTable update failed:', error) // 실패 시 전체 새로고침 window.location.reload() } @@ -679,7 +679,7 @@ function SubTables() { if (!response.ok) { const errorData = await response.json() - throw new Error(errorData.error || '파일 다운로드에 실패했습니다.') + throw new Error(errorData.error || 'Failed to download file.') } const blob = await response.blob() @@ -692,8 +692,8 @@ function SubTables() { window.document.body.removeChild(link) window.URL.revokeObjectURL(url) } catch (error) { - console.error('파일 다운로드 오류:', error) - alert(`파일 다운로드 실패: ${error instanceof Error ? error.message : '알 수 없는 오류'}`) + console.error('File download error:', error) + alert(`File download failed: ${error instanceof Error ? error.message : 'Unknown error'}`) } }, []) @@ -707,7 +707,7 @@ function SubTables() { if (viewer.current && !isCancelled.current) { import("@pdftron/webviewer").then(({ default: WebViewer }) => { if (isCancelled.current) { - console.log("WebViewer 초기화 취소됨 (Dialog 닫힘)") + console.log("WebViewer initialization cancelled (Dialog closed)") return } @@ -764,7 +764,7 @@ function SubTables() { const tab = await UI.TabManager.addTab(blob, options) tabIds.push(tab) } catch (error) { - console.error("파일 로드 실패:", attachment.filePath, error) + console.error("File load failed:", attachment.filePath, error) } } @@ -818,9 +818,9 @@ function SubTables() { <Dialog open={viewerOpen} onOpenChange={handleCloseViewer}> <DialogContent className="w-[90vw] h-[90vh]" style={{ maxWidth: "none" }}> <DialogHeader className="h-[38px]"> - <DialogTitle>문서 미리보기</DialogTitle> + <DialogTitle>Document Preview</DialogTitle> <DialogDescription> - 리비전 {selectedRevision?.revision} 첨부파일 + Revision {selectedRevision?.revision} attachments </DialogDescription> </DialogHeader> <div @@ -831,7 +831,7 @@ function SubTables() { <div className="flex flex-col items-center justify-center py-12"> <Loader2 className="h-8 w-8 text-blue-500 animate-spin mb-4" /> <p className="text-sm text-muted-foreground"> - 문서 뷰어 로딩 중... + Loading document viewer... </p> </div> )} @@ -885,7 +885,7 @@ function SelectedDocumentInfo() { <div className="flex flex-wrap items-center gap-3 rounded-lg bg-gray-50 p-4"> <div className="flex items-center gap-2"> <Badge variant="secondary" className="text-sm"> - 문서: {doc.docNumber} + Document: {doc.docNumber} </Badge> <span className="max-w-[300px] truncate text-sm font-medium text-gray-700"> {doc.title} @@ -893,14 +893,14 @@ function SelectedDocumentInfo() { </div> <div className="flex items-center gap-2 text-sm text-gray-600"> <span>•</span> - <span>총 {totalRevisions}개 리비전</span> + <span>Total {totalRevisions} revisions</span> {selectedRevision && ( <> <span>•</span> <Badge variant="outline" className="text-sm"> - 선택된 리비전: {selectedRevision.revision} + Selected revision: {selectedRevision.revision} </Badge> - <span>({selectedRevision.attachments.length}개 파일)</span> + <span>({selectedRevision.attachments.length} files)</span> </> )} </div> @@ -960,7 +960,7 @@ export function UserVendorDocumentDisplay({ <CardContent className="flex items-center justify-center py-8"> <div className="text-center"> <AlertCircle className="mx-auto mb-2 h-8 w-8 text-gray-400" /> - <p className="text-gray-600">데이터를 불러올 수 없습니다.</p> + <p className="text-gray-600">Unable to load data.</p> </div> </CardContent> </Card> |
