Spaces:
Sleeping
Sleeping
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Loading - Spaces Dashboard</title> | |
| <style> | |
| * { | |
| margin: 0; | |
| padding: 0; | |
| box-sizing: border-box; | |
| } | |
| body { | |
| font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, sans-serif; | |
| background: #0a0a0a; | |
| color: #e5e5e5; | |
| min-height: 100vh; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| } | |
| .container { | |
| text-align: center; | |
| max-width: 400px; | |
| width: 90%; | |
| } | |
| h1 { | |
| font-size: 1.25rem; | |
| font-weight: 500; | |
| margin-bottom: 0.5rem; | |
| } | |
| .subtitle { | |
| color: #666; | |
| font-size: 0.875rem; | |
| margin-bottom: 2rem; | |
| } | |
| .progress-container { | |
| margin-bottom: 1.5rem; | |
| } | |
| .progress-bar { | |
| height: 4px; | |
| background: #222; | |
| border-radius: 2px; | |
| overflow: hidden; | |
| margin-bottom: 0.75rem; | |
| } | |
| .progress-fill { | |
| height: 100%; | |
| background: #22c55e; | |
| width: 0%; | |
| transition: width 0.3s; | |
| } | |
| .progress-text { | |
| font-size: 0.875rem; | |
| color: #888; | |
| } | |
| .stage { | |
| font-size: 0.75rem; | |
| color: #555; | |
| text-transform: uppercase; | |
| letter-spacing: 0.05em; | |
| margin-bottom: 0.5rem; | |
| } | |
| .error { | |
| color: #ef4444; | |
| margin-top: 1rem; | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <div class="container"> | |
| <h1>Loading your spaces</h1> | |
| <p class="subtitle">Fetching data from Hugging Face...</p> | |
| <div class="progress-container"> | |
| <div class="stage" id="stage">Initializing</div> | |
| <div class="progress-bar"> | |
| <div class="progress-fill" id="progress-fill"></div> | |
| </div> | |
| <div class="progress-text" id="progress-text">0%</div> | |
| </div> | |
| <div class="error" id="error" style="display: none;"></div> | |
| </div> | |
| <script> | |
| const jobId = "{{ job_id }}"; | |
| const progressFill = document.getElementById('progress-fill'); | |
| const progressText = document.getElementById('progress-text'); | |
| const stageEl = document.getElementById('stage'); | |
| const errorEl = document.getElementById('error'); | |
| const stageNames = { | |
| 'spaces': 'Fetching spaces', | |
| 'discussions': 'Loading discussions', | |
| 'pending': 'Initializing', | |
| '': 'Initializing' | |
| }; | |
| async function poll() { | |
| try { | |
| const resp = await fetch('/api/job/' + jobId); | |
| const job = await resp.json(); | |
| if (job.error) { | |
| errorEl.textContent = 'Error: ' + job.error; | |
| errorEl.style.display = 'block'; | |
| return; | |
| } | |
| if (job.status === 'completed') { | |
| progressFill.style.width = '100%'; | |
| progressText.textContent = 'Done!'; | |
| stageEl.textContent = 'Complete'; | |
| setTimeout(() => { | |
| window.location.href = '/dashboard'; | |
| }, 500); | |
| return; | |
| } | |
| if (job.status === 'failed') { | |
| errorEl.textContent = 'Error: ' + (job.error || 'Unknown error'); | |
| errorEl.style.display = 'block'; | |
| progressFill.style.background = '#ef4444'; | |
| return; | |
| } | |
| // Update progress | |
| const stage = job.progress_stage || ''; | |
| stageEl.textContent = stageNames[stage] || stage; | |
| if (job.progress_total > 0) { | |
| const pct = Math.round((job.progress_current / job.progress_total) * 100); | |
| progressFill.style.width = pct + '%'; | |
| progressText.textContent = `${job.progress_current} / ${job.progress_total}`; | |
| } | |
| setTimeout(poll, 500); | |
| } catch (err) { | |
| errorEl.textContent = 'Connection error: ' + err.message; | |
| errorEl.style.display = 'block'; | |
| setTimeout(poll, 2000); | |
| } | |
| } | |
| poll(); | |
| </script> | |
| </body> | |
| </html> | |