Implement reliability improvements across frontend
- api.js: add exponential backoff retry (3 attempts, 500/1000/2000ms) for GET requests on network errors and 5xx responses; mutating methods are not retried since they are not idempotent - api.js: add offline indicator — fixed pill banner appears at bottom of page when navigator goes offline, disappears when back online - style.css: add styles for offline banner and session expiry warning - auth.js: show amber warning banner below nav when session expires within 24 hours (with exact hours remaining); dismissible with X button - auth.js: fix password min-length client-side check from 6 to 10 to match the backend - log.js, flock.js, budget.js: disable submit button during async request and re-enable in finally block to prevent double-submits and make loading state visible - dashboard.js: fix chart date labels to use user's configured timezone instead of the browser's local timezone Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -87,10 +87,26 @@ function buildTimezoneOptions(selected) {
|
||||
|
||||
// ── Nav + settings modal ──────────────────────────────────────────────────────
|
||||
|
||||
function _checkSessionExpiry(user) {
|
||||
const msLeft = (user.exp * 1000) - Date.now();
|
||||
const hoursLeft = msLeft / (1000 * 60 * 60);
|
||||
if (hoursLeft > 24) return;
|
||||
|
||||
const warning = document.createElement('div');
|
||||
warning.id = 'session-warning';
|
||||
const label = hoursLeft < 1
|
||||
? 'Your session expires in less than an hour — please log out and back in.'
|
||||
: `Your session expires in ${Math.floor(hoursLeft)} hours — please log out and back in.`;
|
||||
warning.innerHTML = `<span>${label}</span><button title="Dismiss" onclick="this.parentElement.remove()">✕</button>`;
|
||||
document.querySelector('.nav')?.insertAdjacentElement('afterend', warning);
|
||||
}
|
||||
|
||||
function initNav() {
|
||||
const user = Auth.requireAuth();
|
||||
if (!user) return;
|
||||
|
||||
_checkSessionExpiry(user);
|
||||
|
||||
const nav = document.querySelector('.nav');
|
||||
if (!nav) return;
|
||||
|
||||
@@ -201,8 +217,8 @@ async function submitPasswordChange() {
|
||||
msgEl.className = 'message error visible';
|
||||
return;
|
||||
}
|
||||
if (newPw.length < 6) {
|
||||
msgEl.textContent = 'Password must be at least 6 characters';
|
||||
if (newPw.length < 10) {
|
||||
msgEl.textContent = 'Password must be at least 10 characters';
|
||||
msgEl.className = 'message error visible';
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user