dashboard.html
220 lignes · 9280 octets
{% extends "base.html" %} {% block title %}{{ page_title }}{% endblock %} {% block navbar %} {% include "components/navbar.html" %} {% endblock %} {% block content %} <div class="container mx-auto px-4 py-4"> <!-- Breadcrumb --> <div class="text-sm breadcrumbs mb-3"> <ul> <li><a href="/">{{ breadcrumb_home }}</a></li> <li>{{ breadcrumb_admin }}</li> </ul> </div> <h1 class="text-2xl font-bold mb-4">{{ heading }}</h1> <!-- Statistics Cards --> <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4 mb-4"> <!-- Total Users Card --> <div class="card bg-base-100 shadow-md"> <div class="card-body p-4"> <h2 class="card-title text-primary text-base">👥 {{ users_card_title }}</h2> <p class="text-xs text-base-content/70 mb-1">{{ users_card_subtitle }}</p> <p class="text-2xl font-bold">{{ total_users }}</p> <div class="card-actions justify-end mt-2"> <a href="/admin/users" class="btn btn-primary btn-sm">{{ access_button }}</a> </div> </div> </div> <!-- Active Sessions Card --> <div class="card bg-base-100 shadow-md"> <div class="card-body p-4"> <h2 class="card-title text-secondary text-base">🔐 {{ sessions_card_title }}</h2> <p class="text-xs text-base-content/70 mb-1">{{ sessions_card_subtitle }}</p> <p class="text-2xl font-bold">{{ active_sessions }}</p> </div> </div> <!-- Admins Card --> <div class="card bg-base-100 shadow-md"> <div class="card-body p-4"> <h2 class="card-title text-accent text-base">👑 {{ admins_card_title }}</h2> <p class="text-xs text-base-content/70 mb-1">{{ admins_card_subtitle }}</p> <p class="text-2xl font-bold">{{ total_admins }}</p> </div> </div> <!-- Last Activity Card --> <div class="card bg-base-100 shadow-md"> <div class="card-body p-4"> <h2 class="card-title text-info text-base">⏰ {{ last_activity_card_title }}</h2> <p class="text-xs text-base-content/70 mb-1">{{ last_activity_card_subtitle }}</p> <p class="text-base font-semibold">{{ last_activity }}</p> </div> </div> </div> <!-- Audit Log Statistics (if available) --> {% if has_audit_logs %} <div class="card bg-base-100 shadow-md mb-4"> <div class="card-body p-4"> <h2 class="card-title text-lg mb-3">📊 {{ audit_section_title }}</h2> <div class="grid grid-cols-1 lg:grid-cols-2 gap-4"> <!-- Histogram Chart --> <div> <canvas id="audit-logs-chart" width="400" height="200"></canvas> </div> <!-- Statistics and Legends --> <div class="space-y-3"> <div class="grid grid-cols-2 gap-3"> <div> <p class="text-xs text-base-content/70">{{ audit_total_logs_label }}</p> <p class="text-xl font-bold">{{ audit_total_logs }}</p> </div> <div> <p class="text-xs text-base-content/70">{{ audit_last_24h }}</p> <p class="text-xl font-bold">{{ audit_logs_last_24h }}</p> </div> </div> <div> <p class="text-xs text-base-content/70 mb-2">{{ audit_by_level }}</p> <div class="flex flex-wrap gap-2"> <span class="badge badge-info badge-sm">DEBUG: {{ audit_debug_count }}</span> <span class="badge badge-success badge-sm">INFO: {{ audit_info_count }}</span> <span class="badge badge-warning badge-sm">WARN: {{ audit_warn_count }}</span> <span class="badge badge-error badge-sm">ERROR: {{ audit_error_count }}</span> </div> </div> </div> </div> <div class="card-actions justify-end mt-3"> <a href="/admin/logs" class="btn btn-sm btn-outline">{{ view_logs }}</a> </div> </div> </div> {% endif %} <!-- Navigation Links --> <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4"> <a href="/admin/logs" class="card bg-base-100 shadow-md hover:shadow-lg transition-shadow"> <div class="card-body p-4"> <h2 class="card-title text-info text-base">{{ logs_card_title }}</h2> <p class="text-sm">{{ logs_card_desc }}</p> <div class="card-actions justify-end mt-2"> <span class="btn btn-info btn-sm">{{ view_logs }}</span> </div> </div> </a> <a href="/admin/roles" class="card bg-base-100 shadow-md hover:shadow-lg transition-shadow"> <div class="card-body p-4"> <h2 class="card-title text-warning text-base">🛡️ {{ roles_card_title }}</h2> <p class="text-sm">{{ roles_card_desc }}</p> <div class="stats shadow-sm mt-2"> <div class="stat py-1 px-2"> <div class="stat-title text-xs">{{ roles_stat_title }}</div> <div class="stat-value text-base">{{ total_roles }}</div> </div> </div> <div class="card-actions justify-end mt-2"> <button class="btn btn-warning btn-sm">{{ access_button }}</button> </div> </div> </a> <a href="/admin/settings" class="card bg-base-100 shadow-md hover:shadow-lg transition-shadow"> <div class="card-body p-4"> <h2 class="card-title text-secondary text-base">⚙️ {{ settings_card_title }}</h2> <p class="text-sm">{{ settings_card_desc }}</p> <div class="card-actions justify-end mt-2"> <button class="btn btn-secondary btn-sm">{{ access_button }}</button> </div> </div> </a> <a href="/admin/apps" class="card bg-base-100 shadow-md hover:shadow-lg transition-shadow"> <div class="card-body p-4"> <h2 class="card-title text-accent text-base">📦 {{ apps_card_title }}</h2> <p class="text-sm">{{ apps_card_desc }}</p> <div class="card-actions justify-end mt-2"> <button class="btn btn-accent btn-sm">{{ access_button }}</button> </div> </div> </a> {% for card in extra_cards %} <a href="{{ card.href }}" class="card bg-base-100 shadow-md hover:shadow-lg transition-shadow"> <div class="card-body p-4"> <h2 class="card-title text-info text-base">{{ card.icon }} {{ card.title }}</h2> <p class="text-sm">{{ card.desc }}</p> <div class="card-actions justify-end mt-2"> <button class="btn btn-info btn-sm">{{ access_button }}</button> </div> </div> </a> {% endfor %} </div> </div> {% endblock %} {% block scripts %} {% if has_audit_logs %} <script src="/static/js/chart.umd.min.js"></script> <script> document.addEventListener('DOMContentLoaded', function() { const ctx = document.getElementById('audit-logs-chart'); if (ctx) { new Chart(ctx, { type: 'bar', data: { labels: ['DEBUG', 'INFO', 'WARN', 'ERROR'], datasets: [{ label: '{{ chart_label }}', data: [ {{ audit_debug_count }}, {{ audit_info_count }}, {{ audit_warn_count }}, {{ audit_error_count }} ], backgroundColor: [ 'rgba(59, 130, 246, 0.5)', // info 'rgba(34, 197, 94, 0.5)', // success 'rgba(251, 191, 36, 0.5)', // warning 'rgba(239, 68, 68, 0.5)' // error ], borderColor: [ 'rgba(59, 130, 246, 1)', 'rgba(34, 197, 94, 1)', 'rgba(251, 191, 36, 1)', 'rgba(239, 68, 68, 1)' ], borderWidth: 1 }] }, options: { responsive: true, maintainAspectRatio: true, scales: { y: { beginAtZero: true } }, plugins: { legend: { display: false } } } }); } }); </script> {% endif %} {% endblock %}
GitRust