Если кому то было интересно как выглядит админ панель на Majestic RP то вот одна из вкладок
и что нам делать с данной инфой?Если кому то было интересно как выглядит админ панель на Majestic RP то вот одна из вкладок
Посмотреть вложение 25411
много хочешьНорм.
Сделайте верстку и на гугл диск

нигдегде скачат
мне в лс фулл исходник пожалуйста.Ну... Я конечно же это сверстал вся вёрстка готова просто мне лень привязывать к серверу![]()
10к пожалуйста мне в лсмне в лс фулл исходник пожалуйста.
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
<title>Статистика репортов | Административная панель</title>
<!-- Font Awesome 6 (free) -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css">
<!-- Google Fonts: Inter & Roboto Mono -->
<link href="https://fonts.googleapis.com/css2?family=Inter:opsz,wght@14..32,300;14..32,400;14..32,500;14..32,600;14..32,700&family=Roboto+Mono:wght@400;500&display=swap" rel="stylesheet">
<!-- Chart.js CDN -->
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.0/dist/chart.umd.min.js"></script>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Inter', sans-serif;
background: #f1f5f9;
color: #0f172a;
line-height: 1.4;
}
/* app layout */
.app {
display: flex;
min-height: 100vh;
}
/* SIDEBAR */
.sidebar {
width: 280px;
background: #ffffff;
border-right: 1px solid #e2e8f0;
display: flex;
flex-direction: column;
position: sticky;
top: 0;
height: 100vh;
overflow-y: auto;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.02);
transition: all 0.2s;
z-index: 10;
}
/* sidebar inner */
.sidebar-header {
padding: 24px 20px 12px 20px;
border-bottom: 1px solid #eef2ff;
}
.logo-area h2 {
font-size: 1.5rem;
font-weight: 700;
background: linear-gradient(135deg, #2563eb, #1e40af);
background-clip: text;
-webkit-background-clip: text;
color: transparent;
letter-spacing: -0.3px;
}
.logo-area p {
font-size: 0.75rem;
color: #5b6e8c;
margin-top: 4px;
}
/* search box */
.search-menu {
margin: 20px 0 12px 0;
position: relative;
}
.search-menu input {
width: 100%;
padding: 10px 36px 10px 38px;
border: 1px solid #e2e8f0;
border-radius: 14px;
background: #f8fafc;
font-size: 0.85rem;
font-weight: 500;
transition: all 0.2s;
color: #0f172a;
}
.search-menu input:focus {
outline: none;
border-color: #3b82f6;
box-shadow: 0 0 0 3px rgba(59,130,246,0.2);
background: #fff;
}
.search-menu i {
position: absolute;
left: 12px;
top: 50%;
transform: translateY(-50%);
color: #94a3b8;
font-size: 0.9rem;
}
.kbd-hint {
position: absolute;
right: 12px;
top: 50%;
transform: translateY(-50%);
background: #eef2ff;
padding: 2px 8px;
border-radius: 8px;
font-size: 0.7rem;
font-weight: 600;
font-family: monospace;
color: #1e293b;
pointer-events: none;
letter-spacing: 0.5px;
}
/* navigation sections */
.nav-section {
padding: 0 16px 20px 16px;
border-bottom: 1px solid #f0f2f5;
}
.nav-section:last-child {
border-bottom: none;
}
.nav-title {
font-size: 0.7rem;
text-transform: uppercase;
letter-spacing: 0.6px;
font-weight: 700;
color: #5b6e8c;
margin: 16px 0 10px 4px;
}
.nav-list {
list-style: none;
display: flex;
flex-direction: column;
gap: 6px;
}
.nav-item {
padding: 8px 12px;
border-radius: 12px;
font-size: 0.9rem;
font-weight: 500;
color: #1e293b;
transition: all 0.2s;
cursor: default;
display: flex;
align-items: center;
gap: 10px;
}
.nav-item i {
width: 20px;
font-size: 1rem;
color: #5b6e8c;
}
.nav-item:hover {
background: #f1f5f9;
color: #2563eb;
}
.nav-item.hidden-menu {
display: none;
}
/* main content */
.main-content {
flex: 1;
padding: 28px 32px;
overflow-x: auto;
}
/* page header */
.page-header {
display: flex;
justify-content: space-between;
align-items: baseline;
flex-wrap: wrap;
margin-bottom: 28px;
}
.page-header h1 {
font-size: 1.9rem;
font-weight: 700;
background: linear-gradient(135deg, #0f2b3d, #1e3a8a);
background-clip: text;
-webkit-background-clip: text;
color: transparent;
}
.badge-online {
background: #d9f99d;
color: #365314;
padding: 4px 12px;
border-radius: 40px;
font-size: 0.75rem;
font-weight: 600;
}
/* cards grid */
.stats-grid {
background: white;
border-radius: 24px;
padding: 20px 24px;
box-shadow: 0 1px 3px rgba(0,0,0,0.05), 0 1px 2px rgba(0,0,0,0.03);
margin-bottom: 28px;
border: 1px solid #eef2ff;
}
.section-title {
font-size: 1.3rem;
font-weight: 700;
margin-bottom: 6px;
display: flex;
align-items: center;
gap: 8px;
}
.section-sub {
font-size: 0.8rem;
color: #5b6e8c;
border-left: 3px solid #3b82f6;
padding-left: 12px;
margin-bottom: 20px;
}
.metrics-row {
display: flex;
flex-wrap: wrap;
gap: 20px;
margin-top: 12px;
}
.metric-card {
background: #f8fafc;
border-radius: 20px;
padding: 16px 18px;
min-width: 160px;
flex: 1 1 180px;
border: 1px solid #eef2ff;
transition: all 0.2s;
}
.metric-label {
font-size: 0.75rem;
text-transform: uppercase;
font-weight: 600;
color: #4b5563;
letter-spacing: 0.4px;
margin-bottom: 8px;
}
.metric-value {
font-size: 2rem;
font-weight: 800;
font-family: 'Roboto Mono', monospace;
color: #0f172a;
line-height: 1.2;
}
.metric-unit {
font-size: 0.8rem;
font-weight: 500;
color: #5b6e8c;
}
.badge-moderator {
background: #e6f0ff;
border-radius: 30px;
padding: 4px 12px;
font-size: 0.7rem;
font-weight: 600;
color: #2563eb;
display: inline-block;
margin-bottom: 12px;
}
/* double chart layout */
.charts-container {
display: flex;
flex-wrap: wrap;
gap: 28px;
margin-bottom: 28px;
}
.chart-card {
background: white;
border-radius: 24px;
padding: 18px 20px;
box-shadow: 0 1px 3px rgba(0,0,0,0.05);
border: 1px solid #eef2ff;
flex: 1 1 400px;
}
.chart-title {
font-weight: 700;
font-size: 1.1rem;
margin-bottom: 16px;
display: flex;
align-items: center;
gap: 8px;
border-left: 3px solid #3b82f6;
padding-left: 12px;
}
canvas {
max-height: 280px;
width: 100%;
}
.test-level-card {
background: linear-gradient(145deg, #ffffff, #fef9e3);
border-radius: 24px;
padding: 18px 24px;
margin-bottom: 28px;
border: 1px solid #ffedd5;
display: flex;
align-items: center;
justify-content: space-between;
flex-wrap: wrap;
}
.test-info h4 {
font-size: 1.1rem;
font-weight: 700;
}
.level-badge {
background: #f97316;
color: white;
padding: 8px 24px;
border-radius: 60px;
font-weight: 800;
font-size: 1.5rem;
font-family: monospace;
box-shadow: 0 4px 8px rgba(249,115,22,0.2);
}
.help-footer {
background: #f1f5f9;
border-radius: 20px;
padding: 14px 20px;
display: flex;
justify-content: space-between;
align-items: center;
color: #334155;
font-size: 0.85rem;
font-weight: 500;
border: 1px solid #e2e8f0;
}
hr {
margin: 12px 0;
border: 0;
border-top: 1px solid #eef2ff;
}
@media (max-width: 850px) {
.app {
flex-direction: column;
}
.sidebar {
width: 100%;
height: auto;
position: relative;
border-right: none;
border-bottom: 1px solid #e2e8f0;
}
.main-content {
padding: 20px;
}
.metrics-row {
gap: 12px;
}
}
/* scrollbar */
::-webkit-scrollbar {
width: 6px;
}
::-webkit-scrollbar-track {
background: #f1f1f1;
border-radius: 10px;
}
::-webkit-scrollbar-thumb {
background: #cbd5e1;
border-radius: 10px;
}
</style>
</head>
<body>
<div class="app">
<!-- Боковая панель с поиском и меню -->
<aside class="sidebar">
<div class="sidebar-header">
<div class="logo-area">
<h2><i class="fas fa-chart-line" style="color: #2563eb; font-size: 1.5rem;"></i> Test онлайн</h2>
<p>статистика & репорты</p>
</div>
<div class="search-menu">
<i class="fas fa-search"></i>
<input type="text" id="menuSearch" placeholder="Поиск по меню" autocomplete="off">
<span class="kbd-hint">Ctrl+K</span>
</div>
</div>
<!-- Навигационная группа 1 (быстрые ссылки) -->
<div class="nav-section">
<div class="nav-title"><i class="fas fa-bolt"></i> БЫСТРЫЙ ДОСТУП</div>
<ul class="nav-list" id="navListFast">
<li class="nav-item" data-search-term="Статистика Репорты"><i class="fas fa-chart-pie"></i> Статистика / Репорты</li>
<li class="nav-item" data-search-term="Правила Государствен"><i class="fas fa-gavel"></i> Правила / Государствен...</li>
<li class="nav-item" data-search-term="Правила Общие правила"><i class="fas fa-book"></i> Правила / Общие правила</li>
<li class="nav-item" data-search-term="Семьи"><i class="fas fa-users"></i> Семьи</li>
<li class="nav-item" data-search-term="Фракции"><i class="fas fa-flag-checkered"></i> Фракции</li>
</ul>
</div>
<!-- Основное меню (полный список) -->
<div class="nav-section">
<div class="nav-title"><i class="fas fa-compass"></i> ОСНОВНОЕ</div>
<ul class="nav-list" id="navListMain">
<li class="nav-item" data-search-term="Главная"><i class="fas fa-home"></i> Главная</li>
<li class="nav-item" data-search-term="Команды сервера"><i class="fas fa-terminal"></i> Команды сервера</li>
<li class="nav-item" data-search-term="Отпуска"><i class="fas fa-umbrella-beach"></i> Отпуска</li>
<li class="nav-item" data-search-term="Наказания"><i class="fas fa-ban"></i> Наказания</li>
<li class="nav-item" data-search-term="Модерация"><i class="fas fa-shield-haltered"></i> Модерация</li>
<li class="nav-item" data-search-term="Штрафные баллы"><i class="fas fa-exclamation-triangle"></i> Штрафные баллы</li>
<li class="nav-item" data-search-term="Экономика"><i class="fas fa-coins"></i> Экономика</li>
<li class="nav-item" data-search-term="Транспорт"><i class="fas fa-truck"></i> Транспорт</li>
<li class="nav-item" data-search-term="Предметы"><i class="fas fa-box"></i> Предметы</li>
<li class="nav-item" data-search-term="Контент"><i class="fas fa-newspaper"></i> Контент</li>
<li class="nav-item" data-search-term="Обучение"><i class="fas fa-graduation-cap"></i> Обучение</li>
<li class="nav-item" data-search-term="Семьи"><i class="fas fa-heart"></i> Семьи</li>
<li class="nav-item" data-search-term="Фракции"><i class="fas fa-handshake"></i> Фракции</li>
</ul>
</div>
<div style="padding: 16px; margin-top: auto; font-size: 11px; color: #94a3b8; border-top: 1px solid #eef2ff; text-align: center;">
<i class="fas fa-database"></i> Данные в реальном времени
</div>
</aside>
<!-- Основной контент -->
<main class="main-content">
<div class="page-header">
<h1><i class="fas fa-chart-simple"></i> Статистика репортов</h1>
<div class="badge-online"><i class="fas fa-circle" style="font-size: 0.5rem; color: #22c55e;"></i> Live обновления</div>
</div>
<!-- Карточка статистики репортов -->
<div class="stats-grid">
<div class="section-title">
<i class="fas fa-flag-checkered" style="color:#2563eb"></i> Модераторские репорты
</div>
<div class="section-sub">
Остроковое данные по репортам за выбранный период • актуально на текущую сессию
</div>
<div class="metrics-row">
<div class="metric-card">
<div class="metric-label"><i class="fas fa-ticket-alt"></i> Стандартные</div>
<div class="metric-value">640</div>
<div class="metric-unit">репортов</div>
</div>
<div class="metric-card">
<div class="metric-label"><i class="fas fa-hourglass-half"></i> Среднее время ответа</div>
<div class="metric-value">0.01 <span class="metric-unit">ч</span></div>
</div>
<div class="metric-card">
<div class="metric-label"><i class="fas fa-user-check"></i> Активисты администраторов</div>
<div class="metric-value">0.01 <span class="metric-unit">%</span></div>
</div>
<div class="metric-card">
<div class="metric-label"><i class="fas fa-clock"></i> Среднее время решения</div>
<div class="metric-value">0.01 <span class="metric-unit">ч</span></div>
</div>
<div class="metric-card">
<div class="metric-label"><i class="fas fa-check-double"></i> Обработали репорты</div>
<div class="metric-value">0.01 <span class="metric-unit">тыс.</span></div>
</div>
</div>
</div>
<!-- Двойной график: основной график (модераторские/стандартные) и тест-уровень -->
<div class="charts-container">
<div class="chart-card">
<div class="chart-title">
<i class="fas fa-chart-line" style="color:#3b82f6"></i> График
<span style="font-size: 0.7rem; background: #eff6ff; padding: 2px 8px; border-radius: 40px;">Модераторские / Стандартные</span>
</div>
<canvas id="trendChart" width="400" height="250" style="width:100%; height:auto; max-height:250px"></canvas>
<div class="section-sub" style="margin-top: 10px; text-align: center;">Динамика за последние 7 дней</div>
</div>
<div class="chart-card">
<div class="chart-title">
<i class="fas fa-chart-bar"></i> Нагрузка по часам
</div>
<canvas id="hourlyChart" width="400" height="250" style="width:100%; height:auto; max-height:250px"></canvas>
<div class="section-sub" style="margin-top: 10px; text-align: center;">Распределение репортов по часам (МСК)</div>
</div>
</div>
<!-- Блок "Тест 9 level" и дополнительная информация -->
<div class="test-level-card">
<div class="test-info">
<h4><i class="fas fa-brain"></i> Тест компетенций</h4>
<p style="font-size: 0.8rem; color: #92400e;">Квалификация модератора & проверка знаний</p>
</div>
<div class="level-badge">
9 level
</div>
</div>
<!-- Дополнительный блок: справка и завершение работы -->
<div class="help-footer">
<span><i class="fas fa-info-circle"></i> Справка: актуальные инструкции по работе с репортами</span>
<span><i class="fas fa-clock"></i> Завершение работы в 23:59</span>
</div>
<div style="margin-top: 18px; font-size: 12px; color: #6c757d; text-align: right;">
<i class="fas fa-chart-line"></i> Обновлено: сегодня, статистика в реальном времени
</div>
</main>
</div>
<script>
(function() {
// ------------------- ФИЛЬТРАЦИЯ МЕНЮ ПО ПОИСКУ (Ctrl+K) -------------------
const searchInput = document.getElementById('menuSearch');
const fastItems = document.querySelectorAll('#navListFast .nav-item');
const mainItems = document.querySelectorAll('#navListMain .nav-item');
const allMenuItems = [...fastItems, ...mainItems];
function filterMenu() {
const searchTerm = searchInput.value.trim().toLowerCase();
allMenuItems.forEach(item => {
const text = item.innerText.toLowerCase();
const searchAttr = item.getAttribute('data-search-term')?.toLowerCase() || '';
const matches = text.includes(searchTerm) || searchAttr.includes(searchTerm);
if (!matches && searchTerm !== '') {
item.classList.add('hidden-menu');
} else {
item.classList.remove('hidden-menu');
}
});
}
searchInput.addEventListener('input', filterMenu);
// Ctrl+K фокус на поиск
window.addEventListener('keydown', function(e) {
if ((e.ctrlKey || e.metaKey) && e.key === 'k') {
e.preventDefault();
searchInput.focus();
}
// Escape для очистки
if (e.key === 'Escape') {
searchInput.value = '';
filterMenu();
searchInput.blur();
}
});
// ------------------- ИНИЦИАЛИЗАЦИЯ ГРАФИКОВ (Chart.js) -------------------
// 1. График "Модераторские vs Стандартные" (линейный)
const ctxTrend = document.getElementById('trendChart').getContext('2d');
const trendChart = new Chart(ctxTrend, {
type: 'line',
data: {
labels: ['Пн', 'Вт', 'Ср', 'Чт', 'Пт', 'Сб', 'Вс'],
datasets: [
{
label: 'Модераторские репорты',
data: [42, 38, 47, 52, 49, 44, 39],
borderColor: '#3b82f6',
backgroundColor: 'rgba(59, 130, 246, 0.05)',
borderWidth: 2.5,
pointBackgroundColor: '#1e40af',
pointBorderColor: '#fff',
pointRadius: 4,
pointHoverRadius: 6,
tension: 0.2,
fill: true,
},
{
label: 'Стандартные репорты',
data: [82, 78, 91, 102, 98, 88, 79],
borderColor: '#f97316',
backgroundColor: 'rgba(249, 115, 22, 0.03)',
borderWidth: 2.5,
pointBackgroundColor: '#c2410c',
pointBorderColor: '#fff',
pointRadius: 4,
pointHoverRadius: 6,
tension: 0.2,
fill: true,
}
]
},
options: {
responsive: true,
maintainAspectRatio: true,
plugins: {
tooltip: { mode: 'index', intersect: false },
legend: { position: 'top', labels: { usePointStyle: true, boxWidth: 10, font: { size: 11 } } }
},
scales: {
y: {
beginAtZero: true,
grid: { color: '#eef2ff' },
title: { display: true, text: 'Количество репортов', font: { size: 10 } }
},
x: {
grid: { display: false },
title: { display: true, text: 'День недели', font: { size: 10 } }
}
}
}
});
// 2. График "Нагрузка по часам" (распределение репортов)
const ctxHour = document.getElementById('hourlyChart').getContext('2d');
const hoursLabels = [];
for (let i = 0; i < 24; i++) {
hoursLabels.push(`${i}:00`);
}
// Эмуляция нагрузки: утренний рост, пик в 17-20 часов, спад ночью
const hourlyData = [5, 3, 2, 4, 8, 14, 28, 42, 58, 67, 72, 84, 91, 95, 102, 110, 124, 135, 142, 128, 98, 67, 34, 18];
const hourlyChart = new Chart(ctxHour, {
type: 'bar',
data: {
labels: hoursLabels,
datasets: [
{
label: 'Репорты (шт)',
data: hourlyData,
backgroundColor: 'rgba(59, 130, 246, 0.7)',
borderRadius: 8,
borderSkipped: false,
barPercentage: 0.75,
categoryPercentage: 0.9,
}
]
},
options: {
responsive: true,
maintainAspectRatio: true,
plugins: {
tooltip: { callbacks: { label: (ctx) => `${ctx.raw} репортов` } },
legend: { display: false }
},
scales: {
y: {
beginAtZero: true,
grid: { color: '#eef2ff' },
title: { display: true, text: 'Количество репортов', font: { size: 10 } }
},
x: {
ticks: { maxRotation: 45, minRotation: 35, autoSkip: true, maxTicksLimit: 12 },
title: { display: true, text: 'Часы (UTC+3)', font: { size: 10 } }
}
}
}
});
// дополнительная анимация / подпись с данными (соответствие тексту "Стандартные: 640" и т.д.)
// Можно добавить декоративный эффект обновления метрик (чисто визуально, числа уже отображены)
// Добавим эмуляцию динамического изменения метрик для "Активисты администраторов" и прочих - не требуется, но для ощущения живости, сделаем незначительный эффект?
// В целях соблюдения ТЗ, просто оставляем статические данные, они полностью соответствуют описанию: 640, 0.01 и т.д.
// Визуальный эффект для карточек (необязательно)
const metricCards = document.querySelectorAll('.metric-card');
metricCards.forEach(card => {
card.addEventListener('mouseenter', () => {
card.style.transform = 'translateY(-2px)';
card.style.transition = '0.2s';
card.style.boxShadow = '0 8px 20px rgba(0,0,0,0.05)';
});
card.addEventListener('mouseleave', () => {
card.style.transform = 'translateY(0)';
card.style.boxShadow = 'none';
});
});
// Убедимся, что при изменении размера окна графики адаптируются
window.addEventListener('resize', () => {
trendChart.resize();
hourlyChart.resize();
});
// маленькая деталь: добавить плейсхолдер при пустом поиске, убираем hidden при очистке
// плюс показываем количество видимых элементов - но это опционально.
// Убедимся, что изначально все пункты видны
function resetVisibility() {
allMenuItems.forEach(item => item.classList.remove('hidden-menu'));
}
window.resetFilter = resetVisibility;
// Небольшой "live" счетчик для обработки репортов? Но оставим как статику, это соответствует исходным данным.
// Добавим консольное сообщение об успешной загрузке.
console.log('Dashboard статистики загружен | Модераторские репорты: стандартные 640, графики активны');
})();
</script>
</body>
</html>
Аааааа ИИ блэнHTML:<!DOCTYPE html> <html lang="ru"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes"> <title>Статистика репортов | Административная панель</title> <!-- Font Awesome 6 (free) --> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css"> <!-- Google Fonts: Inter & Roboto Mono --> <link href="https://fonts.googleapis.com/css2?family=Inter:opsz,wght@14..32,300;14..32,400;14..32,500;14..32,600;14..32,700&family=Roboto+Mono:wght@400;500&display=swap" rel="stylesheet"> <!-- Chart.js CDN --> <script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.0/dist/chart.umd.min.js"></script> <style> * { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: 'Inter', sans-serif; background: #f1f5f9; color: #0f172a; line-height: 1.4; } /* app layout */ .app { display: flex; min-height: 100vh; } /* SIDEBAR */ .sidebar { width: 280px; background: #ffffff; border-right: 1px solid #e2e8f0; display: flex; flex-direction: column; position: sticky; top: 0; height: 100vh; overflow-y: auto; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.02); transition: all 0.2s; z-index: 10; } /* sidebar inner */ .sidebar-header { padding: 24px 20px 12px 20px; border-bottom: 1px solid #eef2ff; } .logo-area h2 { font-size: 1.5rem; font-weight: 700; background: linear-gradient(135deg, #2563eb, #1e40af); background-clip: text; -webkit-background-clip: text; color: transparent; letter-spacing: -0.3px; } .logo-area p { font-size: 0.75rem; color: #5b6e8c; margin-top: 4px; } /* search box */ .search-menu { margin: 20px 0 12px 0; position: relative; } .search-menu input { width: 100%; padding: 10px 36px 10px 38px; border: 1px solid #e2e8f0; border-radius: 14px; background: #f8fafc; font-size: 0.85rem; font-weight: 500; transition: all 0.2s; color: #0f172a; } .search-menu input:focus { outline: none; border-color: #3b82f6; box-shadow: 0 0 0 3px rgba(59,130,246,0.2); background: #fff; } .search-menu i { position: absolute; left: 12px; top: 50%; transform: translateY(-50%); color: #94a3b8; font-size: 0.9rem; } .kbd-hint { position: absolute; right: 12px; top: 50%; transform: translateY(-50%); background: #eef2ff; padding: 2px 8px; border-radius: 8px; font-size: 0.7rem; font-weight: 600; font-family: monospace; color: #1e293b; pointer-events: none; letter-spacing: 0.5px; } /* navigation sections */ .nav-section { padding: 0 16px 20px 16px; border-bottom: 1px solid #f0f2f5; } .nav-section:last-child { border-bottom: none; } .nav-title { font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.6px; font-weight: 700; color: #5b6e8c; margin: 16px 0 10px 4px; } .nav-list { list-style: none; display: flex; flex-direction: column; gap: 6px; } .nav-item { padding: 8px 12px; border-radius: 12px; font-size: 0.9rem; font-weight: 500; color: #1e293b; transition: all 0.2s; cursor: default; display: flex; align-items: center; gap: 10px; } .nav-item i { width: 20px; font-size: 1rem; color: #5b6e8c; } .nav-item:hover { background: #f1f5f9; color: #2563eb; } .nav-item.hidden-menu { display: none; } /* main content */ .main-content { flex: 1; padding: 28px 32px; overflow-x: auto; } /* page header */ .page-header { display: flex; justify-content: space-between; align-items: baseline; flex-wrap: wrap; margin-bottom: 28px; } .page-header h1 { font-size: 1.9rem; font-weight: 700; background: linear-gradient(135deg, #0f2b3d, #1e3a8a); background-clip: text; -webkit-background-clip: text; color: transparent; } .badge-online { background: #d9f99d; color: #365314; padding: 4px 12px; border-radius: 40px; font-size: 0.75rem; font-weight: 600; } /* cards grid */ .stats-grid { background: white; border-radius: 24px; padding: 20px 24px; box-shadow: 0 1px 3px rgba(0,0,0,0.05), 0 1px 2px rgba(0,0,0,0.03); margin-bottom: 28px; border: 1px solid #eef2ff; } .section-title { font-size: 1.3rem; font-weight: 700; margin-bottom: 6px; display: flex; align-items: center; gap: 8px; } .section-sub { font-size: 0.8rem; color: #5b6e8c; border-left: 3px solid #3b82f6; padding-left: 12px; margin-bottom: 20px; } .metrics-row { display: flex; flex-wrap: wrap; gap: 20px; margin-top: 12px; } .metric-card { background: #f8fafc; border-radius: 20px; padding: 16px 18px; min-width: 160px; flex: 1 1 180px; border: 1px solid #eef2ff; transition: all 0.2s; } .metric-label { font-size: 0.75rem; text-transform: uppercase; font-weight: 600; color: #4b5563; letter-spacing: 0.4px; margin-bottom: 8px; } .metric-value { font-size: 2rem; font-weight: 800; font-family: 'Roboto Mono', monospace; color: #0f172a; line-height: 1.2; } .metric-unit { font-size: 0.8rem; font-weight: 500; color: #5b6e8c; } .badge-moderator { background: #e6f0ff; border-radius: 30px; padding: 4px 12px; font-size: 0.7rem; font-weight: 600; color: #2563eb; display: inline-block; margin-bottom: 12px; } /* double chart layout */ .charts-container { display: flex; flex-wrap: wrap; gap: 28px; margin-bottom: 28px; } .chart-card { background: white; border-radius: 24px; padding: 18px 20px; box-shadow: 0 1px 3px rgba(0,0,0,0.05); border: 1px solid #eef2ff; flex: 1 1 400px; } .chart-title { font-weight: 700; font-size: 1.1rem; margin-bottom: 16px; display: flex; align-items: center; gap: 8px; border-left: 3px solid #3b82f6; padding-left: 12px; } canvas { max-height: 280px; width: 100%; } .test-level-card { background: linear-gradient(145deg, #ffffff, #fef9e3); border-radius: 24px; padding: 18px 24px; margin-bottom: 28px; border: 1px solid #ffedd5; display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; } .test-info h4 { font-size: 1.1rem; font-weight: 700; } .level-badge { background: #f97316; color: white; padding: 8px 24px; border-radius: 60px; font-weight: 800; font-size: 1.5rem; font-family: monospace; box-shadow: 0 4px 8px rgba(249,115,22,0.2); } .help-footer { background: #f1f5f9; border-radius: 20px; padding: 14px 20px; display: flex; justify-content: space-between; align-items: center; color: #334155; font-size: 0.85rem; font-weight: 500; border: 1px solid #e2e8f0; } hr { margin: 12px 0; border: 0; border-top: 1px solid #eef2ff; } @media (max-width: 850px) { .app { flex-direction: column; } .sidebar { width: 100%; height: auto; position: relative; border-right: none; border-bottom: 1px solid #e2e8f0; } .main-content { padding: 20px; } .metrics-row { gap: 12px; } } /* scrollbar */ ::-webkit-scrollbar { width: 6px; } ::-webkit-scrollbar-track { background: #f1f1f1; border-radius: 10px; } ::-webkit-scrollbar-thumb { background: #cbd5e1; border-radius: 10px; } </style> </head> <body> <div class="app"> <!-- Боковая панель с поиском и меню --> <aside class="sidebar"> <div class="sidebar-header"> <div class="logo-area"> <h2><i class="fas fa-chart-line" style="color: #2563eb; font-size: 1.5rem;"></i> Test онлайн</h2> <p>статистика & репорты</p> </div> <div class="search-menu"> <i class="fas fa-search"></i> <input type="text" id="menuSearch" placeholder="Поиск по меню" autocomplete="off"> <span class="kbd-hint">Ctrl+K</span> </div> </div> <!-- Навигационная группа 1 (быстрые ссылки) --> <div class="nav-section"> <div class="nav-title"><i class="fas fa-bolt"></i> БЫСТРЫЙ ДОСТУП</div> <ul class="nav-list" id="navListFast"> <li class="nav-item" data-search-term="Статистика Репорты"><i class="fas fa-chart-pie"></i> Статистика / Репорты</li> <li class="nav-item" data-search-term="Правила Государствен"><i class="fas fa-gavel"></i> Правила / Государствен...</li> <li class="nav-item" data-search-term="Правила Общие правила"><i class="fas fa-book"></i> Правила / Общие правила</li> <li class="nav-item" data-search-term="Семьи"><i class="fas fa-users"></i> Семьи</li> <li class="nav-item" data-search-term="Фракции"><i class="fas fa-flag-checkered"></i> Фракции</li> </ul> </div> <!-- Основное меню (полный список) --> <div class="nav-section"> <div class="nav-title"><i class="fas fa-compass"></i> ОСНОВНОЕ</div> <ul class="nav-list" id="navListMain"> <li class="nav-item" data-search-term="Главная"><i class="fas fa-home"></i> Главная</li> <li class="nav-item" data-search-term="Команды сервера"><i class="fas fa-terminal"></i> Команды сервера</li> <li class="nav-item" data-search-term="Отпуска"><i class="fas fa-umbrella-beach"></i> Отпуска</li> <li class="nav-item" data-search-term="Наказания"><i class="fas fa-ban"></i> Наказания</li> <li class="nav-item" data-search-term="Модерация"><i class="fas fa-shield-haltered"></i> Модерация</li> <li class="nav-item" data-search-term="Штрафные баллы"><i class="fas fa-exclamation-triangle"></i> Штрафные баллы</li> <li class="nav-item" data-search-term="Экономика"><i class="fas fa-coins"></i> Экономика</li> <li class="nav-item" data-search-term="Транспорт"><i class="fas fa-truck"></i> Транспорт</li> <li class="nav-item" data-search-term="Предметы"><i class="fas fa-box"></i> Предметы</li> <li class="nav-item" data-search-term="Контент"><i class="fas fa-newspaper"></i> Контент</li> <li class="nav-item" data-search-term="Обучение"><i class="fas fa-graduation-cap"></i> Обучение</li> <li class="nav-item" data-search-term="Семьи"><i class="fas fa-heart"></i> Семьи</li> <li class="nav-item" data-search-term="Фракции"><i class="fas fa-handshake"></i> Фракции</li> </ul> </div> <div style="padding: 16px; margin-top: auto; font-size: 11px; color: #94a3b8; border-top: 1px solid #eef2ff; text-align: center;"> <i class="fas fa-database"></i> Данные в реальном времени </div> </aside> <!-- Основной контент --> <main class="main-content"> <div class="page-header"> <h1><i class="fas fa-chart-simple"></i> Статистика репортов</h1> <div class="badge-online"><i class="fas fa-circle" style="font-size: 0.5rem; color: #22c55e;"></i> Live обновления</div> </div> <!-- Карточка статистики репортов --> <div class="stats-grid"> <div class="section-title"> <i class="fas fa-flag-checkered" style="color:#2563eb"></i> Модераторские репорты </div> <div class="section-sub"> Остроковое данные по репортам за выбранный период • актуально на текущую сессию </div> <div class="metrics-row"> <div class="metric-card"> <div class="metric-label"><i class="fas fa-ticket-alt"></i> Стандартные</div> <div class="metric-value">640</div> <div class="metric-unit">репортов</div> </div> <div class="metric-card"> <div class="metric-label"><i class="fas fa-hourglass-half"></i> Среднее время ответа</div> <div class="metric-value">0.01 <span class="metric-unit">ч</span></div> </div> <div class="metric-card"> <div class="metric-label"><i class="fas fa-user-check"></i> Активисты администраторов</div> <div class="metric-value">0.01 <span class="metric-unit">%</span></div> </div> <div class="metric-card"> <div class="metric-label"><i class="fas fa-clock"></i> Среднее время решения</div> <div class="metric-value">0.01 <span class="metric-unit">ч</span></div> </div> <div class="metric-card"> <div class="metric-label"><i class="fas fa-check-double"></i> Обработали репорты</div> <div class="metric-value">0.01 <span class="metric-unit">тыс.</span></div> </div> </div> </div> <!-- Двойной график: основной график (модераторские/стандартные) и тест-уровень --> <div class="charts-container"> <div class="chart-card"> <div class="chart-title"> <i class="fas fa-chart-line" style="color:#3b82f6"></i> График <span style="font-size: 0.7rem; background: #eff6ff; padding: 2px 8px; border-radius: 40px;">Модераторские / Стандартные</span> </div> <canvas id="trendChart" width="400" height="250" style="width:100%; height:auto; max-height:250px"></canvas> <div class="section-sub" style="margin-top: 10px; text-align: center;">Динамика за последние 7 дней</div> </div> <div class="chart-card"> <div class="chart-title"> <i class="fas fa-chart-bar"></i> Нагрузка по часам </div> <canvas id="hourlyChart" width="400" height="250" style="width:100%; height:auto; max-height:250px"></canvas> <div class="section-sub" style="margin-top: 10px; text-align: center;">Распределение репортов по часам (МСК)</div> </div> </div> <!-- Блок "Тест 9 level" и дополнительная информация --> <div class="test-level-card"> <div class="test-info"> <h4><i class="fas fa-brain"></i> Тест компетенций</h4> <p style="font-size: 0.8rem; color: #92400e;">Квалификация модератора & проверка знаний</p> </div> <div class="level-badge"> 9 level </div> </div> <!-- Дополнительный блок: справка и завершение работы --> <div class="help-footer"> <span><i class="fas fa-info-circle"></i> Справка: актуальные инструкции по работе с репортами</span> <span><i class="fas fa-clock"></i> Завершение работы в 23:59</span> </div> <div style="margin-top: 18px; font-size: 12px; color: #6c757d; text-align: right;"> <i class="fas fa-chart-line"></i> Обновлено: сегодня, статистика в реальном времени </div> </main> </div> <script> (function() { // ------------------- ФИЛЬТРАЦИЯ МЕНЮ ПО ПОИСКУ (Ctrl+K) ------------------- const searchInput = document.getElementById('menuSearch'); const fastItems = document.querySelectorAll('#navListFast .nav-item'); const mainItems = document.querySelectorAll('#navListMain .nav-item'); const allMenuItems = [...fastItems, ...mainItems]; function filterMenu() { const searchTerm = searchInput.value.trim().toLowerCase(); allMenuItems.forEach(item => { const text = item.innerText.toLowerCase(); const searchAttr = item.getAttribute('data-search-term')?.toLowerCase() || ''; const matches = text.includes(searchTerm) || searchAttr.includes(searchTerm); if (!matches && searchTerm !== '') { item.classList.add('hidden-menu'); } else { item.classList.remove('hidden-menu'); } }); } searchInput.addEventListener('input', filterMenu); // Ctrl+K фокус на поиск window.addEventListener('keydown', function(e) { if ((e.ctrlKey || e.metaKey) && e.key === 'k') { e.preventDefault(); searchInput.focus(); } // Escape для очистки if (e.key === 'Escape') { searchInput.value = ''; filterMenu(); searchInput.blur(); } }); // ------------------- ИНИЦИАЛИЗАЦИЯ ГРАФИКОВ (Chart.js) ------------------- // 1. График "Модераторские vs Стандартные" (линейный) const ctxTrend = document.getElementById('trendChart').getContext('2d'); const trendChart = new Chart(ctxTrend, { type: 'line', data: { labels: ['Пн', 'Вт', 'Ср', 'Чт', 'Пт', 'Сб', 'Вс'], datasets: [ { label: 'Модераторские репорты', data: [42, 38, 47, 52, 49, 44, 39], borderColor: '#3b82f6', backgroundColor: 'rgba(59, 130, 246, 0.05)', borderWidth: 2.5, pointBackgroundColor: '#1e40af', pointBorderColor: '#fff', pointRadius: 4, pointHoverRadius: 6, tension: 0.2, fill: true, }, { label: 'Стандартные репорты', data: [82, 78, 91, 102, 98, 88, 79], borderColor: '#f97316', backgroundColor: 'rgba(249, 115, 22, 0.03)', borderWidth: 2.5, pointBackgroundColor: '#c2410c', pointBorderColor: '#fff', pointRadius: 4, pointHoverRadius: 6, tension: 0.2, fill: true, } ] }, options: { responsive: true, maintainAspectRatio: true, plugins: { tooltip: { mode: 'index', intersect: false }, legend: { position: 'top', labels: { usePointStyle: true, boxWidth: 10, font: { size: 11 } } } }, scales: { y: { beginAtZero: true, grid: { color: '#eef2ff' }, title: { display: true, text: 'Количество репортов', font: { size: 10 } } }, x: { grid: { display: false }, title: { display: true, text: 'День недели', font: { size: 10 } } } } } }); // 2. График "Нагрузка по часам" (распределение репортов) const ctxHour = document.getElementById('hourlyChart').getContext('2d'); const hoursLabels = []; for (let i = 0; i < 24; i++) { hoursLabels.push(`${i}:00`); } // Эмуляция нагрузки: утренний рост, пик в 17-20 часов, спад ночью const hourlyData = [5, 3, 2, 4, 8, 14, 28, 42, 58, 67, 72, 84, 91, 95, 102, 110, 124, 135, 142, 128, 98, 67, 34, 18]; const hourlyChart = new Chart(ctxHour, { type: 'bar', data: { labels: hoursLabels, datasets: [ { label: 'Репорты (шт)', data: hourlyData, backgroundColor: 'rgba(59, 130, 246, 0.7)', borderRadius: 8, borderSkipped: false, barPercentage: 0.75, categoryPercentage: 0.9, } ] }, options: { responsive: true, maintainAspectRatio: true, plugins: { tooltip: { callbacks: { label: (ctx) => `${ctx.raw} репортов` } }, legend: { display: false } }, scales: { y: { beginAtZero: true, grid: { color: '#eef2ff' }, title: { display: true, text: 'Количество репортов', font: { size: 10 } } }, x: { ticks: { maxRotation: 45, minRotation: 35, autoSkip: true, maxTicksLimit: 12 }, title: { display: true, text: 'Часы (UTC+3)', font: { size: 10 } } } } } }); // дополнительная анимация / подпись с данными (соответствие тексту "Стандартные: 640" и т.д.) // Можно добавить декоративный эффект обновления метрик (чисто визуально, числа уже отображены) // Добавим эмуляцию динамического изменения метрик для "Активисты администраторов" и прочих - не требуется, но для ощущения живости, сделаем незначительный эффект? // В целях соблюдения ТЗ, просто оставляем статические данные, они полностью соответствуют описанию: 640, 0.01 и т.д. // Визуальный эффект для карточек (необязательно) const metricCards = document.querySelectorAll('.metric-card'); metricCards.forEach(card => { card.addEventListener('mouseenter', () => { card.style.transform = 'translateY(-2px)'; card.style.transition = '0.2s'; card.style.boxShadow = '0 8px 20px rgba(0,0,0,0.05)'; }); card.addEventListener('mouseleave', () => { card.style.transform = 'translateY(0)'; card.style.boxShadow = 'none'; }); }); // Убедимся, что при изменении размера окна графики адаптируются window.addEventListener('resize', () => { trendChart.resize(); hourlyChart.resize(); }); // маленькая деталь: добавить плейсхолдер при пустом поиске, убираем hidden при очистке // плюс показываем количество видимых элементов - но это опционально. // Убедимся, что изначально все пункты видны function resetVisibility() { allMenuItems.forEach(item => item.classList.remove('hidden-menu')); } window.resetFilter = resetVisibility; // Небольшой "live" счетчик для обработки репортов? Но оставим как статику, это соответствует исходным данным. // Добавим консольное сообщение об успешной загрузке. console.log('Dashboard статистики загружен | Модераторские репорты: стандартные 640, графики активны'); })(); </script> </body> </html>
Выглядит даже лучше, чем оригинал
Вы видели лишь одну страницу там есть ещё интереснее просто не всё показываюВыглядит даже лучше, чем оригинал
Фу пакажиВы видели лишь одну страницу там есть ещё интереснее просто не всё показываю![]()