Примеры админ-панели

Готовые примеры создания административной панели с использованием MNRFY Framework

Базовый макет админ-панели

layouts/admin.html

<!DOCTYPE html>
<html lang="{{ locale }}">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>{% block title %}{{ t('admin.panel') }}{% endblock %} - {{ config('app.name') }}</title>
    <meta name="csrf-token" content="{{ csrf_token() }}">
    
    {% block styles %}
        <link rel="stylesheet" href="{{ asset('css/bootstrap.min.css') }}">
        <link rel="stylesheet" href="{{ asset('css/fontawesome.min.css') }}">
        <link rel="stylesheet" href="{{ asset('css/admin.css') }}">
    {% endblock %}
</head>
<body class="admin-layout">
    <!-- Верхняя панель -->
    <nav class="admin-navbar">
        <div class="navbar-brand">
            <i class="fas fa-shield-alt"></i>
            {{ t('admin.panel') }}
        </div>
        
        <div class="navbar-menu">
            <a href="{{ route('home') }}" target="_blank" class="navbar-item">
                <i class="fas fa-external-link-alt"></i>
                {{ t('admin.view_site') }}
            </a>
            
            <div class="navbar-user dropdown">
                <button class="dropdown-toggle" data-toggle="dropdown">
                    <img src="{{ auth().avatar ?? asset('images/default-avatar.png') }}" 
                         alt="{{ auth().name }}" class="user-avatar">
                    {{ auth().name }}
                    <i class="fas fa-chevron-down"></i>
                </button>
                <div class="dropdown-menu">
                    <a href="{{ route('profile') }}" class="dropdown-item">
                        <i class="fas fa-user"></i> {{ t('menu.profile') }}
                    </a>
                    <a href="{{ route('settings') }}" class="dropdown-item">
                        <i class="fas fa-cog"></i> {{ t('menu.settings') }}
                    </a>
                    <div class="dropdown-divider"></div>
                    <a href="{{ route('logout') }}" class="dropdown-item">
                        <i class="fas fa-sign-out-alt"></i> {{ t('menu.logout') }}
                    </a>
                </div>
            </div>
        </div>
    </nav>

    <div class="admin-wrapper">
        <!-- Боковая панель -->
        <aside class="admin-sidebar">
            {% block sidebar %}
                <div class="sidebar-menu">
                    <a href="{{ route('admin.dashboard') }}" 
                       class="menu-item {{ is_current_route('admin.dashboard') ? 'active' : '' }}">
                        <i class="fas fa-tachometer-alt"></i>
                        {{ t('admin.dashboard') }}
                    </a>
                    
                    <div class="menu-section">
                        <h4>{{ t('admin.content_management') }}</h4>
                        
                        <a href="{{ route('admin.users') }}" 
                           class="menu-item {{ is_current_route('admin.users') ? 'active' : '' }}">
                            <i class="fas fa-users"></i>
                            {{ t('admin.users') }}
                            <span class="badge">{{ db('1752665380840')->countItems('users', {'ban': 0}) }}</span>
                        </a>
                        
                        <a href="{{ route('admin.posts') }}" 
                           class="menu-item {{ is_current_route('admin.posts') ? 'active' : '' }}">
                            <i class="fas fa-newspaper"></i>
                            {{ t('admin.posts') }}
                        </a>
                        
                        <a href="{{ route('admin.comments') }}" 
                           class="menu-item {{ is_current_route('admin.comments') ? 'active' : '' }}">
                            <i class="fas fa-comments"></i>
                            {{ t('admin.comments') }}
                            {% set pendingComments = db('1752665380840')->countItems('comments', {'status': 'pending'}) %}
                            {% if pendingComments > 0 %}
                                <span class="badge badge-warning">{{ pendingComments }}</span>
                            {% endif %}
                        </a>
                    </div>
                    
                    <div class="menu-section">
                        <h4>{{ t('admin.system') }}</h4>
                        
                        <a href="{{ route('admin.settings') }}" 
                           class="menu-item {{ is_current_route('admin.settings') ? 'active' : '' }}">
                            <i class="fas fa-cogs"></i>
                            {{ t('admin.settings') }}
                        </a>
                        
                        <a href="{{ route('admin.logs') }}" 
                           class="menu-item {{ is_current_route('admin.logs') ? 'active' : '' }}">
                            <i class="fas fa-list"></i>
                            {{ t('admin.logs') }}
                        </a>
                    </div>
                </div>
            {% endblock %}
        </aside>

        <!-- Основной контент -->
        <main class="admin-content">
            <!-- Хлебные крошки -->
            {% block breadcrumbs %}
                <nav class="breadcrumb-nav">
                    <ol class="breadcrumb">
                        <li class="breadcrumb-item">
                            <a href="{{ route('admin.dashboard') }}">{{ t('admin.dashboard') }}</a>
                        </li>
                        {% block breadcrumb_items %}{% endblock %}
                    </ol>
                </nav>
            {% endblock %}

            <!-- Заголовок страницы -->
            {% block page_header %}
                <div class="page-header">
                    <div class="page-title">
                        <h1>{% block page_title %}{{ t('admin.panel') }}{% endblock %}</h1>
                        {% block page_subtitle %}{% endblock %}
                    </div>
                    <div class="page-actions">
                        {% block page_actions %}{% endblock %}
                    </div>
                </div>
            {% endblock %}

            <!-- Уведомления -->
            {% if flash('success') %}
                <div class="alert alert-success alert-dismissible">
                    <i class="fas fa-check-circle"></i>
                    {{ flash('success') }}
                    <button type="button" class="btn-close" onclick="this.parentElement.remove()">
                        <i class="fas fa-times"></i>
                    </button>
                </div>
            {% endif %}

            {% if flash('error') %}
                <div class="alert alert-danger alert-dismissible">
                    <i class="fas fa-exclamation-circle"></i>
                    {{ flash('error') }}
                    <button type="button" class="btn-close" onclick="this.parentElement.remove()">
                        <i class="fas fa-times"></i>
                    </button>
                </div>
            {% endif %}

            <!-- Основное содержимое -->
            <div class="page-content">
                {% block content %}{% endblock %}
            </div>
        </main>
    </div>

    {% block scripts %}
        <script src="{{ asset('js/jquery.min.js') }}"></script>
        <script src="{{ asset('js/bootstrap.min.js') }}"></script>
        <script src="{{ asset('js/admin.js') }}"></script>
    {% endblock %}
    
    {% block page_scripts %}{% endblock %}
