Счетчик

Как проверить посещаемость сайта ? 
Можно разместить разные сервисы на подобие google analytics и ещё милион других . 
Но я предлагаю сделать свою статистику.

📊 Возможности скрипта статистики посещений

Этот универсальный скрипт предоставляет следующие возможности:
При первом открытии скрипт создаст базу sqlite , для глубокого анализа есть  "Админ-панель".


📌 Основная статистика (баннер)

  1. Сейчас онлайн
    • Количество уникальных посетителей за последние 5 минут (исключая администратора)
  2. Новые посетители
    • Количество новых пользователей за последние 5 минут
  3. Посещения за сегодня
    • Уникальные посетители с 00:00 текущих суток
  4. Посещения за месяц
    • Уникальные посетители с 1 числа текущего месяца
  5. Всего посещений
    • Общее количество уникальных посещений за всё время

🔐 Административная панель

Доступна по клику на баннер (открывается в новой вкладке).
Функционал админки:

  1. Авторизация
    • Пароль по умолчанию: password (можно изменить)
    • Пароль хранится в зашифрованном виде (используется password_hash)
  2. Расширенная статистика
    • IP за последние 15 минут
      • Список всех IP-адресов и количество их посещений
    • Повторяющиеся IP за день
      • IP-адреса, которые посещали сайт более 1 раза сегодня
    • Автоматическое определение IP администратора
      • При первом входе в админку IP сохраняется и исключается из статистики
  3. Управление паролем
    • Смена пароля админки (новый пароль также хранится в зашифрованном виде)

🛡️ Технические особенности

  1. Хранение данных
    • Используется SQLite (файл visitors.db)
    • 3 таблицы:
      • visitors (данные о посетителях, включая IP и отметку администратора)
      • stats (общая статистика)
      • admin (пароль и IP администратора)
  2. Защита данных
    • IP администратора исключается из общей статистики
    • Пароли хранятся в виде хешей (password_hash)
    • Нет уязвимостей к SQL-инъекциям (используются подготовленные запросы PDO)
  3. Автоматические сбросы
    • Счетчик месячных посещений сбрасывается 1 числа каждого месяца
    • Счетчик дневных посещений сбрасывается в 00:00
  4. Кросс-браузерность
    • Баннер корректно отображается на любых устройствах
    • Админ-панель работает во всех современных браузерах

⚙️ Как использовать?

  1. Разместите файл visitor_counter.php в корне сайта.
  2. Вставьте код для отображения баннера:

    html
    Copy
    <iframe src="/visitor_counter.php" width="150" height="130" style="border: none;"></iframe>
  • Для доступа к админке кликните на баннер (откроется в новой вкладке).

 

 
