From 991ff9de000a498f1f20f2ce8b6ef0ebc3a12ab6 Mon Sep 17 00:00:00 2001 From: igor Date: Sun, 14 Jun 2026 07:41:52 +0200 Subject: [PATCH] implemented step 09 by Gemini - added 3. step of wizard with smart questions --- data/categories.json | 28 +++++++ public/css/wizard.css | 36 +++++++++ public/index.html | 25 +++++- public/js/wizard.js | 139 +++++++++++++++++++++++++++++++++ src/Actions/ProjectActions.php | 8 ++ 5 files changed, 232 insertions(+), 4 deletions(-) diff --git a/data/categories.json b/data/categories.json index a06ecb5..5ab36aa 100644 --- a/data/categories.json +++ b/data/categories.json @@ -9,6 +9,12 @@ {"id": "cafe", "name": "Kaviareň / Bistro"}, {"id": "bar", "name": "Bar / Pub"}, {"id": "catering", "name": "Catering"} + ], + "smart_questions": [ + {"id": "delivery", "name": "Ponúkate donášku?", "type": "boolean"}, + {"id": "reservation", "name": "Prijímate rezervácie vopred?", "type": "boolean"}, + {"id": "parking", "name": "Máte k dispozícii parkovisko pre zákazníkov?", "type": "boolean"}, + {"id": "terrace", "name": "Máte letnú terasu?", "type": "boolean"} ] }, { @@ -20,6 +26,12 @@ {"id": "nails", "name": "Manikúra / Pedikúra"}, {"id": "fitness", "name": "Fitness / Gym"}, {"id": "dentist", "name": "Zubár / Poliklinika"} + ], + "smart_questions": [ + {"id": "booking_online", "name": "Umožňujete online objednávky?", "type": "boolean"}, + {"id": "gift_vouchers", "name": "Predávate darčekové poukážky?", "type": "boolean"}, + {"id": "first_visit_discount", "name": "Ponúkate zľavu na prvú návštevu?", "type": "boolean"}, + {"id": "parking", "name": "Je v blízkosti parkovanie?", "type": "boolean"} ] }, { @@ -31,6 +43,12 @@ {"id": "builder", "name": "Stavebné práce"}, {"id": "mechanic", "name": "Autoservis"}, {"id": "cleaning", "name": "Upratovacie služby"} + ], + "smart_questions": [ + {"id": "emergency_service", "name": "Poskytujete havarijnú službu 24/7?", "type": "boolean"}, + {"id": "warranty", "name": "Poskytujete na prácu predĺženú záruku?", "type": "boolean"}, + {"id": "free_quote", "name": "Je obhliadka a cenová ponuka zdarma?", "type": "boolean"}, + {"id": "materials_included", "name": "Zabezpečujete aj nákup materiálu?", "type": "boolean"} ] }, { @@ -42,6 +60,12 @@ {"id": "consulting", "name": "Konzultant / Kouč"}, {"id": "marketing", "name": "Marketingová agentúra"}, {"id": "it_services", "name": "IT služby / Software"} + ], + "smart_questions": [ + {"id": "online_consultation", "name": "Umožňujete online konzultácie?", "type": "boolean"}, + {"id": "fixed_prices", "name": "Máte fixné cenníky služieb?", "type": "boolean"}, + {"id": "international", "name": "Pôsobíte aj medzinárodne?", "type": "boolean"}, + {"id": "languages", "name": "V akých jazykoch komunikujete?", "type": "text"} ] }, { @@ -49,6 +73,10 @@ "name": "Iné", "subcategories": [ {"id": "custom", "name": "Vlastná kategória"} + ], + "smart_questions": [ + {"id": "unique_selling_point", "name": "V čom ste jedinečný oproti konkurencii?", "type": "text"}, + {"id": "target_audience", "name": "Kto sú vaši hlavní zákazníci?", "type": "text"} ] } ] diff --git a/public/css/wizard.css b/public/css/wizard.css index 3a8b207..0bbde85 100644 --- a/public/css/wizard.css +++ b/public/css/wizard.css @@ -277,6 +277,42 @@ textarea:focus, input[type="text"]:focus, input[type="email"]:focus { font-weight: 400; } +/* Service Items */ +.service-item { + background-color: #f8fafc; + border: 1px solid var(--border-color); + border-radius: 0.5rem; + padding: 1.25rem; + margin-bottom: 1rem; + position: relative; +} + +.service-item-header { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 1rem; +} + +.btn-remove-service { + background: none; + border: none; + color: #ef4444; + cursor: pointer; + padding: 0.25rem; + font-size: 1.25rem; + line-height: 1; +} + +.btn-remove-service:hover { + color: #dc2626; +} + +/* Smart Questions */ +.smart-question-item { + margin-bottom: 1.5rem; +} + button:disabled { opacity: 0.5; cursor: not-allowed; diff --git a/public/index.html b/public/index.html index 7dd8cc9..a021f8b 100644 --- a/public/index.html +++ b/public/index.html @@ -106,10 +106,27 @@
-

Služby

-

Čo presne ponúkate vašim zákazníkom?

-
-

Obsah pre krok 3...

+

Služby a doplňujúce otázky

+

Čo presne ponúkate vašim zákazníkom? AI na základe týchto dát pripraví texty.

+ +
+

Vaše hlavné služby

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

Doplňujúce informácie

+
+ +
diff --git a/public/js/wizard.js b/public/js/wizard.js index 68aa8cf..5a7e1b1 100644 --- a/public/js/wizard.js +++ b/public/js/wizard.js @@ -88,6 +88,16 @@ const App = { document.getElementById('contact-facebook').value = wd.contact.socials?.facebook || ''; document.getElementById('contact-instagram').value = wd.contact.socials?.instagram || ''; } + + // Step 3 + if (wd.services && wd.services.items) { + const list = document.getElementById('services-list'); + list.innerHTML = ''; + wd.services.items.forEach(item => this.addServiceItem(item)); + document.getElementById('pricing-note').value = wd.services.pricing_note || ''; + } else { + this.addServiceItem(); + } } }, @@ -174,6 +184,9 @@ const App = { el.addEventListener('change', () => this.updateUI()); } }); + + // Step 3 events + document.getElementById('btn-add-service').addEventListener('click', () => this.addServiceItem()); }, renderCategories() { @@ -209,6 +222,7 @@ const App = { this.renderCategories(); this.renderSubcategories(categoryId); + this.renderSmartQuestions(categoryId); document.getElementById('subcategory-container').classList.remove('hidden'); @@ -241,6 +255,92 @@ const App = { }); }, + addServiceItem(data = {}) { + const container = document.getElementById('services-list'); + const itemDiv = document.createElement('div'); + itemDiv.className = 'service-item'; + + itemDiv.innerHTML = ` +
+ Služba + +
+
+ + +
+
+
+ + +
+
+ + +
+
+ `; + + itemDiv.querySelector('.btn-remove-service').addEventListener('click', () => { + if (container.querySelectorAll('.service-item').length > 1) { + itemDiv.remove(); + } else { + alert('Zadajte aspoň jednu službu.'); + } + }); + + container.appendChild(itemDiv); + }, + + renderSmartQuestions(categoryId) { + const container = document.getElementById('smart-questions-list'); + container.innerHTML = ''; + + const category = this.state.categories.find(c => c.id === categoryId); + if (!category || !category.smart_questions) { + document.getElementById('smart-questions-container').classList.add('hidden'); + return; + } + + document.getElementById('smart-questions-container').classList.remove('hidden'); + + category.smart_questions.forEach(q => { + const qDiv = document.createElement('div'); + qDiv.className = 'smart-question-item'; + + if (q.type === 'boolean') { + qDiv.innerHTML = ` +
+ + +
+ `; + } else { + qDiv.innerHTML = ` +
+ + +
+ `; + } + + container.appendChild(qDiv); + + // Apply existing answer if available + if (this.state.project && this.state.project.wizard_data.smart_answers) { + const answer = this.state.project.wizard_data.smart_answers[q.id]; + if (answer !== undefined) { + const input = qDiv.querySelector(`#sq-${q.id}`); + if (q.type === 'boolean') { + input.checked = !!answer; + } else { + input.value = answer; + } + } + } + }); + }, + showStep(n) { const steps = document.querySelectorAll('.step'); steps.forEach(step => step.classList.remove('active')); @@ -324,6 +424,45 @@ const App = { alert('Nepodarilo sa uložiť dáta: ' + error.message); return; } + } else if (this.state.currentStep === 3) { + const serviceItems = []; + document.querySelectorAll('.service-item').forEach(item => { + const name = item.querySelector('.service-name').value; + if (name) { + serviceItems.push({ + name: name, + price_from: item.querySelector('.service-price').value, + description: item.querySelector('.service-desc').value + }); + } + }); + + const smartAnswers = {}; + document.querySelectorAll('.smart-question-item input').forEach(input => { + const id = input.getAttribute('data-id'); + if (input.type === 'checkbox') { + smartAnswers[id] = input.checked; + } else { + smartAnswers[id] = input.value; + } + }); + + try { + await this.apiCall('saveStep', { + step: 3, + data: { + services: { + items: serviceItems, + pricing_note: document.getElementById('pricing-note').value + }, + smart_answers: smartAnswers + } + }); + } catch (error) { + console.error('Save step 3 failed:', error); + alert('Nepodarilo sa uložiť dáta: ' + error.message); + return; + } } if (this.state.currentStep < this.state.totalSteps) { diff --git a/src/Actions/ProjectActions.php b/src/Actions/ProjectActions.php index c68d1b0..c7184b5 100644 --- a/src/Actions/ProjectActions.php +++ b/src/Actions/ProjectActions.php @@ -156,6 +156,14 @@ class ProjectActions $projectData['wizard_data']['contact'] = $data['contact']; break; + case 3: + if (!isset($data['services']) || !isset($data['smart_answers'])) { + throw new Exception("Missing services or smart_answers data.", 400); + } + $projectData['wizard_data']['services'] = $data['services']; + $projectData['wizard_data']['smart_answers'] = $data['smart_answers']; + break; + // More steps will be added later }