</body>
</html>

Дашборд админ-панели

admin-dashboard.html

{% extends 'layouts/admin.html' %}

{% block title %}{{ t('admin.dashboard') }} - {{ parent() }}{% endblock %}

{% block content %}
<div class="dashboard-container">
    <!-- Статистические карточки -->
    <div class="stats-grid">
        {% set totalUsers = db('1752665380840')->countItems('users') %}
        {% set activeUsers = db('1752665380840')->countItems('users', {'ban': 0}) %}
        {% set onlineUsers = db('1752665380840')->countItems('users', {'last_seen': '>' ~ (time() - 300)}) %}
        {% set todayRegistrations = db('1752665380840')->countItems('users', {'created_at': '>' ~ strtotime('today')}) %}

        <div class="stat-card stat-primary">
            <div class="stat-icon">
                <i class="fas fa-users"></i>
            </div>
            <div class="stat-content">
                <h3 class="stat-number">{{ totalUsers | number }}</h3>
                <p class="stat-label">{{ t('admin.total_users') }}</p>
                <div class="stat-details">
                    <span class="text-success">
                        <i class="fas fa-check-circle"></i>
                        {{ activeUsers }} {{ t('admin.active') }}
                    </span>
                </div>
            </div>
        </div>

        <div class="stat-card stat-success">
            <div class="stat-icon">
                <i class="fas fa-circle"></i>
            </div>
            <div class="stat-content">
                <h3 class="stat-number">{{ onlineUsers | number }}</h3>
                <p class="stat-label">{{ t('admin.online_now') }}</p>
                <div class="stat-details">
                    <small>{{ t('admin.last_5_minutes') }}</small>
                </div>
            </div>
        </div>

        <div class="stat-card stat-info">
            <div class="stat-icon">
                <i class="fas fa-user-plus"></i>
            </div>
            <div class="stat-content">
                <h3 class="stat-number">{{ todayRegistrations | number }}</h3>
                <p class="stat-label">{{ t('admin.today_registrations') }}</p>
                {% set yesterdayRegs = db('1752665380840')->countItems('users', {
                    'created_at': '>' ~ strtotime('yesterday'),
                    'created_at': '<' ~ strtotime('today')
                }) %}
                <div class="stat-details">
                    {% if todayRegistrations > yesterdayRegs %}
                        <span class="text-success">
                            <i class="fas fa-arrow-up"></i>
                            {{ ((todayRegistrations - yesterdayRegs) / (yesterdayRegs | default(1)) * 100) | round }}%
                        </span>
                    {% else %}
                        <span class="text-danger">
                            <i class="fas fa-arrow-down"></i>
                            {{ ((yesterdayRegs - todayRegistrations) / (yesterdayRegs | default(1)) * 100) | round }}%
                        </span>
                    {% endif %}
                </div>
            </div>
        </div>

        {% set pendingComments = db('1752665380840')->countItems('comments', {'status': 'pending'}) %}
        <div class="stat-card stat-warning">
            <div class="stat-icon">
                <i class="fas fa-clock"></i>
            </div>
            <div class="stat-content">
                <h3 class="stat-number">{{ pendingComments | number }}</h3>
                <p class="stat-label">{{ t('admin.pending_comments') }}</p>
                {% if pendingComments > 0 %}
                    <div class="stat-details">
                        <a href="{{ route('admin.comments', {'status': 'pending'}) }}" 
                           class="btn btn-sm btn-warning">
                            {{ t('admin.review') }}
                        </a>
                    </div>
                {% endif %}
            </div>
        </div>
    </div>

    <div class="dashboard-grid">
        <!-- Последние пользователи -->
        <div class="dashboard-widget">
            <div class="widget-header">
                <h3>{{ t('admin.recent_users') }}</h3>
                <a href="{{ route('admin.users') }}" class="btn btn-sm btn-outline-primary">
                    {{ t('admin.view_all') }}
                </a>
            </div>
            <div class="widget-content">
                {% set recentUsers = db('1752665380840')->getItems('users', {}, 
                    ['id', 'login', 'fname', 'lname', 'email', 'avatar', 'created_at'], 
                    'created_at', 'DESC', null, 5) %}
                
                {% if recentUsers %}
                    <div class="user-list">
                        {% foreach recentUsers as user %}
                            <div class="user-item">
                                <div class="user-avatar">
                                    <img src="{{ user.avatar ?? asset('images/default-avatar.png') }}" 
                                         alt="{{ user.login }}">
                                </div>
                                <div class="user-info">
                                    <h5>{{ user.fname ~ ' ' ~ user.lname }}</h5>
                                    <p>@{{ user.login }}</p>
                                    <small>{{ user.created_at | date('d.m.Y H:i') }}</small>
                                </div>
                                <div class="user-actions">
                                    <a href="{{ route('admin.user.view', {'id': user.id}) }}" 
                                       class="btn btn-sm btn-outline-info">
                                        <i class="fas fa-eye"></i>
                                    </a>
                                </div>
                            </div>
                        {% endforeach %}
                    </div>
                {% else %}
                    <div class="empty-state">
                        <p>{{ t('admin.no_users') }}</p>
                    </div>
                {% endif %}
            </div>
        </div>

        <!-- Системная информация -->
        <div class="dashboard-widget">
            <div class="widget-header">
                <h3>{{ t('admin.system_info') }}</h3>
            </div>
            <div class="widget-content">
                <div class="system-stats">
                    <div class="system-item">
                        <span class="label">{{ t('system.php_version') }}:</span>
                        <span class="value">{{ phpversion() }}</span>
                    </div>
                    <div class="system-item">
                        <span class="label">{{ t('system.memory_usage') }}:</span>
                        <span class="value">{{ (memory_get_usage() / 1024 / 1024) | round(2) }} MB</span>
                    </div>
                    <div class="system-item">
                        <span class="label">{{ t('system.peak_memory') }}:</span>
                        <span class="value">{{ (memory_get_peak_usage() / 1024 / 1024) | round(2) }} MB</span>
                    </div>
                    <div class="system-item">
                        <span class="label">{{ t('system.execution_time') }}:</span>
                        <span class="value">{{ (microtime(true) - MNRFY_START_TIME) * 1000 | round(2) }} ms</span>
                    </div>
                    <div class="system-item">
                        <span class="label">{{ t('system.framework') }}:</span>
                        <span class="value">MNRFY {{ MNRFY_VERSION ?? '1.0' }}</span>
                    </div>
                </div>
            </div>
        </div>

        <!-- График активности -->
        <div class="dashboard-widget dashboard-chart">
            <div class="widget-header">
                <h3>{{ t('admin.activity_chart') }}</h3>
                <div class="chart-controls">
                    <select id="chartPeriod" onchange="updateChart(this.value)">
                        <option value="7">{{ t('admin.last_7_days') }}</option>
                        <option value="30">{{ t('admin.last_30_days') }}</option>
                        <option value="90">{{ t('admin.last_90_days') }}</option>
                    </select>
                </div>
            </div>
            <div class="widget-content">
                {% set activityData = db('1752665380840')->query('
                    SELECT 
                        DATE(FROM_UNIXTIME(created_at)) as date,
                        COUNT(*) as registrations
                    FROM users 
                    WHERE created_at >= ?
                    GROUP BY date
                    ORDER BY date DESC
                    LIMIT 7
                ', [strtotime('-7 days')]) %}
                
                <canvas id="activityChart" width="400" height="200"></canvas>
                
                {% set chartLabels = [] %}
                {% set chartData = [] %}
                {% foreach activityData | reverse as item %}
                    {% set chartLabels = chartLabels | push(item.date | date('d.m')) %}
                    {% set chartData = chartData | push(item.registrations) %}
                {% endforeach %}
                
                <script>
                document.addEventListener('DOMContentLoaded', function() {
                    const ctx = document.getElementById('activityChart').getContext('2d');
                    new Chart(ctx, {
                        type: 'line',
                        data: {
                            labels: {{ chartLabels | json }},
                            datasets: [{
                                label: '{{ t("admin.registrations") }}',
                                data: {{ chartData | json }},
                                borderColor: '#007bff',
                                backgroundColor: 'rgba(0, 123, 255, 0.1)',
                                tension: 0.4,
                                fill: true
                            }]
                        },
                        options: {
                            responsive: true,
                            maintainAspectRatio: false,
                            plugins: {
                                legend: {
                                    display: false
                                }
                            },
                            scales: {
                                y: {
                                    beginAtZero: true,
                                    ticks: {
                                        stepSize: 1
                                    }
                                }
                            }
                        }
                    });
                });
                </script>
            </div>
        </div>
    </div>
</div>
{% endblock %}

{% block page_scripts %}
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script>
function updateChart(days) {
    // AJAX запрос для обновления данных графика
    fetch('/admin/api/activity-data', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
            'X-CSRF-Token': document.querySelector('[name="csrf-token"]').content
        },
        body: JSON.stringify({days: days})
    })
    .then(response => response.json())
    .then(data => {
        // Обновление графика
        console.log('Chart updated for', days, 'days');
    });
}
</script>
{% endblock %}

