implemented step 09 by Gemini
- added 3. step of wizard with smart questions
This commit is contained in:
@ -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"}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -106,10 +106,27 @@
|
||||
|
||||
<!-- Step 3: Služby a smart otázky -->
|
||||
<div class="step" data-step="3">
|
||||
<h2>Služby</h2>
|
||||
<p class="step-description">Čo presne ponúkate vašim zákazníkom?</p>
|
||||
<div class="form-placeholder">
|
||||
<p>Obsah pre krok 3...</p>
|
||||
<h2>Služby a doplňujúce otázky</h2>
|
||||
<p class="step-description">Čo presne ponúkate vašim zákazníkom? AI na základe týchto dát pripraví texty.</p>
|
||||
|
||||
<div class="form-section">
|
||||
<h3>Vaše hlavné služby</h3>
|
||||
<div id="services-list">
|
||||
<!-- Service items will be added here -->
|
||||
</div>
|
||||
<button id="btn-add-service" class="btn-secondary" style="margin-top: 1rem;">+ Pridať službu</button>
|
||||
|
||||
<div class="form-group" style="margin-top: 2rem;">
|
||||
<label for="pricing-note">Poznámka k cenám (voliteľné)</label>
|
||||
<input type="text" id="pricing-note" placeholder="Napr. Ceny sú orientačné, Konečná cena po obhliadke...">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="smart-questions-container" class="form-section">
|
||||
<h3>Doplňujúce informácie</h3>
|
||||
<div id="smart-questions-list">
|
||||
<!-- Smart questions will be injected here -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@ -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 = `
|
||||
<div class="service-item-header">
|
||||
<span class="service-number">Služba</span>
|
||||
<button class="btn-remove-service" title="Odstrániť">×</button>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Názov služby *</label>
|
||||
<input type="text" class="service-name" placeholder="Napr. Klasická masáž" value="${data.name || ''}" required>
|
||||
</div>
|
||||
<div class="form-grid">
|
||||
<div class="form-group">
|
||||
<label>Cena od (€)</label>
|
||||
<input type="text" class="service-price" placeholder="25" value="${data.price_from || ''}">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Stručný popis</label>
|
||||
<input type="text" class="service-desc" placeholder="Trvanie 45 minút..." value="${data.description || ''}">
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
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 = `
|
||||
<div class="checkbox-group">
|
||||
<input type="checkbox" id="sq-${q.id}" data-id="${q.id}">
|
||||
<label for="sq-${q.id}">${q.name}</label>
|
||||
</div>
|
||||
`;
|
||||
} else {
|
||||
qDiv.innerHTML = `
|
||||
<div class="form-group">
|
||||
<label for="sq-${q.id}">${q.name}</label>
|
||||
<input type="text" id="sq-${q.id}" data-id="${q.id}" placeholder="Vaša odpoveď...">
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
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) {
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user