implemented step 06 by Gemini

- added skeleton for wizard
This commit is contained in:
2026-06-12 18:08:20 +02:00
parent 071aa2f5c9
commit b4960c4e39
3 changed files with 370 additions and 0 deletions

149
public/css/wizard.css Normal file
View File

@ -0,0 +1,149 @@
:root {
--primary-color: #2563eb;
--primary-hover: #1d4ed8;
--bg-color: #f8fafc;
--card-bg: #ffffff;
--text-main: #1e293b;
--text-muted: #64748b;
--border-color: #e2e8f0;
--success-color: #22c55e;
}
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
background-color: var(--bg-color);
color: var(--text-main);
line-height: 1.5;
display: flex;
flex-direction: column;
min-height: 100vh;
}
header {
background-color: var(--card-bg);
border-bottom: 1px solid var(--border-color);
padding: 1rem 2rem;
text-align: center;
}
main {
flex: 1;
display: flex;
justify-content: center;
align-items: flex-start;
padding: 2rem;
}
.wizard-container {
background-color: var(--card-bg);
width: 100%;
max-width: 800px;
border-radius: 0.75rem;
box-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
overflow: hidden;
}
.progress-bar {
height: 0.5rem;
background-color: var(--border-color);
width: 100%;
}
.progress-fill {
height: 100%;
background-color: var(--primary-color);
width: 0%;
transition: width 0.3s ease;
}
.wizard-content {
padding: 2.5rem;
}
.step {
display: none;
}
.step.active {
display: block;
animation: fadeIn 0.3s ease-in-out;
}
@keyframes fadeIn {
from { opacity: 0; transform: translateY(10px); }
to { opacity: 1; transform: translateY(0); }
}
h2 {
margin-bottom: 1rem;
font-size: 1.5rem;
}
p.step-description {
color: var(--text-muted);
margin-bottom: 2rem;
}
.wizard-footer {
padding: 1.5rem 2.5rem;
background-color: #f1f5f9;
display: flex;
justify-content: space-between;
border-top: 1px solid var(--border-color);
}
button {
padding: 0.625rem 1.25rem;
border-radius: 0.375rem;
font-weight: 500;
cursor: pointer;
transition: all 0.2s;
font-size: 0.875rem;
}
.btn-secondary {
background-color: transparent;
border: 1px solid var(--border-color);
color: var(--text-main);
}
.btn-secondary:hover {
background-color: #e2e8f0;
}
.btn-primary {
background-color: var(--primary-color);
border: 1px solid var(--primary-color);
color: white;
}
.btn-primary:hover {
background-color: var(--primary-hover);
}
button:disabled {
opacity: 0.5;
cursor: not-allowed;
}
.hidden {
display: none;
}
@media (max-width: 640px) {
main {
padding: 1rem;
}
.wizard-content {
padding: 1.5rem;
}
.wizard-footer {
padding: 1rem 1.5rem;
}
}

104
public/index.html Normal file
View File