Управление пользователями

admin-users.html

{% extends 'layouts/admin.html' %}

{% block title %}{{ t('admin.users') }} - {{ parent() }}{% endblock %}

{% block breadcrumb_items %}
    <li class="breadcrumb-item active">{{ t('admin.users') }}</li>
{% endblock %}

{% block page_title %}
    {{ t('admin.users') }}
    <small class="text-muted">({{ users.total }} {{ t('admin.total') }})</small>
{% endblock %}

{% block page_actions %}
    <div class="btn-group">
        <button type="button" class="btn btn-success" data-bs-toggle="modal" data-bs-target="#addUserModal">
            <i class="fas fa-plus"></i> {{ t('admin.add_user') }}
        </button>
        
        <div class="btn-group">
            <button type="button" class="btn btn-outline-secondary dropdown-toggle" 
                    data-bs-toggle="dropdown">
                <i class="fas fa-filter"></i> {{ t('admin.filter') }}
            </button>
            <ul class="dropdown-menu">
                <li><a class="dropdown-item" href="?filter=all">{{ t('filter.all') }}</a></li>
                <li><a class="dropdown-item" href="?filter=active">{{ t('status.active') }}</a></li>
                <li><a class="dropdown-item" href="?filter=banned">{{ t('status.banned') }}</a></li>
                <li><a class="dropdown-item" href="?filter=premium">{{ t('status.premium') }}</a></li>
                <li><hr class="dropdown-divider"></li>
                <li><a class="dropdown-item" href="?filter=today">{{ t('filter.registered_today') }}</a></li>
            </ul>
        </div>
        
        <button type="button" class="btn btn-outline-secondary" onclick="exportUsers()">
            <i class="fas fa-download"></i> {{ t('admin.export') }}
        </button>
    </div>
{% endblock %}

