- Added CompanyRecommendation system - Made company pages public (removed @login_required) - CSS refactor: inline styles instead of external fluent CSS - Added release notes page - Added admin recommendations panel - Company logos (webp format) - Docker compose configuration Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
224 lines
7.0 KiB
HTML
Executable File
224 lines
7.0 KiB
HTML
Executable File
{% extends "base.html" %}
|
|
|
|
{% block title %}Analityka Chatu AI - Norda Biznes Hub{% endblock %}
|
|
|
|
{% block extra_css %}
|
|
<style>
|
|
.analytics-header {
|
|
margin-bottom: var(--spacing-xl);
|
|
}
|
|
|
|
.analytics-header h1 {
|
|
font-size: var(--font-size-3xl);
|
|
color: var(--text-primary);
|
|
}
|
|
|
|
.stats-grid {
|
|
display: grid;
|
|
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
|
gap: var(--spacing-lg);
|
|
margin-bottom: var(--spacing-2xl);
|
|
}
|
|
|
|
.stat-card {
|
|
background: var(--surface);
|
|
padding: var(--spacing-lg);
|
|
border-radius: var(--radius-lg);
|
|
box-shadow: var(--shadow);
|
|
text-align: center;
|
|
}
|
|
|
|
.stat-value {
|
|
font-size: var(--font-size-3xl);
|
|
font-weight: 700;
|
|
color: var(--primary);
|
|
}
|
|
|
|
.stat-value.positive { color: var(--success); }
|
|
.stat-value.negative { color: var(--error); }
|
|
.stat-value.neutral { color: var(--secondary); }
|
|
|
|
.stat-label {
|
|
color: var(--text-secondary);
|
|
font-size: var(--font-size-sm);
|
|
margin-top: var(--spacing-xs);
|
|
}
|
|
|
|
.section {
|
|
background: var(--surface);
|
|
padding: var(--spacing-xl);
|
|
border-radius: var(--radius-lg);
|
|
box-shadow: var(--shadow);
|
|
margin-bottom: var(--spacing-xl);
|
|
}
|
|
|
|
.section h2 {
|
|
font-size: var(--font-size-xl);
|
|
margin-bottom: var(--spacing-lg);
|
|
color: var(--text-primary);
|
|
border-bottom: 2px solid var(--border);
|
|
padding-bottom: var(--spacing-sm);
|
|
}
|
|
|
|
.query-list {
|
|
list-style: none;
|
|
}
|
|
|
|
.query-item {
|
|
padding: var(--spacing-md);
|
|
border-bottom: 1px solid var(--border);
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
}
|
|
|
|
.query-item:last-child {
|
|
border-bottom: none;
|
|
}
|
|
|
|
.query-text {
|
|
flex: 1;
|
|
font-size: var(--font-size-base);
|
|
}
|
|
|
|
.query-meta {
|
|
color: var(--text-secondary);
|
|
font-size: var(--font-size-sm);
|
|
text-align: right;
|
|
}
|
|
|
|
.feedback-badge {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: var(--spacing-xs);
|
|
padding: var(--spacing-xs) var(--spacing-sm);
|
|
border-radius: var(--radius);
|
|
font-size: var(--font-size-sm);
|
|
font-weight: 500;
|
|
}
|
|
|
|
.feedback-badge.positive {
|
|
background: rgba(16, 185, 129, 0.1);
|
|
color: var(--success);
|
|
}
|
|
|
|
.feedback-badge.negative {
|
|
background: rgba(239, 68, 68, 0.1);
|
|
color: var(--error);
|
|
}
|
|
|
|
.satisfaction-bar {
|
|
height: 8px;
|
|
background: var(--border);
|
|
border-radius: 4px;
|
|
overflow: hidden;
|
|
margin-top: var(--spacing-sm);
|
|
}
|
|
|
|
.satisfaction-fill {
|
|
height: 100%;
|
|
background: linear-gradient(90deg, var(--error), var(--warning), var(--success));
|
|
transition: width 0.3s ease;
|
|
}
|
|
|
|
.response-preview {
|
|
background: var(--background);
|
|
padding: var(--spacing-md);
|
|
border-radius: var(--radius);
|
|
margin-top: var(--spacing-sm);
|
|
font-size: var(--font-size-sm);
|
|
color: var(--text-secondary);
|
|
max-height: 100px;
|
|
overflow: hidden;
|
|
}
|
|
</style>
|
|
{% endblock %}
|
|
|
|
{% block content %}
|
|
<div class="analytics-header">
|
|
<h1>Analityka Chatu AI</h1>
|
|
<p class="text-muted">Monitoruj jakość odpowiedzi i zachowania użytkowników</p>
|
|
</div>
|
|
|
|
<!-- Stats Grid -->
|
|
<div class="stats-grid">
|
|
<div class="stat-card">
|
|
<div class="stat-value">{{ total_conversations }}</div>
|
|
<div class="stat-label">Rozmów</div>
|
|
</div>
|
|
<div class="stat-card">
|
|
<div class="stat-value">{{ total_user_messages }}</div>
|
|
<div class="stat-label">Zapytań użytkowników</div>
|
|
</div>
|
|
<div class="stat-card">
|
|
<div class="stat-value positive">{{ positive_feedback }}</div>
|
|
<div class="stat-label">Pozytywnych ocen</div>
|
|
</div>
|
|
<div class="stat-card">
|
|
<div class="stat-value negative">{{ negative_feedback }}</div>
|
|
<div class="stat-label">Negatywnych ocen</div>
|
|
</div>
|
|
<div class="stat-card">
|
|
<div class="stat-value {% if satisfaction_rate >= 70 %}positive{% elif satisfaction_rate >= 40 %}neutral{% else %}negative{% endif %}">
|
|
{{ satisfaction_rate }}%
|
|
</div>
|
|
<div class="stat-label">Satysfakcja</div>
|
|
<div class="satisfaction-bar">
|
|
<div class="satisfaction-fill" style="width: {{ satisfaction_rate }}%"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Recent Queries -->
|
|
<div class="section">
|
|
<h2>Ostatnie zapytania użytkowników</h2>
|
|
{% if recent_queries %}
|
|
<ul class="query-list">
|
|
{% for query in recent_queries %}
|
|
<li class="query-item">
|
|
<div class="query-text">{{ query.content }}</div>
|
|
<div class="query-meta">
|
|
{{ query.created_at.strftime('%d.%m %H:%M') }}
|
|
</div>
|
|
</li>
|
|
{% endfor %}
|
|
</ul>
|
|
{% else %}
|
|
<p class="text-muted">Brak zapytań</p>
|
|
{% endif %}
|
|
</div>
|
|
|
|
<!-- Feedback Section -->
|
|
<div class="section">
|
|
<h2>Odpowiedzi z oceną</h2>
|
|
{% if recent_feedback %}
|
|
<ul class="query-list">
|
|
{% for msg in recent_feedback %}
|
|
<li class="query-item" style="flex-direction: column; align-items: flex-start;">
|
|
<div style="display: flex; justify-content: space-between; width: 100%; align-items: center;">
|
|
<span class="feedback-badge {% if msg.feedback_rating == 2 %}positive{% else %}negative{% endif %}">
|
|
{% if msg.feedback_rating == 2 %}
|
|
<svg width="16" height="16" fill="currentColor" viewBox="0 0 20 20"><path d="M2 10.5a1.5 1.5 0 113 0v6a1.5 1.5 0 01-3 0v-6zM6 10.333v5.43a2 2 0 001.106 1.79l.05.025A4 4 0 008.943 18h5.416a2 2 0 001.962-1.608l1.2-6A2 2 0 0015.56 8H12V4a2 2 0 00-2-2 1 1 0 00-1 1v.667a4 4 0 01-.8 2.4L6.8 7.933a4 4 0 00-.8 2.4z"/></svg>
|
|
Pomocne
|
|
{% else %}
|
|
<svg width="16" height="16" fill="currentColor" viewBox="0 0 20 20"><path d="M18 9.5a1.5 1.5 0 11-3 0v-6a1.5 1.5 0 013 0v6zM14 9.667v-5.43a2 2 0 00-1.105-1.79l-.05-.025A4 4 0 0011.055 2H5.64a2 2 0 00-1.962 1.608l-1.2 6A2 2 0 004.44 12H8v4a2 2 0 002 2 1 1 0 001-1v-.667a4 4 0 01.8-2.4l1.4-1.866a4 4 0 00.8-2.4z"/></svg>
|
|
Do poprawy
|
|
{% endif %}
|
|
</span>
|
|
<span class="query-meta">{{ msg.feedback_at.strftime('%d.%m %H:%M') if msg.feedback_at else '' }}</span>
|
|
</div>
|
|
<div class="response-preview">{{ msg.content[:300] }}{% if msg.content|length > 300 %}...{% endif %}</div>
|
|
{% if msg.feedback_comment %}
|
|
<div style="margin-top: var(--spacing-sm); font-size: var(--font-size-sm);">
|
|
<strong>Komentarz:</strong> {{ msg.feedback_comment }}
|
|
</div>
|
|
{% endif %}
|
|
</li>
|
|
{% endfor %}
|
|
</ul>
|
|
{% else %}
|
|
<p class="text-muted">Brak ocen - poproś użytkowników o feedback!</p>
|
|
{% endif %}
|
|
</div>
|
|
{% endblock %}
|