diff --git a/public/css/wizard.css b/public/css/wizard.css
index 3c524a5..3a8b207 100644
--- a/public/css/wizard.css
+++ b/public/css/wizard.css
@@ -216,7 +216,7 @@ label {
font-size: 0.875rem;
}
-textarea, input[type="text"] {
+textarea, input[type="text"], input[type="email"] {
width: 100%;
padding: 0.75rem;
border: 1px solid var(--border-color);
@@ -225,12 +225,58 @@ textarea, input[type="text"] {
font-size: 0.875rem;
}
-textarea:focus, input[type="text"]:focus {
+textarea:focus, input[type="text"]:focus, input[type="email"]:focus {
outline: none;
border-color: var(--primary-color);
box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.1);
}
+.form-section {
+ margin-bottom: 2.5rem;
+}
+
+.form-section h3 {
+ font-size: 1.125rem;
+ margin-bottom: 1.25rem;
+ padding-bottom: 0.5rem;
+ border-bottom: 1px solid var(--border-color);
+}
+
+.form-grid {
+ display: grid;
+ grid-template-columns: 1fr 1fr;
+ gap: 1rem;
+}
+
+.form-hint {
+ font-size: 0.75rem;
+ color: var(--text-muted);
+ margin-top: 0.5rem;
+}
+
+.checkbox-group {
+ display: flex;
+ align-items: flex-start;
+ gap: 0.75rem;
+ padding: 1rem;
+ background-color: #f8fafc;
+ border-radius: 0.375rem;
+ border: 1px solid var(--border-color);
+}
+
+.checkbox-group input[type="checkbox"] {
+ margin-top: 0.25rem;
+ width: 1rem;
+ height: 1rem;
+ cursor: pointer;
+}
+
+.checkbox-group label {
+ margin-bottom: 0;
+ cursor: pointer;
+ font-weight: 400;
+}
+
button:disabled {
opacity: 0.5;
cursor: not-allowed;
diff --git a/public/index.html b/public/index.html
index 667206c..7dd8cc9 100644
--- a/public/index.html
+++ b/public/index.html
@@ -43,9 +43,64 @@
Identita a kontakt
-
Základné informácie o vašej firme a GDPR súhlas.
-
diff --git a/public/js/wizard.js b/public/js/wizard.js
index c324a51..68aa8cf 100644
--- a/public/js/wizard.js
+++ b/public/js/wizard.js
@@ -57,16 +57,36 @@ const App = {
},
syncSelectionWithProject() {
- if (this.state.project && this.state.project.wizard_data.business_category) {
- const bc = this.state.project.wizard_data.business_category;
- this.state.selection.category = bc.group;
- this.state.selection.subcategory = bc.subcategory;
- this.state.selection.customDescription = bc.custom_description || '';
+ if (this.state.project && this.state.project.wizard_data) {
+ const wd = this.state.project.wizard_data;
- if (this.state.selection.category) {
- this.selectCategory(this.state.selection.category);
- this.state.selection.subcategory = bc.subcategory; // restore after selectCategory resets it
- this.renderSubcategories(this.state.selection.category);
+ // Step 1
+ if (wd.business_category) {
+ const bc = wd.business_category;
+ this.state.selection.category = bc.group;
+ this.state.selection.subcategory = bc.subcategory;
+ this.state.selection.customDescription = bc.custom_description || '';
+
+ if (this.state.selection.category) {
+ this.selectCategory(this.state.selection.category);
+ this.state.selection.subcategory = bc.subcategory;
+ this.renderSubcategories(this.state.selection.category);
+ }
+ }
+
+ // Step 2
+ if (wd.identity) {
+ document.getElementById('business-name').value = wd.identity.business_name || '';
+ document.getElementById('business-tagline').value = wd.identity.tagline || '';
+ document.getElementById('business-description').value = wd.identity.description || '';
+ }
+ if (wd.contact) {
+ document.getElementById('contact-email').value = wd.contact.email || '';
+ document.getElementById('contact-phone').value = wd.contact.phone || '';
+ document.getElementById('contact-address').value = wd.contact.address || '';
+ document.getElementById('contact-city').value = wd.contact.city || '';
+ document.getElementById('contact-facebook').value = wd.contact.socials?.facebook || '';
+ document.getElementById('contact-instagram').value = wd.contact.socials?.instagram || '';
}
}
},
@@ -145,6 +165,15 @@ const App = {
document.getElementById('custom-description').addEventListener('input', (e) => {
this.state.selection.customDescription = e.target.value;
});
+
+ // Step 2 validation listeners
+ ['business-name', 'gdpr-consent', 'contact-email', 'contact-phone'].forEach(id => {
+ const el = document.getElementById(id);
+ if (el) {
+ el.addEventListener('input', () => this.updateUI());
+ el.addEventListener('change', () => this.updateUI());
+ }
+ });
},
renderCategories() {
@@ -248,6 +277,53 @@ const App = {
alert('Nepodarilo sa uložiť dáta.');
return;
}
+ } else if (this.state.currentStep === 2) {
+ const businessName = document.getElementById('business-name').value;
+ const tagline = document.getElementById('business-tagline').value;
+ const description = document.getElementById('business-description').value;
+ const email = document.getElementById('contact-email').value;
+ const phone = document.getElementById('contact-phone').value;
+ const address = document.getElementById('contact-address').value;
+ const city = document.getElementById('contact-city').value;
+ const gdpr = document.getElementById('gdpr-consent').checked;
+
+ if (!businessName || !gdpr || (!email && !phone)) {
+ alert('Prosím, vyplňte povinné údaje a zaškrtnite GDPR súhlas.');
+ return;
+ }
+
+ try {
+ // 1. Save Consent
+ await this.apiCall('saveConsent', {
+ consent_text: document.querySelector('label[for="gdpr-consent"]').textContent
+ });
+
+ // 2. Save Step 2
+ await this.apiCall('saveStep', {
+ step: 2,
+ data: {
+ identity: {
+ business_name: businessName,
+ tagline: tagline,
+ description: description
+ },
+ contact: {
+ email: email,
+ phone: phone,
+ address: address,
+ city: city,
+ socials: {
+ facebook: document.getElementById('contact-facebook').value,
+ instagram: document.getElementById('contact-instagram').value
+ }
+ }
+ }
+ });
+ } catch (error) {
+ console.error('Save step 2 failed:', error);
+ alert('Nepodarilo sa uložiť dáta: ' + error.message);
+ return;
+ }
}
if (this.state.currentStep < this.state.totalSteps) {
@@ -267,6 +343,20 @@ const App = {
btnPrev.disabled = this.state.currentStep === 1;
+ // Validation for Next button
+ let nextDisabled = false;
+ if (this.state.currentStep === 1) {
+ nextDisabled = !this.state.selection.category || !this.state.selection.subcategory;
+ } else if (this.state.currentStep === 2) {
+ const name = document.getElementById('business-name').value;
+ const email = document.getElementById('contact-email').value;
+ const phone = document.getElementById('contact-phone').value;
+ const gdpr = document.getElementById('gdpr-consent').checked;
+ nextDisabled = !name || !gdpr || (!email && !phone);
+ }
+
+ btnNext.disabled = nextDisabled;
+
if (this.state.currentStep === this.state.totalSteps) {
btnNext.textContent = 'Dokončiť';
} else {
diff --git a/src/Actions/ProjectActions.php b/src/Actions/ProjectActions.php
index e661f71..c68d1b0 100644
--- a/src/Actions/ProjectActions.php
+++ b/src/Actions/ProjectActions.php
@@ -137,6 +137,25 @@ class ProjectActions
$projectData['wizard_data']['business_category'] = $data['business_category'];
break;
+ case 2:
+ // Verify GDPR consent
+ $consentService = new \App\Services\ConsentService();
+ if (!$consentService->hasConsent($projectId)) {
+ throw new Exception("GDPR consent is required before saving identity and contact data.", 403);
+ }
+
+ if (empty($data['identity']['business_name'])) {
+ throw new Exception("Business name is required.", 400);
+ }
+
+ if (empty($data['contact']['email']) && empty($data['contact']['phone'])) {
+ throw new Exception("Either email or phone is required.", 400);
+ }
+
+ $projectData['wizard_data']['identity'] = $data['identity'];
+ $projectData['wizard_data']['contact'] = $data['contact'];
+ break;
+
// More steps will be added later
}