<?php
// Путь к файлу базы данных SQLite
$db_file = 'visitors.db';
// Создаем или открываем базу данных
try {
    $db = new PDO("sqlite:$db_file");
    $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
    die("Ошибка подключения к базе данных: " . $e->getMessage());
}
// Создаем таблицы, если они не существуют
$create_table_query = "
CREATE TABLE IF NOT EXISTS visitors (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    visitor_id TEXT NOT NULL UNIQUE,
    first_visit_time INTEGER NOT NULL,
    last_visit_time INTEGER NOT NULL,
    ip_address TEXT NOT NULL,
    is_admin INTEGER DEFAULT 0
);
CREATE TABLE IF NOT EXISTS stats (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    total_visits INTEGER DEFAULT 0,
    monthly_visits INTEGER DEFAULT 0,
    today_visits INTEGER DEFAULT 0,
    current_month INTEGER DEFAULT 0,
    current_year INTEGER DEFAULT 0
);
CREATE TABLE IF NOT EXISTS admin (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    password_hash TEXT NOT NULL,
    admin_ip TEXT
);
";
$db->exec($create_table_query);
// Если таблица admin пуста, добавляем пароль по умолчанию (password)
$stmt = $db->query("SELECT COUNT(*) as count FROM admin");
if ($stmt->fetch()['count'] == 0) {
    $default_password = 'password';
    $password_hash = password_hash($default_password, PASSWORD_DEFAULT);
    $db->exec("INSERT INTO admin (password_hash) VALUES ('$password_hash')");
}
// Получаем данные админа из базы
$admin_data = $db->query("SELECT password_hash, admin_ip FROM admin LIMIT 1")->fetch(PDO::FETCH_ASSOC);
$password_hash = $admin_data['password_hash'];
$admin_ip = $admin_data['admin_ip'];
// Обработка смены пароля
if (isset($_POST['change_password'])) {
    $new_password = $_POST['new_password'];
    if (!empty($new_password)) {
        $new_hash = password_hash($new_password, PASSWORD_DEFAULT);
        $db->exec("UPDATE admin SET password_hash = '$new_hash'");
        $password_hash = $new_hash;
        echo "<p style='color: green;'>Пароль успешно изменен!</p>";
    } else {
        echo "<p style='color: red;'>Пароль не может быть пустым!</p>";
    }
}
// Проверка входа в админку
$is_admin = false;
if (isset($_POST['login'])) {
    $input_password = $_POST['password'];
    if (password_verify($input_password, $password_hash)) {
        $is_admin = true;
        // Запоминаем IP администратора при первом входе
        if (empty($admin_ip)) {
            $current_ip = $_SERVER['REMOTE_ADDR'];
            $db->exec("UPDATE admin SET admin_ip = '$current_ip'");
            $admin_ip = $current_ip;
            // Помечаем текущего пользователя как администратора
            $db->exec("UPDATE visitors SET is_admin = 1 WHERE ip_address = '$current_ip'");
        }
    } else {
        echo "<p style='color: red;'>Неверный пароль!</p>";
    }
}
// Получаем IP-адрес текущего пользователя
$current_ip = $_SERVER['REMOTE_ADDR'];
$is_current_admin = ($current_ip === $admin_ip);
// Текущее время и временные метки
$current_time = time();
$five_minutes_ago = $current_time - 300;
$fifteen_minutes_ago = $current_time - 900;
$current_month = date('n');
$current_year = date('Y');
$start_of_today = strtotime('today 00:00:00');
$start_of_month = strtotime('first day of this month 00:00:00');
// Обработка посещения
$is_new_visitor = true;
if (isset($_COOKIE['visitor_id'])) {
    $visitor_id = $_COOKIE['visitor_id'];
    $stmt = $db->prepare("SELECT * FROM visitors WHERE visitor_id = :visitor_id");
    $stmt->execute([':visitor_id' => $visitor_id]);
    if ($row = $stmt->fetch()) {
        $is_new_visitor = false;
        $db->prepare("UPDATE visitors SET last_visit_time = :last_visit_time WHERE visitor_id = :visitor_id")
           ->execute([':last_visit_time' => $current_time, ':visitor_id' => $visitor_id]);
    }
} else {
    $visitor_id = uniqid();
    setcookie('visitor_id', $visitor_id, time() + (86400 * 30), "/");
}
if ($is_new_visitor) {
    $is_admin_flag = $is_current_admin ? 1 : 0;
    $db->prepare("INSERT INTO visitors (visitor_id, first_visit_time, last_visit_time, ip_address, is_admin) VALUES (:visitor_id, :first_visit_time, :last_visit_time, :ip_address, :is_admin)")
       ->execute([
           ':visitor_id' => $visitor_id,
           ':first_visit_time' => $current_time,
           ':last_visit_time' => $current_time,
           ':ip_address' => $current_ip,
           ':is_admin' => $is_admin_flag
       ]);
}
// Обновление статистики
$stats = $db->query("SELECT * FROM stats LIMIT 1")->fetch(PDO::FETCH_ASSOC);
if (!$stats) {
    $db->exec("INSERT INTO stats (total_visits, monthly_visits, today_visits, current_month, current_year) VALUES (0, 0, 0, 0, 0)");
    $stats = $db->query("SELECT * FROM stats LIMIT 1")->fetch(PDO::FETCH_ASSOC);
}
if ($stats['current_month'] != $current_month || $stats['current_year'] != $current_year) {
    $db->exec("UPDATE stats SET monthly_visits = 0, current_month = $current_month, current_year = $current_year");
}
if ($is_new_visitor && !$is_current_admin) {
    $db->exec("UPDATE stats SET total_visits = total_visits + 1, monthly_visits = monthly_visits + 1, today_visits = today_visits + 1");
}
// Получение статистики
$stats = $db->query("SELECT * FROM stats LIMIT 1")->fetch(PDO::FETCH_ASSOC);
$total_visits = $stats['total_visits'];
$monthly_visits = $stats['monthly_visits'];
$today_visits = $stats['today_visits'];
// Подсчет посещений (исключая администратора)
function getCount($db, $sql, $params) {
    $stmt = $db->prepare($sql . " AND is_admin = 0");
    $stmt->execute($params);
    return $stmt->fetch()['count'];
}
$current_visits_last_5_minutes = getCount($db, 
    "SELECT COUNT(*) as count FROM visitors WHERE last_visit_time >= :time", 
    [':time' => $five_minutes_ago]
);
$new_visitors_last_5_minutes = getCount($db,
    "SELECT COUNT(*) as count FROM visitors WHERE first_visit_time >= :time",
    [':time' => $five_minutes_ago]
);
$today_visits = getCount($db,
    "SELECT COUNT(*) as count FROM visitors WHERE last_visit_time >= :time",
    [':time' => $start_of_today]
);
$monthly_visits = getCount($db,
    "SELECT COUNT(*) as count FROM visitors WHERE last_visit_time >= :time",
    [':time' => $start_of_month]
);
// Админ-панель
if (isset($_GET['admin'])) {
    echo "<h2>Админ-панель</h2>";
    if (!$is_admin) {
        echo "<form method='post'>
                <input type='password' name='password' placeholder='Введите пароль' required>
                <button type='submit' name='login'>Войти</button>
              </form>";
    } else {
        echo "<h3>Расширенная статистика</h3>";
        echo "<p><strong>Ваш IP (админ):</strong> $admin_ip</p>";
        // IP за последние 15 минут
        $stmt = $db->prepare("SELECT ip_address, COUNT(*) as count FROM visitors WHERE last_visit_time >= :time AND is_admin = 0 GROUP BY ip_address");
        $stmt->execute([':time' => $fifteen_minutes_ago]);
        echo "<h4>IP за последние 15 минут:</h4><ul>";
        foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $ip) {
            echo "<li>{$ip['ip_address']} ({$ip['count']})</li>";
        }
        echo "</ul>";
        // Повторяющиеся IP
        $stmt = $db->prepare("SELECT ip_address, COUNT(*) as count FROM visitors WHERE last_visit_time >= :time AND is_admin = 0 GROUP BY ip_address HAVING count > 1");
        $stmt->execute([':time' => $start_of_today]);
        echo "<h4>Повторные IP за день:</h4><ul>";
        foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $ip) {
            echo "<li>{$ip['ip_address']} ({$ip['count']})</li>";
        }
        echo "</ul>";
        // Смена пароля
        echo "<h4>Смена пароля:</h4>
              <form method='post'>
                <input type='password' name='new_password' placeholder='Новый пароль' required>
                <button type='submit' name='change_password'>Сменить</button>
              </form>";
    }
    exit;
}
// Баннер (открывается в новой вкладке)
echo "<a href='?admin=1' target='_blank' style='text-decoration: none; color: inherit;'>";
echo "<div style='border: 1px solid #ccc; padding: 5px; width: 120px; font-size: 12px; text-align: center; background-color: #f9f9f9; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); font-family: Arial, sans-serif; color: #333;'>";
echo "<strong style='font-size: 14px; color: #555;'>Статистика</strong><br>";
echo "<div style='margin-top: 8px;'>";
echo "👥 Сейчас: <span style='color: #007BFF; font-weight: bold;'>$current_visits_last_5_minutes</span><br>";
echo "🆕 Новые: <span style='color: #28a745; font-weight: bold;'>$new_visitors_last_5_minutes</span><br>";
echo "📅 Сегодня: <span style='color: #ffc107; font-weight: bold;'>$today_visits</span><br>";
echo "📊 Месяц: <span style='color: #dc3545; font-weight: bold;'>$monthly_visits</span><br>";
echo "🌍 Всего: <span style='color: #6c757d; font-weight: bold;'>$total_visits</span>";
echo "</div></div></a>";
?>




 

