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 %}