summaryrefslogtreecommitdiff
path: root/components/ship-vendor-document
diff options
context:
space:
mode:
Diffstat (limited to 'components/ship-vendor-document')
-rw-r--r--components/ship-vendor-document/add-attachment-dialog.tsx40
-rw-r--r--components/ship-vendor-document/new-revision-dialog.tsx62
-rw-r--r--components/ship-vendor-document/user-vendor-document-table-container.tsx76
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>