Доработал админку , имеется гафик посещений и довлены поля для размещения гугл и подобных счетчиков.

В прочем тестируйте кому понравится.

 

<?php
// Путь к файлу базы данных SQLite
$db_file = 'visitors.db';

// Создаем или открываем базу данных
try {
    $db = new PDO("sqlite:$db_file");
    $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
    die("Ошибка подключения к базе данных: " . $e->getMessage());
}

// Создаем таблицы, если они не существуют
$create_table_query = "
CREATE TABLE IF NOT EXISTS visitors (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    visitor_id TEXT NOT NULL UNIQUE,
    first_visit_time INTEGER NOT NULL,
    last_visit_time INTEGER NOT NULL,
    ip_address TEXT NOT NULL,
    is_admin INTEGER DEFAULT 0
);
CREATE TABLE IF NOT EXISTS stats (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    total_visits INTEGER DEFAULT 0,
    monthly_visits INTEGER DEFAULT 0,
    today_visits INTEGER DEFAULT 0,
    current_month INTEGER DEFAULT 0,
    current_year INTEGER DEFAULT 0
);
CREATE TABLE IF NOT EXISTS admin (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    password_hash TEXT NOT NULL,
    admin_ip TEXT
);
CREATE TABLE IF NOT EXISTS settings (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    meta_title TEXT,
    meta_description TEXT,
    google_analytics TEXT
);
";
$db->exec($create_table_query);

