Files
email_alerts/templates/index.html
T
2025-08-05 22:29:54 +01:00

320 lines
10 KiB
HTML

{% extends "base.html" %}
{% block title %}Dashboard - Email Alerts System{% endblock %}
{% block content %}
<div class="row">
<div class="col-12">
<h2 class="mb-4">
<i class="fas fa-tachometer-alt me-2"></i>
Dashboard
</h2>
</div>
</div>
<!-- Status Cards -->
<div class="row mb-4">
<div class="col-md-3">
<div class="card">
<div class="card-body text-center">
<i class="fas fa-envelope fa-2x text-primary mb-2"></i>
<h5 class="card-title">Email Address</h5>
<p class="card-text">{{ config.email_address }}</p>
</div>
</div>
</div>
<div class="col-md-3">
<div class="card">
<div class="card-body text-center">
<i class="fas fa-clock fa-2x text-warning mb-2"></i>
<h5 class="card-title">Time Frames</h5>
<p class="card-text">{{ config.time_frames|length }} configured</p>
</div>
</div>
</div>
<div class="col-md-3">
<div class="card">
<div class="card-body text-center">
<i class="fas fa-calendar-day fa-2x text-info mb-2"></i>
<h5 class="card-title">Email Range</h5>
<p class="card-text">Last {{ config.email_days_back }} days</p>
</div>
</div>
</div>
<div class="col-md-3">
<div class="card">
<div class="card-body text-center">
<i class="fas fa-building fa-2x text-success mb-2"></i>
<h5 class="card-title">Agency Domains</h5>
<p class="card-text">{{ config.agency_domains|length }} domains</p>
</div>
</div>
</div>
</div>
<!-- Action Buttons -->
<div class="row mb-4">
<div class="col-12">
<div class="card">
<div class="card-body">
<h5 class="card-title mb-3">
<i class="fas fa-play-circle me-2"></i>
System Actions
</h5>
<div class="row">
<div class="col-md-4">
<button class="btn btn-primary w-100 mb-2" onclick="testConnection()">
<i class="fas fa-wifi me-2"></i>
Test Connection
</button>
</div>
<div class="col-md-4">
<button class="btn btn-success w-100 mb-2" onclick="processEmails()">
<i class="fas fa-envelope-open me-2"></i>
Process Emails
</button>
</div>
<div class="col-md-4">
<button class="btn btn-info w-100 mb-2" onclick="refreshThreads()">
<i class="fas fa-sync-alt me-2"></i>
Refresh Threads
</button>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Results Section -->
<div class="row">
<div class="col-12">
<div class="card">
<div class="card-body">
<h5 class="card-title mb-3">
<i class="fas fa-list me-2"></i>
Processing Results
</h5>
<div id="results-container">
<div class="text-center text-muted">
<i class="fas fa-info-circle fa-2x mb-2"></i>
<p>Click "Process Emails" to start processing and view results here.</p>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Threads Table -->
<div class="row mt-4">
<div class="col-12">
<div class="card">
<div class="card-body">
<h5 class="card-title mb-3">
<i class="fas fa-exclamation-triangle me-2"></i>
Threads Needing Alerts
</h5>
<div id="threads-container">
<div class="text-center">
<div class="spinner-border text-primary" role="status">
<span class="visually-hidden">Loading...</span>
</div>
<p class="mt-2">Loading threads...</p>
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
{% block scripts %}
<script>
function testConnection() {
const button = event.target;
const originalText = button.innerHTML;
button.innerHTML = '<i class="fas fa-spinner fa-spin me-2"></i>Testing...';
button.disabled = true;
fetch('/test_connection')
.then(response => response.json())
.then(data => {
if (data.status === 'success') {
showAlert('success', data.message);
} else {
showAlert('danger', data.message);
}
})
.catch(error => {
showAlert('danger', 'Connection test failed: ' + error.message);
})
.finally(() => {
button.innerHTML = originalText;
button.disabled = false;
});
}
function processEmails() {
const button = event.target;
const originalText = button.innerHTML;
button.innerHTML = '<i class="fas fa-spinner fa-spin me-2"></i>Processing...';
button.disabled = true;
fetch('/process_emails', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
}
})
.then(response => response.json())
.then(data => {
if (data.status === 'success') {
showAlert('success', data.message);
updateResults(data.data);
} else {
showAlert('danger', data.message);
}
})
.catch(error => {
showAlert('danger', 'Processing failed: ' + error.message);
})
.finally(() => {
button.innerHTML = originalText;
button.disabled = false;
});
}
function refreshThreads() {
const container = document.getElementById('threads-container');
container.innerHTML = `
<div class="text-center">
<div class="spinner-border text-primary" role="status">
<span class="visually-hidden">Loading...</span>
</div>
<p class="mt-2">Loading threads...</p>
</div>
`;
fetch('/get_threads')
.then(response => response.json())
.then(data => {
if (data.status === 'success') {
updateThreadsTable(data.threads);
} else {
container.innerHTML = `
<div class="alert alert-danger">
<i class="fas fa-exclamation-triangle me-2"></i>
${data.message}
</div>
`;
}
})
.catch(error => {
container.innerHTML = `
<div class="alert alert-danger">
<i class="fas fa-exclamation-triangle me-2"></i>
Error loading threads: ${error.message}
</div>
`;
});
}
function updateResults(data) {
const container = document.getElementById('results-container');
container.innerHTML = `
<div class="row">
<div class="col-md-4">
<div class="text-center">
<h4 class="text-primary">${data.total_emails}</h4>
<p class="text-muted">Total Emails</p>
</div>
</div>
<div class="col-md-4">
<div class="text-center">
<h4 class="text-warning">${data.actionable_emails}</h4>
<p class="text-muted">Actionable Emails</p>
</div>
</div>
<div class="col-md-4">
<div class="text-center">
<h4 class="text-success">${data.sent_alerts}</h4>
<p class="text-muted">Alerts Sent</p>
</div>
</div>
</div>
`;
}
function updateThreadsTable(threads) {
const container = document.getElementById('threads-container');
if (threads.length === 0) {
container.innerHTML = `
<div class="text-center text-muted">
<i class="fas fa-check-circle fa-2x mb-2"></i>
<p>No threads currently need alerts.</p>
</div>
`;
return;
}
let tableHtml = `
<div class="table-responsive">
<table class="table table-hover">
<thead class="table-light">
<tr>
<th>Subject</th>
<th>Last Message</th>
<th>Hours Since</th>
<th>Alert Level</th>
</tr>
</thead>
<tbody>
`;
threads.forEach(thread => {
const alertClass = thread.alert_level === 3 ? 'danger' :
thread.alert_level === 2 ? 'warning' : 'info';
const alertText = thread.alert_level === 3 ? 'CRITICAL' :
thread.alert_level === 2 ? 'URGENT' : 'NORMAL';
tableHtml += `
<tr>
<td><strong>${thread.subject}</strong></td>
<td>${thread.last_message}</td>
<td>${thread.hours_since} hours</td>
<td><span class="badge bg-${alertClass}">${alertText}</span></td>
</tr>
`;
});
tableHtml += `
</tbody>
</table>
</div>
`;
container.innerHTML = tableHtml;
}
function showAlert(type, message) {
const alertHtml = `
<div class="alert alert-${type} alert-dismissible fade show" role="alert">
${message}
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
</div>
`;
const container = document.querySelector('.main-content');
const alertDiv = document.createElement('div');
alertDiv.innerHTML = alertHtml;
container.insertBefore(alertDiv.firstElementChild, container.firstChild);
}
// Load threads on page load
document.addEventListener('DOMContentLoaded', function() {
refreshThreads();
});
</script>
{% endblock %}