| 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()); |
| |
| |
| 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()); |
| |
| |
| 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'; |
| |
| |
| document.dispatchEvent(new CustomEvent('batch-created')); |
| |
| |
| 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); |