// Проверяем и добавляем отсутствующие колонки в таблицу settings
try {
    $columns = $db->query("PRAGMA table_info(settings)")->fetchAll(PDO::FETCH_ASSOC);
    $existing_columns = array_column($columns, 'name');
    
    $required_columns = ['meta_title', 'meta_description', 'google_analytics'];
    foreach ($required_columns as $column) {
        if (!in_array($column, $existing_columns)) {
            $db->exec("ALTER TABLE settings ADD COLUMN $column TEXT");
        }
    }
} catch (PDOException $e) {
    $db->exec("DROP TABLE IF EXISTS settings");
    $db->exec("CREATE TABLE settings (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        meta_title TEXT,
        meta_description TEXT,
        google_analytics TEXT
    )");
}

// Если таблица admin пуста, добавляем пароль по умолчанию (password)
$stmt = $db->query("SELECT COUNT(*) as count FROM admin");
if ($stmt->fetch()['count'] == 0) {
    $default_password = 'password';
    $password_hash = password_hash($default_password, PASSWORD_DEFAULT);
    $db->exec("INSERT INTO admin (password_hash) VALUES ('$password_hash')");
}

// Если таблица settings пуста, добавляем настройки по умолчанию
$stmt = $db->query("SELECT COUNT(*) as count FROM settings");
if ($stmt->fetch()['count'] == 0) {
    $db->exec("INSERT INTO settings (meta_title, meta_description, google_analytics) VALUES ('Мой сайт', 'Описание моего сайта', '')");
}

// Получаем данные админа из базы
$admin_data = $db->query("SELECT password_hash, admin_ip FROM admin LIMIT 1")->fetch(PDO::FETCH_ASSOC);
$password_hash = $admin_data['password_hash'];
$admin_ip = $admin_data['admin_ip'];

// Получаем настройки сайта
$settings = $db->query("SELECT * FROM settings LIMIT 1")->fetch(PDO::FETCH_ASSOC);
$meta_title = $settings['meta_title'] ?? 'Мой сайт';
$meta_description = $settings['meta_description'] ?? 'Описание моего сайта';
$google_analytics = $settings['google_analytics'] ?? '';

