feat: add progress bar for file upload and implement XMLHttpRequest for better status handling
This commit is contained in:
parent
b0e088b9de
commit
38ce6dfea4
@ -39,6 +39,16 @@ const markup = `
|
|||||||
<button id="clearBtn" type="button" class="text-xs text-zinc-500 hover:text-red-400 transition-colors font-semibold px-2">Remover</button>
|
<button id="clearBtn" type="button" class="text-xs text-zinc-500 hover:text-red-400 transition-colors font-semibold px-2">Remover</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div id="progressContainer" class="hidden space-y-2 mb-6">
|
||||||
|
<div class="flex justify-between text-[10px] uppercase tracking-wider text-zinc-500 font-bold">
|
||||||
|
<span>Subiendo archivo...</span>
|
||||||
|
<span id="progressPercent">0%</span>
|
||||||
|
</div>
|
||||||
|
<div class="h-1.5 w-full bg-zinc-800 rounded-full overflow-hidden">
|
||||||
|
<div id="progressBar" class="h-full bg-emerald-500 w-0 transition-all duration-300 ease-out shadow-[0_0_8px_rgba(16,185,129,0.5)]"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<button id="submitBtn" type="submit" class="w-full bg-emerald-600 hover:bg-emerald-500 text-white font-semibold py-3 rounded-xl transition-all shadow-lg shadow-emerald-900/20 active:scale-[0.98]">
|
<button id="submitBtn" type="submit" class="w-full bg-emerald-600 hover:bg-emerald-500 text-white font-semibold py-3 rounded-xl transition-all shadow-lg shadow-emerald-900/20 active:scale-[0.98]">
|
||||||
Actualizar Cookies
|
Actualizar Cookies
|
||||||
</button>
|
</button>
|
||||||
@ -59,6 +69,10 @@ const fileInfo = document.getElementById('fileInfo')
|
|||||||
const fileName = document.getElementById('fileName')
|
const fileName = document.getElementById('fileName')
|
||||||
const clearBtn = document.getElementById('clearBtn')
|
const clearBtn = document.getElementById('clearBtn')
|
||||||
const status = document.getElementById('status')
|
const status = document.getElementById('status')
|
||||||
|
const submitBtn = document.getElementById('submitBtn')
|
||||||
|
const progressContainer = document.getElementById('progressContainer')
|
||||||
|
const progressBar = document.getElementById('progressBar')
|
||||||
|
const progressPercent = document.getElementById('progressPercent')
|
||||||
|
|
||||||
function showStatus(text, ok = true) {
|
function showStatus(text, ok = true) {
|
||||||
status.textContent = text
|
status.textContent = text
|
||||||
@ -95,17 +109,61 @@ dropZone.addEventListener('drop', (e) => {
|
|||||||
fileInput.addEventListener('change', updateFileInfo)
|
fileInput.addEventListener('change', updateFileInfo)
|
||||||
clearBtn.addEventListener('click', () => { fileInput.value = ''; updateFileInfo() })
|
clearBtn.addEventListener('click', () => { fileInput.value = ''; updateFileInfo() })
|
||||||
|
|
||||||
uploadForm.addEventListener('submit', async (e) => {
|
uploadForm.addEventListener('submit', (e) => {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
if (!fileInput.files || !fileInput.files[0]) return showStatus('Selecciona un archivo .txt primero', false)
|
|
||||||
const fd = new FormData()
|
if (!fileInput.files || !fileInput.files[0]) {
|
||||||
fd.append('cookies', fileInput.files[0])
|
return showStatus('Selecciona un archivo .txt primero', false)
|
||||||
try {
|
|
||||||
const res = await fetch('/upload-cookies', { method: 'POST', body: fd })
|
|
||||||
const json = await res.json()
|
|
||||||
if (res.ok) showStatus(json.message || 'Subida correcta')
|
|
||||||
else showStatus(json.message || json.error || 'Error al subir', false)
|
|
||||||
} catch (err) {
|
|
||||||
showStatus(err.message || 'Error de red', false)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const file = fileInput.files[0]
|
||||||
|
const fd = new FormData()
|
||||||
|
fd.append('cookies', file)
|
||||||
|
|
||||||
|
// Reset UI
|
||||||
|
status.classList.add('hidden')
|
||||||
|
progressContainer.classList.remove('hidden')
|
||||||
|
progressBar.style.width = '0%'
|
||||||
|
progressPercent.textContent = '0%'
|
||||||
|
submitBtn.disabled = true
|
||||||
|
submitBtn.classList.add('opacity-50', 'cursor-not-allowed')
|
||||||
|
|
||||||
|
const xhr = new XMLHttpRequest()
|
||||||
|
|
||||||
|
xhr.upload.addEventListener('progress', (ev) => {
|
||||||
|
if (ev.lengthComputable) {
|
||||||
|
const percent = Math.round((ev.loaded / ev.total) * 100)
|
||||||
|
progressBar.style.width = percent + '%'
|
||||||
|
progressPercent.textContent = percent + '%'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
xhr.onload = () => {
|
||||||
|
submitBtn.disabled = false
|
||||||
|
submitBtn.classList.remove('opacity-50', 'cursor-not-allowed')
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
progressContainer.classList.add('hidden')
|
||||||
|
try {
|
||||||
|
const res = JSON.parse(xhr.responseText)
|
||||||
|
if (xhr.status >= 200 && xhr.status < 300) {
|
||||||
|
showStatus(res.message || 'Cookies actualizadas con éxito')
|
||||||
|
} else {
|
||||||
|
showStatus(res.message || 'Error en el servidor', false)
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
showStatus('Error al procesar respuesta', false)
|
||||||
|
}
|
||||||
|
}, 500)
|
||||||
|
}
|
||||||
|
|
||||||
|
xhr.onerror = () => {
|
||||||
|
submitBtn.disabled = false
|
||||||
|
submitBtn.classList.remove('opacity-50', 'cursor-not-allowed')
|
||||||
|
progressContainer.classList.add('hidden')
|
||||||
|
showStatus('Error de conexión a la red', false)
|
||||||
|
}
|
||||||
|
|
||||||
|
xhr.open('POST', '/upload-cookies')
|
||||||
|
xhr.send(fd)
|
||||||
})
|
})
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user