From c01eb306327ed758457e788b5a7f403467b4d300 Mon Sep 17 00:00:00 2001 From: igor Date: Sun, 14 Jun 2026 09:06:03 +0200 Subject: [PATCH] implemented step 11 - sections on website --- public/css/wizard.css | 43 +++++++++++++- public/index.html | 91 +++++++++++++++++++++++++++-- public/js/wizard.js | 104 +++++++++++++++++++++++++++++++++ src/Actions/ProjectActions.php | 28 +++++++++ 4 files changed, 260 insertions(+), 6 deletions(-) diff --git a/public/css/wizard.css b/public/css/wizard.css index 5b53ad0..2ee7cb8 100644 --- a/public/css/wizard.css +++ b/public/css/wizard.css @@ -216,7 +216,7 @@ label { font-size: 0.875rem; } -textarea, input[type="text"], input[type="email"] { +textarea, input[type="text"], input[type="email"], input[type="password"] { width: 100%; padding: 0.75rem; border: 1px solid var(--border-color); @@ -225,7 +225,7 @@ textarea, input[type="text"], input[type="email"] { font-size: 0.875rem; } -textarea:focus, input[type="text"]:focus, input[type="email"]:focus { +textarea:focus, input[type="text"]:focus, input[type="email"]:focus, input[type="password"]:focus { outline: none; border-color: var(--primary-color); box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.1); @@ -398,6 +398,45 @@ textarea:focus, input[type="text"]:focus, input[type="email"]:focus { border-radius: 0.25rem; } +/* Checkbox Grid */ +.checkbox-grid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); + gap: 1rem; +} + +/* Radio Group Tabs */ +.radio-group-tabs { + display: flex; + gap: 0.5rem; + background-color: #f1f5f9; + padding: 0.25rem; + border-radius: 0.5rem; + margin-top: 0.5rem; +} + +.radio-group-tabs input[type="radio"] { + display: none; +} + +.radio-group-tabs label { + flex: 1; + text-align: center; + padding: 0.5rem; + cursor: pointer; + border-radius: 0.375rem; + transition: all 0.2s; + font-size: 0.875rem; + margin-bottom: 0; +} + +.radio-group-tabs input[type="radio"]:checked + label { + background-color: white; + box-shadow: 0 1px 3px rgba(0,0,0,0.1); + color: var(--primary-color); + font-weight: 600; +} + .gallery-upload-grid { display: flex; flex-wrap: wrap; diff --git a/public/index.html b/public/index.html index bf7a856..1299a5f 100644 --- a/public/index.html +++ b/public/index.html @@ -214,10 +214,93 @@
-

Moduly webu

-

Vyberte si sekcie a funkcie vášho webu.

-
-

Obsah pre krok 5...

+

Moduly a funkcie webu

+

Vyberte si sekcie, ktoré chcete mať na úvodnej stránke a nastavte kontaktný formulár.

+ +
+

Sekcie domovskej stránky

+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+ +
+

Kontaktný formulár

+
+ + +
+ +
+ +
+ + + + + +
+ +
+ + +

Týmto heslom sa budete prihlasovať do zabezpečeného priečinka so správami.

+
+ + +
diff --git a/public/js/wizard.js b/public/js/wizard.js index 321e80e..fd9c74b 100644 --- a/public/js/wizard.js +++ b/public/js/wizard.js @@ -102,6 +102,48 @@ const App = { } else { this.addServiceItem(); } + + // Step 4 + if (wd.visuals) { + this.state.selection.style = wd.visuals.style; + this.state.selection.palette = wd.visuals.palette; + this.updateStyleSelection(); + this.updatePaletteSelection(); + } + if (wd.assets) { + this.state.selection.logo = wd.assets.logo; + this.state.selection.gallery = wd.assets.gallery || []; + if (this.state.selection.logo) this.renderLogoPreview(); + this.renderGalleryPreviews(); + } + + // Step 5 + if (wd.modules) { + const m = wd.modules; + if (m.sections) { + m.sections.forEach(sec => { + const el = document.querySelector(`input[data-module="${sec}"]`); + if (el) el.checked = true; + }); + } + if (m.contact_form) { + document.getElementById('form-enabled').checked = m.contact_form.enabled; + document.getElementById('form-config-container').classList.toggle('hidden', !m.contact_form.enabled); + + if (m.contact_form.mode) { + document.querySelector(`input[name="form-mode"][value="${m.contact_form.mode}"]`).checked = true; + document.getElementById('config-local').classList.toggle('hidden', m.contact_form.mode !== 'local'); + document.getElementById('config-smtp').classList.toggle('hidden', m.contact_form.mode !== 'smtp'); + } + + if (m.contact_form.smtp) { + document.getElementById('smtp-host').value = m.contact_form.smtp.host || ''; + document.getElementById('smtp-port').value = m.contact_form.smtp.port || ''; + document.getElementById('smtp-user').value = m.contact_form.smtp.user || ''; + document.getElementById('smtp-recipient').value = m.contact_form.smtp.recipient || ''; + } + } + } } }, @@ -212,6 +254,18 @@ const App = { document.getElementById('gallery-add-box').addEventListener('click', () => document.getElementById('gallery-input').click()); document.getElementById('gallery-input').addEventListener('change', (e) => this.handleFileUpload(e, 'gallery')); + + // Step 5 events + document.getElementById('form-enabled').addEventListener('change', (e) => { + document.getElementById('form-config-container').classList.toggle('hidden', !e.target.checked); + }); + + document.querySelectorAll('input[name="form-mode"]').forEach(radio => { + radio.addEventListener('change', (e) => { + document.getElementById('config-local').classList.toggle('hidden', e.target.value !== 'local'); + document.getElementById('config-smtp').classList.toggle('hidden', e.target.value !== 'smtp'); + }); + }); }, renderCategories() { @@ -610,6 +664,46 @@ const App = { alert('Nepodarilo sa uložiť dáta: ' + error.message); return; } + } else if (this.state.currentStep === 5) { + const sections = []; + document.querySelectorAll('input[data-module]:checked').forEach(el => { + sections.push(el.getAttribute('data-module')); + }); + + const formEnabled = document.getElementById('form-enabled').checked; + const formMode = document.querySelector('input[name="form-mode"]:checked').value; + + const modulesData = { + pages: ['home'], + sections: sections, + contact_form: { + enabled: formEnabled, + mode: formMode, + smtp: formMode === 'smtp' ? { + host: document.getElementById('smtp-host').value, + port: document.getElementById('smtp-port').value, + user: document.getElementById('smtp-user').value, + pass: document.getElementById('smtp-pass').value, + recipient: document.getElementById('smtp-recipient').value + } : null, + local_viewer: formMode === 'local' ? { + password: document.getElementById('local-password').value + } : null + } + }; + + try { + await this.apiCall('saveStep', { + step: 5, + data: { + modules: modulesData + } + }); + } catch (error) { + console.error('Save step 5 failed:', error); + alert('Nepodarilo sa uložiť dáta: ' + error.message); + return; + } } if (this.state.currentStep < this.state.totalSteps) { @@ -641,6 +735,16 @@ const App = { nextDisabled = !name || !gdpr || (!email && !phone); } else if (this.state.currentStep === 4) { nextDisabled = !this.state.selection.style || !this.state.selection.palette; + } else if (this.state.currentStep === 5) { + const formEnabled = document.getElementById('form-enabled').checked; + if (formEnabled) { + const mode = document.querySelector('input[name="form-mode"]:checked').value; + if (mode === 'local') { + nextDisabled = !document.getElementById('local-password').value; + } else { + nextDisabled = !document.getElementById('smtp-host').value || !document.getElementById('smtp-recipient').value; + } + } } btnNext.disabled = nextDisabled; diff --git a/src/Actions/ProjectActions.php b/src/Actions/ProjectActions.php index 08a7ec3..8fc7e0d 100644 --- a/src/Actions/ProjectActions.php +++ b/src/Actions/ProjectActions.php @@ -171,6 +171,34 @@ class ProjectActions $projectData['wizard_data']['visuals'] = $data['visuals']; $projectData['wizard_data']['assets'] = $data['assets']; break; + + case 5: + if (!isset($data['modules'])) { + throw new Exception("Missing modules data.", 400); + } + + $modules = $data['modules']; + + // Secure local password if present + if ($modules['contact_form']['enabled'] && $modules['contact_form']['mode'] === 'local') { + if (!empty($modules['contact_form']['local_viewer']['password'])) { + $modules['contact_form']['local_viewer']['password_hash'] = password_hash( + $modules['contact_form']['local_viewer']['password'], + PASSWORD_DEFAULT + ); + // Never store plain-text password + unset($modules['contact_form']['local_viewer']['password']); + } else { + // Keep existing hash if password not provided (updating other fields) + $oldHash = $projectData['wizard_data']['modules']['contact_form']['local_viewer']['password_hash'] ?? null; + if ($oldHash) { + $modules['contact_form']['local_viewer']['password_hash'] = $oldHash; + } + } + } + + $projectData['wizard_data']['modules'] = $modules; + break; // More steps will be added later }