{% block content %}
<!-- Быстрая статистика -->
<div class="quick-stats mb-4">
    <div class="row">
        <div class="col-md-3">
            <div class="stat-box bg-primary">
                <div class="stat-number">{{ db('1752665380840')->countItems('users') }}</div>
                <div class="stat-label">{{ t('admin.total_users') }}</div>
            </div>
        </div>
        <div class="col-md-3">
            <div class="stat-box bg-success">
                <div class="stat-number">{{ db('1752665380840')->countItems('users', {'ban': 0}) }}</div>
                <div class="stat-label">{{ t('admin.active_users') }}</div>
            </div>
        </div>
        <div class="col-md-3">
            <div class="stat-box bg-warning">
                <div class="stat-number">{{ db('1752665380840')->countItems('users', {'ban': 1}) }}</div>
                <div class="stat-label">{{ t('admin.banned_users') }}</div>
            </div>
        </div>
        <div class="col-md-3">
            <div class="stat-box bg-info">
                <div class="stat-number">{{ db('1752665380840')->countItems('users', {'last_seen': '>' ~ (time() - 300)}) }}</div>
                <div class="stat-label">{{ t('admin.online_now') }}</div>
            </div>
        </div>
    </div>
</div>

<!-- Поиск и фильтры -->
<div class="filters-panel">
    <form method="GET" class="row g-3 align-items-end">
        <div class="col-md-4">
            <label for="search" class="form-label">{{ t('admin.search') }}</label>
            <div class="input-group">
                <input type="text" id="search" name="search" class="form-control" 
                       placeholder="{{ t('admin.search_users_placeholder') }}"
                       value="{{ request.input('search') }}">
                <button class="btn btn-outline-secondary" type="submit">
                    <i class="fas fa-search"></i>
                </button>
            </div>
        </div>
        
        <div class="col-md-2">
            <label for="role" class="form-label">{{ t('admin.role') }}</label>
            <select id="role" name="role" class="form-select">
                <option value="">{{ t('filter.all_roles') }}</option>
                <option value="user" {{ request.input('role') == 'user' ? 'selected' : '' }}>{{ t('role.user') }}</option>
                <option value="moderator" {{ request.input('role') == 'moderator' ? 'selected' : '' }}>{{ t('role.moderator') }}</option>
                <option value="admin" {{ request.input('role') == 'admin' ? 'selected' : '' }}>{{ t('role.admin') }}</option>
            </select>
        </div>
        
        <div class="col-md-2">
            <label for="status" class="form-label">{{ t('admin.status') }}</label>
            <select id="status" name="status" class="form-select">
                <option value="">{{ t('filter.all_statuses') }}</option>
                <option value="active" {{ request.input('status') == 'active' ? 'selected' : '' }}>{{ t('status.active') }}</option>
                <option value="banned" {{ request.input('status') == 'banned' ? 'selected' : '' }}>{{ t('status.banned') }}</option>
            </select>
        </div>
        
        <div class="col-md-2">
            <label for="sort" class="form-label">{{ t('admin.sort_by') }}</label>
            <select id="sort" name="sort" class="form-select">
                <option value="created_at_desc" {{ request.input('sort') == 'created_at_desc' ? 'selected' : '' }}>{{ t('sort.newest') }}</option>
                <option value="created_at_asc" {{ request.input('sort') == 'created_at_asc' ? 'selected' : '' }}>{{ t('sort.oldest') }}</option>
                <option value="login_asc" {{ request.input('sort') == 'login_asc' ? 'selected' : '' }}>{{ t('sort.username_az') }}</option>
                <option value="balance_desc" {{ request.input('sort') == 'balance_desc' ? 'selected' : '' }}>{{ t('sort.balance_high') }}</option>
                <option value="last_seen_desc" {{ request.input('sort') == 'last_seen_desc' ? 'selected' : '' }}>{{ t('sort.last_active') }}</option>
            </select>
        </div>
        
        <div class="col-md-2">
            <button type="submit" class="btn btn-primary w-100">
                <i class="fas fa-filter"></i> {{ t('button.apply') }}
            </button>
        </div>
    </form>
