feat(library): 자료실 드래그 업로드 + 오버레이

자료실 페이지에서 드래그 앤 드롭 업로드 지원.
업로드 후 자료실 내에서 트리+목록 새로고침 (문서 페이지로 이동하지 않음).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Hyungi Ahn
2026-04-14 15:53:09 +09:00
parent d6756010b1
commit e89e19f365
+46 -4
View File
@@ -152,13 +152,43 @@
window.open(`/api/documents/${doc.id}/preview?token=${getAccessToken()}&download=true`);
}
// ─── 업로드 ───
// ─── 업로드 (버튼 + 드래그) ───
const MAX_UPLOAD_BYTES = 100 * 1024 * 1024;
let fileInput;
let uploadingCount = $state(0);
let dragging = $state(false);
let dragCounter = 0;
async function handleUpload(e) {
const files = Array.from(e.target.files || []);
onMount(() => {
function onDragEnter(e) { e.preventDefault(); dragCounter++; dragging = true; }
function onDragOver(e) { e.preventDefault(); }
function onDragLeave(e) { e.preventDefault(); dragCounter--; if (dragCounter <= 0) { dragging = false; dragCounter = 0; } }
function onDrop(e) { e.preventDefault(); dragging = false; dragCounter = 0; uploadFiles(e.dataTransfer?.files); }
window.addEventListener('dragenter', onDragEnter);
window.addEventListener('dragover', onDragOver);
window.addEventListener('dragleave', onDragLeave);
window.addEventListener('drop', onDrop);
return () => {
window.removeEventListener('dragenter', onDragEnter);
window.removeEventListener('dragover', onDragOver);
window.removeEventListener('dragleave', onDragLeave);
window.removeEventListener('drop', onDrop);
};
});
function handleUpload(e) {
uploadFiles(e.target.files);
fileInput.value = '';
}
async function uploadFiles(fileList) {
const allFiles = Array.from(fileList || []);
const files = allFiles.filter(f => f.size <= MAX_UPLOAD_BYTES);
const tooLarge = allFiles.filter(f => f.size > MAX_UPLOAD_BYTES);
if (tooLarge.length > 0) {
addToast('error', `100MB 초과 파일 ${tooLarge.length}건 제외됨`);
}
if (files.length === 0) return;
uploadingCount = files.length;
@@ -178,7 +208,6 @@
}
uploadingCount = 0;
fileInput.value = '';
if (success > 0) {
addToast('success', `${success}건 업로드 완료`);
@@ -460,3 +489,16 @@
</main>
</div>
</div>
<!-- 드래그 업로드 오버레이 -->
{#if dragging}
<div class="fixed inset-0 z-50 bg-accent/10 border-2 border-dashed border-accent flex items-center justify-center">
<div class="bg-surface rounded-xl px-8 py-6 shadow-xl text-center">
<Upload size={32} class="mx-auto mb-2 text-accent" />
<p class="text-sm font-medium text-accent">자료실에 파일 업로드</p>
{#if activePath}
<p class="text-xs text-dim mt-1">경로: {activePath}</p>
{/if}
</div>
</div>
{/if}