// Обработка смены пароля
if (isset($_POST['change_password'])) {
    $new_password = $_POST['new_password'];
    if (!empty($new_password)) {
        $new_hash = password_hash($new_password, PASSWORD_DEFAULT);
        $db->exec("UPDATE admin SET password_hash = '$new_hash'");
        $password_hash = $new_hash;
        echo "<p style='color: green;'>Пароль успешно изменен!</p>";
    } else {
        echo "<p style='color: red;'>Пароль не может быть пустым!</p>";
    }
}

// Обработка сохранения настроек
if (isset($_POST['save_settings'])) {
    $new_meta_title = $_POST['meta_title'];
    $new_meta_description = $_POST['meta_description'];
    $new_google_analytics = $_POST['google_analytics'];
    
    $stmt = $db->prepare("UPDATE settings SET meta_title = ?, meta_description = ?, google_analytics = ?");
    $stmt->execute([$new_meta_title, $new_meta_description, $new_google_analytics]);
    
    $meta_title = $new_meta_title;
    $meta_description = $new_meta_description;
    $google_analytics = $new_google_analytics;
    
    echo "<p style='color: green;'>Настройки успешно сохранены!</p>";
}

// Проверка входа в админку
$is_admin = false;
if (isset($_POST['login'])) {
    $input_password = $_POST['password'];
    if (password_verify($input_password, $password_hash)) {
        $is_admin = true;
        $current_ip = $_SERVER['REMOTE_ADDR'];
        $db->exec("UPDATE admin SET admin_ip = '$current_ip'");
        
        if (!empty($admin_ip) && $admin_ip != $current_ip) {
            $db->exec("UPDATE visitors SET is_admin = 0 WHERE ip_address = '$admin_ip'");
        }
        
        $db->exec("UPDATE visitors SET is_admin = 1 WHERE ip_address = '$current_ip'");
        $admin_ip = $current_ip;
    } else {
        echo "<p style='color: red;'>Неверный пароль!</p>";
    }
}

// Получаем IP-адрес текущего пользователя
$current_ip = $_SERVER['REMOTE_ADDR'];
$is_current_admin = ($current_ip === $admin_ip);

// Текущее время и временные метки
$current_time = time();
$five_minutes_ago = $current_time - 300;
$fifteen_minutes_ago = $current_time - 900;
$current_month = date('n');
$current_year = date('Y');
$start_of_today = strtotime('today 00:00:00');
$start_of_month = strtotime('first day of this month 00:00:00');

// Обработка посещения
$is_new_visitor = true;
if (isset($_COOKIE['visitor_id'])) {
    $visitor_id = $_COOKIE['visitor_id'];
    $stmt = $db->prepare("SELECT * FROM visitors WHERE visitor_id = :visitor_id");
    $stmt->execute([':visitor_id' => $visitor_id]);
    if ($row = $stmt->fetch()) {
        $is_new_visitor = false;
        $db->prepare("UPDATE visitors SET last_visit_time = :last_visit_time WHERE visitor_id = :visitor_id")
           ->execute([':last_visit_time' => $current_time, ':visitor_id' => $visitor_id]);
    }
} else {
    $visitor_id = uniqid();
    setcookie('visitor_id', $visitor_id, time() + (86400 * 30), "/");
}

if ($is_new_visitor) {
    $is_admin_flag = $is_current_admin ? 1 : 0;
    $db->prepare("INSERT INTO visitors (visitor_id, first_visit_time, last_visit_time, ip_address, is_admin) VALUES (:visitor_id, :first_visit_time, :last_visit_time, :ip_address, :is_admin)")
       ->execute([
           ':visitor_id' => $visitor_id,
           ':first_visit_time' => $current_time,
           ':last_visit_time' => $current_time,
           ':ip_address' => $current_ip,
           ':is_admin' => $is_admin_flag
       ]);
}

// Обновление статистики
$stats = $db->query("SELECT * FROM stats LIMIT 1")->fetch(PDO::FETCH_ASSOC);
if (!$stats) {
    $db->exec("INSERT INTO stats (total_visits, monthly_visits, today_visits, current_month, current_year) VALUES (0, 0, 0, 0, 0)");
    $stats = $db->query("SELECT * FROM stats LIMIT 1")->fetch(PDO::FETCH_ASSOC);
}

