Updated CSS class definitions in all 4 audit templates to use the same 5-level color scale as inline styles: - .score-excellent: #10b981 (green, 90-100%) - .score-good: #84cc16 (lime, 70-89%) - .score-average: #f59e0b (amber, 50-69%) - .score-needs-work: #f97316 (orange, 30-49%) - .score-poor: #ef4444 (red, 0-29%) This ensures consistency between company profile banners and detailed audit page score circles/text. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1201 lines
45 KiB
HTML
1201 lines
45 KiB
HTML
{% extends "base.html" %}
|
|
|
|
{% block title %}Audyt Social Media - {{ company.name }} - Norda Biznes Hub{% endblock %}
|
|
|
|
{% block extra_css %}
|
|
<style>
|
|
.audit-header {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: flex-start;
|
|
margin-bottom: var(--spacing-xl);
|
|
flex-wrap: wrap;
|
|
gap: var(--spacing-md);
|
|
}
|
|
|
|
.audit-header-info h1 {
|
|
font-size: var(--font-size-2xl);
|
|
color: var(--text-primary);
|
|
margin-bottom: var(--spacing-xs);
|
|
}
|
|
|
|
.audit-header-info p {
|
|
color: var(--text-secondary);
|
|
font-size: var(--font-size-sm);
|
|
}
|
|
|
|
.data-source-info {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: var(--spacing-xs);
|
|
margin-top: var(--spacing-sm);
|
|
padding: var(--spacing-xs) var(--spacing-sm);
|
|
background: rgba(168, 85, 247, 0.1);
|
|
border-radius: var(--radius);
|
|
font-size: var(--font-size-sm);
|
|
color: #a855f7;
|
|
}
|
|
|
|
.header-actions {
|
|
display: flex;
|
|
gap: var(--spacing-sm);
|
|
align-items: center;
|
|
}
|
|
|
|
/* Score Section */
|
|
.score-section {
|
|
display: grid;
|
|
grid-template-columns: auto 1fr;
|
|
gap: var(--spacing-xl);
|
|
margin-bottom: var(--spacing-xl);
|
|
background: var(--surface);
|
|
padding: var(--spacing-xl);
|
|
border-radius: var(--radius-lg);
|
|
box-shadow: var(--shadow);
|
|
}
|
|
|
|
@media (max-width: 768px) {
|
|
.score-section {
|
|
grid-template-columns: 1fr;
|
|
text-align: center;
|
|
}
|
|
}
|
|
|
|
.score-circle {
|
|
width: 180px;
|
|
height: 180px;
|
|
border-radius: 50%;
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
justify-content: center;
|
|
position: relative;
|
|
background: conic-gradient(
|
|
var(--score-color, var(--secondary)) calc(var(--score-percent, 0) * 3.6deg),
|
|
#e2e8f0 0deg
|
|
);
|
|
margin: 0 auto;
|
|
}
|
|
|
|
.score-circle::before {
|
|
content: '';
|
|
position: absolute;
|
|
width: 150px;
|
|
height: 150px;
|
|
border-radius: 50%;
|
|
background: var(--surface);
|
|
}
|
|
|
|
.score-value {
|
|
position: relative;
|
|
z-index: 1;
|
|
font-size: 3rem;
|
|
font-weight: 700;
|
|
line-height: 1;
|
|
}
|
|
|
|
/* Unified 5-level color scale: 0-29 red, 30-49 orange, 50-69 amber, 70-89 lime, 90-100 green */
|
|
.score-value.score-excellent { color: #10b981; }
|
|
.score-value.score-good { color: #84cc16; }
|
|
.score-value.score-average { color: #f59e0b; }
|
|
.score-value.score-needs-work { color: #f97316; }
|
|
.score-value.score-poor { color: #ef4444; }
|
|
|
|
.score-label {
|
|
position: relative;
|
|
z-index: 1;
|
|
font-size: var(--font-size-sm);
|
|
color: var(--text-secondary);
|
|
margin-top: var(--spacing-xs);
|
|
}
|
|
|
|
.score-details {
|
|
display: flex;
|
|
flex-direction: column;
|
|
justify-content: center;
|
|
}
|
|
|
|
.score-category {
|
|
font-size: var(--font-size-lg);
|
|
font-weight: 600;
|
|
margin-bottom: var(--spacing-sm);
|
|
}
|
|
|
|
/* Unified 5-level color scale */
|
|
.score-category.excellent { color: #10b981; }
|
|
.score-category.good { color: #84cc16; }
|
|
.score-category.average { color: #f59e0b; }
|
|
.score-category.needs-work { color: #f97316; }
|
|
.score-category.poor { color: #ef4444; }
|
|
|
|
.score-description {
|
|
color: var(--text-secondary);
|
|
font-size: var(--font-size-sm);
|
|
line-height: 1.6;
|
|
margin-bottom: var(--spacing-md);
|
|
}
|
|
|
|
.platforms-summary {
|
|
display: flex;
|
|
gap: var(--spacing-lg);
|
|
font-size: var(--font-size-sm);
|
|
color: var(--text-secondary);
|
|
flex-wrap: wrap;
|
|
}
|
|
|
|
.platforms-summary-item {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: var(--spacing-xs);
|
|
}
|
|
|
|
.platforms-summary-item svg {
|
|
width: 16px;
|
|
height: 16px;
|
|
}
|
|
|
|
.platforms-summary-item.found { color: var(--success); }
|
|
.platforms-summary-item.missing { color: var(--text-secondary); }
|
|
|
|
/* Section Title */
|
|
.section-title {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: var(--spacing-sm);
|
|
font-size: var(--font-size-lg);
|
|
font-weight: 600;
|
|
color: var(--text-primary);
|
|
margin-bottom: var(--spacing-lg);
|
|
}
|
|
|
|
.section-title svg {
|
|
width: 24px;
|
|
height: 24px;
|
|
color: #a855f7;
|
|
}
|
|
|
|
/* Platforms Grid */
|
|
.platforms-grid {
|
|
display: grid;
|
|
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
|
|
gap: var(--spacing-md);
|
|
margin-bottom: var(--spacing-xl);
|
|
}
|
|
|
|
.platform-card {
|
|
background: var(--surface);
|
|
border-radius: var(--radius-lg);
|
|
padding: var(--spacing-lg);
|
|
box-shadow: var(--shadow);
|
|
border-left: 4px solid;
|
|
transition: transform 0.2s ease, box-shadow 0.2s ease;
|
|
}
|
|
|
|
.platform-card:hover {
|
|
transform: translateY(-2px);
|
|
box-shadow: var(--shadow-lg);
|
|
}
|
|
|
|
.platform-card.found {
|
|
border-left-color: var(--success);
|
|
}
|
|
|
|
.platform-card.missing {
|
|
border-left-color: var(--text-tertiary);
|
|
opacity: 0.7;
|
|
}
|
|
|
|
.platform-header {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: var(--spacing-sm);
|
|
margin-bottom: var(--spacing-md);
|
|
}
|
|
|
|
.platform-icon {
|
|
width: 40px;
|
|
height: 40px;
|
|
border-radius: var(--radius);
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
font-size: 20px;
|
|
}
|
|
|
|
.platform-icon.facebook { background: #1877f2; color: white; }
|
|
.platform-icon.instagram { background: linear-gradient(45deg, #f09433, #e6683c, #dc2743, #cc2366, #bc1888); color: white; }
|
|
.platform-icon.linkedin { background: #0a66c2; color: white; }
|
|
.platform-icon.youtube { background: #ff0000; color: white; }
|
|
.platform-icon.twitter { background: #000000; color: white; }
|
|
.platform-icon.tiktok { background: #000000; color: white; }
|
|
|
|
.platform-name {
|
|
font-weight: 600;
|
|
font-size: var(--font-size-base);
|
|
color: var(--text-primary);
|
|
}
|
|
|
|
.platform-status {
|
|
margin-left: auto;
|
|
display: flex;
|
|
align-items: center;
|
|
gap: var(--spacing-xs);
|
|
font-size: var(--font-size-sm);
|
|
padding: 2px 8px;
|
|
border-radius: var(--radius);
|
|
}
|
|
|
|
.platform-status.active {
|
|
background: rgba(34, 197, 94, 0.1);
|
|
color: var(--success);
|
|
}
|
|
|
|
.platform-status.inactive {
|
|
background: rgba(107, 114, 128, 0.1);
|
|
color: var(--text-tertiary);
|
|
}
|
|
|
|
.platform-details {
|
|
font-size: var(--font-size-sm);
|
|
color: var(--text-secondary);
|
|
}
|
|
|
|
.platform-url {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: var(--spacing-xs);
|
|
margin-bottom: var(--spacing-xs);
|
|
word-break: break-all;
|
|
}
|
|
|
|
.platform-url a {
|
|
color: var(--primary);
|
|
text-decoration: none;
|
|
}
|
|
|
|
.platform-url a:hover {
|
|
text-decoration: underline;
|
|
}
|
|
|
|
.platform-meta {
|
|
display: flex;
|
|
gap: var(--spacing-md);
|
|
margin-top: var(--spacing-sm);
|
|
flex-wrap: wrap;
|
|
}
|
|
|
|
.platform-meta-item {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 4px;
|
|
font-size: var(--font-size-xs);
|
|
color: var(--text-tertiary);
|
|
}
|
|
|
|
.platform-meta-item svg {
|
|
width: 14px;
|
|
height: 14px;
|
|
}
|
|
|
|
.platform-missing-text {
|
|
color: var(--text-tertiary);
|
|
font-style: italic;
|
|
}
|
|
|
|
/* No data state */
|
|
.no-data {
|
|
text-align: center;
|
|
padding: var(--spacing-2xl);
|
|
background: var(--surface);
|
|
border-radius: var(--radius-lg);
|
|
box-shadow: var(--shadow);
|
|
}
|
|
|
|
.no-data svg {
|
|
width: 64px;
|
|
height: 64px;
|
|
color: var(--text-tertiary);
|
|
margin-bottom: var(--spacing-md);
|
|
}
|
|
|
|
.no-data h3 {
|
|
color: var(--text-primary);
|
|
margin-bottom: var(--spacing-sm);
|
|
}
|
|
|
|
.no-data p {
|
|
color: var(--text-secondary);
|
|
margin-bottom: var(--spacing-lg);
|
|
}
|
|
|
|
/* Buttons */
|
|
.btn {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: var(--spacing-xs);
|
|
padding: var(--spacing-sm) var(--spacing-md);
|
|
border-radius: var(--radius);
|
|
font-weight: 500;
|
|
font-size: var(--font-size-sm);
|
|
cursor: pointer;
|
|
transition: all 0.2s ease;
|
|
border: 1px solid transparent;
|
|
text-decoration: none;
|
|
}
|
|
|
|
.btn svg {
|
|
width: 16px;
|
|
height: 16px;
|
|
}
|
|
|
|
.btn-primary {
|
|
background: #a855f7;
|
|
color: white;
|
|
border-color: #a855f7;
|
|
}
|
|
|
|
.btn-primary:hover {
|
|
background: #9333ea;
|
|
border-color: #9333ea;
|
|
}
|
|
|
|
.btn-outline {
|
|
background: transparent;
|
|
color: var(--text-secondary);
|
|
border-color: var(--border);
|
|
}
|
|
|
|
.btn-outline:hover {
|
|
background: var(--background);
|
|
color: var(--text-primary);
|
|
}
|
|
|
|
.btn-sm {
|
|
padding: var(--spacing-xs) var(--spacing-sm);
|
|
font-size: var(--font-size-xs);
|
|
}
|
|
|
|
/* Recommendations */
|
|
.recommendations {
|
|
background: var(--surface);
|
|
border-radius: var(--radius-lg);
|
|
padding: var(--spacing-lg);
|
|
box-shadow: var(--shadow);
|
|
}
|
|
|
|
.recommendation-item {
|
|
display: flex;
|
|
gap: var(--spacing-sm);
|
|
padding: var(--spacing-sm) 0;
|
|
border-bottom: 1px solid var(--border);
|
|
}
|
|
|
|
.recommendation-item:last-child {
|
|
border-bottom: none;
|
|
}
|
|
|
|
.recommendation-icon {
|
|
width: 24px;
|
|
height: 24px;
|
|
border-radius: 50%;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
flex-shrink: 0;
|
|
font-size: 12px;
|
|
}
|
|
|
|
.recommendation-icon.priority-high {
|
|
background: rgba(239, 68, 68, 0.1);
|
|
color: var(--error);
|
|
}
|
|
|
|
.recommendation-icon.priority-medium {
|
|
background: rgba(245, 158, 11, 0.1);
|
|
color: var(--warning);
|
|
}
|
|
|
|
.recommendation-icon.priority-low {
|
|
background: rgba(34, 197, 94, 0.1);
|
|
color: var(--success);
|
|
}
|
|
|
|
.recommendation-text {
|
|
font-size: var(--font-size-sm);
|
|
color: var(--text-secondary);
|
|
}
|
|
|
|
.recommendation-text strong {
|
|
color: var(--text-primary);
|
|
}
|
|
|
|
/* Loading Overlay */
|
|
.loading-overlay {
|
|
display: none;
|
|
position: fixed;
|
|
top: 0;
|
|
left: 0;
|
|
right: 0;
|
|
bottom: 0;
|
|
background: rgba(255, 255, 255, 0.95);
|
|
z-index: 9999;
|
|
align-items: center;
|
|
justify-content: center;
|
|
flex-direction: column;
|
|
gap: var(--spacing-lg);
|
|
}
|
|
|
|
.loading-overlay.active {
|
|
display: flex;
|
|
}
|
|
|
|
.loading-content {
|
|
background: var(--surface);
|
|
padding: var(--spacing-xl);
|
|
border-radius: var(--radius-lg);
|
|
box-shadow: var(--shadow-lg);
|
|
max-width: 450px;
|
|
width: 90%;
|
|
text-align: center;
|
|
}
|
|
|
|
.loading-header {
|
|
margin-bottom: var(--spacing-lg);
|
|
}
|
|
|
|
.loading-header h3 {
|
|
font-size: var(--font-size-lg);
|
|
color: var(--text-primary);
|
|
margin-bottom: var(--spacing-xs);
|
|
}
|
|
|
|
.loading-header p {
|
|
color: var(--text-secondary);
|
|
font-size: var(--font-size-sm);
|
|
}
|
|
|
|
.loading-steps {
|
|
text-align: left;
|
|
margin-bottom: var(--spacing-lg);
|
|
}
|
|
|
|
.loading-step {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: var(--spacing-sm);
|
|
padding: var(--spacing-sm) 0;
|
|
border-bottom: 1px solid var(--border-light, #f1f5f9);
|
|
}
|
|
|
|
.loading-step:last-child {
|
|
border-bottom: none;
|
|
}
|
|
|
|
.step-icon {
|
|
width: 24px;
|
|
height: 24px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.step-icon.pending { color: var(--text-tertiary); }
|
|
.step-icon.in_progress { color: #a855f7; }
|
|
.step-icon.complete { color: var(--success); }
|
|
.step-icon.error { color: var(--error); }
|
|
.step-icon.missing { color: var(--text-tertiary); opacity: 0.6; }
|
|
.step-icon.skipped { color: var(--text-tertiary); opacity: 0.5; }
|
|
|
|
.step-spinner {
|
|
width: 18px;
|
|
height: 18px;
|
|
border: 2px solid var(--border);
|
|
border-top-color: #a855f7;
|
|
border-radius: 50%;
|
|
animation: spin 1s linear infinite;
|
|
}
|
|
|
|
@keyframes spin {
|
|
to { transform: rotate(360deg); }
|
|
}
|
|
|
|
.step-text {
|
|
flex: 1;
|
|
font-size: var(--font-size-sm);
|
|
}
|
|
|
|
.step-text.pending { color: var(--text-tertiary); }
|
|
.step-text.in_progress { color: var(--text-primary); font-weight: 500; }
|
|
.step-text.complete { color: var(--text-secondary); }
|
|
.step-text.error { color: var(--error); }
|
|
.step-text.missing { color: var(--text-tertiary); font-style: italic; }
|
|
.step-text.skipped { color: var(--text-tertiary); opacity: 0.6; }
|
|
|
|
/* Source tag styling */
|
|
.source-tag {
|
|
display: inline-block;
|
|
font-size: 9px;
|
|
font-weight: 600;
|
|
padding: 1px 5px;
|
|
border-radius: 3px;
|
|
margin-left: 4px;
|
|
text-transform: uppercase;
|
|
vertical-align: middle;
|
|
}
|
|
|
|
.source-tag.website { background: #6366f1; color: white; }
|
|
.source-tag.brave { background: #fb542b; color: white; }
|
|
.source-tag.google { background: #4285f4; color: white; }
|
|
.source-tag.facebook { background: #1877f2; color: white; }
|
|
.source-tag.instagram { background: #e4405f; color: white; }
|
|
.source-tag.linkedin { background: #0a66c2; color: white; }
|
|
.source-tag.youtube { background: #ff0000; color: white; }
|
|
.source-tag.twitter { background: #000000; color: white; }
|
|
.source-tag.tiktok { background: #000000; color: white; }
|
|
|
|
/* Modal */
|
|
.modal-overlay {
|
|
position: fixed;
|
|
top: 0;
|
|
left: 0;
|
|
width: 100%;
|
|
height: 100%;
|
|
background: rgba(0, 0, 0, 0.5);
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
z-index: 10000;
|
|
opacity: 0;
|
|
visibility: hidden;
|
|
transition: opacity 0.3s ease, visibility 0.3s ease;
|
|
}
|
|
|
|
.modal-overlay.active {
|
|
opacity: 1;
|
|
visibility: visible;
|
|
}
|
|
|
|
.modal-content {
|
|
background: var(--surface);
|
|
padding: var(--spacing-xl);
|
|
border-radius: var(--radius-lg);
|
|
max-width: 400px;
|
|
width: 90%;
|
|
text-align: center;
|
|
}
|
|
|
|
.modal-icon {
|
|
width: 48px;
|
|
height: 48px;
|
|
border-radius: 50%;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
margin: 0 auto var(--spacing-md);
|
|
}
|
|
|
|
.modal-icon.success {
|
|
background: rgba(34, 197, 94, 0.1);
|
|
color: var(--success);
|
|
}
|
|
|
|
.modal-icon.error {
|
|
background: rgba(239, 68, 68, 0.1);
|
|
color: var(--error);
|
|
}
|
|
|
|
.modal-title {
|
|
font-size: var(--font-size-lg);
|
|
font-weight: 600;
|
|
color: var(--text-primary);
|
|
margin-bottom: var(--spacing-sm);
|
|
}
|
|
|
|
.modal-description {
|
|
color: var(--text-secondary);
|
|
font-size: var(--font-size-sm);
|
|
margin-bottom: var(--spacing-lg);
|
|
}
|
|
|
|
.modal-btn {
|
|
background: #a855f7;
|
|
color: white;
|
|
border: none;
|
|
padding: var(--spacing-sm) var(--spacing-lg);
|
|
border-radius: var(--radius);
|
|
font-weight: 500;
|
|
cursor: pointer;
|
|
transition: background 0.2s ease;
|
|
}
|
|
|
|
.modal-btn:hover {
|
|
background: #9333ea;
|
|
}
|
|
</style>
|
|
{% endblock %}
|
|
|
|
{% block content %}
|
|
<!-- Breadcrumb -->
|
|
<div class="breadcrumb">
|
|
<a href="{{ url_for('index') }}">Firmy</a>
|
|
<span class="breadcrumb-separator">/</span>
|
|
<a href="{{ url_for('company_detail', company_id=company.id) }}">{{ company.name }}</a>
|
|
<span class="breadcrumb-separator">/</span>
|
|
<span>Audyt Social Media</span>
|
|
</div>
|
|
|
|
<div class="audit-header">
|
|
<div class="audit-header-info">
|
|
<h1>Audyt Social Media</h1>
|
|
<p>{{ company.name }}</p>
|
|
<div class="data-source-info">
|
|
<svg width="16" height="16" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 8h2a2 2 0 012 2v6a2 2 0 01-2 2h-2v4l-4-4H9a1.994 1.994 0 01-1.414-.586m0 0L11 14h4a2 2 0 002-2V6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2v4l.586-.586z"/>
|
|
</svg>
|
|
<span>Analiza obecnosci w mediach spolecznosciowych</span>
|
|
</div>
|
|
</div>
|
|
<div class="header-actions">
|
|
<a href="{{ url_for('company_detail', company_id=company.id) }}" class="btn btn-outline btn-sm">
|
|
<svg width="16" height="16" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 19l-7-7m0 0l7-7m-7 7h18"/>
|
|
</svg>
|
|
Profil firmy
|
|
</a>
|
|
{% if can_audit %}
|
|
<button class="btn btn-primary btn-sm" onclick="runAudit()" id="runAuditBtn">
|
|
<svg width="16" height="16" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"/>
|
|
</svg>
|
|
Uruchom audyt
|
|
</button>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Score Section -->
|
|
{# Unified 5-level color scale: 0-29 red, 30-49 orange, 50-69 amber, 70-89 lime, 90-100 green #}
|
|
{% set score = social_data.score %}
|
|
<div class="score-section">
|
|
<div class="score-circle" style="--score-percent: {{ score }}; --score-color: {% if score >= 90 %}#10b981{% elif score >= 70 %}#84cc16{% elif score >= 50 %}#f59e0b{% elif score >= 30 %}#f97316{% else %}#ef4444{% endif %};">
|
|
<span class="score-value" style="color: {% if score >= 90 %}#10b981{% elif score >= 70 %}#84cc16{% elif score >= 50 %}#f59e0b{% elif score >= 30 %}#f97316{% else %}#ef4444{% endif %};">{{ score }}</span>
|
|
<span class="score-label">/ 100</span>
|
|
</div>
|
|
<div class="score-details">
|
|
<div class="score-category" style="color: {% if score >= 90 %}#10b981{% elif score >= 70 %}#84cc16{% elif score >= 50 %}#f59e0b{% elif score >= 30 %}#f97316{% else %}#ef4444{% endif %};">
|
|
{% if score >= 90 %}
|
|
Doskonala obecnosc w Social Media
|
|
{% elif score >= 70 %}
|
|
Dobra obecnosc w Social Media
|
|
{% elif score >= 50 %}
|
|
Przecietna obecnosc w Social Media
|
|
{% elif score >= 30 %}
|
|
Obecnosc wymaga rozbudowy
|
|
{% else %}
|
|
Slaba obecnosc w Social Media
|
|
{% endif %}
|
|
</div>
|
|
<p class="score-description">
|
|
{% if score >= 80 %}
|
|
Firma jest obecna na wiekszosci waznych platform spolecznosciowych. Utrzymuj aktywnosc i rozwijaj zaangazowanie.
|
|
{% elif score >= 60 %}
|
|
Firma ma dobra obecnosc w social media. Rozważ dodanie brakujacych platform dla pelniejszego zasiegu.
|
|
{% elif score >= 40 %}
|
|
Firma jest obecna na kilku platformach. Warto rozszerzyc obecnosc o kolejne kanaly komunikacji.
|
|
{% else %}
|
|
Firma ma ograniczona obecnosc w social media. Zalecamy utworzenie profili na kluczowych platformach.
|
|
{% endif %}
|
|
</p>
|
|
<div class="platforms-summary">
|
|
<div class="platforms-summary-item found">
|
|
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/>
|
|
</svg>
|
|
<span>{{ social_data.platforms_count }} {{ 'platforma' if social_data.platforms_count == 1 else ('platformy' if social_data.platforms_count in [2,3,4] else 'platform') }}</span>
|
|
</div>
|
|
<div class="platforms-summary-item missing">
|
|
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"/>
|
|
</svg>
|
|
<span>{{ social_data.total_platforms - social_data.platforms_count }} brakujacych</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Platforms Grid -->
|
|
<h2 class="section-title">
|
|
<svg width="24" height="24" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 8h2a2 2 0 012 2v6a2 2 0 01-2 2h-2v4l-4-4H9a1.994 1.994 0 01-1.414-.586m0 0L11 14h4a2 2 0 002-2V6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2v4l.586-.586z"/>
|
|
</svg>
|
|
Platformy Social Media
|
|
</h2>
|
|
|
|
<div class="platforms-grid">
|
|
{% set platform_names = {'facebook': 'Facebook', 'instagram': 'Instagram', 'linkedin': 'LinkedIn', 'youtube': 'YouTube', 'twitter': 'X (Twitter)', 'tiktok': 'TikTok'} %}
|
|
{% set platform_icons = {'facebook': 'f', 'instagram': 'ig', 'linkedin': 'in', 'youtube': 'yt', 'twitter': 'X', 'tiktok': 'tk'} %}
|
|
|
|
{% for platform in social_data.all_platforms %}
|
|
{% set profile = social_data.profiles.get(platform) %}
|
|
<div class="platform-card {{ 'found' if profile else 'missing' }}">
|
|
<div class="platform-header">
|
|
<div class="platform-icon {{ platform }}">
|
|
{% if platform == 'facebook' %}
|
|
<svg width="20" height="20" fill="currentColor" viewBox="0 0 24 24"><path d="M24 12.073c0-6.627-5.373-12-12-12s-12 5.373-12 12c0 5.99 4.388 10.954 10.125 11.854v-8.385H7.078v-3.47h3.047V9.43c0-3.007 1.792-4.669 4.533-4.669 1.312 0 2.686.235 2.686.235v2.953H15.83c-1.491 0-1.956.925-1.956 1.874v2.25h3.328l-.532 3.47h-2.796v8.385C19.612 23.027 24 18.062 24 12.073z"/></svg>
|
|
{% elif platform == 'instagram' %}
|
|
<svg width="20" height="20" fill="currentColor" viewBox="0 0 24 24"><path d="M12 2.163c3.204 0 3.584.012 4.85.07 3.252.148 4.771 1.691 4.919 4.919.058 1.265.069 1.645.069 4.849 0 3.205-.012 3.584-.069 4.849-.149 3.225-1.664 4.771-4.919 4.919-1.266.058-1.644.07-4.85.07-3.204 0-3.584-.012-4.849-.07-3.26-.149-4.771-1.699-4.919-4.92-.058-1.265-.07-1.644-.07-4.849 0-3.204.013-3.583.07-4.849.149-3.227 1.664-4.771 4.919-4.919 1.266-.057 1.645-.069 4.849-.069zm0-2.163c-3.259 0-3.667.014-4.947.072-4.358.2-6.78 2.618-6.98 6.98-.059 1.281-.073 1.689-.073 4.948 0 3.259.014 3.668.072 4.948.2 4.358 2.618 6.78 6.98 6.98 1.281.058 1.689.072 4.948.072 3.259 0 3.668-.014 4.948-.072 4.354-.2 6.782-2.618 6.979-6.98.059-1.28.073-1.689.073-4.948 0-3.259-.014-3.667-.072-4.947-.196-4.354-2.617-6.78-6.979-6.98-1.281-.059-1.69-.073-4.949-.073zm0 5.838c-3.403 0-6.162 2.759-6.162 6.162s2.759 6.163 6.162 6.163 6.162-2.759 6.162-6.163c0-3.403-2.759-6.162-6.162-6.162zm0 10.162c-2.209 0-4-1.79-4-4 0-2.209 1.791-4 4-4s4 1.791 4 4c0 2.21-1.791 4-4 4zm6.406-11.845c-.796 0-1.441.645-1.441 1.44s.645 1.44 1.441 1.44c.795 0 1.439-.645 1.439-1.44s-.644-1.44-1.439-1.44z"/></svg>
|
|
{% elif platform == 'linkedin' %}
|
|
<svg width="20" height="20" fill="currentColor" viewBox="0 0 24 24"><path d="M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433c-1.144 0-2.063-.926-2.063-2.065 0-1.138.92-2.063 2.063-2.063 1.14 0 2.064.925 2.064 2.063 0 1.139-.925 2.065-2.064 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z"/></svg>
|
|
{% elif platform == 'youtube' %}
|
|
<svg width="20" height="20" fill="currentColor" viewBox="0 0 24 24"><path d="M23.498 6.186a3.016 3.016 0 0 0-2.122-2.136C19.505 3.545 12 3.545 12 3.545s-7.505 0-9.377.505A3.017 3.017 0 0 0 .502 6.186C0 8.07 0 12 0 12s0 3.93.502 5.814a3.016 3.016 0 0 0 2.122 2.136c1.871.505 9.376.505 9.376.505s7.505 0 9.377-.505a3.015 3.015 0 0 0 2.122-2.136C24 15.93 24 12 24 12s0-3.93-.502-5.814zM9.545 15.568V8.432L15.818 12l-6.273 3.568z"/></svg>
|
|
{% elif platform == 'twitter' %}
|
|
<svg width="20" height="20" fill="currentColor" viewBox="0 0 24 24"><path d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z"/></svg>
|
|
{% elif platform == 'tiktok' %}
|
|
<svg width="20" height="20" fill="currentColor" viewBox="0 0 24 24"><path d="M12.525.02c1.31-.02 2.61-.01 3.91-.02.08 1.53.63 3.09 1.75 4.17 1.12 1.11 2.7 1.62 4.24 1.79v4.03c-1.44-.05-2.89-.35-4.2-.97-.57-.26-1.1-.59-1.62-.93-.01 2.92.01 5.84-.02 8.75-.08 1.4-.54 2.79-1.35 3.94-1.31 1.92-3.58 3.17-5.91 3.21-1.43.08-2.86-.31-4.08-1.03-2.02-1.19-3.44-3.37-3.65-5.71-.02-.5-.03-1-.01-1.49.18-1.9 1.12-3.72 2.58-4.96 1.66-1.44 3.98-2.13 6.15-1.72.02 1.48-.04 2.96-.04 4.44-.99-.32-2.15-.23-3.02.37-.63.41-1.11 1.04-1.36 1.75-.21.51-.15 1.07-.14 1.61.24 1.64 1.82 3.02 3.5 2.87 1.12-.01 2.19-.66 2.77-1.61.19-.33.4-.67.41-1.06.1-1.79.06-3.57.07-5.36.01-4.03-.01-8.05.02-12.07z"/></svg>
|
|
{% endif %}
|
|
</div>
|
|
<span class="platform-name">{{ platform_names.get(platform, platform|title) }}</span>
|
|
<span class="platform-status {{ 'active' if profile else 'inactive' }}">
|
|
{% if profile %}
|
|
<svg width="12" height="12" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/>
|
|
</svg>
|
|
Aktywny
|
|
{% else %}
|
|
<svg width="12" height="12" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"/>
|
|
</svg>
|
|
Brak profilu
|
|
{% endif %}
|
|
</span>
|
|
</div>
|
|
<div class="platform-details">
|
|
{% if profile %}
|
|
<div class="platform-url">
|
|
<svg width="14" height="14" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1"/>
|
|
</svg>
|
|
<a href="{{ profile.url }}" target="_blank" rel="noopener">{{ profile.url|truncate(40) }}</a>
|
|
</div>
|
|
<div class="platform-meta">
|
|
{% if profile.page_name %}
|
|
<div class="platform-meta-item">
|
|
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z"/>
|
|
</svg>
|
|
{{ profile.page_name }}
|
|
</div>
|
|
{% endif %}
|
|
{% if profile.followers_count %}
|
|
<div class="platform-meta-item">
|
|
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0zm6 3a2 2 0 11-4 0 2 2 0 014 0zM7 10a2 2 0 11-4 0 2 2 0 014 0z"/>
|
|
</svg>
|
|
{{ '{:,}'.format(profile.followers_count).replace(',', ' ') }} obserwujacych
|
|
</div>
|
|
{% endif %}
|
|
{% if profile.verified_at %}
|
|
<div class="platform-meta-item">
|
|
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z"/>
|
|
</svg>
|
|
{{ profile.verified_at.strftime('%d.%m.%Y') }}
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
{% else %}
|
|
<p class="platform-missing-text">Nie znaleziono profilu na tej platformie</p>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
{% endfor %}
|
|
</div>
|
|
|
|
{% if social_data.total_platforms - social_data.platforms_count > 0 %}
|
|
<!-- Recommendations -->
|
|
<h2 class="section-title">
|
|
<svg width="24" height="24" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9.663 17h4.673M12 3v1m6.364 1.636l-.707.707M21 12h-1M4 12H3m3.343-5.657l-.707-.707m2.828 9.9a5 5 0 117.072 0l-.548.547A3.374 3.374 0 0014 18.469V19a2 2 0 11-4 0v-.531c0-.895-.356-1.754-.988-2.386l-.548-.547z"/>
|
|
</svg>
|
|
Rekomendacje
|
|
</h2>
|
|
|
|
<div class="recommendations">
|
|
{% set missing_platforms = [] %}
|
|
{% for platform in social_data.all_platforms %}
|
|
{% if platform not in social_data.profiles %}
|
|
{% set _ = missing_platforms.append(platform) %}
|
|
{% endif %}
|
|
{% endfor %}
|
|
|
|
{% if 'facebook' in missing_platforms %}
|
|
<div class="recommendation-item">
|
|
<div class="recommendation-icon priority-high">!</div>
|
|
<div class="recommendation-text">
|
|
<strong>Facebook</strong> - Najpopularniejsza platforma w Polsce. Zalozenie strony firmowej pozwoli dotrzec do szerokiego grona klientow.
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
|
|
{% if 'linkedin' in missing_platforms %}
|
|
<div class="recommendation-item">
|
|
<div class="recommendation-icon priority-high">!</div>
|
|
<div class="recommendation-text">
|
|
<strong>LinkedIn</strong> - Kluczowa platforma dla firm B2B. Idealna do budowania relacji biznesowych i employer brandingu.
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
|
|
{% if 'instagram' in missing_platforms %}
|
|
<div class="recommendation-item">
|
|
<div class="recommendation-icon priority-medium">!</div>
|
|
<div class="recommendation-text">
|
|
<strong>Instagram</strong> - Swietna platforma do prezentacji wizualnej firmy. Szczegolnie wazna dla firm z produktami/uslugami wizualnymi.
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
|
|
{% if 'youtube' in missing_platforms %}
|
|
<div class="recommendation-item">
|
|
<div class="recommendation-icon priority-medium">!</div>
|
|
<div class="recommendation-text">
|
|
<strong>YouTube</strong> - Druga najwieksza wyszukiwarka na swiecie. Video content buduje zaufanie i pokazuje ekspertyze.
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
|
|
{% if 'tiktok' in missing_platforms %}
|
|
<div class="recommendation-item">
|
|
<div class="recommendation-icon priority-low">!</div>
|
|
<div class="recommendation-text">
|
|
<strong>TikTok</strong> - Najszybciej rosnaca platforma. Warto rozwazyc jesli celujecie w mlodszych odbiorców.
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
|
|
{% if 'twitter' in missing_platforms %}
|
|
<div class="recommendation-item">
|
|
<div class="recommendation-icon priority-low">!</div>
|
|
<div class="recommendation-text">
|
|
<strong>X (Twitter)</strong> - Platforma do szybkiej komunikacji i budowania wizerunku eksperta. Przydatna w branzy tech/media.
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
{% endif %}
|
|
|
|
<!-- Loading Overlay -->
|
|
<div class="loading-overlay" id="loadingOverlay">
|
|
<div class="loading-content">
|
|
<div class="loading-header">
|
|
<h3>Audyt Social Media</h3>
|
|
<p>Szukam profili w mediach spolecznosciowych...</p>
|
|
</div>
|
|
<div class="loading-steps" id="loadingSteps">
|
|
<!-- Step 1: Scan Website -->
|
|
<div class="loading-step" id="step-website">
|
|
<div class="step-icon in_progress">
|
|
<div class="step-spinner"></div>
|
|
</div>
|
|
<span class="step-text in_progress">Skanuje strone WWW <span class="source-tag website">WWW</span></span>
|
|
</div>
|
|
|
|
<!-- Step 2: Facebook -->
|
|
<div class="loading-step" id="step-facebook">
|
|
<div class="step-icon pending">
|
|
<svg width="18" height="18" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<circle cx="12" cy="12" r="10" stroke-width="2"/>
|
|
</svg>
|
|
</div>
|
|
<span class="step-text pending">Szukam Facebook <span class="source-tag facebook">FB</span></span>
|
|
</div>
|
|
|
|
<!-- Step 3: Instagram -->
|
|
<div class="loading-step" id="step-instagram">
|
|
<div class="step-icon pending">
|
|
<svg width="18" height="18" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<circle cx="12" cy="12" r="10" stroke-width="2"/>
|
|
</svg>
|
|
</div>
|
|
<span class="step-text pending">Szukam Instagram <span class="source-tag instagram">IG</span></span>
|
|
</div>
|
|
|
|
<!-- Step 4: LinkedIn -->
|
|
<div class="loading-step" id="step-linkedin">
|
|
<div class="step-icon pending">
|
|
<svg width="18" height="18" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<circle cx="12" cy="12" r="10" stroke-width="2"/>
|
|
</svg>
|
|
</div>
|
|
<span class="step-text pending">Szukam LinkedIn <span class="source-tag linkedin">LI</span></span>
|
|
</div>
|
|
|
|
<!-- Step 5: YouTube -->
|
|
<div class="loading-step" id="step-youtube">
|
|
<div class="step-icon pending">
|
|
<svg width="18" height="18" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<circle cx="12" cy="12" r="10" stroke-width="2"/>
|
|
</svg>
|
|
</div>
|
|
<span class="step-text pending">Szukam YouTube <span class="source-tag youtube">YT</span></span>
|
|
</div>
|
|
|
|
<!-- Step 6: Twitter/X -->
|
|
<div class="loading-step" id="step-twitter">
|
|
<div class="step-icon pending">
|
|
<svg width="18" height="18" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<circle cx="12" cy="12" r="10" stroke-width="2"/>
|
|
</svg>
|
|
</div>
|
|
<span class="step-text pending">Szukam X (Twitter) <span class="source-tag twitter">X</span></span>
|
|
</div>
|
|
|
|
<!-- Step 7: TikTok -->
|
|
<div class="loading-step" id="step-tiktok">
|
|
<div class="step-icon pending">
|
|
<svg width="18" height="18" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<circle cx="12" cy="12" r="10" stroke-width="2"/>
|
|
</svg>
|
|
</div>
|
|
<span class="step-text pending">Szukam TikTok <span class="source-tag tiktok">TK</span></span>
|
|
</div>
|
|
|
|
<!-- Step 8: Google Business -->
|
|
<div class="loading-step" id="step-google">
|
|
<div class="step-icon pending">
|
|
<svg width="18" height="18" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<circle cx="12" cy="12" r="10" stroke-width="2"/>
|
|
</svg>
|
|
</div>
|
|
<span class="step-text pending">Pobieram dane Google <span class="source-tag google">Google</span></span>
|
|
</div>
|
|
|
|
<!-- Step 9: Save -->
|
|
<div class="loading-step" id="step-save">
|
|
<div class="step-icon pending">
|
|
<svg width="18" height="18" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<circle cx="12" cy="12" r="10" stroke-width="2"/>
|
|
</svg>
|
|
</div>
|
|
<span class="step-text pending">Zapisuje wyniki</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Modal -->
|
|
<div class="modal-overlay" id="modalOverlay">
|
|
<div class="modal-content">
|
|
<div class="modal-icon" id="modalIcon">
|
|
<svg width="24" height="24" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/>
|
|
</svg>
|
|
</div>
|
|
<div class="modal-title" id="modalTitle">Sukces</div>
|
|
<div class="modal-description" id="modalDescription">Operacja zakonczona pomyslnie.</div>
|
|
<button class="modal-btn" onclick="closeModal()">OK</button>
|
|
</div>
|
|
</div>
|
|
|
|
{% endblock %}
|
|
|
|
{% block extra_js %}
|
|
const csrfToken = '{{ csrf_token() }}';
|
|
const companySlug = '{{ company.slug }}';
|
|
|
|
// All step IDs in order
|
|
const allSteps = [
|
|
'step-website',
|
|
'step-facebook', 'step-instagram', 'step-linkedin',
|
|
'step-youtube', 'step-twitter', 'step-tiktok',
|
|
'step-google', 'step-save'
|
|
];
|
|
|
|
// Platform step mapping
|
|
const platformSteps = {
|
|
'facebook': 'step-facebook',
|
|
'instagram': 'step-instagram',
|
|
'linkedin': 'step-linkedin',
|
|
'youtube': 'step-youtube',
|
|
'twitter': 'step-twitter',
|
|
'tiktok': 'step-tiktok'
|
|
};
|
|
|
|
// SVG icons for different states
|
|
const icons = {
|
|
pending: '<svg width="18" height="18" fill="none" stroke="currentColor" viewBox="0 0 24 24"><circle cx="12" cy="12" r="10" stroke-width="2"/></svg>',
|
|
in_progress: '<div class="step-spinner"></div>',
|
|
complete: '<svg width="18" height="18" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/></svg>',
|
|
error: '<svg width="18" height="18" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"/></svg>',
|
|
missing: '<svg width="18" height="18" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M20 12H4"/></svg>'
|
|
};
|
|
|
|
function resetSteps() {
|
|
allSteps.forEach((stepId, index) => {
|
|
const stepEl = document.getElementById(stepId);
|
|
if (stepEl) {
|
|
const iconEl = stepEl.querySelector('.step-icon');
|
|
const textEl = stepEl.querySelector('.step-text');
|
|
|
|
if (index === 0) {
|
|
iconEl.className = 'step-icon in_progress';
|
|
iconEl.innerHTML = icons.in_progress;
|
|
textEl.className = 'step-text in_progress';
|
|
} else {
|
|
iconEl.className = 'step-icon pending';
|
|
iconEl.innerHTML = icons.pending;
|
|
textEl.className = 'step-text pending';
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
function updateStep(stepId, status, message) {
|
|
const stepEl = document.getElementById(stepId);
|
|
if (!stepEl) return;
|
|
|
|
const iconEl = stepEl.querySelector('.step-icon');
|
|
const textEl = stepEl.querySelector('.step-text');
|
|
|
|
iconEl.className = 'step-icon ' + status;
|
|
iconEl.innerHTML = icons[status] || icons.pending;
|
|
textEl.className = 'step-text ' + status;
|
|
if (message) {
|
|
textEl.innerHTML = message;
|
|
}
|
|
}
|
|
|
|
function showLoading() {
|
|
resetSteps();
|
|
document.getElementById('loadingOverlay').classList.add('active');
|
|
}
|
|
|
|
function hideLoading() {
|
|
document.getElementById('loadingOverlay').classList.remove('active');
|
|
}
|
|
|
|
function showModal(title, description, isSuccess) {
|
|
const modal = document.getElementById('modalOverlay');
|
|
const icon = document.getElementById('modalIcon');
|
|
const titleEl = document.getElementById('modalTitle');
|
|
const descEl = document.getElementById('modalDescription');
|
|
|
|
titleEl.textContent = title;
|
|
descEl.textContent = description;
|
|
|
|
icon.className = 'modal-icon ' + (isSuccess ? 'success' : 'error');
|
|
icon.innerHTML = isSuccess
|
|
? '<svg width="24" height="24" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/></svg>'
|
|
: '<svg width="24" height="24" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"/></svg>';
|
|
|
|
modal.classList.add('active');
|
|
}
|
|
|
|
function closeModal() {
|
|
document.getElementById('modalOverlay').classList.remove('active');
|
|
}
|
|
|
|
// Animate step-by-step progress for social media platforms
|
|
async function animatePlatformSteps(foundPlatforms, googleData) {
|
|
const delay = 400; // ms between steps - slower for readability
|
|
|
|
// Website scan complete
|
|
updateStep('step-website', 'complete', 'Skanowanie strony WWW zakonczone <span class="source-tag website">WWW</span>');
|
|
await new Promise(r => setTimeout(r, delay));
|
|
|
|
// Process each platform
|
|
const platforms = ['facebook', 'instagram', 'linkedin', 'youtube', 'twitter', 'tiktok'];
|
|
for (const platform of platforms) {
|
|
const stepId = platformSteps[platform];
|
|
const platformLabel = platform === 'twitter' ? 'X (Twitter)' : platform.charAt(0).toUpperCase() + platform.slice(1);
|
|
const sourceTag = `<span class="source-tag ${platform}">${platform === 'twitter' ? 'X' : platform.substring(0,2).toUpperCase()}</span>`;
|
|
|
|
updateStep(stepId, 'in_progress', `Szukam ${platformLabel}... ${sourceTag}`);
|
|
await new Promise(r => setTimeout(r, delay / 2));
|
|
|
|
if (foundPlatforms && foundPlatforms.includes(platform)) {
|
|
updateStep(stepId, 'complete', `<strong>${platformLabel}</strong>: ZNALEZIONO ${sourceTag}`);
|
|
} else {
|
|
updateStep(stepId, 'missing', `${platformLabel}: brak profilu ${sourceTag}`);
|
|
}
|
|
await new Promise(r => setTimeout(r, delay / 2));
|
|
}
|
|
|
|
// Google data
|
|
updateStep('step-google', 'in_progress', 'Pobieram dane z Google... <span class="source-tag google">Google</span>');
|
|
await new Promise(r => setTimeout(r, delay));
|
|
|
|
if (googleData && (googleData.google_rating || googleData.google_reviews_count)) {
|
|
const rating = googleData.google_rating ? `${googleData.google_rating}/5` : '';
|
|
const reviews = googleData.google_reviews_count ? `${googleData.google_reviews_count} opinii` : '';
|
|
const details = [rating, reviews].filter(Boolean).join(', ');
|
|
updateStep('step-google', 'complete', `Google: ${details} <span class="source-tag google">Google</span>`);
|
|
} else {
|
|
updateStep('step-google', 'missing', 'Google: brak profilu GBP <span class="source-tag google">Google</span>');
|
|
}
|
|
}
|
|
|
|
async function runAudit() {
|
|
const btn = document.getElementById('runAuditBtn');
|
|
if (btn) {
|
|
btn.disabled = true;
|
|
}
|
|
showLoading();
|
|
|
|
// Start animation
|
|
await new Promise(r => setTimeout(r, 300));
|
|
|
|
try {
|
|
const response = await fetch('/api/social/audit', {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
'X-CSRFToken': csrfToken
|
|
},
|
|
body: JSON.stringify({ slug: companySlug })
|
|
});
|
|
|
|
const data = await response.json();
|
|
console.log('Audit response:', data); // Debug
|
|
|
|
// Animate the steps with found platforms and Google data
|
|
const foundPlatforms = data.platforms || [];
|
|
const googleData = data.google_reviews || {};
|
|
await animatePlatformSteps(foundPlatforms, googleData);
|
|
|
|
// Save step
|
|
updateStep('step-save', 'in_progress', 'Zapisuje wyniki do bazy...');
|
|
await new Promise(r => setTimeout(r, 400));
|
|
|
|
if (response.ok && data.success) {
|
|
const summary = `Zapisano: ${data.profiles_found || 0} profili, wynik: ${data.score || 0}/100`;
|
|
updateStep('step-save', 'complete', summary);
|
|
|
|
// Wait longer for user to see complete results
|
|
await new Promise(r => setTimeout(r, 4000));
|
|
hideLoading();
|
|
showModal('Audyt zakonczony', `Znaleziono ${data.profiles_found || 0} profili social media. Strona zostanie odswiezona.`, true);
|
|
setTimeout(() => location.reload(), 2000);
|
|
} else {
|
|
updateStep('step-save', 'error', 'Blad zapisu: ' + (data.error || 'nieznany blad'));
|
|
await new Promise(r => setTimeout(r, 4000));
|
|
hideLoading();
|
|
showModal('Blad', data.error || 'Wystapil nieznany blad podczas audytu.', false);
|
|
if (btn) btn.disabled = false;
|
|
}
|
|
} catch (error) {
|
|
hideLoading();
|
|
showModal('Blad polaczenia', 'Nie udalo sie polaczyc z serwerem: ' + error.message, false);
|
|
if (btn) btn.disabled = false;
|
|
}
|
|
}
|
|
|
|
// Close modal on overlay click
|
|
document.getElementById('modalOverlay').addEventListener('click', function(e) {
|
|
if (e.target === this) {
|
|
closeModal();
|
|
}
|
|
});
|
|
{% endblock %}
|