</div>

<!-- Таблица пользователей -->
{% set page = request.input('page', 1) %}
{% set search = request.input('search') %}
{% set role = request.input('role') %}
{% set status = request.input('status') %}
{% set sort = request.input('sort', 'created_at_desc') %}

{% set whereConditions = {} %}
{% if role %}
    {% set whereConditions = whereConditions | merge({'role': role}) %}
{% endif %}
{% if status == 'active' %}
    {% set whereConditions = whereConditions | merge({'ban': 0}) %}
{% elseif status == 'banned' %}
    {% set whereConditions = whereConditions | merge({'ban': 1}) %}
{% endif %}

{% set sortParts = sort | split('_') %}
{% set sortField = sortParts[0] ~ (sortParts[1] ? ('_' ~ sortParts[1]) : '') %}
{% set sortDirection = sortParts | last == 'desc' ? 'DESC' : 'ASC' %}

{% set users = db('1752665380840')->paginate(
    'users', page, 25, whereConditions, sortField, sortDirection
) %}

<div class="users-table-container">
    <div class="table-header">
        <div class="bulk-actions" id="bulkActions" style="display: none;">
            <div class="bulk-info">
                <span id="selectedCount">0</span> {{ t('admin.users_selected') }}
            </div>
            <div class="bulk-buttons">
                <button type="button" class="btn btn-sm btn-success" onclick="bulkAction('activate')">
                    <i class="fas fa-check"></i> {{ t('admin.activate') }}
                </button>
                <button type="button" class="btn btn-sm btn-warning" onclick="bulkAction('ban')">
                    <i class="fas fa-ban"></i> {{ t('admin.ban') }}
                </button>
                <button type="button" class="btn btn-sm btn-danger" onclick="bulkAction('delete')">
                    <i class="fas fa-trash"></i> {{ t('admin.delete') }}
                </button>
            </div>
        </div>
    </div>
    
    <div class="table-responsive">
        <table class="table table-hover users-table">
            <thead>
                <tr>
                    <th width="40">
                        <input type="checkbox" class="form-check-input" id="selectAll" 
                               onchange="toggleSelectAll(this)">
                    </th>
                    <th width="80">{{ t('admin.avatar') }}</th>
                    <th>{{ t('admin.user') }}</th>
                    <th>{{ t('admin.role') }}</th>
                    <th>{{ t('admin.balance') }}</th>
                    <th>{{ t('admin.status') }}</th>
                    <th>{{ t('admin.last_seen') }}</th>
                    <th>{{ t('admin.registered') }}</th>
                    <th width="150">{{ t('admin.actions') }}</th>
                </tr>
            </thead>
            <tbody>
                {% if users.data and users.data | length > 0 %}
                    {% foreach users.data as user %}
                        <tr class="user-row" data-user-id="{{ user.id }}">
                            <td>
                                <input type="checkbox" class="form-check-input user-checkbox" 
                                       value="{{ user.id }}" onchange="updateBulkActions()">
                            </td>
                            <td>
                                <img src="{{ user.avatar ?? asset('images/default-avatar.png') }}" 
                                     alt="{{ user.login }}" class="user-avatar-small">
                            </td>
                            <td>
                                <div class="user-info">
                                    <div class="user-name">
                                        <strong>{{ user.fname ~ ' ' ~ user.lname }}</strong>
                                        {% if user.last_seen and (time() - user.last_seen) < 300 %}
                                            <span class="online-indicator" title="{{ t('admin.online') }}"></span>
                                        {% endif %}
                                    </div>
                                    <div class="user-login">@{{ user.login }}</div>
                                    {% if user.email %}
                                        <div class="user-email">{{ user.email }}</div>
                                    {% endif %}
                                </div>
                            </td>
                            <td>
                                {% switch user.role %}
                                    {% case 'admin' %}
                                        <span class="badge bg-danger">
                                            <i class="fas fa-crown"></i> {{ t('role.admin') }}
                                        </span>
                                    {% case 'moderator' %}
                                        <span class="badge bg-warning">
                                            <i class="fas fa-shield-alt"></i> {{ t('role.moderator') }}
                                        </span>
                                    {% default %}
                                        <span class="badge bg-secondary">
                                            <i class="fas fa-user"></i> {{ t('role.user') }}
                                        </span>
                                {% endswitch %}
                                
                                {% if user.is_premium %}
                                    <span class="badge bg-info ms-1">
                                        <i class="fas fa-star"></i> {{ t('status.premium') }}
                                    </span>
                                {% endif %}
                            </td>
                            <td>
                                <span class="balance {{ user.balance > 0 ? 'text-success' : 'text-muted' }}">
                                    {{ user.balance | money('₽') }}
                                </span>
                            </td>
                            <td>
                                {% if user.ban %}
                                    <span class="badge bg-danger">
                                        <i class="fas fa-ban"></i> {{ t('status.banned') }}
                                    </span>
                                {% else %}
                                    <span class="badge bg-success">
                                        <i class="fas fa-check"></i> {{ t('status.active') }}
                                    </span>
                                {% endif %}
                                
                                {% if user.email_verified %}
                                    <span class="badge bg-info ms-1" title="{{ t('status.email_verified') }}">
                                        <i class="fas fa-check-circle"></i>
                                    </span>
                                {% endif %}
                            </td>
                            <td>
                                {% if user.last_seen %}
                                    {% set timeDiff = time() - user.last_seen %}
                                    {% if timeDiff < 60 %}
                                        <span class="text-success">{{ t('time.just_now') }}</span>
                                    {% elseif timeDiff < 3600 %}
                                        <span class="text-info">{{ (timeDiff / 60) | round }} {{ t('time.minutes_ago') }}</span>
                                    {% elseif timeDiff < 86400 %}
                                        <span class="text-warning">{{ (timeDiff / 3600) | round }} {{ t('time.hours_ago') }}</span>
                                    {% else %}
                                        <span class="text-muted">{{ user.last_seen | date('d.m.Y') }}</span>
                                    {% endif %}
                                {% else %}
                                    <span class="text-muted">{{ t('admin.never') }}</span>
                                {% endif %}
                            </td>
                            <td>
                                <span class="text-muted">{{ user.created_at | date('d.m.Y H:i') }}</span>
                            </td>
                            <td>
                                <div class="btn-group" role="group">
                                    <a href="{{ route('admin.user.view', {'id': user.id}) }}" 
                                       class="btn btn-sm btn-outline-info" 
                                       title="{{ t('admin.view') }}">
                                        <i class="fas fa-eye"></i>
                                    </a>
                                    <a href="{{ route('admin.user.edit', {'id': user.id}) }}" 
                                       class="btn btn-sm btn-outline-warning"
                                       title="{{ t('admin.edit') }}">
                                        <i class="fas fa-edit"></i>
                                    </a>
                                    
                                    {% if not user.ban %}
                                        <button type="button" class="btn btn-sm btn-outline-danger" 
                                                onclick="banUser({{ user.id }})"
                                                title="{{ t('admin.ban') }}">
                                            <i class="fas fa-ban"></i>
                                        </button>
                                    {% else %}
                                        <button type="button" class="btn btn-sm btn-outline-success" 
                                                onclick="unbanUser({{ user.id }})"
                                                title="{{ t('admin.unban') }}">
                                            <i class="fas fa-check"></i>
                                        </button>
                                    {% endif %}
                                    
                                    {% if user.role != 'admin' or auth().id == user.id %}
                                        <button type="button" class="btn btn-sm btn-outline-danger" 
                                                onclick="deleteUser({{ user.id }}, '{{ user.login }}')"
                                                title="{{ t('admin.delete') }}">
                                            <i class="fas fa-trash"></i>
                                        </button>
                                    {% endif %}
                                </div>
                            </td>
                        </tr>
                    {% endforeach %}
                {% else %}
                    <tr>
                        <td colspan="9" class="text-center py-4">
                            <div class="empty-state">
                                <i class="fas fa-users fa-3x text-muted mb-3"></i>
                                <h4>{{ t('admin.no_users_found') }}</h4>
                                <p class="text-muted">{{ t('admin.try_different_filters') }}</p>
                            </div>
                        </td>
                    </tr>
                {% endif %}
            </tbody>
        </table>
    </div>
    
    <!-- Пагинация -->
    {% if users.last_page > 1 %}
        {% component 'pagination' with {
            'data': users,
            'url': request.path,
            'preserve_query': true
        } %}
    {% endif %}
