fix(config): prevent card text overflow; fix(onboarding): persist completion server-side
Cards/Grid: - Add min-width:0 to .device-grid to prevent grid overflow - Add max-width:100%, overflow:hidden, word-break:break-word to .device-card - Add min-width:0 and overflow-wrap to .device-card__body - Bump config.css cache-bust to v=2 Onboarding: - Add GET/POST /pos/api/config/onboarding-status endpoints in config_bp.py - onboarding.js now checks server first before showing wizard - On finish, POSTs completion to server (tenant_config table) - Falls back to localStorage for fast path and offline resilience - Bump onboarding.js cache-bust to v=2 in catalog.html
This commit is contained in:
@@ -1029,6 +1029,7 @@
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
|
||||
gap: var(--space-4);
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.device-card {
|
||||
@@ -1042,7 +1043,10 @@
|
||||
box-shadow: var(--shadow-sm);
|
||||
transition: var(--transition-normal);
|
||||
min-width: 0;
|
||||
max-width: 100%;
|
||||
overflow: hidden;
|
||||
overflow-wrap: break-word;
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
[data-theme="modern"] .device-card {
|
||||
|
||||
@@ -1,18 +1,41 @@
|
||||
/* ==========================================================================
|
||||
NEXUS POS — Onboarding Wizard for New Tenants
|
||||
Shows a step-by-step setup guide on first login.
|
||||
Persists completion in localStorage('pos_onboarding_done').
|
||||
Persists completion in localStorage('pos_onboarding_done') and server.
|
||||
========================================================================== */
|
||||
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
/* ------------------------------------------------------------------
|
||||
GUARD — skip if already completed
|
||||
GUARD — skip if already completed locally (fast path)
|
||||
------------------------------------------------------------------ */
|
||||
|
||||
if (localStorage.getItem('pos_onboarding_done') === 'true') return;
|
||||
|
||||
/* ------------------------------------------------------------------
|
||||
CHECK SERVER — if completed on server, cache locally and skip
|
||||
------------------------------------------------------------------ */
|
||||
|
||||
function checkServerAndMaybeInit() {
|
||||
var token = '';
|
||||
try { token = localStorage.getItem('pos_token') || ''; } catch (e) {}
|
||||
fetch('/pos/api/config/onboarding-status', {
|
||||
headers: token ? { 'Authorization': 'Bearer ' + token } : {}
|
||||
}).then(function (r) {
|
||||
if (!r.ok) return null;
|
||||
return r.json();
|
||||
}).then(function (data) {
|
||||
if (data && data.completed) {
|
||||
localStorage.setItem('pos_onboarding_done', 'true');
|
||||
return;
|
||||
}
|
||||
initWizard();
|
||||
}).catch(function () {
|
||||
initWizard();
|
||||
});
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------
|
||||
STATE
|
||||
------------------------------------------------------------------ */
|
||||
@@ -335,6 +358,13 @@
|
||||
|
||||
function finish() {
|
||||
localStorage.setItem('pos_onboarding_done', 'true');
|
||||
var token = '';
|
||||
try { token = localStorage.getItem('pos_token') || ''; } catch (e) {}
|
||||
fetch('/pos/api/config/onboarding-status', {
|
||||
method: 'POST',
|
||||
headers: token ? { 'Authorization': 'Bearer ' + token, 'Content-Type': 'application/json' } : { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ completed: true })
|
||||
}).catch(function () {});
|
||||
if (overlay && overlay.parentNode) {
|
||||
overlay.style.opacity = '0';
|
||||
overlay.style.transition = 'opacity var(--duration-normal) var(--ease-in)';
|
||||
@@ -439,11 +469,15 @@
|
||||
renderCurrentStep();
|
||||
}
|
||||
|
||||
/* Wait for DOM */
|
||||
if (document.readyState === 'loading') {
|
||||
document.addEventListener('DOMContentLoaded', init);
|
||||
} else {
|
||||
function initWizard() {
|
||||
init();
|
||||
}
|
||||
|
||||
/* Wait for DOM, then check server before showing wizard */
|
||||
if (document.readyState === 'loading') {
|
||||
document.addEventListener('DOMContentLoaded', checkServerAndMaybeInit);
|
||||
} else {
|
||||
checkServerAndMaybeInit();
|
||||
}
|
||||
|
||||
})();
|
||||
|
||||
Reference in New Issue
Block a user