diff --git a/.Jules/palette.md b/.Jules/palette.md new file mode 100644 index 0000000..f0adc6b --- /dev/null +++ b/.Jules/palette.md @@ -0,0 +1,3 @@ +## 2024-05-14 - Missing Loading States on Async Actions +**Learning:** In the ClimaAI app, form buttons (Login, Register, Google Auth) lack visual feedback and disable states during async API requests. +**Action:** Always add loading spinners/text changes and disable the button natively (via `disabled=true` and `aria-busy=true`) during async submissions to prevent double-clicks and provide immediate feedback. Use `try...finally` to ensure state is cleaned up robustly. diff --git a/web-demo/js/app.js b/web-demo/js/app.js index 11508de..3ccf8a7 100644 --- a/web-demo/js/app.js +++ b/web-demo/js/app.js @@ -144,6 +144,15 @@ class ClimaAI { e.preventDefault(); const email = document.getElementById('loginEmail').value; const password = document.getElementById('loginPassword').value; + const submitBtn = e.submitter; + let originalContent = ''; + + if (submitBtn) { + originalContent = submitBtn.innerHTML; + submitBtn.disabled = true; + submitBtn.setAttribute('aria-busy', 'true'); + submitBtn.innerHTML = 'Signing in...'; + } try { this.showToast('Logging in...', 'info'); @@ -155,6 +164,12 @@ class ClimaAI { this.checkSubscription(); } catch (error) { this.showToast(error.message || 'Login failed', 'error'); + } finally { + if (submitBtn) { + submitBtn.disabled = false; + submitBtn.removeAttribute('aria-busy'); + submitBtn.innerHTML = originalContent; + } } }