</div>

<!-- Модальное окно добавления пользователя -->
<div class="modal fade" id="addUserModal" tabindex="-1">
    <div class="modal-dialog modal-lg">
        <div class="modal-content">
            <div class="modal-header">
                <h5 class="modal-title">{{ t('admin.add_user') }}</h5>
                <button type="button" class="btn-close" data-bs-dismiss="modal"></button>
            </div>
            <form id="addUserForm" method="POST" action="/" data-ajax="true">
                {{ csrf() }}
                <input type="hidden" name="__handler" value="admin-add-user">
                
                <div class="modal-body">
                    <div class="row">
                        <div class="col-md-6">
                            <div class="mb-3">
                                <label for="login" class="form-label">{{ t('form.login') }} *</label>
                                <input type="text" id="login" name="login" class="form-control" required>
                            </div>
                        </div>
                        <div class="col-md-6">
                            <div class="mb-3">
                                <label for="email" class="form-label">{{ t('form.email') }} *</label>
                                <input type="email" id="email" name="email" class="form-control" required>
                            </div>
                        </div>
                    </div>
                    
                    <div class="row">
                        <div class="col-md-6">
                            <div class="mb-3">
                                <label for="fname" class="form-label">{{ t('form.first_name') }}</label>
                                <input type="text" id="fname" name="fname" class="form-control">
                            </div>
                        </div>
                        <div class="col-md-6">
                            <div class="mb-3">
                                <label for="lname" class="form-label">{{ t('form.last_name') }}</label>
                                <input type="text" id="lname" name="lname" class="form-control">
                            </div>
                        </div>
                    </div>
                    
                    <div class="row">
                        <div class="col-md-6">
                            <div class="mb-3">
                                <label for="password" class="form-label">{{ t('form.password') }} *</label>
                                <input type="password" id="password" name="password" class="form-control" required>
                            </div>
                        </div>
                        <div class="col-md-6">
                            <div class="mb-3">
                                <label for="role" class="form-label">{{ t('form.role') }}</label>
                                <select id="role" name="role" class="form-select">
                                    <option value="user">{{ t('role.user') }}</option>
                                    <option value="moderator">{{ t('role.moderator') }}</option>
                                    {% if auth().role == 'admin' %}
                                        <option value="admin">{{ t('role.admin') }}</option>
                                    {% endif %}
                                </select>
                            </div>
                        </div>
                    </div>
                    
                    <div class="row">
                        <div class="col-md-6">
                            <div class="mb-3">
                                <label for="balance" class="form-label">{{ t('form.balance') }}</label>
                                <input type="number" id="balance" name="balance" class="form-control" 
                                       value="0" min="0" step="0.01">
                            </div>
                        </div>
                        <div class="col-md-6">
                            <div class="mb-3">
                                <div class="form-check">
                                    <input type="checkbox" id="email_verified" name="email_verified" 
                                           class="form-check-input" value="1">
                                    <label for="email_verified" class="form-check-label">
                                        {{ t('form.email_verified') }}
                                    </label>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
                
                <div class="modal-footer">
                    <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">
                        {{ t('button.cancel') }}
                    </button>
                    <button type="submit" class="btn btn-success">
                        <i class="fas fa-plus"></i> {{ t('admin.add_user') }}
                    </button>
                </div>
            </form>
        </div>
    </div>
