Depassage's picture
### 1. ABSTRACT
c6db453 verified
Raw
History Blame Contribute Delete
5.93 kB
class CustomUpload extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: 'open' });
this.shadowRoot.innerHTML = `
<style>
@import url('https://cdnjs.cloudflare.com/ajax/libs/tailwindcss/2.2.19/tailwind.min.css');
</style>
<form class="space-y-4">
<div>
<label for="batchType" class="block text-sm font-medium text-gray-700 mb-1">Batch Type</label>
<select id="batchType" class="w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500">
<option value="Anonymisation">Anonymisation</option>
</select>
</div>
<div>
<label for="fileInput" class="block text-sm font-medium text-gray-700 mb-1">Input File</label>
<div class="file-input-label" id="dropZone">
<div class="flex flex-col items-center justify-center pt-5 pb-6">
<i data-feather="upload-cloud" class="w-10 h-10 text-gray-400 mb-2"></i>
<p class="mb-2 text-sm text-gray-500"><span class="font-semibold">Click to upload</span> or drag and drop</p>
<p class="text-xs text-gray-500">CSV files only</p>
</div>
<input id="fileInput" type="file" class="hidden" accept=".csv" />
</div>
</div>
<button type="submit" class="w-full flex justify-center py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">
Process File
</button>
<div id="statusMessage" class="hidden p-3 rounded-md text-sm"></div>
</form>
`;
}
connectedCallback() {
this.shadowRoot.querySelector('form').addEventListener('submit', this.handleSubmit.bind(this));
const fileInput = this.shadowRoot.getElementById('fileInput');
const dropZone = this.shadowRoot.getElementById('dropZone');
fileInput.addEventListener('change', () => this.updateFileDisplay());
// Drag and drop handlers
dropZone.addEventListener('dragover', (e) => {
e.preventDefault();
dropZone.classList.add('drag-over');
});
['dragleave', 'dragend'].forEach(type => {
dropZone.addEventListener(type, () => {
dropZone.classList.remove('drag-over');
});
});
dropZone.addEventListener('drop', (e) => {
e.preventDefault();
dropZone.classList.remove('drag-over');
if (e.dataTransfer.files.length) {
fileInput.files = e.dataTransfer.files;
this.updateFileDisplay();
}
});
dropZone.addEventListener('click', () => fileInput.click());
// Initialize Feather icons
feather.replace({ width: 20, height: 20 });
}
updateFileDisplay() {
const fileInput = this.shadowRoot.getElementById('fileInput');
const dropZone = this.shadowRoot.getElementById('dropZone');
if (fileInput.files.length > 0) {
const file = fileInput.files[0];
dropZone.innerHTML = `
<div class="flex items-center p-4">
<i data-feather="file-text" class="w-6 h-6 text-indigo-500 mr-3"></i>
<div>
<p class="text-sm font-medium text-gray-900">${file.name}</p>
<p class="text-xs text-gray-500">${(file.size / 1024).toFixed(2)} KB</p>
</div>
</div>
`;
feather.replace({ width: 20, height: 20 });
}
}
async handleSubmit(e) {
e.preventDefault();
const batchType = this.shadowRoot.getElementById('batchType').value;
const fileInput = this.shadowRoot.getElementById('fileInput');
const statusMessage = this.shadowRoot.getElementById('statusMessage');
if (!fileInput.files.length) {
statusMessage.textContent = 'Please select a file first';
statusMessage.className = 'bg-red-50 text-red-700';
statusMessage.classList.remove('hidden');
return;
}
const file = fileInput.files[0];
if (!file.name.endsWith('.csv')) {
statusMessage.textContent = 'Only CSV files are allowed';
statusMessage.className = 'bg-red-50 text-red-700';
statusMessage.classList.remove('hidden');
return;
}
statusMessage.textContent = 'Processing your file...';
statusMessage.className = 'bg-blue-50 text-blue-700';
statusMessage.classList.remove('hidden');
try {
const batch = await window.batchService.createBatch(batchType, file);
statusMessage.textContent = `Batch #${batch.id} created successfully!`;
statusMessage.className = 'bg-green-50 text-green-700';
// Dispatch event to notify list component
document.dispatchEvent(new CustomEvent('batch-created'));
// Reset form
fileInput.value = '';
this.updateFileDisplay();
} catch (error) {
statusMessage.textContent = 'Error creating batch: ' + error.message;
statusMessage.className = 'bg-red-50 text-red-700';
}
}
}
customElements.define('custom-upload', CustomUpload);