implemented step 11
- sections on website
This commit is contained in:
@ -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;
|
||||
|
||||
@ -214,10 +214,93 @@
|
||||
|
||||
<!-- Step 5: Moduly -->
|
||||
<div class="step" data-step="5">
|
||||
<h2>Moduly webu</h2>
|
||||
<p class="step-description">Vyberte si sekcie a funkcie vášho webu.</p>
|
||||
<div class="form-placeholder">
|
||||
<p>Obsah pre krok 5...</p>
|
||||
<h2>Moduly a funkcie webu</h2>
|
||||
<p class="step-description">Vyberte si sekcie, ktoré chcete mať na úvodnej stránke a nastavte kontaktný formulár.</p>
|
||||
|
||||
<div class="form-section">
|
||||
<h3>Sekcie domovskej stránky</h3>
|
||||
<div class="checkbox-grid">
|
||||
<div class="checkbox-group">
|
||||
<input type="checkbox" id="mod-hero" data-module="hero" checked disabled>
|
||||
<label for="mod-hero">Hero sekcia (Úvod)</label>
|
||||
</div>
|
||||
<div class="checkbox-group">
|
||||
<input type="checkbox" id="mod-about" data-module="about">
|
||||
<label for="mod-about">O nás</label>
|
||||
</div>
|
||||
<div class="checkbox-group">
|
||||
<input type="checkbox" id="mod-services" data-module="services" checked>
|
||||
<label for="mod-services">Služby</label>
|
||||
</div>
|
||||
<div class="checkbox-group">
|
||||
<input type="checkbox" id="mod-pricing" data-module="pricing">
|
||||
<label for="mod-pricing">Cenník</label>
|
||||
</div>
|
||||
<div class="checkbox-group">
|
||||
<input type="checkbox" id="mod-gallery" data-module="gallery">
|
||||
<label for="mod-gallery">Galéria</label>
|
||||
</div>
|
||||
<div class="checkbox-group">
|
||||
<input type="checkbox" id="mod-faq" data-module="faq">
|
||||
<label for="mod-faq">Časté otázky (FAQ)</label>
|
||||
</div>
|
||||
<div class="checkbox-group">
|
||||
<input type="checkbox" id="mod-contact" data-module="contact" checked disabled>
|
||||
<label for="mod-contact">Kontakt</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-section">
|
||||
<h3>Kontaktný formulár</h3>
|
||||
<div class="checkbox-group" style="margin-bottom: 1.5rem;">
|
||||
<input type="checkbox" id="form-enabled" checked>
|
||||
<label for="form-enabled">Aktivovať kontaktný formulár na webe</label>
|
||||
</div>
|
||||
|
||||
<div id="form-config-container">
|
||||
<label>Spôsob spracovania správ</label>
|
||||
<div class="radio-group-tabs">
|
||||
<input type="radio" id="mode-local" name="form-mode" value="local" checked>
|
||||
<label for="mode-local">Lokálny mód (Prezeranie v administrácii)</label>
|
||||
|
||||
<input type="radio" id="mode-smtp" name="form-mode" value="smtp">
|
||||
<label for="mode-smtp">Email (SMTP odosielanie)</label>
|
||||
</div>
|
||||
|
||||
<div id="config-local" class="form-group" style="margin-top: 1.5rem;">
|
||||
<label for="local-password">Heslo pre prístup k správam *</label>
|
||||
<input type="password" id="local-password" placeholder="Zadajte bezpečné heslo">
|
||||
<p class="form-hint">Týmto heslom sa budete prihlasovať do zabezpečeného priečinka so správami.</p>
|
||||
</div>
|
||||
|
||||
<div id="config-smtp" class="hidden" style="margin-top: 1.5rem;">
|
||||
<div class="form-grid">
|
||||
<div class="form-group">
|
||||
<label for="smtp-host">SMTP Host</label>
|
||||
<input type="text" id="smtp-host" placeholder="smtp.priklad.sk">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="smtp-port">Port</label>
|
||||
<input type="text" id="smtp-port" placeholder="465">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-grid">
|
||||
<div class="form-group">
|
||||
<label for="smtp-user">Užívateľské meno</label>
|
||||
<input type="text" id="smtp-user" placeholder="meno@domena.sk">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="smtp-pass">Heslo</label>
|
||||
<input type="password" id="smtp-pass">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="smtp-recipient">Cieľový email pre správy</label>
|
||||
<input type="email" id="smtp-recipient" placeholder="info@vasadomena.sk">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user