Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .Jules/palette.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
## 2026-08-08 - Added Visual Feedback and Disabled State to Form Buttons
**Learning:** During asynchronous operations like login or registration, users may double-click submission buttons if they don't see immediate feedback, leading to duplicate requests.
**Action:** Always disable form submission buttons and provide a visual loading indicator (e.g., changing text to "⏳ Logging in...") during async requests, restoring the state in a `finally` block to ensure a smooth and robust user experience.
26 changes: 26 additions & 0 deletions web-demo/js/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,14 @@ class ClimaAI {
e.preventDefault();
const email = document.getElementById('loginEmail').value;
const password = document.getElementById('loginPassword').value;
const submitBtn = e.submitter;
let originalText = '';

if (submitBtn) {
originalText = submitBtn.innerHTML;
submitBtn.disabled = true;
submitBtn.innerHTML = '⏳ Logging in...';
}

try {
this.showToast('Logging in...', 'info');
Expand All @@ -155,6 +163,11 @@ class ClimaAI {
this.checkSubscription();
} catch (error) {
this.showToast(error.message || 'Login failed', 'error');
} finally {
if (submitBtn) {
submitBtn.disabled = false;
submitBtn.innerHTML = originalText;
}
}
}

Expand All @@ -163,6 +176,14 @@ class ClimaAI {
const name = document.getElementById('registerName').value;
const email = document.getElementById('registerEmail').value;
const password = document.getElementById('registerPassword').value;
const submitBtn = e.submitter;
let originalText = '';

if (submitBtn) {
originalText = submitBtn.innerHTML;
submitBtn.disabled = true;
submitBtn.innerHTML = '⏳ Signing up...';
}

try {
this.showToast('Creating account...', 'info');
Expand All @@ -174,6 +195,11 @@ class ClimaAI {
this.checkSubscription();
} catch (error) {
this.showToast(error.message || 'Registration failed', 'error');
} finally {
if (submitBtn) {
submitBtn.disabled = false;
submitBtn.innerHTML = originalText;
}
}
}

Expand Down