@ -0,0 +1,104 @@
<!DOCTYPE html>
<html lang="sk">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>WebWizard - AI Website Concierge</title>
<link rel="stylesheet" href="css/wizard.css">
</head>
<body>
<header>
<h1>WebWizard</h1>
</header>
<main>
<div class="wizard-container">
<div class="progress-bar">
<div class="progress-fill"></div>
</div>
<div class="wizard-content">
<!-- Step 1: Segmentácia biznisu -->
<div class="step active" data-step="1">
<h2>Oblasť podnikania</h2>
<p class="step-description">V čom podnikáte? Pomôže nám to prispôsobiť váš web.</p>
<div class="form-placeholder">
<!-- Budúce formulárové prvky -->
<p>Obsah pre krok 1...</p>
</div>
</div>
<!-- Step 2: Identita, kontakt a GDPR -->
<div class="step" data-step="2">
<h2>Identita a kontakt</h2>
<p class="step-description">Základné informácie o vašej firme a GDPR súhlas.</p>
<div class="form-placeholder">
<p>Obsah pre krok 2...</p>
</div>
</div>
<!-- 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>
</div>
</div>
<!-- Step 4: Vizuálny štýl -->
<div class="step" data-step="4">
<h2>Vizuálny štýl</h2>
<p class="step-description">Ako by mal váš nový web vyzerať?</p>
<div class="form-placeholder">
<p>Obsah pre krok 4...</p>
</div>
</div>
<!-- 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>
</div>
</div>
<!-- Step 6: Generovanie -->
<div class="step" data-step="6">
<h2>Generovanie obsahu</h2>
<p class="step-description">Naša AI teraz pripravuje váš textový obsah.</p>
<div class="form-placeholder">
<p>Obsah pre krok 6...</p>
</div>
</div>
<!-- Step 7: Preview -->
<div class="step" data-step="7">
<h2>Náhľad webu</h2>
<p class="step-description">Pozrite si, ako vyzerá váš nový web.</p>
<div class="form-placeholder">
<p>Obsah pre krok 7...</p>
</div>
</div>
<!-- Step 8: Export -->
<div class="step" data-step="8">
<h2>Hotovo!</h2>
<p class="step-description">Váš web je pripravený na stiahnutie.</p>
<div class="form-placeholder">
<p>Obsah pre krok 8...</p>
</div>
</div>
</div>
<div class="wizard-footer">
<button id="btn-prev" class="btn-secondary" disabled>Späť</button>
<button id="btn-next" class="btn-primary">Pokračovať</button>
</div>
</div>
</main>
<script src="js/wizard.js"></script>
</body>
</html>

117
public/js/wizard.js Normal file
View File

@ -0,0 +1,117 @@
/**
* WebWizard Frontend Logic
*/
const App = {
state: {
userId: localStorage.getItem('ww_user_id'),
currentStep: 1,
totalSteps: 8,
project: null
},
async init() {
console.log('Initializing WebWizard...');
if (!this.state.userId) {
await this.initSession();
}
this.bindEvents();
this.showStep(this.state.currentStep);
},
async initSession() {
try {
const response = await this.apiCall('initSession');
if (response.success) {
this.state.userId = response.data.user_id;
localStorage.setItem('ww_user_id', this.state.userId);
console.log('Session initialized:', this.state.userId);
}
} catch (error) {
console.error('Failed to initialize session:', error);
alert('Chyba pri inicializácii session. Skontrolujte pripojenie.');
}
},
async apiCall(action, payload = {}, projectId = null) {
const body = {
action,
project_id: projectId,
payload
};
const headers = {
'Content-Type': 'application/json'
};
if (this.state.userId) {
headers['X-User-ID'] = this.state.userId;
}
const response = await fetch('/ajax.php', {
method: 'POST',
headers,
body: JSON.stringify(body)
});
const result = await response.json();
if (!result.success) {
throw new Error(result.error.message || 'API Error');
}
return result;
},
bindEvents() {
document.getElementById('btn-next').addEventListener('click', () => this.nextStep());
document.getElementById('btn-prev').addEventListener('click', () => this.prevStep());
},
showStep(n) {
const steps = document.querySelectorAll('.step');
steps.forEach(step => step.classList.remove('active'));
const activeStep = document.querySelector(`.step[data-step="${n}"]`);
if (activeStep) {
activeStep.classList.add('active');
}
this.state.currentStep = n;
this.updateUI();
},
nextStep() {
if (this.state.currentStep < this.state.totalSteps) {
this.showStep(this.state.currentStep + 1);
}
},
prevStep() {
if (this.state.currentStep > 1) {
this.showStep(this.state.currentStep - 1);
}
},
updateUI() {
// Update buttons
const btnPrev = document.getElementById('btn-prev');
const btnNext = document.getElementById('btn-next');
btnPrev.disabled = this.state.currentStep === 1;
if (this.state.currentStep === this.state.totalSteps) {
btnNext.textContent = 'Dokončiť';
} else {
btnNext.textContent = 'Pokračovať';
}
// Update progress bar
const progressFill = document.querySelector('.progress-fill');
const percent = ((this.state.currentStep - 1) / (this.state.totalSteps - 1)) * 100;
progressFill.style.width = `${percent}%`;
}
};
document.addEventListener('DOMContentLoaded', () => App.init());