</div>
{% endblock %}

{% block page_scripts %}
<script>
// Функции управления пользователями
function toggleSelectAll(checkbox) {
    const userCheckboxes = document.querySelectorAll('.user-checkbox');
    userCheckboxes.forEach(cb => cb.checked = checkbox.checked);
    updateBulkActions();
}

function updateBulkActions() {
    const selected = document.querySelectorAll('.user-checkbox:checked');
    const bulkActions = document.getElementById('bulkActions');
    const selectedCount = document.getElementById('selectedCount');
    
    if (selected.length > 0) {
        bulkActions.style.display = 'flex';
        selectedCount.textContent = selected.length;
    } else {
        bulkActions.style.display = 'none';
    }
}

function bulkAction(action) {
    const selected = Array.from(document.querySelectorAll('.user-checkbox:checked'))
                         .map(cb => cb.value);
    
    if (selected.length === 0) {
        alert('{{ t("admin.select_users_first") }}');
        return;
    }
    
    let confirmMessage = '';
    switch(action) {
        case 'activate':
            confirmMessage = '{{ t("admin.confirm_bulk_activate") }}';
            break;
        case 'ban':
            confirmMessage = '{{ t("admin.confirm_bulk_ban") }}';
            break;
        case 'delete':
            confirmMessage = '{{ t("admin.confirm_bulk_delete") }}';
            break;
    }
    
    if (confirm(confirmMessage)) {
        performBulkAction(action, selected);
    }
}