if ($stats['current_month'] != $current_month || $stats['current_year'] != $current_year) {
    $db->exec("UPDATE stats SET monthly_visits = 0, current_month = $current_month, current_year = $current_year");
}

if ($is_new_visitor && !$is_current_admin) {
    $db->exec("UPDATE stats SET total_visits = total_visits + 1, monthly_visits = monthly_visits + 1, today_visits = today_visits + 1");
}

// Получение статистики
$stats = $db->query("SELECT * FROM stats LIMIT 1")->fetch(PDO::FETCH_ASSOC);
$total_visits = $stats['total_visits'];
$monthly_visits = $stats['monthly_visits'];
$today_visits = $stats['today_visits'];

// Подсчет посещений (исключая администратора)
function getCount($db, $sql, $params) {
    $stmt = $db->prepare($sql . " AND is_admin = 0");
    $stmt->execute($params);
    return $stmt->fetch()['count'];
}

$current_visits_last_5_minutes = getCount($db,
    "SELECT COUNT(*) as count FROM visitors WHERE last_visit_time >= :time",
    [':time' => $five_minutes_ago]
);

$new_visitors_last_5_minutes = getCount($db,
    "SELECT COUNT(*) as count FROM visitors WHERE first_visit_time >= :time",
    [':time' => $five_minutes_ago]
);

$today_visits = getCount($db,
    "SELECT COUNT(*) as count FROM visitors WHERE last_visit_time >= :time",
    [':time' => $start_of_today]
);

$monthly_visits = getCount($db,
    "SELECT COUNT(*) as count FROM visitors WHERE last_visit_time >= :time",
    [':time' => $start_of_month]
);

// Функция для получения данных для графика посещений
function getVisitsByDay($db, $days = 30) {
    $result = [];
    
    for ($i = 0; $i < $days; $i++) {
        $day_start = strtotime("-$i days 00:00:00");
        $day_end = strtotime("-$i days 23:59:59");
        $day_label = date("d.m", $day_start);
        
        $stmt = $db->prepare("SELECT COUNT(*) as count FROM visitors WHERE last_visit_time BETWEEN :start AND :end AND is_admin = 0");
        $stmt->execute([':start' => $day_start, ':end' => $day_end]);
        $count = $stmt->fetch()['count'];
        
        $result[$day_label] = $count;
    }
    
    return array_reverse($result);
}

// Функция для получения данных для графика уникальных посещений
function getUniqueVisitsByDay($db, $days = 30) {
    $result = [];
    
    for ($i = 0; $i < $days; $i++) {
        $day_start = strtotime("-$i days 00:00:00");
        $day_end = strtotime("-$i days 23:59:59");
        $day_label = date("d.m", $day_start);
        
        $stmt = $db->prepare("SELECT COUNT(DISTINCT ip_address) as count FROM visitors WHERE last_visit_time BETWEEN :start AND :end AND is_admin = 0");
        $stmt->execute([':start' => $day_start, ':end' => $day_end]);
        $count = $stmt->fetch()['count'];
        
        $result[$day_label] = $count;
    }
    
    return array_reverse($result);
}

