Some checks are pending
NordaBiz Tests / Unit & Integration Tests (push) Waiting to run
NordaBiz Tests / E2E Tests (Playwright) (push) Blocked by required conditions
NordaBiz Tests / Smoke Tests (Production) (push) Blocked by required conditions
NordaBiz Tests / Send Failure Notification (push) Blocked by required conditions
KRS for PROS POLAND has no www/email/phone. All Brave results are directory sites (filtered). Show clear message about what's missing from registry. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1193 lines
52 KiB
HTML
1193 lines
52 KiB
HTML
{% extends "base.html" %}
|
|
|
|
{% block title %}Kreator Dodawania Firmy - Norda Biznes Partner{% endblock %}
|
|
|
|
{% block extra_css %}
|
|
<style>
|
|
.wizard-container {
|
|
max-width: 860px;
|
|
margin: 0 auto;
|
|
}
|
|
|
|
.wizard-header {
|
|
margin-bottom: var(--spacing-2xl);
|
|
text-align: center;
|
|
}
|
|
|
|
.wizard-header h1 {
|
|
font-size: var(--font-size-2xl);
|
|
color: var(--text-primary);
|
|
margin: 0 0 var(--spacing-md) 0;
|
|
}
|
|
|
|
.wizard-steps {
|
|
display: flex;
|
|
justify-content: center;
|
|
gap: var(--spacing-lg);
|
|
margin-bottom: var(--spacing-lg);
|
|
flex-wrap: wrap;
|
|
}
|
|
|
|
.wizard-step {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: var(--spacing-sm);
|
|
color: var(--text-secondary);
|
|
font-size: var(--font-size-sm);
|
|
cursor: default;
|
|
}
|
|
|
|
.wizard-step.active { color: var(--primary); font-weight: 600; }
|
|
.wizard-step.completed { color: var(--success); }
|
|
|
|
.step-number {
|
|
width: 32px; height: 32px;
|
|
border-radius: 50%;
|
|
background: var(--border);
|
|
display: flex; align-items: center; justify-content: center;
|
|
font-weight: 600; font-size: var(--font-size-sm);
|
|
}
|
|
|
|
.wizard-step.active .step-number { background: var(--primary); color: white; }
|
|
.wizard-step.completed .step-number { background: var(--success); color: white; }
|
|
|
|
.wizard-content {
|
|
background: var(--surface);
|
|
padding: var(--spacing-2xl);
|
|
border-radius: var(--radius-lg);
|
|
box-shadow: var(--shadow);
|
|
}
|
|
|
|
.step-panel { display: none; }
|
|
.step-panel.active { display: block; }
|
|
|
|
.form-section { margin-bottom: var(--spacing-xl); }
|
|
.form-section h2 {
|
|
font-size: var(--font-size-lg);
|
|
color: var(--text-primary);
|
|
margin: 0 0 var(--spacing-lg) 0;
|
|
padding-bottom: var(--spacing-sm);
|
|
border-bottom: 2px solid var(--border);
|
|
}
|
|
|
|
.form-group { margin-bottom: var(--spacing-lg); }
|
|
.form-group label {
|
|
display: block; font-weight: 500;
|
|
margin-bottom: var(--spacing-xs); color: var(--text-primary);
|
|
}
|
|
.form-group label .required { color: var(--error); }
|
|
|
|
.form-control {
|
|
width: 100%;
|
|
padding: var(--spacing-sm) var(--spacing-md);
|
|
border: 1px solid var(--border);
|
|
border-radius: var(--radius);
|
|
font-size: var(--font-size-base);
|
|
transition: var(--transition);
|
|
background: var(--surface);
|
|
color: var(--text-primary);
|
|
}
|
|
.form-control:focus { outline: none; border-color: var(--primary); box-shadow: 0 0 0 3px rgba(var(--primary-rgb), 0.1); }
|
|
|
|
.form-row {
|
|
display: grid;
|
|
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
|
gap: var(--spacing-md);
|
|
}
|
|
|
|
.form-hint { font-size: var(--font-size-sm); color: var(--text-secondary); margin-top: var(--spacing-xs); }
|
|
|
|
.nip-input-row { display: flex; gap: var(--spacing-sm); }
|
|
.nip-input-row .form-control { flex: 1; }
|
|
|
|
.btn-wizard {
|
|
padding: var(--spacing-sm) var(--spacing-xl);
|
|
border: none; border-radius: var(--radius);
|
|
font-size: var(--font-size-base); font-weight: 500;
|
|
cursor: pointer; transition: var(--transition);
|
|
display: inline-flex; align-items: center; gap: var(--spacing-sm);
|
|
}
|
|
.btn-wizard:disabled { opacity: 0.5; cursor: not-allowed; }
|
|
.btn-primary { background: var(--primary); color: white; }
|
|
.btn-primary:hover:not(:disabled) { opacity: 0.9; }
|
|
.btn-secondary { background: var(--surface); color: var(--text-primary); border: 1px solid var(--border); }
|
|
.btn-secondary:hover:not(:disabled) { background: var(--background); }
|
|
.btn-success { background: var(--success); color: white; }
|
|
.btn-success:hover:not(:disabled) { opacity: 0.9; }
|
|
.btn-danger { background: var(--error); color: white; }
|
|
.btn-danger:hover:not(:disabled) { opacity: 0.9; }
|
|
.btn-link { background: none; border: none; color: var(--primary); cursor: pointer; padding: 0; font-size: var(--font-size-sm); text-decoration: underline; }
|
|
|
|
.wizard-actions {
|
|
display: flex; justify-content: space-between; align-items: center;
|
|
margin-top: var(--spacing-xl);
|
|
padding-top: var(--spacing-lg);
|
|
border-top: 1px solid var(--border);
|
|
}
|
|
|
|
/* Status indicators */
|
|
.status-badge {
|
|
display: inline-flex; align-items: center; gap: var(--spacing-xs);
|
|
padding: 2px var(--spacing-sm);
|
|
border-radius: var(--radius-full);
|
|
font-size: var(--font-size-xs); font-weight: 600;
|
|
}
|
|
.status-badge.krs { background: rgba(59, 130, 246, 0.1); color: #3b82f6; }
|
|
.status-badge.ceidg { background: rgba(16, 185, 129, 0.1); color: #10b981; }
|
|
.status-badge.manual { background: rgba(245, 158, 11, 0.1); color: #f59e0b; }
|
|
|
|
.lookup-status {
|
|
margin-top: var(--spacing-sm); padding: var(--spacing-sm) var(--spacing-md);
|
|
background: var(--background); border-radius: var(--radius);
|
|
font-size: var(--font-size-sm); color: var(--text-secondary);
|
|
}
|
|
.lookup-status.loading { background: rgba(59, 130, 246, 0.1); color: #3b82f6; }
|
|
.lookup-status.success { background: rgba(16, 185, 129, 0.05); color: var(--success); }
|
|
.lookup-status.error { background: rgba(239, 68, 68, 0.05); color: var(--error); }
|
|
|
|
.registry-preview {
|
|
background: var(--background); border: 1px solid var(--border);
|
|
border-radius: var(--radius); padding: var(--spacing-lg);
|
|
margin-top: var(--spacing-md);
|
|
}
|
|
.registry-preview.success { border-color: var(--success); background: rgba(var(--success-rgb), 0.03); }
|
|
.registry-preview h4 {
|
|
margin: 0 0 var(--spacing-sm) 0; color: var(--success);
|
|
display: flex; align-items: center; gap: var(--spacing-sm);
|
|
}
|
|
|
|
.registry-data { display: grid; gap: var(--spacing-xs); }
|
|
.registry-data-row { display: flex; gap: var(--spacing-sm); }
|
|
.registry-data-label { font-weight: 500; color: var(--text-secondary); min-width: 120px; }
|
|
|
|
/* Logo gallery */
|
|
.logo-gallery {
|
|
display: grid; grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
|
|
gap: var(--spacing-md); margin-top: var(--spacing-md);
|
|
}
|
|
.logo-candidate {
|
|
position: relative; padding: var(--spacing-sm); border: 2px solid var(--border);
|
|
border-radius: var(--radius); text-align: center; cursor: pointer;
|
|
transition: var(--transition); background: var(--surface);
|
|
}
|
|
.logo-candidate:hover { border-color: var(--primary); }
|
|
.logo-candidate.selected { border-color: var(--success); background: rgba(var(--success-rgb), 0.03); }
|
|
.logo-candidate img { max-width: 100%; max-height: 80px; object-fit: contain; }
|
|
.logo-candidate .label { font-size: var(--font-size-xs); color: var(--text-secondary); margin-top: var(--spacing-xs); }
|
|
.logo-candidate.recommended::after {
|
|
content: 'Rekomendowane'; position: absolute; top: -8px; right: -8px;
|
|
background: var(--primary); color: white; font-size: 10px;
|
|
padding: 1px 6px; border-radius: var(--radius-full);
|
|
}
|
|
|
|
/* Audit cards */
|
|
.audit-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: var(--spacing-md); }
|
|
.audit-card {
|
|
padding: var(--spacing-lg); border: 1px solid var(--border);
|
|
border-radius: var(--radius); background: var(--surface);
|
|
}
|
|
.audit-card-header { display: flex; align-items: center; gap: var(--spacing-sm); margin-bottom: var(--spacing-sm); }
|
|
.audit-card-header h3 { margin: 0; font-size: var(--font-size-base); }
|
|
.audit-icon { font-size: var(--font-size-xl); }
|
|
.audit-status {
|
|
display: inline-flex; align-items: center; gap: var(--spacing-xs);
|
|
font-size: var(--font-size-sm); padding: 2px var(--spacing-sm);
|
|
border-radius: var(--radius-full);
|
|
}
|
|
.audit-status.pending { background: var(--background); color: var(--text-secondary); }
|
|
.audit-status.running { background: rgba(59, 130, 246, 0.1); color: #3b82f6; }
|
|
.audit-status.completed { background: rgba(16, 185, 129, 0.1); color: #10b981; }
|
|
.audit-status.error { background: rgba(239, 68, 68, 0.1); color: #ef4444; }
|
|
.audit-status.skipped { background: var(--background); color: var(--text-secondary); }
|
|
.audit-score { font-size: var(--font-size-2xl); font-weight: 700; margin-top: var(--spacing-sm); }
|
|
|
|
@keyframes spin { to { transform: rotate(360deg); } }
|
|
.spinner { display: inline-block; width: 14px; height: 14px; border: 2px solid currentColor; border-top-color: transparent; border-radius: 50%; animation: spin 0.8s linear infinite; }
|
|
|
|
/* Summary cards */
|
|
.summary-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: var(--spacing-md); }
|
|
.summary-card {
|
|
padding: var(--spacing-lg); border: 1px solid var(--border);
|
|
border-radius: var(--radius); background: var(--surface);
|
|
}
|
|
.summary-card h3 {
|
|
margin: 0 0 var(--spacing-md) 0; font-size: var(--font-size-base);
|
|
color: var(--text-primary); padding-bottom: var(--spacing-sm);
|
|
border-bottom: 1px solid var(--border);
|
|
}
|
|
.summary-row { display: flex; justify-content: space-between; padding: var(--spacing-xs) 0; }
|
|
.summary-label { color: var(--text-secondary); font-size: var(--font-size-sm); }
|
|
.summary-value { font-weight: 500; font-size: var(--font-size-sm); }
|
|
|
|
.success-message {
|
|
text-align: center; padding: var(--spacing-2xl);
|
|
}
|
|
.success-message h2 { color: var(--success); margin-bottom: var(--spacing-md); }
|
|
|
|
/* Draft resume banner */
|
|
.draft-banner {
|
|
background: rgba(245, 158, 11, 0.1); border: 1px solid rgba(245, 158, 11, 0.3);
|
|
border-radius: var(--radius); padding: var(--spacing-md) var(--spacing-lg);
|
|
margin-bottom: var(--spacing-lg); display: flex; justify-content: space-between; align-items: center;
|
|
}
|
|
.draft-banner-text { font-size: var(--font-size-sm); color: var(--text-primary); }
|
|
.draft-banner-actions { display: flex; gap: var(--spacing-sm); }
|
|
|
|
@media (max-width: 768px) {
|
|
.wizard-steps { gap: var(--spacing-sm); }
|
|
.wizard-step span { display: none; }
|
|
.wizard-content { padding: var(--spacing-lg); }
|
|
.form-row { grid-template-columns: 1fr; }
|
|
.logo-gallery { grid-template-columns: repeat(auto-fill, minmax(90px, 1fr)); }
|
|
.audit-cards { grid-template-columns: 1fr; }
|
|
.summary-grid { grid-template-columns: 1fr; }
|
|
}
|
|
</style>
|
|
{% endblock %}
|
|
|
|
{% block content %}
|
|
<div class="wizard-container">
|
|
<div class="wizard-header">
|
|
<h1>Kreator Dodawania Firmy</h1>
|
|
<div class="wizard-steps" id="wizardSteps">
|
|
<div class="wizard-step active" data-step="1">
|
|
<div class="step-number">1</div>
|
|
<span>NIP</span>
|
|
</div>
|
|
<div class="wizard-step" data-step="2">
|
|
<div class="step-number">2</div>
|
|
<span>Dane</span>
|
|
</div>
|
|
<div class="wizard-step" data-step="3">
|
|
<div class="step-number">3</div>
|
|
<span>Logo</span>
|
|
</div>
|
|
<div class="wizard-step" data-step="4">
|
|
<div class="step-number">4</div>
|
|
<span>Audyty</span>
|
|
</div>
|
|
<div class="wizard-step" data-step="5">
|
|
<div class="step-number">5</div>
|
|
<span>Zapis</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{% if draft %}
|
|
<div class="draft-banner" id="draftBanner">
|
|
<div class="draft-banner-text">
|
|
Masz nieukończony szkic: <strong>{{ draft.name }}</strong> (NIP: {{ draft.nip }}, krok {{ draft.step }})
|
|
</div>
|
|
<div class="draft-banner-actions">
|
|
<button class="btn-wizard btn-primary" onclick="resumeDraft({{ draft.id }}, {{ draft.step }})">Wznów</button>
|
|
<button class="btn-wizard btn-secondary" onclick="cancelDraft({{ draft.id }})">Usuń szkic</button>
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
|
|
<div class="wizard-content">
|
|
<!-- ==================== STEP 1: NIP ==================== -->
|
|
<div class="step-panel active" id="step1">
|
|
<div class="form-section">
|
|
<h2>Wyszukaj firmę po NIP</h2>
|
|
<p class="form-hint" style="margin-bottom: var(--spacing-lg)">
|
|
Wpisz NIP firmy. System automatycznie pobierze dane z KRS lub CEIDG.
|
|
</p>
|
|
<div class="form-group">
|
|
<label>NIP <span class="required">*</span></label>
|
|
<div class="nip-input-row">
|
|
<input type="text" id="nipInput" class="form-control"
|
|
placeholder="np. 5851491213" maxlength="10"
|
|
oninput="this.value=this.value.replace(/[^0-9]/g,'')">
|
|
<button class="btn-wizard btn-primary" id="btnCheckNip" onclick="checkNip()">
|
|
Sprawdź
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<div id="nipStatus" style="display:none"></div>
|
|
<div id="registryPreview" style="display:none"></div>
|
|
</div>
|
|
|
|
<div class="wizard-actions">
|
|
<a href="{{ url_for('admin.admin_companies') }}" class="btn-wizard btn-secondary">Anuluj</a>
|
|
<button class="btn-wizard btn-primary" id="btnStep1Next" disabled onclick="goToStep(2)">
|
|
Dalej
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- ==================== STEP 2: EDIT DATA ==================== -->
|
|
<div class="step-panel" id="step2">
|
|
<div class="form-section">
|
|
<h2>Dane firmy</h2>
|
|
<p class="form-hint" style="margin-bottom: var(--spacing-lg)">
|
|
Sprawdź i popraw dane pobrane z rejestru. Pola oznaczone <span class="required">*</span> są wymagane.
|
|
</p>
|
|
|
|
<div class="form-group">
|
|
<label>Nazwa firmy <span class="required">*</span></label>
|
|
<input type="text" id="editName" class="form-control">
|
|
</div>
|
|
<div class="form-group">
|
|
<label>Nazwa prawna</label>
|
|
<input type="text" id="editLegalName" class="form-control">
|
|
</div>
|
|
|
|
<div class="form-row">
|
|
<div class="form-group">
|
|
<label>Kategoria</label>
|
|
<select id="editCategory" class="form-control">
|
|
<option value="">-- Wybierz --</option>
|
|
{% for cat in categories %}
|
|
<option value="{{ cat.id }}">{{ cat.name }}</option>
|
|
{% endfor %}
|
|
</select>
|
|
</div>
|
|
<div class="form-group">
|
|
<label>Forma prawna</label>
|
|
<input type="text" id="editLegalForm" class="form-control" readonly
|
|
style="background: var(--background);">
|
|
</div>
|
|
</div>
|
|
|
|
<div class="form-row">
|
|
<div class="form-group">
|
|
<label>NIP</label>
|
|
<input type="text" id="editNip" class="form-control" readonly
|
|
style="background: var(--background);">
|
|
</div>
|
|
<div class="form-group">
|
|
<label>REGON</label>
|
|
<input type="text" id="editRegon" class="form-control" readonly
|
|
style="background: var(--background);">
|
|
</div>
|
|
<div class="form-group">
|
|
<label>KRS</label>
|
|
<input type="text" id="editKrs" class="form-control" readonly
|
|
style="background: var(--background);">
|
|
</div>
|
|
</div>
|
|
|
|
<h2 style="margin-top: var(--spacing-xl)">Adres</h2>
|
|
<div class="form-group">
|
|
<label>Ulica i numer</label>
|
|
<input type="text" id="editStreet" class="form-control">
|
|
</div>
|
|
<div class="form-row">
|
|
<div class="form-group">
|
|
<label>Kod pocztowy</label>
|
|
<input type="text" id="editPostal" class="form-control" placeholder="XX-XXX">
|
|
</div>
|
|
<div class="form-group">
|
|
<label>Miasto</label>
|
|
<input type="text" id="editCity" class="form-control">
|
|
</div>
|
|
</div>
|
|
|
|
<h2 style="margin-top: var(--spacing-xl)">Kontakt</h2>
|
|
<div class="form-row">
|
|
<div class="form-group">
|
|
<label>Email</label>
|
|
<input type="email" id="editEmail" class="form-control">
|
|
</div>
|
|
<div class="form-group">
|
|
<label>Telefon</label>
|
|
<input type="text" id="editPhone" class="form-control">
|
|
</div>
|
|
</div>
|
|
<div class="form-group">
|
|
<label>Strona WWW</label>
|
|
<div class="nip-input-row">
|
|
<input type="text" id="editWebsite" class="form-control" placeholder="https://">
|
|
<button class="btn-wizard btn-secondary" id="btnDiscoverWebsite" onclick="discoverWebsite()">
|
|
Wyszukaj stronę
|
|
</button>
|
|
</div>
|
|
<div id="discoverStatus" style="display:none"></div>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label>Krótki opis</label>
|
|
<textarea id="editDescShort" class="form-control" rows="3"
|
|
placeholder="Krótki opis firmy (widoczny w katalogu)"></textarea>
|
|
</div>
|
|
|
|
<!-- Read-only section: PKD, people -->
|
|
<div id="readOnlySection" style="display:none">
|
|
<h2 style="margin-top: var(--spacing-xl)">Dane z rejestru (tylko do odczytu)</h2>
|
|
<div id="pkdList" class="form-hint"></div>
|
|
<div id="peopleList" class="form-hint" style="margin-top: var(--spacing-sm)"></div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="wizard-actions">
|
|
<button class="btn-wizard btn-secondary" onclick="goToStep(1)">Wstecz</button>
|
|
<button class="btn-wizard btn-primary" id="btnStep2Next" onclick="saveStep2()">
|
|
Dalej
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- ==================== STEP 3: LOGO ==================== -->
|
|
<div class="step-panel" id="step3">
|
|
<div class="form-section">
|
|
<h2>Strona internetowa i logo</h2>
|
|
<p class="form-hint" style="margin-bottom: var(--spacing-lg)">
|
|
Pobierz logo ze strony internetowej firmy. Możesz też pominąć ten krok.
|
|
</p>
|
|
|
|
<div class="form-group">
|
|
<label>Adres strony WWW</label>
|
|
<div class="nip-input-row">
|
|
<input type="text" id="logoWebsite" class="form-control" placeholder="https://">
|
|
<button class="btn-wizard btn-primary" id="btnFetchLogos" onclick="fetchLogos()">
|
|
Pobierz logo
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="logoStatus" style="display:none"></div>
|
|
<div id="logoGallery" class="logo-gallery" style="display:none"></div>
|
|
<div id="logoActions" style="display:none; margin-top: var(--spacing-md)">
|
|
<button class="btn-wizard btn-success" id="btnSelectLogo" onclick="selectLogo()">
|
|
Zatwierdz wybrane logo
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="wizard-actions">
|
|
<button class="btn-wizard btn-secondary" onclick="goToStep(2)">Wstecz</button>
|
|
<div>
|
|
<button class="btn-link" onclick="skipStep3()" style="margin-right: var(--spacing-lg)">Pomiń logo</button>
|
|
<button class="btn-wizard btn-primary" id="btnStep3Next" onclick="goToStep(4)" disabled>
|
|
Dalej
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- ==================== STEP 4: AUDITS ==================== -->
|
|
<div class="step-panel" id="step4">
|
|
<div class="form-section">
|
|
<h2>Audyty</h2>
|
|
<p class="form-hint" style="margin-bottom: var(--spacing-lg)">
|
|
Uruchom automatyczne audyty SEO, Google Business Profile i Social Media.
|
|
Możesz też pominąć ten krok — audyty można uruchomić później.
|
|
</p>
|
|
|
|
<div class="audit-cards" id="auditCards">
|
|
<div class="audit-card" id="auditSeo">
|
|
<div class="audit-card-header">
|
|
<span class="audit-icon">🔍</span>
|
|
<h3>SEO</h3>
|
|
</div>
|
|
<div class="audit-status pending" id="auditSeoStatus">Oczekuje...</div>
|
|
<div class="audit-score" id="auditSeoScore" style="display:none"></div>
|
|
</div>
|
|
<div class="audit-card" id="auditGbp">
|
|
<div class="audit-card-header">
|
|
<span class="audit-icon">📍</span>
|
|
<h3>Google Business</h3>
|
|
</div>
|
|
<div class="audit-status pending" id="auditGbpStatus">Oczekuje...</div>
|
|
<div class="audit-score" id="auditGbpScore" style="display:none"></div>
|
|
</div>
|
|
<div class="audit-card" id="auditSocial">
|
|
<div class="audit-card-header">
|
|
<span class="audit-icon">📱</span>
|
|
<h3>Social Media</h3>
|
|
</div>
|
|
<div class="audit-status pending" id="auditSocialStatus">Oczekuje...</div>
|
|
<div class="audit-score" id="auditSocialScore" style="display:none"></div>
|
|
</div>
|
|
</div>
|
|
|
|
<div style="text-align: center; margin-top: var(--spacing-lg)">
|
|
<button class="btn-wizard btn-primary" id="btnStartAudits" onclick="startAudits()">
|
|
Uruchom wszystkie audyty
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="wizard-actions">
|
|
<button class="btn-wizard btn-secondary" onclick="goToStep(3)">Wstecz</button>
|
|
<div>
|
|
<button class="btn-link" onclick="skipStep4()" style="margin-right: var(--spacing-lg)">Pomiń audyty</button>
|
|
<button class="btn-wizard btn-primary" id="btnStep4Next" onclick="goToStep(5)">
|
|
Dalej
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- ==================== STEP 5: SUMMARY ==================== -->
|
|
<div class="step-panel" id="step5">
|
|
<div class="form-section" id="summarySection">
|
|
<h2>Podsumowanie</h2>
|
|
<p class="form-hint" style="margin-bottom: var(--spacing-lg)">
|
|
Sprawdź dane firmy przed zapisaniem. Po zatwierdzeniu firma pojawi się na portalu.
|
|
</p>
|
|
|
|
<div class="summary-grid" id="summaryGrid">
|
|
<!-- Filled by JS -->
|
|
</div>
|
|
|
|
<div class="form-row" style="margin-top: var(--spacing-xl)">
|
|
<div class="form-group">
|
|
<label>Status firmy</label>
|
|
<select id="finalStatus" class="form-control">
|
|
<option value="active">Aktywna (widoczna na portalu)</option>
|
|
<option value="pending">Oczekująca (ukryta)</option>
|
|
</select>
|
|
</div>
|
|
<div class="form-group">
|
|
<label>Kategoria</label>
|
|
<select id="finalCategory" class="form-control">
|
|
<option value="">-- Bez zmian --</option>
|
|
{% for cat in categories %}
|
|
<option value="{{ cat.id }}">{{ cat.name }}</option>
|
|
{% endfor %}
|
|
</select>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="success-message" id="successMessage" style="display:none">
|
|
<h2>Firma dodana pomyślnie!</h2>
|
|
<p id="successDetails"></p>
|
|
<div style="margin-top: var(--spacing-lg); display: flex; justify-content: center; gap: var(--spacing-md);">
|
|
<a id="linkToCompany" href="#" class="btn-wizard btn-primary">Zobacz profil firmy</a>
|
|
<a href="{{ url_for('admin.admin_companies') }}" class="btn-wizard btn-secondary">Lista firm</a>
|
|
<a href="{{ url_for('admin.company_wizard') }}" class="btn-wizard btn-success">Dodaj kolejną</a>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="wizard-actions" id="finalActions">
|
|
<button class="btn-wizard btn-secondary" onclick="goToStep(4)">Wstecz</button>
|
|
<button class="btn-wizard btn-success" id="btnFinalize" onclick="finalize()">
|
|
Zapisz firme
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endblock %}
|
|
|
|
{% block extra_js %}
|
|
var wizardState = {
|
|
companyId: null,
|
|
currentStep: 1,
|
|
registrySource: null,
|
|
companyData: {},
|
|
selectedLogoIndex: null,
|
|
auditPollTimer: null
|
|
};
|
|
|
|
// ==================== NAVIGATION ====================
|
|
|
|
function goToStep(step) {
|
|
// Hide all panels
|
|
document.querySelectorAll('.step-panel').forEach(function(p) { p.classList.remove('active'); });
|
|
document.getElementById('step' + step).classList.add('active');
|
|
|
|
// Update step indicators
|
|
document.querySelectorAll('.wizard-step').forEach(function(s) {
|
|
var sn = parseInt(s.dataset.step);
|
|
s.classList.remove('active', 'completed');
|
|
if (sn === step) s.classList.add('active');
|
|
else if (sn < step) s.classList.add('completed');
|
|
});
|
|
|
|
wizardState.currentStep = step;
|
|
|
|
// Step-specific init
|
|
if (step === 2) populateEditForm();
|
|
if (step === 3) document.getElementById('logoWebsite').value = wizardState.companyData.website || '';
|
|
if (step === 5) buildSummary();
|
|
}
|
|
|
|
// ==================== STEP 1: NIP CHECK ====================
|
|
|
|
function checkNip() {
|
|
var nip = document.getElementById('nipInput').value.trim().replace(/[-\s]/g, '');
|
|
if (nip.length !== 10) {
|
|
showNipStatus('Wpisz 10 cyfr NIP', 'error');
|
|
return;
|
|
}
|
|
|
|
var btn = document.getElementById('btnCheckNip');
|
|
btn.disabled = true;
|
|
btn.innerHTML = '<span class="spinner"></span> Sprawdzam...';
|
|
showNipStatus('Szukam firmy w rejestrach KRS i CEIDG\u2026', 'loading');
|
|
document.getElementById('registryPreview').style.display = 'none';
|
|
|
|
fetch('/admin/companies/wizard/step1', {
|
|
method: 'POST',
|
|
headers: {'Content-Type': 'application/json', 'X-CSRFToken': getCSRF()},
|
|
body: JSON.stringify({nip: nip})
|
|
})
|
|
.then(function(r) { return r.json().then(function(d) { return {ok: r.ok, data: d}; }); })
|
|
.then(function(res) {
|
|
btn.disabled = false;
|
|
btn.innerHTML = 'Sprawdź';
|
|
|
|
if (!res.ok || !res.data.success) {
|
|
var errMsg = res.data.error || 'Nieznany b\u0142\u0105d';
|
|
showNipStatus(errMsg, 'error');
|
|
if (res.data.existing_id) {
|
|
document.getElementById('nipStatus').innerHTML +=
|
|
' <a href="/admin/companies/' + res.data.existing_id + '/detail" style="color:var(--primary)">' +
|
|
'Zobacz istniejaca firme</a>';
|
|
}
|
|
return;
|
|
}
|
|
|
|
var c = res.data.company;
|
|
wizardState.companyId = c.id;
|
|
wizardState.companyData = c;
|
|
wizardState.registrySource = c.registry_source;
|
|
|
|
var sourceLabel = c.registry_source === 'KRS' ? 'KRS' :
|
|
c.registry_source === 'CEIDG' ? 'CEIDG' : 'Ręczne wprowadzanie';
|
|
var sourceClass = (c.registry_source || 'manual').toLowerCase();
|
|
|
|
showNipStatus('Znaleziono firmę w rejestrze', 'success');
|
|
showRegistryPreview(c, sourceLabel, sourceClass);
|
|
document.getElementById('btnStep1Next').disabled = false;
|
|
})
|
|
.catch(function(err) {
|
|
btn.disabled = false;
|
|
btn.innerHTML = 'Sprawdź';
|
|
showNipStatus('Błąd połączenia: ' + err.message, 'error');
|
|
});
|
|
}
|
|
|
|
function showNipStatus(msg, type) {
|
|
var el = document.getElementById('nipStatus');
|
|
el.style.display = 'block';
|
|
el.className = 'lookup-status ' + type;
|
|
el.innerHTML = (type === 'loading' ? '<span class="spinner"></span> ' : '') + msg;
|
|
}
|
|
|
|
function showRegistryPreview(c, sourceLabel, sourceClass) {
|
|
var rows = '';
|
|
if (c.name) rows += '<div class="registry-data-row"><span class="registry-data-label">Nazwa:</span><span>' + esc(c.name) + '</span></div>';
|
|
if (c.legal_name && c.legal_name !== c.name) rows += '<div class="registry-data-row"><span class="registry-data-label">Nazwa prawna:</span><span>' + esc(c.legal_name) + '</span></div>';
|
|
if (c.nip) rows += '<div class="registry-data-row"><span class="registry-data-label">NIP:</span><span>' + c.nip + '</span></div>';
|
|
if (c.regon) rows += '<div class="registry-data-row"><span class="registry-data-label">REGON:</span><span>' + c.regon + '</span></div>';
|
|
if (c.krs) rows += '<div class="registry-data-row"><span class="registry-data-label">KRS:</span><span>' + c.krs + '</span></div>';
|
|
if (c.address_full) rows += '<div class="registry-data-row"><span class="registry-data-label">Adres:</span><span>' + esc(c.address_full) + '</span></div>';
|
|
if (c.legal_form) rows += '<div class="registry-data-row"><span class="registry-data-label">Forma:</span><span>' + esc(c.legal_form) + '</span></div>';
|
|
if (c.website) rows += '<div class="registry-data-row"><span class="registry-data-label">WWW:</span><span>' + esc(c.website) + '</span></div>';
|
|
if (c.email) rows += '<div class="registry-data-row"><span class="registry-data-label">Email:</span><span>' + esc(c.email) + '</span></div>';
|
|
if (c.phone) rows += '<div class="registry-data-row"><span class="registry-data-label">Telefon:</span><span>' + esc(c.phone) + '</span></div>';
|
|
|
|
if (c.pkd_codes && c.pkd_codes.length) {
|
|
var pkdText = c.pkd_codes.map(function(p) {
|
|
return p.code + ' ' + p.description + (p.is_primary ? ' (gl.)' : '');
|
|
}).join(', ');
|
|
rows += '<div class="registry-data-row"><span class="registry-data-label">PKD:</span><span>' + esc(pkdText) + '</span></div>';
|
|
}
|
|
|
|
if (c.people && c.people.length) {
|
|
var pplText = c.people.map(function(p) { return p.name + ' — ' + p.role; }).join(', ');
|
|
rows += '<div class="registry-data-row"><span class="registry-data-label">Zarzad:</span><span>' + esc(pplText) + '</span></div>';
|
|
}
|
|
|
|
var html = '<div class="registry-preview success">' +
|
|
'<h4><span class="status-badge ' + sourceClass + '">' + sourceLabel + '</span> Dane z rejestru</h4>' +
|
|
'<div class="registry-data">' + rows + '</div></div>';
|
|
|
|
var el = document.getElementById('registryPreview');
|
|
el.style.display = 'block';
|
|
el.innerHTML = html;
|
|
}
|
|
|
|
// ==================== STEP 2: EDIT FORM ====================
|
|
|
|
function populateEditForm() {
|
|
var c = wizardState.companyData;
|
|
document.getElementById('editName').value = c.name || '';
|
|
document.getElementById('editLegalName').value = c.legal_name || '';
|
|
document.getElementById('editNip').value = c.nip || '';
|
|
document.getElementById('editRegon').value = c.regon || '';
|
|
document.getElementById('editKrs').value = c.krs || '';
|
|
document.getElementById('editLegalForm').value = c.legal_form || '';
|
|
document.getElementById('editStreet').value = c.address_street || '';
|
|
document.getElementById('editPostal').value = c.address_postal || '';
|
|
document.getElementById('editCity').value = c.address_city || '';
|
|
document.getElementById('editEmail').value = c.email || '';
|
|
document.getElementById('editPhone').value = c.phone || '';
|
|
document.getElementById('editWebsite').value = c.website || '';
|
|
document.getElementById('editDescShort').value = c.description_short || '';
|
|
if (c.category_id) document.getElementById('editCategory').value = c.category_id;
|
|
|
|
// PKD codes
|
|
var pkdEl = document.getElementById('pkdList');
|
|
var roSection = document.getElementById('readOnlySection');
|
|
if (c.pkd_codes && c.pkd_codes.length) {
|
|
pkdEl.innerHTML = '<strong>Kody PKD:</strong> ' + c.pkd_codes.map(function(p) {
|
|
return p.code + ' ' + p.description;
|
|
}).join(' | ');
|
|
roSection.style.display = 'block';
|
|
}
|
|
if (c.people && c.people.length) {
|
|
document.getElementById('peopleList').innerHTML = '<strong>Zarząd:</strong> ' + c.people.map(function(p) {
|
|
return p.name + ' (' + p.role + ')';
|
|
}).join(' | ');
|
|
roSection.style.display = 'block';
|
|
}
|
|
|
|
// Show hint if contact data is missing from registry
|
|
var missing = [];
|
|
if (!c.website) missing.push('strony WWW');
|
|
if (!c.email) missing.push('adresu email');
|
|
if (!c.phone) missing.push('telefonu');
|
|
if (missing.length > 0) {
|
|
var hint = document.getElementById('discoverStatus');
|
|
if (hint) {
|
|
hint.style.display = 'block';
|
|
hint.className = 'lookup-status';
|
|
hint.innerHTML = 'Rejestr ' + (wizardState.registrySource || 'KRS') +
|
|
' nie zawiera: ' + missing.join(', ') +
|
|
'. Użyj przycisku <strong>Wyszukaj stronę</strong> lub uzupełnij ręcznie.';
|
|
}
|
|
}
|
|
}
|
|
|
|
function discoverWebsite() {
|
|
var btn = document.getElementById('btnDiscoverWebsite');
|
|
btn.disabled = true;
|
|
btn.innerHTML = '<span class="spinner"></span> Szukam...';
|
|
var statusEl = document.getElementById('discoverStatus');
|
|
statusEl.style.display = 'block';
|
|
statusEl.className = 'lookup-status loading';
|
|
statusEl.innerHTML = '<span class="spinner"></span> Szukam strony w internecie...';
|
|
|
|
fetch('/admin/companies/wizard/discover-website', {
|
|
method: 'POST',
|
|
headers: {'Content-Type': 'application/json', 'X-CSRFToken': getCSRF()},
|
|
body: JSON.stringify({company_id: wizardState.companyId})
|
|
})
|
|
.then(function(r) { return r.json(); })
|
|
.then(function(data) {
|
|
btn.disabled = false;
|
|
btn.innerHTML = 'Wyszukaj stronę';
|
|
if (data.success && data.website) {
|
|
document.getElementById('editWebsite').value = data.website;
|
|
wizardState.companyData.website = data.website;
|
|
statusEl.className = 'lookup-status success';
|
|
statusEl.innerHTML = 'Znaleziono: ' + esc(data.website);
|
|
} else {
|
|
statusEl.className = 'lookup-status error';
|
|
statusEl.innerHTML = data.error || 'Nie znaleziono strony internetowej';
|
|
}
|
|
})
|
|
.catch(function(err) {
|
|
btn.disabled = false;
|
|
btn.innerHTML = 'Wyszukaj stronę';
|
|
statusEl.className = 'lookup-status error';
|
|
statusEl.innerHTML = 'Błąd: ' + err.message;
|
|
});
|
|
}
|
|
|
|
function saveStep2() {
|
|
var btn = document.getElementById('btnStep2Next');
|
|
btn.disabled = true;
|
|
btn.innerHTML = '<span class="spinner"></span> Zapisuje...';
|
|
|
|
var payload = {
|
|
company_id: wizardState.companyId,
|
|
name: document.getElementById('editName').value.trim(),
|
|
legal_name: document.getElementById('editLegalName').value.trim(),
|
|
category_id: document.getElementById('editCategory').value,
|
|
address_street: document.getElementById('editStreet').value.trim(),
|
|
address_postal: document.getElementById('editPostal').value.trim(),
|
|
address_city: document.getElementById('editCity').value.trim(),
|
|
email: document.getElementById('editEmail').value.trim(),
|
|
phone: document.getElementById('editPhone').value.trim(),
|
|
website: document.getElementById('editWebsite').value.trim(),
|
|
description_short: document.getElementById('editDescShort').value.trim()
|
|
};
|
|
|
|
if (!payload.name) {
|
|
alert('Nazwa firmy jest wymagana');
|
|
btn.disabled = false;
|
|
btn.innerHTML = 'Dalej';
|
|
return;
|
|
}
|
|
|
|
fetch('/admin/companies/wizard/step2', {
|
|
method: 'POST',
|
|
headers: {'Content-Type': 'application/json', 'X-CSRFToken': getCSRF()},
|
|
body: JSON.stringify(payload)
|
|
})
|
|
.then(function(r) { return r.json(); })
|
|
.then(function(data) {
|
|
btn.disabled = false;
|
|
btn.innerHTML = 'Dalej';
|
|
if (data.success) {
|
|
wizardState.companyData = data.company;
|
|
goToStep(3);
|
|
} else {
|
|
alert(data.error || 'Błąd zapisu');
|
|
}
|
|
})
|
|
.catch(function(err) {
|
|
btn.disabled = false;
|
|
btn.innerHTML = 'Dalej';
|
|
alert('Błąd połączenia: ' + err.message);
|
|
});
|
|
}
|
|
|
|
// ==================== STEP 3: LOGO ====================
|
|
|
|
function fetchLogos() {
|
|
var btn = document.getElementById('btnFetchLogos');
|
|
var url = document.getElementById('logoWebsite').value.trim();
|
|
if (!url) { alert('Podaj adres strony WWW'); return; }
|
|
|
|
btn.disabled = true;
|
|
btn.innerHTML = '<span class="spinner"></span> Pobieram...';
|
|
showLogoStatus('Szukam logo na stronie\u2026', 'loading');
|
|
|
|
fetch('/admin/companies/wizard/step3/fetch-logos', {
|
|
method: 'POST',
|
|
headers: {'Content-Type': 'application/json', 'X-CSRFToken': getCSRF()},
|
|
body: JSON.stringify({company_id: wizardState.companyId, website_url: url})
|
|
})
|
|
.then(function(r) { return r.json(); })
|
|
.then(function(data) {
|
|
btn.disabled = false;
|
|
btn.innerHTML = 'Pobierz logo';
|
|
|
|
if (!data.success) {
|
|
showLogoStatus(data.error || 'Nie udało się pobrać logo', 'error');
|
|
return;
|
|
}
|
|
|
|
var candidates = data.candidates || [];
|
|
if (candidates.length === 0) {
|
|
showLogoStatus('Nie znaleziono logo na stronie', 'error');
|
|
return;
|
|
}
|
|
|
|
showLogoStatus('Znaleziono ' + candidates.length + ' kandydatów', 'success');
|
|
renderLogoGallery(candidates, data.recommended_index || 0);
|
|
})
|
|
.catch(function(err) {
|
|
btn.disabled = false;
|
|
btn.innerHTML = 'Pobierz logo';
|
|
showLogoStatus('Błąd: ' + err.message, 'error');
|
|
});
|
|
}
|
|
|
|
function showLogoStatus(msg, type) {
|
|
var el = document.getElementById('logoStatus');
|
|
el.style.display = 'block';
|
|
el.className = 'lookup-status ' + type;
|
|
el.innerHTML = (type === 'loading' ? '<span class="spinner"></span> ' : '') + msg;
|
|
}
|
|
|
|
function renderLogoGallery(candidates, recommendedIdx) {
|
|
var gallery = document.getElementById('logoGallery');
|
|
gallery.style.display = 'grid';
|
|
gallery.innerHTML = '';
|
|
|
|
var slug = wizardState.companyData.slug;
|
|
candidates.forEach(function(cand, i) {
|
|
var ext = cand.ext || 'webp';
|
|
var src = '/static/img/companies/' + slug + '_cand_' + i + '.' + ext + '?t=' + Date.now();
|
|
var div = document.createElement('div');
|
|
div.className = 'logo-candidate' + (i === recommendedIdx ? ' recommended' : '') + (i === recommendedIdx ? ' selected' : '');
|
|
div.innerHTML = '<img src="' + src + '" alt="Kandydat ' + (i + 1) + '" onerror="this.src=\'/static/img/placeholder.png\'">' +
|
|
'<div class="label">' + (cand.source || cand.label || 'Logo ' + (i + 1)) + '</div>';
|
|
div.onclick = function() { selectLogoCandidate(i); };
|
|
gallery.appendChild(div);
|
|
});
|
|
|
|
wizardState.selectedLogoIndex = recommendedIdx;
|
|
document.getElementById('logoActions').style.display = 'block';
|
|
}
|
|
|
|
function selectLogoCandidate(idx) {
|
|
wizardState.selectedLogoIndex = idx;
|
|
document.querySelectorAll('.logo-candidate').forEach(function(el, i) {
|
|
el.classList.toggle('selected', i === idx);
|
|
});
|
|
}
|
|
|
|
function selectLogo() {
|
|
if (wizardState.selectedLogoIndex === null) { alert('Wybierz logo'); return; }
|
|
|
|
var btn = document.getElementById('btnSelectLogo');
|
|
btn.disabled = true;
|
|
btn.innerHTML = '<span class="spinner"></span> Zapisuje...';
|
|
|
|
fetch('/admin/companies/wizard/step3/select-logo', {
|
|
method: 'POST',
|
|
headers: {'Content-Type': 'application/json', 'X-CSRFToken': getCSRF()},
|
|
body: JSON.stringify({company_id: wizardState.companyId, candidate_index: wizardState.selectedLogoIndex})
|
|
})
|
|
.then(function(r) { return r.json(); })
|
|
.then(function(data) {
|
|
btn.disabled = false;
|
|
btn.innerHTML = 'Zatwierdz wybrane logo';
|
|
if (data.success) {
|
|
showLogoStatus('Logo zapisane!', 'success');
|
|
document.getElementById('btnStep3Next').disabled = false;
|
|
wizardState.companyData.logo_path = data.logo_path;
|
|
} else {
|
|
alert(data.error || 'Błąd zapisu logo');
|
|
}
|
|
})
|
|
.catch(function(err) {
|
|
btn.disabled = false;
|
|
btn.innerHTML = 'Zatwierdz wybrane logo';
|
|
alert('Błąd: ' + err.message);
|
|
});
|
|
}
|
|
|
|
function skipStep3() {
|
|
fetch('/admin/companies/wizard/step3/skip', {
|
|
method: 'POST',
|
|
headers: {'Content-Type': 'application/json', 'X-CSRFToken': getCSRF()},
|
|
body: JSON.stringify({company_id: wizardState.companyId})
|
|
}).then(function() { goToStep(4); });
|
|
}
|
|
|
|
// ==================== STEP 4: AUDITS ====================
|
|
|
|
function startAudits() {
|
|
var btn = document.getElementById('btnStartAudits');
|
|
btn.disabled = true;
|
|
btn.innerHTML = '<span class="spinner"></span> Uruchamiam...';
|
|
|
|
fetch('/admin/companies/wizard/step4/start-audits', {
|
|
method: 'POST',
|
|
headers: {'Content-Type': 'application/json', 'X-CSRFToken': getCSRF()},
|
|
body: JSON.stringify({company_id: wizardState.companyId})
|
|
})
|
|
.then(function(r) { return r.json(); })
|
|
.then(function(data) {
|
|
if (data.success) {
|
|
updateAuditUI(data.audit_status);
|
|
wizardState.auditPollTimer = setInterval(pollAuditStatus, 3000);
|
|
} else {
|
|
btn.disabled = false;
|
|
btn.innerHTML = 'Uruchom wszystkie audyty';
|
|
alert(data.error || 'Błąd uruchomienia audytów');
|
|
}
|
|
});
|
|
}
|
|
|
|
function pollAuditStatus() {
|
|
fetch('/admin/companies/wizard/step4/audit-status?company_id=' + wizardState.companyId)
|
|
.then(function(r) { return r.json(); })
|
|
.then(function(data) {
|
|
if (data.success) {
|
|
updateAuditUI(data.audit_status);
|
|
if (data.all_done) {
|
|
clearInterval(wizardState.auditPollTimer);
|
|
wizardState.auditPollTimer = null;
|
|
document.getElementById('btnStartAudits').style.display = 'none';
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
function updateAuditUI(status) {
|
|
var mapping = {
|
|
pending: {label: 'Oczekuje...', cls: 'pending'},
|
|
running: {label: '<span class="spinner"></span> Trwa...', cls: 'running'},
|
|
completed: {label: 'Gotowe', cls: 'completed'},
|
|
skipped: {label: 'Pominięto', cls: 'skipped'},
|
|
not_found: {label: 'Nie znaleziono', cls: 'skipped'}
|
|
};
|
|
|
|
['seo', 'gbp', 'social'].forEach(function(key) {
|
|
var val = status[key] || 'pending';
|
|
var statusEl = document.getElementById('audit' + capitalize(key) + 'Status');
|
|
var scoreEl = document.getElementById('audit' + capitalize(key) + 'Score');
|
|
|
|
if (val.startsWith('error')) {
|
|
statusEl.className = 'audit-status error';
|
|
statusEl.innerHTML = 'Błąd';
|
|
} else {
|
|
var m = mapping[val] || mapping.pending;
|
|
statusEl.className = 'audit-status ' + m.cls;
|
|
statusEl.innerHTML = m.label;
|
|
}
|
|
|
|
// Show score
|
|
var scoreKey = key + '_score';
|
|
if (key === 'social') scoreKey = 'social_count';
|
|
if (status[scoreKey] !== undefined) {
|
|
scoreEl.style.display = 'block';
|
|
if (key === 'social') {
|
|
scoreEl.textContent = status[scoreKey] + ' profili';
|
|
} else {
|
|
scoreEl.textContent = status[scoreKey] + '%';
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
function capitalize(s) { return s.charAt(0).toUpperCase() + s.slice(1); }
|
|
|
|
function skipStep4() {
|
|
if (wizardState.auditPollTimer) {
|
|
clearInterval(wizardState.auditPollTimer);
|
|
wizardState.auditPollTimer = null;
|
|
}
|
|
fetch('/admin/companies/wizard/step4/skip', {
|
|
method: 'POST',
|
|
headers: {'Content-Type': 'application/json', 'X-CSRFToken': getCSRF()},
|
|
body: JSON.stringify({company_id: wizardState.companyId})
|
|
}).then(function() { goToStep(5); });
|
|
}
|
|
|
|
// ==================== STEP 5: SUMMARY ====================
|
|
|
|
function buildSummary() {
|
|
var c = wizardState.companyData;
|
|
var grid = document.getElementById('summaryGrid');
|
|
|
|
var companyCard = '<div class="summary-card"><h3>Dane firmy</h3>' +
|
|
summaryRow('Nazwa', c.name) +
|
|
summaryRow('Nazwa prawna', c.legal_name) +
|
|
summaryRow('NIP', c.nip) +
|
|
summaryRow('REGON', c.regon) +
|
|
summaryRow('KRS', c.krs) +
|
|
summaryRow('Forma', c.legal_form) +
|
|
summaryRow('PKD', c.pkd_code) +
|
|
summaryRow('Źródło danych', wizardState.registrySource) +
|
|
'</div>';
|
|
|
|
var addressCard = '<div class="summary-card"><h3>Adres i kontakt</h3>' +
|
|
summaryRow('Ulica', c.address_street) +
|
|
summaryRow('Kod', c.address_postal) +
|
|
summaryRow('Miasto', c.address_city) +
|
|
summaryRow('Email', c.email) +
|
|
summaryRow('Telefon', c.phone) +
|
|
summaryRow('WWW', c.website) +
|
|
'</div>';
|
|
|
|
var logoHtml = '';
|
|
if (c.logo_path) {
|
|
logoHtml = '<img src="' + c.logo_path + '?t=' + Date.now() + '" style="max-width:80px;max-height:60px;margin-top:var(--spacing-sm)">';
|
|
}
|
|
|
|
var extrasCard = '<div class="summary-card"><h3>Logo i audyty</h3>' +
|
|
summaryRow('Logo', c.logo_path ? 'Tak' : 'Brak') + logoHtml +
|
|
summaryRow('Opis', c.description_short ? 'Tak (' + c.description_short.length + ' zn.)' : 'Brak') +
|
|
'</div>';
|
|
|
|
grid.innerHTML = companyCard + addressCard + extrasCard;
|
|
|
|
// Set category from step 2
|
|
if (c.category_id) {
|
|
document.getElementById('finalCategory').value = c.category_id;
|
|
}
|
|
}
|
|
|
|
function summaryRow(label, value) {
|
|
return '<div class="summary-row"><span class="summary-label">' + label + '</span>' +
|
|
'<span class="summary-value">' + (value ? esc(String(value)) : '<em style="color:var(--text-secondary)">—</em>') + '</span></div>';
|
|
}
|
|
|
|
function finalize() {
|
|
var btn = document.getElementById('btnFinalize');
|
|
btn.disabled = true;
|
|
btn.innerHTML = '<span class="spinner"></span> Zapisuje...';
|
|
|
|
fetch('/admin/companies/wizard/step5/finalize', {
|
|
method: 'POST',
|
|
headers: {'Content-Type': 'application/json', 'X-CSRFToken': getCSRF()},
|
|
body: JSON.stringify({
|
|
company_id: wizardState.companyId,
|
|
status: document.getElementById('finalStatus').value,
|
|
category_id: document.getElementById('finalCategory').value
|
|
})
|
|
})
|
|
.then(function(r) { return r.json(); })
|
|
.then(function(data) {
|
|
if (data.success) {
|
|
document.getElementById('summarySection').style.display = 'none';
|
|
document.getElementById('finalActions').style.display = 'none';
|
|
var msg = document.getElementById('successMessage');
|
|
msg.style.display = 'block';
|
|
document.getElementById('successDetails').innerHTML =
|
|
'<strong>' + esc(data.name) + '</strong> (ID: ' + data.company_id + ')<br>' +
|
|
'Status: ' + data.status + ' | Jakość danych: ' + data.data_quality +
|
|
' (' + data.data_quality_score + '%)';
|
|
document.getElementById('linkToCompany').href = '/company/' + data.slug;
|
|
|
|
// Mark all steps as completed
|
|
document.querySelectorAll('.wizard-step').forEach(function(s) {
|
|
s.classList.remove('active');
|
|
s.classList.add('completed');
|
|
});
|
|
} else {
|
|
btn.disabled = false;
|
|
btn.innerHTML = 'Zapisz firme';
|
|
alert(data.error || 'Błąd zapisu');
|
|
}
|
|
})
|
|
.catch(function(err) {
|
|
btn.disabled = false;
|
|
btn.innerHTML = 'Zapisz firme';
|
|
alert('Błąd: ' + err.message);
|
|
});
|
|
}
|
|
|
|
// ==================== DRAFT RESUME/CANCEL ====================
|
|
|
|
function resumeDraft(companyId, step) {
|
|
wizardState.companyId = companyId;
|
|
// Fetch company data
|
|
fetch('/admin/companies/' + companyId, {headers: {'Accept': 'application/json'}})
|
|
.then(function(r) { return r.json(); })
|
|
.then(function(data) {
|
|
if (data.company) {
|
|
wizardState.companyData = data.company;
|
|
wizardState.registrySource = data.company.data_source || 'manual';
|
|
}
|
|
document.getElementById('draftBanner').style.display = 'none';
|
|
goToStep(Math.max(step, 2));
|
|
})
|
|
.catch(function() {
|
|
goToStep(step);
|
|
});
|
|
}
|
|
|
|
function cancelDraft(companyId) {
|
|
if (!confirm('Czy na pewno chcesz usunac ten szkic?')) return;
|
|
fetch('/admin/companies/wizard/cancel', {
|
|
method: 'POST',
|
|
headers: {'Content-Type': 'application/json', 'X-CSRFToken': getCSRF()},
|
|
body: JSON.stringify({company_id: companyId})
|
|
}).then(function() {
|
|
document.getElementById('draftBanner').style.display = 'none';
|
|
});
|
|
}
|
|
|
|
// ==================== UTILITIES ====================
|
|
|
|
function getCSRF() {
|
|
var meta = document.querySelector('meta[name="csrf-token"]');
|
|
return meta ? meta.getAttribute('content') : '';
|
|
}
|
|
|
|
function esc(str) {
|
|
var div = document.createElement('div');
|
|
div.textContent = str;
|
|
return div.innerHTML;
|
|
}
|
|
|
|
// NIP input: enter to check
|
|
document.getElementById('nipInput').addEventListener('keypress', function(e) {
|
|
if (e.key === 'Enter') { e.preventDefault(); checkNip(); }
|
|
});
|
|
{% endblock %}
|