import { Controller } from '@hotwired/stimulus'; export default class extends Controller { static targets = ['item', 'importBtn']; connect() { this._poll(); this._interval = setInterval(() => this._poll(), 5000); this._onImportStarted = () => this._poll(); document.addEventListener('import:started', this._onImportStarted); } disconnect() { clearInterval(this._interval); document.removeEventListener('import:started', this._onImportStarted); } async _poll() { try { const response = await fetch('/api/imports/latest'); if (!response.ok) return; const data = await response.json(); this._update(data); } catch (e) { // silently ignore } } _update(data) { if (!data) { this._showDefault(); return; } const isActive = data.status === 'pending' || data.status === 'processing'; if (isActive) { this._showActive(data); } else if (data.status === 'completed') { this._showCompleted(data); } else if (data.status === 'failed') { this._showFailed(); } else { this._showDefault(); } } _showDefault() { this.importBtnTarget.disabled = false; this.importBtnTarget.textContent = 'Importer ses films'; this._removeStatus(); } _showActive(data) { this.importBtnTarget.disabled = true; this.importBtnTarget.textContent = 'Import en cours\u2026'; const progress = data.totalFilms > 0 ? Math.round((data.processedFilms / data.totalFilms) * 100) : 0; this._setStatus(`${progress}% — ${data.processedFilms}/${data.totalFilms} films`, 'active'); } _showCompleted(data) { this.importBtnTarget.disabled = false; this.importBtnTarget.textContent = 'Importer ses films'; const imported = data.totalFilms - data.failedFilms; this._setStatus(`Dernier import : ${imported}/${data.totalFilms} films`, 'completed'); } _showFailed() { this.importBtnTarget.disabled = false; this.importBtnTarget.textContent = 'Importer ses films'; this._setStatus('Dernier import : échoué', 'failed'); } _setStatus(text, type) { let statusEl = this.itemTarget.querySelector('.import-status-text'); if (!statusEl) { statusEl = document.createElement('span'); statusEl.className = 'import-status-text'; this.itemTarget.appendChild(statusEl); } statusEl.textContent = text; statusEl.className = `import-status-text import-status-${type}`; } _removeStatus() { const statusEl = this.itemTarget.querySelector('.import-status-text'); if (statusEl) statusEl.remove(); } }