// Админ-панель
if (isset($_GET['admin'])) {
    $visits_data = getVisitsByDay($db, 30);
    $unique_visits_data = getUniqueVisitsByDay($db, 30);
    $chart_labels = json_encode(array_keys($visits_data));
    $chart_values = json_encode(array_values($visits_data));
    $unique_chart_values = json_encode(array_values($unique_visits_data));
    
    echo "<!DOCTYPE html>
    <html>
    <head>
        <title>Админ-панель</title>
        <script src='https://cdn.jsdelivr.net/npm/chart.js'></script>
        <script>
        function copyIP(ip) {
            const el = document.createElement('textarea');
            el.value = ip;
            document.body.appendChild(el);
            el.select();
            document.execCommand('copy');
            document.body.removeChild(el);
            alert('IP скопирован: ' + ip);
        }
        </script>
        <style>
            .ip-item {
                cursor: pointer;
                padding: 5px;
                margin: 2px;
                background: #f0f0f0;
                border-radius: 3px;
            }
            .ip-item:hover {
                background: #e0e0e0;
            }
            .chart-container {
                width: 100%;
                max-width: 800px;
                margin: 20px auto;
            }
            .stats-grid {
                display: grid;
                grid-template-columns: repeat(2, 1fr);
                gap: 20px;
                margin-bottom: 20px;
            }
            .stat-box {
                background: #f8f9fa;
                padding: 15px;
                border-radius: 5px;
                box-shadow: 0 2px 4px rgba(0,0,0,0.1);
            }
            .settings-form {
                margin: 20px 0;
                padding: 20px;
                background: #f8f9fa;
                border-radius: 5px;
            }
            .settings-form textarea {
                width: 100%;
                min-height: 100px;
            }
            .charts-container {
                display: flex;
                flex-wrap: wrap;
                gap: 20px;
                justify-content: center;
            }
            .chart-wrapper {
                flex: 1;
                min-width: 300px;
                max-width: 800px;
            }
        </style>
    </head>
    <body>";

    echo "<h2>Админ-панель</h2>";
    if (!$is_admin) {
        echo "<form method='post'>
                <input type='password' name='password' placeholder='Введите пароль' required>
                <button type='submit' name='login'>Войти</button>
              </form>";
    } else {
        echo "<div class='stats-grid'>
                <div class='stat-box'>
                    <h3>Общая статистика</h3>
                    <p><strong>Всего посещений:</strong> $total_visits</p>
                    <p><strong>За месяц:</strong> $monthly_visits</p>
                    <p><strong>За сегодня:</strong> $today_visits</p>
                </div>
                <div class='stat-box'>
                    <h3>Текущая активность</h3>
                    <p><strong>Последние 5 минут:</strong> $current_visits_last_5_minutes</p>
                    <p><strong>Новые посетители (5 мин):</strong> $new_visitors_last_5_minutes</p>
                    <p><strong>Ваш IP:</strong> $current_ip</p>
                </div>
              </div>";

        // Графики посещений
        echo "<div class='charts-container'>
                <div class='chart-wrapper'>
                    <h3>Посещения за последние 30 дней</h3>
                    <div class='chart-container'>
                        <canvas id='visitsChart'></canvas>
                    </div>
                </div>
                <div class='chart-wrapper'>
                    <h3>Уникальные посещения за последние 30 дней</h3>
                    <div class='chart-container'>
                        <canvas id='uniqueVisitsChart'></canvas>
                    </div>
                </div>
              </div>
              <script>
              const ctx = document.getElementById('visitsChart').getContext('2d');
              const visitsChart = new Chart(ctx, {
                  type: 'bar',
                  data: {
                      labels: $chart_labels,
                      datasets: [{
                          label: 'Все посещения',
                          data: $chart_values,
                          backgroundColor: 'rgba(54, 162, 235, 0.5)',
                          borderColor: 'rgba(54, 162, 235, 1)',
                          borderWidth: 1
                      }]
                  },
                  options: {
                      responsive: true,
                      scales: {
                          y: {
                              beginAtZero: true,
                              ticks: {
                                  stepSize: 1
                              }
                          }
                      }
                  }
              });
              
              const uniqueCtx = document.getElementById('uniqueVisitsChart').getContext('2d');
              const uniqueVisitsChart = new Chart(uniqueCtx, {
                  type: 'bar',
                  data: {
                      labels: $chart_labels,
                      datasets: [{
                          label: 'Уникальные посещения',
                          data: $unique_chart_values,
                          backgroundColor: 'rgba(75, 192, 192, 0.5)',
                          borderColor: 'rgba(75, 192, 192, 1)',
                          borderWidth: 1
                      }]
                  },
                  options: {
                      responsive: true,
                      scales: {
                          y: {
                              beginAtZero: true,
                              ticks: {
                                  stepSize: 1
                              }
                          }
                      }
                  }
              });
              </script>";

        // Форма настроек
        echo "<div class='settings-form'>
                <h3>Настройки сайта</h3>
                <form method='post'>
                    <div>
                        <label>Заголовок сайта (meta title):</label><br>
                        <input type='text' name='meta_title' value='" . htmlspecialchars($meta_title) . "' style='width: 100%'>
                    </div>
                    <div>
                        <label>Описание сайта (meta description):</label><br>
                        <textarea name='meta_description'>" . htmlspecialchars($meta_description) . "</textarea>
                    </div>
                    <div>
                        <label>Код Google Analytics:</label><br>
                        <textarea name='google_analytics'>" . htmlspecialchars($google_analytics) . "</textarea>
                    </div>
                    <button type='submit' name='save_settings'>Сохранить настройки</button>
                </form>
              </div>";

        // IP за последние 15 минут
        $stmt = $db->prepare("SELECT ip_address, COUNT(*) as count FROM visitors WHERE last_visit_time >= :time AND is_admin = 0 GROUP BY ip_address");
        $stmt->execute([':time' => $fifteen_minutes_ago]);
        echo "<h4>IP за последние 15 минут:</h4><div>";
        foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $ip) {
            echo "<div class='ip-item' onclick='copyIP(\"{$ip['ip_address']}\")'>{$ip['ip_address']} (посещений: {$ip['count']})</div>";
        }
        echo "</div>";

        // Повторяющиеся IP за день
        $stmt = $db->prepare("SELECT ip_address, COUNT(*) as count FROM visitors WHERE last_visit_time >= :time AND is_admin = 0 GROUP BY ip_address HAVING count > 1");
        $stmt->execute([':time' => $start_of_today]);
        echo "<h4>Повторные IP за день (кликните для копирования):</h4><div>";
        foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $ip) {
            echo "<div class='ip-item' onclick='copyIP(\"{$ip['ip_address']}\")'>{$ip['ip_address']} (посещений: {$ip['count']})</div>";
        }
        echo "</div>";

        // Смена пароля
        echo "<h4>Управление доступом</h4>
              <form method='post'>
                <input type='password' name='new_password' placeholder='Новый пароль' required>
                <button type='submit' name='change_password'>Сменить пароль</button>
              </form>";
    }
    echo "</body></html>";
    exit;
}

