diff options
| author | joonhoekim <26rote@gmail.com> | 2025-11-02 17:42:18 +0900 |
|---|---|---|
| committer | joonhoekim <26rote@gmail.com> | 2025-11-02 17:42:18 +0900 |
| commit | 9694acd0ec21b3f50a8bd65d3a328befd85cbbee (patch) | |
| tree | fb1d94fdc48afcc6a263f874f2c3f41544643460 /lib/vendor-document-list | |
| parent | 397050fffb14cf2f88ad7610fbbce96cf0cb797c (diff) | |
(김준회) dolce: GTT(B4) 일괄업로드 drag&drop 오류 수정
Diffstat (limited to 'lib/vendor-document-list')
| -rw-r--r-- | lib/vendor-document-list/ship/bulk-b4-upload-dialog.tsx | 72 |
1 files changed, 61 insertions, 11 deletions
diff --git a/lib/vendor-document-list/ship/bulk-b4-upload-dialog.tsx b/lib/vendor-document-list/ship/bulk-b4-upload-dialog.tsx index db0fa08e..52252e14 100644 --- a/lib/vendor-document-list/ship/bulk-b4-upload-dialog.tsx +++ b/lib/vendor-document-list/ship/bulk-b4-upload-dialog.tsx @@ -32,14 +32,11 @@ import { SelectValue, } from "@/components/ui/select" import { ScrollArea } from "@/components/ui/scroll-area" -import { Separator } from "@/components/ui/separator" import { Badge } from "@/components/ui/badge" import { Upload, X, Loader2, - FileSpreadsheet, - Files, CheckCircle2, AlertCircle, AlertTriangle, @@ -76,7 +73,7 @@ function parseFileName(fileName: string): { docNumber: string | null; revision: /\b([A-Za-z]{2,3})\s+([A-Za-z]{2,3})\s+([A-Za-z0-9]{2,4})\b/, ] - let docNumber = null + let docNumber: string | null = null for (const pattern of docNumberPatterns) { const match = normalizedName.match(pattern) || cleanedName.match(pattern) if (match) { @@ -115,6 +112,7 @@ export function BulkB4UploadDialog({ }: BulkB4UploadDialogProps) { const [isUploading, setIsUploading] = React.useState(false) const [parsedFiles, setParsedFiles] = React.useState<ParsedFile[]>([]) + const [isDragging, setIsDragging] = React.useState(false) const router = useRouter() // 프로젝트 ID 추출 @@ -158,6 +156,40 @@ export function BulkB4UploadDialog({ form.setValue("files", newParsedFiles.map(pf => pf.file)) } + // Drag & Drop 핸들러 + const handleDragEnter = (e: React.DragEvent) => { + e.preventDefault() + e.stopPropagation() + setIsDragging(true) + } + + const handleDragLeave = (e: React.DragEvent) => { + e.preventDefault() + e.stopPropagation() + // 자식 요소로 이동할 때도 leave가 발생하므로 실제로 영역을 벗어날 때만 처리 + if (e.currentTarget === e.target) { + setIsDragging(false) + } + } + + const handleDragOver = (e: React.DragEvent) => { + e.preventDefault() + e.stopPropagation() + // 드롭 가능하도록 설정 + e.dataTransfer.dropEffect = 'copy' + } + + const handleDrop = (e: React.DragEvent) => { + e.preventDefault() + e.stopPropagation() + setIsDragging(false) + + const droppedFiles = Array.from(e.dataTransfer.files) + if (droppedFiles.length > 0) { + handleFilesChange(droppedFiles) + } + } + // 업로드 처리 async function onSubmit(values: z.infer<typeof formSchema>) { setIsUploading(true) @@ -225,7 +257,7 @@ export function BulkB4UploadDialog({ : pf )) } - } catch (error) { + } catch { toast.error("업로드 중 오류가 발생했습니다") setParsedFiles(prev => prev.map(pf => pf.status === 'uploading' @@ -242,6 +274,7 @@ export function BulkB4UploadDialog({ if (!open) { form.reset() setParsedFiles([]) + setIsDragging(false) } }, [open, form]) @@ -255,7 +288,7 @@ export function BulkB4UploadDialog({ <DialogTitle>B4 Document Bulk Upload</DialogTitle> <DialogDescription> Document numbers and revisions will be automatically extracted from file names. - Example: "agadfg de na oc R01.pdf" → Document Number: DE-NA-OC, Revision: R01 + Example: "agadfg de na oc R01.pdf" → Document Number: DE-NA-OC, Revision: R01 </DialogDescription> </DialogHeader> @@ -288,7 +321,17 @@ export function BulkB4UploadDialog({ <div className="space-y-2"> <FormLabel>Select Files</FormLabel> - <div className="border-2 border-dashed rounded-lg p-6"> + <div + className={`border-2 border-dashed rounded-lg p-6 transition-all duration-200 ${ + isDragging + ? 'border-primary bg-primary/5 scale-[1.02]' + : 'border-muted-foreground/30 hover:border-muted-foreground/50' + }`} + onDragEnter={handleDragEnter} + onDragLeave={handleDragLeave} + onDragOver={handleDragOver} + onDrop={handleDrop} + > <input type="file" multiple @@ -296,14 +339,21 @@ export function BulkB4UploadDialog({ onChange={(e) => handleFilesChange(Array.from(e.target.files || []))} className="hidden" id="file-upload" + disabled={isUploading} /> <label htmlFor="file-upload" - className="flex flex-col items-center justify-center cursor-pointer" + className={`flex flex-col items-center justify-center ${ + isUploading ? 'cursor-not-allowed opacity-50' : 'cursor-pointer' + }`} > - <Upload className="h-10 w-10 text-muted-foreground mb-2" /> - <p className="text-sm text-muted-foreground"> - Click or drag files to upload + <Upload className={`h-10 w-10 mb-2 transition-colors ${ + isDragging ? 'text-primary' : 'text-muted-foreground' + }`} /> + <p className={`text-sm transition-colors ${ + isDragging ? 'text-primary font-medium' : 'text-muted-foreground' + }`}> + {isDragging ? '파일을 여기에 놓으세요' : '클릭하거나 파일을 드래그하여 업로드'} </p> <p className="text-xs text-muted-foreground mt-1"> PDF, DOC, DOCX, XLS, XLSX, DWG, DXF |
