2025-08-12 13:33:25 +03:00

499 lines
22 KiB
HTML

{% extends 'base.html' %}
{% load static %}
{% block title %}Message Analytics{% endblock %}
{% block css %}
<link href="{% static 'assets/plugins/datatables.net-bs5/css/dataTables.bootstrap5.min.css' %}" rel="stylesheet" />
<link href="{% static 'assets/plugins/datatables.net-responsive-bs5/css/responsive.bootstrap5.min.css' %}" rel="stylesheet" />
{% endblock %}
{% block content %}
<div id="content" class="app-content">
<div class="container">
<ul class="breadcrumb">
<li class="breadcrumb-item"><a href="{% url 'core:dashboard' %}">Dashboard</a></li>
<li class="breadcrumb-item"><a href="{% url 'communications:message_list' %}">Messages</a></li>
<li class="breadcrumb-item active">Analytics</li>
</ul>
<div class="row align-items-center mb-3">
<div class="col">
<h1 class="page-header">Message Analytics</h1>
<p class="text-muted">Track message delivery, engagement, and communication effectiveness</p>
</div>
<div class="col-auto">
<div class="btn-group">
<button type="button" class="btn btn-outline-primary" onclick="exportReport('pdf')">
<i class="fa fa-file-pdf me-2"></i>Export PDF
</button>
<button type="button" class="btn btn-outline-success" onclick="exportReport('excel')">
<i class="fa fa-file-excel me-2"></i>Export Excel
</button>
</div>
</div>
</div>
<!-- Date Range Filter -->
<div class="card mb-4">
<div class="card-body">
<form method="get" class="row g-3 align-items-end">
<div class="col-md-3">
<label class="form-label">From Date</label>
<input type="date" name="start_date" class="form-control" value="{{ start_date }}">
</div>
<div class="col-md-3">
<label class="form-label">To Date</label>
<input type="date" name="end_date" class="form-control" value="{{ end_date }}">
</div>
<div class="col-md-3">
<label class="form-label">Message Type</label>
<select name="message_type" class="form-select">
<option value="">All Types</option>
<option value="announcement" {% if message_type == 'announcement' %}selected{% endif %}>Announcement</option>
<option value="alert" {% if message_type == 'alert' %}selected{% endif %}>Alert</option>
<option value="notification" {% if message_type == 'notification' %}selected{% endif %}>Notification</option>
<option value="reminder" {% if message_type == 'reminder' %}selected{% endif %}>Reminder</option>
<option value="emergency" {% if message_type == 'emergency' %}selected{% endif %}>Emergency</option>
</select>
</div>
<div class="col-md-3">
<button type="submit" class="btn btn-primary">
<i class="fa fa-filter me-2"></i>Apply Filter
</button>
<a href="{% url 'communications:message_analytics' %}" class="btn btn-outline-secondary ms-2">
<i class="fa fa-times me-2"></i>Clear
</a>
</div>
</form>
</div>
</div>
<!-- Key Metrics -->
<div class="row mb-4">
<div class="col-md-3">
<div class="card text-center">
<div class="card-body">
<div class="fs-28px fw-600 text-primary">{{ total_messages }}</div>
<div class="text-muted">Total Messages</div>
<div class="progress mt-2" style="height: 4px;">
<div class="progress-bar bg-primary" style="width: 100%"></div>
</div>
</div>
</div>
</div>
<div class="col-md-3">
<div class="card text-center">
<div class="card-body">
<div class="fs-28px fw-600 text-success">{{ delivered_messages }}</div>
<div class="text-muted">Delivered</div>
<div class="progress mt-2" style="height: 4px;">
<div class="progress-bar bg-success" style="width: {{ delivery_rate }}%"></div>
</div>
<small class="text-muted">{{ delivery_rate }}% delivery rate</small>
</div>
</div>
</div>
<div class="col-md-3">
<div class="card text-center">
<div class="card-body">
<div class="fs-28px fw-600 text-info">{{ read_messages }}</div>
<div class="text-muted">Read</div>
<div class="progress mt-2" style="height: 4px;">
<div class="progress-bar bg-info" style="width: {{ read_rate }}%"></div>
</div>
<small class="text-muted">{{ read_rate }}% read rate</small>
</div>
</div>
</div>
<div class="col-md-3">
<div class="card text-center">
<div class="card-body">
<div class="fs-28px fw-600 text-warning">{{ acknowledged_messages }}</div>
<div class="text-muted">Acknowledged</div>
<div class="progress mt-2" style="height: 4px;">
<div class="progress-bar bg-warning" style="width: {{ acknowledgment_rate }}%"></div>
</div>
<small class="text-muted">{{ acknowledgment_rate }}% ack rate</small>
</div>
</div>
</div>
</div>
<!-- Charts Row -->
<div class="row mb-4">
<div class="col-md-6">
<div class="card">
<div class="card-header">
<h4 class="card-title">Message Volume Trend</h4>
</div>
<div class="card-body">
<canvas id="messageVolumeChart" height="300"></canvas>
</div>
</div>
</div>
<div class="col-md-6">
<div class="card">
<div class="card-header">
<h4 class="card-title">Message Types Distribution</h4>
</div>
<div class="card-body">
<canvas id="messageTypesChart" height="300"></canvas>
</div>
</div>
</div>
</div>
<div class="row mb-4">
<div class="col-md-6">
<div class="card">
<div class="card-header">
<h4 class="card-title">Delivery Performance</h4>
</div>
<div class="card-body">
<canvas id="deliveryPerformanceChart" height="300"></canvas>
</div>
</div>
</div>
<div class="col-md-6">
<div class="card">
<div class="card-header">
<h4 class="card-title">Response Time Analysis</h4>
</div>
<div class="card-body">
<canvas id="responseTimeChart" height="300"></canvas>
</div>
</div>
</div>
</div>
<!-- Department Performance -->
<div class="card mb-4">
<div class="card-header">
<h4 class="card-title">Department Performance</h4>
</div>
<div class="card-body">
<div class="table-responsive">
<table class="table table-striped" id="departmentTable">
<thead>
<tr>
<th>Department</th>
<th>Messages Sent</th>
<th>Delivery Rate</th>
<th>Read Rate</th>
<th>Avg Response Time</th>
<th>Engagement Score</th>
</tr>
</thead>
<tbody>
{% for dept in department_stats %}
<tr>
<td>
<div class="d-flex align-items-center">
<div class="w-40px h-40px bg-{{ dept.color|default:'primary' }} bg-opacity-20 d-flex align-items-center justify-content-center rounded me-3">
<i class="fa fa-building text-{{ dept.color|default:'primary' }}"></i>
</div>
<div>
<div class="fw-bold">{{ dept.name }}</div>
<div class="text-muted small">{{ dept.user_count }} users</div>
</div>
</div>
</td>
<td>{{ dept.messages_sent }}</td>
<td>
<div class="d-flex align-items-center">
<div class="flex-fill me-2">
<div class="progress" style="height: 6px;">
<div class="progress-bar bg-success" style="width: {{ dept.delivery_rate }}%"></div>
</div>
</div>
<div class="text-muted small">{{ dept.delivery_rate }}%</div>
</div>
</td>
<td>
<div class="d-flex align-items-center">
<div class="flex-fill me-2">
<div class="progress" style="height: 6px;">
<div class="progress-bar bg-info" style="width: {{ dept.read_rate }}%"></div>
</div>
</div>
<div class="text-muted small">{{ dept.read_rate }}%</div>
</div>
</td>
<td>{{ dept.avg_response_time }}</td>
<td>
<span class="badge bg-{{ dept.engagement_color }}">{{ dept.engagement_score }}</span>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
<!-- Recent Messages Performance -->
<div class="card mb-4">
<div class="card-header">
<h4 class="card-title">Recent Messages Performance</h4>
</div>
<div class="card-body">
<div class="table-responsive">
<table class="table table-striped" id="messagesTable">
<thead>
<tr>
<th>Message</th>
<th>Type</th>
<th>Sent Date</th>
<th>Recipients</th>
<th>Delivered</th>
<th>Read</th>
<th>Acknowledged</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{% for message in recent_messages %}
<tr>
<td>
<div class="fw-bold">{{ message.subject|truncatechars:50 }}</div>
<div class="text-muted small">{{ message.sender.get_full_name }}</div>
</td>
<td>
<span class="badge bg-{{ message.type_color }}">{{ message.get_message_type_display }}</span>
</td>
<td>{{ message.created_at|date:"M d, Y g:i A" }}</td>
<td>{{ message.recipient_count }}</td>
<td>
<div class="text-center">
<div class="fs-14px fw-600 text-success">{{ message.delivered_count }}</div>
<div class="text-muted small">{{ message.delivery_percentage }}%</div>
</div>
</td>
<td>
<div class="text-center">
<div class="fs-14px fw-600 text-info">{{ message.read_count }}</div>
<div class="text-muted small">{{ message.read_percentage }}%</div>
</div>
</td>
<td>
<div class="text-center">
<div class="fs-14px fw-600 text-warning">{{ message.acknowledged_count }}</div>
<div class="text-muted small">{{ message.acknowledgment_percentage }}%</div>
</div>
</td>
<td>
<div class="btn-group">
<button type="button" class="btn btn-outline-primary btn-sm" onclick="viewMessageDetails('{{ message.id }}')">
<i class="fa fa-eye"></i>
</button>
<button type="button" class="btn btn-outline-info btn-sm" onclick="viewRecipients('{{ message.id }}')">
<i class="fa fa-users"></i>
</button>
</div>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
<!-- Communication Channels Performance -->
<div class="card">
<div class="card-header">
<h4 class="card-title">Communication Channels Performance</h4>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-3">
<div class="text-center">
<div class="w-80px h-80px bg-primary bg-opacity-20 d-flex align-items-center justify-content-center rounded-circle mx-auto mb-3">
<i class="fa fa-bell fa-2x text-primary"></i>
</div>
<h5>In-App</h5>
<div class="fs-20px fw-600 text-primary">{{ in_app_stats.delivery_rate }}%</div>
<div class="text-muted small">{{ in_app_stats.total_sent }} sent</div>
</div>
</div>
<div class="col-md-3">
<div class="text-center">
<div class="w-80px h-80px bg-info bg-opacity-20 d-flex align-items-center justify-content-center rounded-circle mx-auto mb-3">
<i class="fa fa-envelope fa-2x text-info"></i>
</div>
<h5>Email</h5>
<div class="fs-20px fw-600 text-info">{{ email_stats.delivery_rate }}%</div>
<div class="text-muted small">{{ email_stats.total_sent }} sent</div>
</div>
</div>
<div class="col-md-3">
<div class="text-center">
<div class="w-80px h-80px bg-success bg-opacity-20 d-flex align-items-center justify-content-center rounded-circle mx-auto mb-3">
<i class="fa fa-mobile fa-2x text-success"></i>
</div>
<h5>SMS</h5>
<div class="fs-20px fw-600 text-success">{{ sms_stats.delivery_rate }}%</div>
<div class="text-muted small">{{ sms_stats.total_sent }} sent</div>
</div>
</div>
<div class="col-md-3">
<div class="text-center">
<div class="w-80px h-80px bg-warning bg-opacity-20 d-flex align-items-center justify-content-center rounded-circle mx-auto mb-3">
<i class="fa fa-mobile-alt fa-2x text-warning"></i>
</div>
<h5>Push</h5>
<div class="fs-20px fw-600 text-warning">{{ push_stats.delivery_rate }}%</div>
<div class="text-muted small">{{ push_stats.total_sent }} sent</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
{% block js %}
<script src="{% static 'assets/plugins/datatables.net/js/jquery.dataTables.min.js' %}"></script>
<script src="{% static 'assets/plugins/datatables.net-bs5/js/dataTables.bootstrap5.min.js' %}"></script>
<script src="{% static 'assets/plugins/chart.js/dist/chart.min.js' %}"></script>
<script>
$(document).ready(function() {
// Initialize DataTables
$('#departmentTable, #messagesTable').DataTable({
responsive: true,
pageLength: 10,
order: [[0, 'asc']]
});
// Initialize Charts
initializeCharts();
});
function initializeCharts() {
// Message Volume Trend Chart
const volumeCtx = document.getElementById('messageVolumeChart').getContext('2d');
new Chart(volumeCtx, {
type: 'line',
data: {
labels: {{ volume_chart_labels|safe }},
datasets: [{
label: 'Messages Sent',
data: {{ volume_chart_data|safe }},
borderColor: '#348fe2',
backgroundColor: 'rgba(52, 143, 226, 0.1)',
tension: 0.4
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
scales: {
y: {
beginAtZero: true
}
}
}
});
// Message Types Chart
const typesCtx = document.getElementById('messageTypesChart').getContext('2d');
new Chart(typesCtx, {
type: 'doughnut',
data: {
labels: {{ types_chart_labels|safe }},
datasets: [{
data: {{ types_chart_data|safe }},
backgroundColor: [
'#348fe2',
'#00acac',
'#f59c1a',
'#ff5b57',
'#727cb6'
]
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: {
position: 'bottom'
}
}
}
});
// Delivery Performance Chart
const deliveryCtx = document.getElementById('deliveryPerformanceChart').getContext('2d');
new Chart(deliveryCtx, {
type: 'bar',
data: {
labels: ['Sent', 'Delivered', 'Read', 'Acknowledged'],
datasets: [{
label: 'Count',
data: [{{ total_messages }}, {{ delivered_messages }}, {{ read_messages }}, {{ acknowledged_messages }}],
backgroundColor: [
'#727cb6',
'#00acac',
'#348fe2',
'#f59c1a'
]
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
scales: {
y: {
beginAtZero: true
}
}
}
});
// Response Time Chart
const responseCtx = document.getElementById('responseTimeChart').getContext('2d');
new Chart(responseCtx, {
type: 'line',
data: {
labels: {{ response_time_labels|safe }},
datasets: [{
label: 'Avg Response Time (hours)',
data: {{ response_time_data|safe }},
borderColor: '#f59c1a',
backgroundColor: 'rgba(245, 156, 26, 0.1)',
tension: 0.4
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
scales: {
y: {
beginAtZero: true
}
}
}
});
}
function viewMessageDetails(messageId) {
window.open('{% url "communications:message_detail" 0 %}'.replace('0', messageId), '_blank');
}
function viewRecipients(messageId) {
window.open('{% url "communications:message_recipients" 0 %}'.replace('0', messageId), '_blank');
}
function exportReport(format) {
var params = new URLSearchParams(window.location.search);
params.set('export', format);
window.location.href = '{% url "communications:message_analytics" %}?' + params.toString();
}
</script>
{% endblock %}