// Основная страница (внешний интерфейс)
echo "<!DOCTYPE html>
<html>
<head>
    <meta charset='UTF-8'>
    <meta name='viewport' content='width=device-width, initial-scale=1.0'>
    <title>" . htmlspecialchars($meta_title) . "</title>
    <meta name='description' content='" . htmlspecialchars($meta_description) . "'>";
    
if (!empty($google_analytics)) {
    echo $google_analytics;
}

echo "</head>
<body>
    <!-- Ваш контент сайта здесь -->
    
    <!-- Баннер статистики (открывается в новой вкладке) -->
    <a href='?admin=1' target='_blank' style='text-decoration: none; color: inherit;'>
        <div style='border: 1px solid #ccc; padding: 5px; width: 120px; font-size: 12px; text-align: center; background-color: #f9f9f9; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); font-family: Arial, sans-serif; color: #333;'>
            <strong style='font-size: 14px; color: #555;'>Статистика</strong><br>
            <div style='margin-top: 8px;'>
                👥 Сейчас: <span style='color: #007BFF; font-weight: bold;'>$current_visits_last_5_minutes</span><br>
                🆕 Новые: <span style='color: #28a745; font-weight: bold;'>$new_visitors_last_5_minutes</span><br>
                📅 Сегодня: <span style='color: #ffc107; font-weight: bold;'>$today_visits</span><br>
                📊 Месяц: <span style='color: #dc3545; font-weight: bold;'>$monthly_visits</span><br>
                🌍 Всего: <span style='color: #6c757d; font-weight: bold;'>$total_visits</span>
            </div>
        </div>
    </a>
</body>
</html>";
?>