function performBulkAction(action, userIds) {
    fetch('/', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded',
            'X-CSRF-Token': document.querySelector('[name="csrf-token"]').content
        },
        body: new URLSearchParams({
            '__handler': 'admin-bulk-users',
            'action': action,
            'user_ids': JSON.stringify(userIds)
        })
    })
    .then(response => response.json())
    .then(data => {
        if (data.success) {
            location.reload();
        } else {
            alert(data.error || '{{ t("admin.error_occurred") }}');
        }
    })
    .catch(error => {
        alert('{{ t("admin.network_error") }}');
    });
}

function banUser(userId) {
    if (confirm('{{ t("admin.confirm_ban_user") }}')) {
        userAction(userId, 'ban');
    }
}

function unbanUser(userId) {
    if (confirm('{{ t("admin.confirm_unban_user") }}')) {
        userAction(userId, 'unban');
    }
}

function deleteUser(userId, username) {
    if (confirm('{{ t("admin.confirm_delete_user") }}'.replace(':username', username))) {
        userAction(userId, 'delete');
    }
}

function userAction(userId, action) {
    fetch('/', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded',
            'X-CSRF-Token': document.querySelector('[name="csrf-token"]').content
        },
        body: new URLSearchParams({
            '__handler': 'admin-user-action',
            'user_id': userId,
            'action': action
        })
    })
    .then(response => response.json())
    .then(data => {
        if (data.success) {
            location.reload();
        } else {
            alert(data.error || '{{ t("admin.error_occurred") }}');
        }
    });
}

function exportUsers() {
    const params = new URLSearchParams(window.location.search);
    params.set('export', '1');
    window.open('?' + params.toString());
}

// Обработка AJAX формы добавления пользователя
document.getElementById('addUserForm').addEventListener('submit', function(e) {
    e.preventDefault();
    
    const formData = new FormData(this);
    const submitButton = this.querySelector('[type="submit"]');
    const originalText = submitButton.innerHTML;
    
    submitButton.disabled = true;
    submitButton.innerHTML = '<i class="fas fa-spinner fa-spin"></i> {{ t("form.saving") }}';
    
    fetch('/', {
        method: 'POST',
        body: formData,
        headers: {
            'X-Requested-With': 'XMLHttpRequest'
        }
    })
    .then(response => response.json())
    .then(data => {
        if (data.success) {
            // Закрываем модальное окно
            const modal = bootstrap.Modal.getInstance(document.getElementById('addUserModal'));
            modal.hide();
            
            // Показываем уведомление об успехе
            showNotification(data.message || '{{ t("admin.user_created_successfully") }}', 'success');
            
            // Перезагружаем страницу через секунду
            setTimeout(() => location.reload(), 1000);
        } else {
            if (data.errors) {
                // Показываем ошибки валидации
                Object.keys(data.errors).forEach(field => {
                    const input = document.querySelector(`[name="${field}"]`);
                    if (input) {
                        input.classList.add('is-invalid');
                        let errorDiv = input.parentNode.querySelector('.invalid-feedback');
                        if (!errorDiv) {
                            errorDiv = document.createElement('div');
                            errorDiv.className = 'invalid-feedback';
                            input.parentNode.appendChild(errorDiv);
                        }
                        errorDiv.textContent = data.errors[field];
                    }
                });
            } else {
                showNotification(data.error || '{{ t("admin.error_occurred") }}', 'error');
            }
        }
    })
    .catch(error => {
        showNotification('{{ t("admin.network_error") }}', 'error');
    })
    .finally(() => {
        submitButton.disabled = false;
        submitButton.innerHTML = originalText;
    });
});

// Очистка ошибок при изменении полей
document.querySelectorAll('#addUserForm input, #addUserForm select').forEach(input => {
    input.addEventListener('input', function() {
        this.classList.remove('is-invalid');
        const errorDiv = this.parentNode.querySelector('.invalid-feedback');
        if (errorDiv) {
            errorDiv.remove();
        }
    });
});

// Функция показа уведомлений
function showNotification(message, type) {
    const alertClass = type === 'success' ? 'alert-success' : 'alert-danger';
    const icon = type === 'success' ? 'fa-check-circle' : 'fa-exclamation-circle';
    
    const alert = document.createElement('div');
    alert.className = `alert ${alertClass} alert-dismissible position-fixed`;
    alert.style.cssText = 'top: 20px; right: 20px; z-index: 1050; min-width: 300px;';
    alert.innerHTML = `
        <i class="fas ${icon}"></i> ${message}
        <button type="button" class="btn-close" onclick="this.parentElement.remove()"></button>
    `;
    
    document.body.appendChild(alert);
    
    // Автоматическое скрытие через 5 секунд
    setTimeout(() => {
        if (alert.parentNode) {
            alert.remove();
        }
    }, 5000);
}
</script>
{% endblock %}
Готово! Теперь у вас есть полнофункциональная админ-панель. Изучите также пользовательские обработчики для создания соответствующих PHP обработчиков форм.