Merge develop: smart setup wizard
This commit is contained in:
+57
-19
@@ -8821,10 +8821,28 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
|
|
||||||
// ===== SETUP WIZARD =====
|
// ===== SETUP WIZARD =====
|
||||||
let _setupStep = 0;
|
let _setupStep = 0;
|
||||||
|
let _setupPendingSteps = [];
|
||||||
const _setupData = { lang: _currentLang, gemini_key: '', bring_email: '', bring_password: '' };
|
const _setupData = { lang: _currentLang, gemini_key: '', bring_email: '', bring_password: '' };
|
||||||
|
|
||||||
function _isFirstRun() {
|
/**
|
||||||
return !localStorage.getItem('dispensa_setup_done');
|
* Returns indices of setup steps that still need configuration.
|
||||||
|
* Existing settings are never overwritten — only missing ones trigger the wizard.
|
||||||
|
*/
|
||||||
|
function _getMissingSetupSteps() {
|
||||||
|
const missing = [];
|
||||||
|
const s = getSettings();
|
||||||
|
|
||||||
|
// Step 0 — language: missing only if never set at all (fresh install)
|
||||||
|
if (!localStorage.getItem('dispensa_lang') && !localStorage.getItem('dispensa_setup_done')) {
|
||||||
|
missing.push(0);
|
||||||
|
}
|
||||||
|
// Step 1 — Gemini API key
|
||||||
|
if (!s.gemini_key) missing.push(1);
|
||||||
|
// Step 2 — Bring! credentials (both must be set)
|
||||||
|
if (!s.bring_email || !s.bring_password) missing.push(2);
|
||||||
|
// Note: step 3 (done screen) gets appended automatically when there are missing steps
|
||||||
|
|
||||||
|
return missing;
|
||||||
}
|
}
|
||||||
|
|
||||||
function _setupSteps() {
|
function _setupSteps() {
|
||||||
@@ -8884,18 +8902,29 @@ function _setupSteps() {
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
function showSetupWizard() {
|
function showSetupWizard(pendingSteps) {
|
||||||
|
_setupPendingSteps = pendingSteps || _getMissingSetupSteps();
|
||||||
|
if (_setupPendingSteps.length === 0) return;
|
||||||
|
// Append the "done" step (3) at the end
|
||||||
|
_setupPendingSteps.push(3);
|
||||||
_setupStep = 0;
|
_setupStep = 0;
|
||||||
|
// Pre-fill _setupData from existing settings so we don't lose them
|
||||||
|
const s = getSettings();
|
||||||
|
if (s.gemini_key) _setupData.gemini_key = s.gemini_key;
|
||||||
|
if (s.bring_email) _setupData.bring_email = s.bring_email;
|
||||||
|
if (s.bring_password) _setupData.bring_password = s.bring_password;
|
||||||
document.getElementById('setup-wizard').style.display = '';
|
document.getElementById('setup-wizard').style.display = '';
|
||||||
_renderSetupStep();
|
_renderSetupStep();
|
||||||
}
|
}
|
||||||
|
|
||||||
function _renderSetupStep() {
|
function _renderSetupStep() {
|
||||||
const steps = _setupSteps();
|
const allSteps = _setupSteps();
|
||||||
const step = steps[_setupStep];
|
const totalPending = _setupPendingSteps.length;
|
||||||
|
const realIndex = _setupPendingSteps[_setupStep];
|
||||||
|
const step = allSteps[realIndex];
|
||||||
|
|
||||||
// Progress dots
|
// Progress dots (based on pending steps only)
|
||||||
const dotsHtml = steps.map((_, i) => {
|
const dotsHtml = _setupPendingSteps.map((_, i) => {
|
||||||
let cls = 'setup-dot';
|
let cls = 'setup-dot';
|
||||||
if (i < _setupStep) cls += ' done';
|
if (i < _setupStep) cls += ' done';
|
||||||
if (i === _setupStep) cls += ' active';
|
if (i === _setupStep) cls += ' active';
|
||||||
@@ -8912,7 +8941,7 @@ function _renderSetupStep() {
|
|||||||
prevBtn.style.display = _setupStep > 0 ? '' : 'none';
|
prevBtn.style.display = _setupStep > 0 ? '' : 'none';
|
||||||
prevBtn.textContent = t('btn.back');
|
prevBtn.textContent = t('btn.back');
|
||||||
|
|
||||||
if (_setupStep === steps.length - 1) {
|
if (_setupStep === totalPending - 1) {
|
||||||
nextBtn.textContent = _currentLang === 'it' ? '🚀 Inizia!' : _currentLang === 'de' ? '🚀 Los geht\'s!' : '🚀 Start!';
|
nextBtn.textContent = _currentLang === 'it' ? '🚀 Inizia!' : _currentLang === 'de' ? '🚀 Los geht\'s!' : '🚀 Start!';
|
||||||
} else {
|
} else {
|
||||||
nextBtn.textContent = _currentLang === 'it' ? 'Avanti →' : _currentLang === 'de' ? 'Weiter →' : 'Next →';
|
nextBtn.textContent = _currentLang === 'it' ? 'Avanti →' : _currentLang === 'de' ? 'Weiter →' : 'Next →';
|
||||||
@@ -8931,10 +8960,11 @@ function _setupSkipStep() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function _setupCollectCurrent() {
|
function _setupCollectCurrent() {
|
||||||
if (_setupStep === 1) {
|
const realIndex = _setupPendingSteps[_setupStep];
|
||||||
|
if (realIndex === 1) {
|
||||||
const el = document.getElementById('setup-gemini-key');
|
const el = document.getElementById('setup-gemini-key');
|
||||||
if (el) _setupData.gemini_key = el.value.trim();
|
if (el) _setupData.gemini_key = el.value.trim();
|
||||||
} else if (_setupStep === 2) {
|
} else if (realIndex === 2) {
|
||||||
const email = document.getElementById('setup-bring-email');
|
const email = document.getElementById('setup-bring-email');
|
||||||
const pass = document.getElementById('setup-bring-password');
|
const pass = document.getElementById('setup-bring-password');
|
||||||
if (email) _setupData.bring_email = email.value.trim();
|
if (email) _setupData.bring_email = email.value.trim();
|
||||||
@@ -8944,24 +8974,25 @@ function _setupCollectCurrent() {
|
|||||||
|
|
||||||
function setupWizardNav(dir) {
|
function setupWizardNav(dir) {
|
||||||
_setupCollectCurrent();
|
_setupCollectCurrent();
|
||||||
const steps = _setupSteps();
|
const totalPending = _setupPendingSteps.length;
|
||||||
|
const realIndex = _setupPendingSteps[_setupStep];
|
||||||
|
|
||||||
if (dir === 1 && _setupStep === steps.length - 1) {
|
if (dir === 1 && _setupStep === totalPending - 1) {
|
||||||
// Finish wizard
|
|
||||||
_finishSetup();
|
_finishSetup();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If language changed, apply it
|
// If language changed, apply it
|
||||||
if (_setupStep === 0 && dir === 1 && _setupData.lang !== _currentLang) {
|
if (realIndex === 0 && dir === 1 && _setupData.lang !== _currentLang) {
|
||||||
localStorage.setItem('dispensa_lang', _setupData.lang);
|
localStorage.setItem('dispensa_lang', _setupData.lang);
|
||||||
localStorage.setItem('dispensa_setup_step', '1');
|
localStorage.setItem('dispensa_setup_step', String(_setupStep + 1));
|
||||||
|
localStorage.setItem('dispensa_setup_pending', JSON.stringify(_setupPendingSteps));
|
||||||
localStorage.setItem('dispensa_setup_data', JSON.stringify(_setupData));
|
localStorage.setItem('dispensa_setup_data', JSON.stringify(_setupData));
|
||||||
location.reload();
|
location.reload();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_setupStep = Math.max(0, Math.min(steps.length - 1, _setupStep + dir));
|
_setupStep = Math.max(0, Math.min(totalPending - 1, _setupStep + dir));
|
||||||
_renderSetupStep();
|
_renderSetupStep();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -8992,15 +9023,22 @@ function _initApp() {
|
|||||||
// Check for setup wizard resume (after language change)
|
// Check for setup wizard resume (after language change)
|
||||||
const resumeStep = localStorage.getItem('dispensa_setup_step');
|
const resumeStep = localStorage.getItem('dispensa_setup_step');
|
||||||
const resumeData = localStorage.getItem('dispensa_setup_data');
|
const resumeData = localStorage.getItem('dispensa_setup_data');
|
||||||
if (resumeStep) {
|
const resumePending = localStorage.getItem('dispensa_setup_pending');
|
||||||
|
if (resumeStep && resumePending) {
|
||||||
try { Object.assign(_setupData, JSON.parse(resumeData)); } catch(e) {}
|
try { Object.assign(_setupData, JSON.parse(resumeData)); } catch(e) {}
|
||||||
|
try { _setupPendingSteps = JSON.parse(resumePending); } catch(e) {}
|
||||||
_setupStep = parseInt(resumeStep) || 0;
|
_setupStep = parseInt(resumeStep) || 0;
|
||||||
localStorage.removeItem('dispensa_setup_step');
|
localStorage.removeItem('dispensa_setup_step');
|
||||||
localStorage.removeItem('dispensa_setup_data');
|
localStorage.removeItem('dispensa_setup_data');
|
||||||
|
localStorage.removeItem('dispensa_setup_pending');
|
||||||
document.getElementById('setup-wizard').style.display = '';
|
document.getElementById('setup-wizard').style.display = '';
|
||||||
_renderSetupStep();
|
_renderSetupStep();
|
||||||
} else if (_isFirstRun()) {
|
} else {
|
||||||
showSetupWizard();
|
// Check for any missing settings and show wizard only for those
|
||||||
|
const missing = _getMissingSetupSteps();
|
||||||
|
if (missing.length > 0) {
|
||||||
|
showSetupWizard(missing);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Migrate old session-based flags to time-based
|
// Migrate old session-based flags to time-based
|
||||||
|
|||||||
Reference in New Issue
Block a user