This commit is contained in:
Iliyan Angelov
2025-11-26 22:32:20 +02:00
commit ed94dd22dd
150 changed files with 14058 additions and 0 deletions

View File

@@ -0,0 +1,80 @@
{% extends 'base.html' %}
{% block title %}Табло за Аналитика - Официален Портал{% endblock %}
{% block content %}
<div class="gov-card">
<div class="gov-card-header">
<h2>Табло за Аналитика</h2>
</div>
<div class="gov-card-body">
<div class="stats-grid">
<div class="stat-card">
<h3>{{ total_reports|default:0 }}</h3>
<p>Общо Доклади</p>
</div>
<div class="stat-card">
<h3>{{ pending_reports|default:0 }}</h3>
<p>Чакащи</p>
</div>
<div class="stat-card">
<h3>{{ verified_reports|default:0 }}</h3>
<p>Потвърдени</p>
</div>
<div class="stat-card">
<h3>{{ rejected_reports|default:0 }}</h3>
<p>Отхвърлени</p>
</div>
<div class="stat-card">
<h3>{{ total_users|default:0 }}</h3>
<p>Общо Потребители</p>
</div>
<div class="stat-card">
<h3>{{ moderators|default:0 }}</h3>
<p>Модератори</p>
</div>
</div>
</div>
</div>
{% if scam_types %}
<div class="gov-card">
<div class="gov-card-header">
<h2>Разпределение по Видове Измами</h2>
</div>
<div class="gov-card-body">
<div class="scam-types-grid">
{% for type in scam_types %}
<div class="scam-type-card">
<div class="scam-type-header">
<span class="badge badge-{{ type.scam_type }}" style="font-size: 0.9rem; padding: 0.5rem 1rem;">
{{ type.display_name }}
</span>
<div class="scam-type-count">
<span class="count-number">{{ type.count }}</span>
<span class="count-label">доклад{{ type.count|pluralize:"а,а" }}</span>
</div>
</div>
<div class="scam-type-bar">
<div class="scam-type-bar-fill" style="width: {{ type.percentage }}%"></div>
</div>
<div class="scam-type-percentage">
{{ type.percentage }}% от общия брой
</div>
</div>
{% endfor %}
</div>
</div>
</div>
{% endif %}
<div class="gov-card">
<div class="gov-card-body">
<div class="analytics-links">
<a href="{% url 'analytics:reports' %}" class="btn btn-secondary">Аналитика на Докладите</a>
<a href="{% url 'analytics:users' %}" class="btn btn-secondary">Аналитика на Потребителите</a>
</div>
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,283 @@
{% extends 'base.html' %}
{% block title %}Аналитика на Докладите - Официален Портал{% endblock %}
{% block content %}
<div class="page-header">
<h1>Аналитика на Докладите</h1>
<p class="lead">Подробна статистика и аналитика за докладите за измами</p>
</div>
<!-- Overall Statistics -->
<div class="gov-card">
<div class="gov-card-header">
<h2>Обща Статистика</h2>
</div>
<div class="gov-card-body">
<div class="stats-grid">
<div class="stat-card">
<h3>{{ total_reports|default:0 }}</h3>
<p>Общо Доклади</p>
</div>
<div class="stat-card stat-pending">
<h3>{{ pending_reports|default:0 }}</h3>
<p>В Очакване</p>
</div>
<div class="stat-card stat-verified">
<h3>{{ verified_reports|default:0 }}</h3>
<p>Потвърдени</p>
</div>
<div class="stat-card stat-rejected">
<h3>{{ rejected_reports|default:0 }}</h3>
<p>Отхвърлени</p>
</div>
<div class="stat-card stat-review">
<h3>{{ under_review_reports|default:0 }}</h3>
<p>В Преглед</p>
</div>
</div>
</div>
</div>
<!-- Time-based Statistics -->
<div class="gov-card">
<div class="gov-card-header">
<h2>Статистика по Период</h2>
</div>
<div class="gov-card-body">
<div class="stats-grid">
<div class="stat-card">
<h3>{{ reports_last_7_days|default:0 }}</h3>
<p>Последните 7 Дни</p>
</div>
<div class="stat-card">
<h3>{{ reports_last_30_days|default:0 }}</h3>
<p>Последните 30 Дни</p>
</div>
<div class="stat-card">
<h3>{{ reports_last_90_days|default:0 }}</h3>
<p>Последните 90 Дни</p>
</div>
</div>
</div>
</div>
<!-- Scam Type Distribution -->
{% if scam_types %}
<div class="gov-card">
<div class="gov-card-header">
<h2>Разпределение по Видове Измами</h2>
</div>
<div class="gov-card-body">
<div class="scam-types-grid">
{% for type in scam_types %}
<div class="scam-type-card">
<div class="scam-type-header">
<span class="badge badge-{{ type.scam_type }}" style="font-size: 0.9rem; padding: 0.5rem 1rem;">
{{ type.display_name }}
</span>
<div class="scam-type-count">
<span class="count-number">{{ type.count }}</span>
<span class="count-label">доклад{{ type.count|pluralize:"а,а" }}</span>
</div>
</div>
<div class="scam-type-bar">
<div class="scam-type-bar-fill" style="width: {{ type.percentage }}%"></div>
</div>
<div class="scam-type-percentage">
{{ type.percentage }}% от общия брой
</div>
</div>
{% endfor %}
</div>
</div>
</div>
{% endif %}
<!-- Moderation Statistics -->
<div class="gov-card">
<div class="gov-card-header">
<h2>Статистика на Модерация</h2>
</div>
<div class="gov-card-body">
<div class="stats-grid">
<div class="stat-card">
<h3>{{ total_moderations|default:0 }}</h3>
<p>Общо Модерации</p>
</div>
<div class="stat-card stat-verified">
<h3>{{ approvals|default:0 }}</h3>
<p>Одобрени</p>
</div>
<div class="stat-card stat-rejected">
<h3>{{ rejections|default:0 }}</h3>
<p>Отхвърлени</p>
</div>
</div>
{% if avg_moderation_time_hours %}
<div style="margin-top: 2rem; padding-top: 2rem; border-top: 1px solid #e0e0e0;">
<h3>Време за Модерация</h3>
<div class="stats-grid" style="margin-top: 1rem;">
<div class="stat-card">
<h3>{{ avg_moderation_time_hours }}ч</h3>
<p>Средно Време</p>
</div>
<div class="stat-card">
<h3>{{ min_moderation_time_hours }}ч</h3>
<p>Минимално Време</p>
</div>
<div class="stat-card">
<h3>{{ max_moderation_time_hours }}ч</h3>
<p>Максимално Време</p>
</div>
</div>
</div>
{% endif %}
</div>
</div>
<!-- Top Reporters -->
{% if top_reporters %}
<div class="gov-card">
<div class="gov-card-header">
<h2>Най-Активни Докладващи</h2>
</div>
<div class="gov-card-body">
<div class="table-responsive">
<table class="gov-table">
<thead>
<tr>
<th>Позиция</th>
<th>Потребител</th>
<th>Брой Доклади</th>
</tr>
</thead>
<tbody>
{% for reporter in top_reporters %}
<tr>
<td>{{ forloop.counter }}</td>
<td>{{ reporter.reporter__username|default:"Анонимен" }}</td>
<td><strong>{{ reporter.report_count }}</strong></td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
{% endif %}
<!-- Daily Reports Chart -->
{% if daily_reports %}
<div class="gov-card">
<div class="gov-card-header">
<h2>Дневна Статистика (Последните 30 Дни)</h2>
</div>
<div class="gov-card-body">
<div class="chart-container">
<canvas id="dailyReportsChart" style="max-height: 400px;"></canvas>
</div>
</div>
</div>
{% endif %}
<!-- Status Over Time -->
{% if status_over_time %}
<div class="gov-card">
<div class="gov-card-header">
<h2>Статуси по Време (Последните 7 Дни)</h2>
</div>
<div class="gov-card-body">
<div class="chart-container">
<canvas id="statusChart" style="max-height: 400px;"></canvas>
</div>
</div>
</div>
{% endif %}
<div style="margin-top: 2rem;">
<a href="{% url 'analytics:dashboard' %}" class="btn btn-secondary">Обратно към Таблото</a>
</div>
{% if daily_reports %}
<script src="https://cdn.jsdelivr.net/npm/chart.js@3.9.1/dist/chart.min.js"></script>
<script>
// Daily Reports Chart
const dailyCtx = document.getElementById('dailyReportsChart');
if (dailyCtx) {
const dailyData = {{ daily_reports }};
new Chart(dailyCtx, {
type: 'line',
data: {
labels: dailyData.map(d => new Date(d.date).toLocaleDateString('bg-BG')),
datasets: [{
label: 'Доклади',
data: dailyData.map(d => d.count),
borderColor: '#1e3a8a',
backgroundColor: 'rgba(30, 58, 138, 0.1)',
tension: 0.4
}]
},
options: {
responsive: true,
maintainAspectRatio: true,
plugins: {
legend: {
display: true
}
},
scales: {
y: {
beginAtZero: true
}
}
}
});
}
// Status Over Time Chart
const statusCtx = document.getElementById('statusChart');
if (statusCtx) {
const statusData = {{ status_over_time }};
new Chart(statusCtx, {
type: 'bar',
data: {
labels: statusData.map(d => new Date(d.date).toLocaleDateString('bg-BG')),
datasets: [
{
label: 'В Очакване',
data: statusData.map(d => d.pending),
backgroundColor: '#f59e0b'
},
{
label: 'Потвърдени',
data: statusData.map(d => d.verified),
backgroundColor: '#10b981'
},
{
label: 'Отхвърлени',
data: statusData.map(d => d.rejected),
backgroundColor: '#ef4444'
}
]
},
options: {
responsive: true,
maintainAspectRatio: true,
plugins: {
legend: {
display: true
}
},
scales: {
y: {
beginAtZero: true,
stacked: false
}
}
}
});
}
</script>
{% endif %}
{% endblock %}

View File

@@ -0,0 +1,18 @@
{% extends 'base.html' %}
{% block title %}Аналитика на Потребителите - Официален Портал{% endblock %}
{% block content %}
<div class="gov-card">
<div class="gov-card-header">
<h2>Аналитика на Потребителите</h2>
</div>
<div class="gov-card-body">
<p>Подробна аналитика на потребителите ще бъде показана тук.</p>
<div style="margin-top: 2rem;">
<a href="{% url 'analytics:dashboard' %}" class="btn btn-secondary">Обратно към Таблото</a>
</div>
</div>
</div>
{% endblock %}