kaauh_ats/templates/admin/sync_dashboard.html

298 lines
9.0 KiB
HTML

{% extends "admin/base_site.html" %}
{% load i18n static %}
{% block title %}{{ title }} - {{ site_title|default:_('Django site admin') }}{% endblock %}
{% block extrastyle %}
{{ block.super }}
<style>
.sync-stats-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 1rem;
margin-bottom: 2rem;
}
.stat-card {
background: white;
border: 1px solid #ddd;
border-radius: 8px;
padding: 1.5rem;
text-align: center;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
.stat-number {
font-size: 2rem;
font-weight: bold;
margin-bottom: 0.5rem;
}
.stat-label {
color: #666;
font-size: 0.9rem;
}
.stat-card.success { border-left: 4px solid #28a745; }
.stat-card.danger { border-left: 4px solid #dc3545; }
.stat-card.warning { border-left: 4px solid #ffc107; }
.stat-card.info { border-left: 4px solid #17a2b8; }
.recent-tasks {
background: white;
border: 1px solid #ddd;
border-radius: 8px;
overflow: hidden;
}
.recent-tasks h3 {
margin: 0;
padding: 1rem;
background: #f8f9fa;
border-bottom: 1px solid #ddd;
}
.task-item {
padding: 1rem;
border-bottom: 1px solid #eee;
display: flex;
justify-content: space-between;
align-items: center;
}
.task-item:last-child {
border-bottom: none;
}
.task-info {
flex: 1;
}
.task-name {
font-weight: bold;
margin-bottom: 0.25rem;
}
.task-meta {
font-size: 0.85rem;
color: #666;
}
.task-status {
padding: 0.25rem 0.75rem;
border-radius: 12px;
font-size: 0.8rem;
font-weight: bold;
text-transform: uppercase;
}
.task-status.success {
background: #d4edda;
color: #155724;
}
.task-status.failed {
background: #f8d7da;
color: #721c24;
}
.task-status.pending {
background: #fff3cd;
color: #856404;
}
.refresh-btn {
background: #007cba;
color: white;
border: none;
padding: 0.5rem 1rem;
border-radius: 4px;
cursor: pointer;
font-size: 0.9rem;
}
.refresh-btn:hover {
background: #005a87;
}
.auto-refresh {
margin-left: 1rem;
display: inline-flex;
align-items: center;
gap: 0.5rem;
}
.chart-container {
background: white;
border: 1px solid #ddd;
border-radius: 8px;
padding: 1.5rem;
margin-bottom: 2rem;
}
</style>
{% endblock %}
{% block content %}
<div id="content-main">
<div class="module">
<h1>{{ title }}</h1>
<!-- Auto-refresh controls -->
<div style="margin-bottom: 1rem;">
<button class="refresh-btn" onclick="refreshStats()">
<i class="fas fa-sync-alt"></i> Refresh Now
</button>
<div class="auto-refresh">
<input type="checkbox" id="autoRefresh" checked>
<label for="autoRefresh">Auto-refresh every 30 seconds</label>
</div>
</div>
<!-- Statistics Grid -->
<div class="sync-stats-grid">
<div class="stat-card info">
<div class="stat-number">{{ total_tasks }}</div>
<div class="stat-label">Total Sync Tasks</div>
</div>
<div class="stat-card success">
<div class="stat-number">{{ successful_tasks }}</div>
<div class="stat-label">Successful Tasks</div>
</div>
<div class="stat-card danger">
<div class="stat-number">{{ failed_tasks }}</div>
<div class="stat-label">Failed Tasks</div>
</div>
<div class="stat-card warning">
<div class="stat-number">{{ pending_tasks }}</div>
<div class="stat-label">Pending Tasks</div>
</div>
</div>
<!-- Success Rate Charts -->
<div class="chart-container">
<h3>Success Rates</h3>
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 2rem;">
<div>
<h4>Overall Success Rate</h4>
<div style="font-size: 2rem; font-weight: bold; color: {% if success_rate > 80 %}#28a745{% elif success_rate > 60 %}#ffc107{% else %}#dc3545{% endif %};">
{{ success_rate|floatformat:1 }}%
</div>
</div>
<div>
<h4>Last 24 Hours</h4>
<div style="font-size: 2rem; font-weight: bold; color: {% if last_24h_success_rate > 80 %}#28a745{% elif last_24h_success_rate > 60 %}#ffc107{% else %}#dc3545{% endif %};">
{{ last_24h_success_rate|floatformat:1 }}%
</div>
</div>
</div>
</div>
<!-- Recent Tasks -->
<div class="recent-tasks">
<h3>Recent Sync Tasks</h3>
{% for task in recent_tasks %}
<div class="task-item">
<div class="task-info">
<div class="task-name">{{ task.name }}</div>
<div class="task-meta">
{% if task.started %}
Started: {{ task.started|date:"Y-m-d H:i:s" }}
{% endif %}
{% if task.stopped %}
• Duration: {{ task.time_taken|floatformat:2 }}s
{% endif %}
{% if task.group %}
• Group: {{ task.group }}
{% endif %}
</div>
</div>
<div class="task-status {% if task.success %}success{% elif task.stopped %}failed{% else %}pending{% endif %}">
{% if task.success %}Success{% elif task.stopped %}Failed{% else %}Pending{% endif %}
</div>
</div>
{% empty %}
<div class="task-item">
<div class="task-info">
<div class="task-name">No sync tasks found</div>
<div class="task-meta">Sync tasks will appear here once they are executed.</div>
</div>
</div>
{% endfor %}
</div>
<!-- Quick Actions -->
<div style="margin-top: 2rem;">
<h3>Quick Actions</h3>
<div style="display: flex; gap: 1rem; flex-wrap: wrap;">
<a href="{% url 'admin:django_q_task_changelist' %}" class="button">
View All Tasks
</a>
<a href="{% url 'admin:django_q_schedule_changelist' %}" class="button">
Manage Schedules
</a>
<a href="/recruitment/sources/" class="button">
Configure Sources
</a>
</div>
</div>
</div>
</div>
<script>
let refreshInterval;
function refreshStats() {
fetch('/admin/api/sync-stats/')
.then(response => response.json())
.then(data => {
// Update statistics
document.querySelector('.stat-card.info .stat-number').textContent = data.total_tasks;
document.querySelector('.stat-card.success .stat-number').textContent = data.successful_24h;
document.querySelector('.stat-card.danger .stat-number').textContent = data.failed_24h;
document.querySelector('.stat-card.warning .stat-number').textContent = data.pending_tasks;
// Show refresh indicator
const btn = document.querySelector('.refresh-btn');
const originalText = btn.innerHTML;
btn.innerHTML = '<i class="fas fa-check"></i> Refreshed!';
btn.style.background = '#28a745';
setTimeout(() => {
btn.innerHTML = originalText;
btn.style.background = '#007cba';
}, 2000);
})
.catch(error => {
console.error('Error refreshing stats:', error);
});
}
function toggleAutoRefresh() {
const checkbox = document.getElementById('autoRefresh');
if (checkbox.checked) {
// Start auto-refresh
refreshInterval = setInterval(refreshStats, 30000); // 30 seconds
} else {
// Stop auto-refresh
if (refreshInterval) {
clearInterval(refreshInterval);
}
}
}
// Initialize auto-refresh
document.addEventListener('DOMContentLoaded', function() {
document.getElementById('autoRefresh').addEventListener('change', toggleAutoRefresh);
// Start auto-refresh if checked
if (document.getElementById('autoRefresh').checked) {
refreshInterval = setInterval(refreshStats, 30000);
}
});
</script>
{% endblock %}