feat: add progress bar for file upload and implement XMLHttpRequest for better status handling

This commit is contained in:
Cesar Mendivil 2026-03-21 20:49:22 -07:00
parent b0e088b9de
commit 38ce6dfea4

View File

@ -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>
</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]">
Actualizar Cookies
</button>
@ -59,6 +69,10 @@ const fileInfo = document.getElementById('fileInfo')
const fileName = document.getElementById('fileName')
const clearBtn = document.getElementById('clearBtn')
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) {
status.textContent = text
@ -95,17 +109,61 @@ dropZone.addEventListener('drop', (e) => {
fileInput.addEventListener('change', updateFileInfo)
clearBtn.addEventListener('click', () => { fileInput.value = ''; updateFileInfo() })
uploadForm.addEventListener('submit', async (e) => {
uploadForm.addEventListener('submit', (e) => {
e.preventDefault()
if (!fileInput.files || !fileInput.files[0]) return showStatus('Selecciona un archivo .txt primero', false)
const fd = new FormData()
fd.append('cookies', fileInput.files[0])
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)
if (!fileInput.files || !fileInput.files[0]) {
return showStatus('Selecciona un archivo .txt primero', 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)
})