This commit is contained in:
2025-09-23 04:16:05 +02:00
parent 244bfa11cb
commit 01d9dc9fa2
16 changed files with 2604 additions and 1 deletions

121
file_drop.js Normal file
View File

@@ -0,0 +1,121 @@
export default {
template: `
<div
class="file-drop-zone"
:class="{ 'dragging': isDragging }"
@click="openFileDialog"
@dragover.prevent="onDragOver"
@dragleave.prevent="onDragLeave"
@drop.prevent="onDrop"
style="border: 2px dashed #d1d5db; border-radius: 8px; padding: 32px; text-align: center; cursor: pointer; transition: all 0.3s ease; min-height: 120px; display: flex; flex-direction: column; align-items: center; justify-content: center;"
>
<div style="color: #9ca3af; font-size: 48px; margin-bottom: 16px;">☁️</div>
<div style="font-size: 18px; color: #6b7280; margin-bottom: 8px;">Drop files here or click to browse</div>
<div style="font-size: 14px; color: #9ca3af;">Drag and drop your files</div>
<input
ref="fileInput"
type="file"
:multiple="multiple"
:accept="accept"
@change="onFileInputChange"
style="display: none;"
/>
</div>
`,
props: {
multiple: {
type: Boolean,
default: true
},
accept: {
type: String,
default: null
}
},
data() {
return {
isDragging: false
};
},
methods: {
openFileDialog() {
this.$refs.fileInput.click();
},
onDragOver(e) {
e.preventDefault();
this.isDragging = true;
},
onDragLeave(e) {
e.preventDefault();
this.isDragging = false;
},
async onDrop(e) {
e.preventDefault();
this.isDragging = false;
const files = Array.from(e.dataTransfer.files);
if (files.length === 0) return;
await this.processFiles(files);
},
async onFileInputChange(e) {
const files = Array.from(e.target.files);
if (files.length === 0) return;
await this.processFiles(files);
// Clear the input
e.target.value = '';
},
async processFiles(files) {
if (!this.multiple && files.length > 1) {
files = [files[0]];
}
const filesData = [];
for (const file of files) {
const content = await this.readFileAsBase64(file);
filesData.push({
name: file.name,
size: file.size,
type: file.type || 'application/octet-stream',
content: content
});
}
this.$emit('upload', filesData);
},
readFileAsBase64(file) {
return new Promise((resolve) => {
const reader = new FileReader();
reader.onload = () => {
// Remove the data URL prefix to get just the base64 content
const base64 = reader.result.split(',')[1];
resolve(base64);
};
reader.readAsDataURL(file);
});
}
},
style: `
.file-drop-zone.dragging {
border-color: #3b82f6 !important;
background-color: #eff6ff !important;
}
.file-drop-zone:hover {
border-color: #9ca3af !important;
background-color: #f9fafb !important;
}
`
};