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
1 change: 1 addition & 0 deletions .Jules/palette.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
## 2024-05-24 - Async Loading States for Form Submissions\n**Learning:** Implementing visual feedback (like disabling buttons and changing their text to 'Loading...') during async form submissions prevents double submissions and reduces user uncertainty. Wait states are essential UX elements for any async network request.\n**Action:** Add disabled styling or inline loading text to form submitters during async operations and ensure state restores in a `finally` block.
26 changes: 26 additions & 0 deletions web-demo/js/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,14 @@ class ClimaAI {
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 = 'Signing In...';
}

try {
this.showToast('Logging in...', 'info');
const response = await api.login(email, password);
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 @@ -164,6 +177,14 @@ class ClimaAI {
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');
const response = await api.register(email, password, name);
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