pets1/public/index.html

625 lines
32 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>🃏 Texas Hold'em Poker</title>
<link rel="stylesheet" href="styles.css">
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet">
</head>
<body>
<!-- Экран авторизации -->
<div id="auth-screen" class="screen active">
<div class="glass-container menu-container">
<div class="logo">
<span class="logo-icon">🃏</span>
<h1>Texas Hold'em</h1>
<p class="subtitle">No-Limit Poker</p>
</div>
<div id="auth-tabs" class="auth-tabs">
<button class="btn btn-tab active" onclick="switchAuthTab('login')">Вход</button>
<button class="btn btn-tab" onclick="switchAuthTab('register')">Регистрация</button>
</div>
<!-- Форма входа -->
<div id="login-form" class="auth-form">
<div class="form-group">
<label>Логин</label>
<input type="text" id="login-username" class="input" placeholder="Введите логин" autocomplete="username">
</div>
<div class="form-group">
<label>Пароль</label>
<input type="password" id="login-password" class="input" placeholder="Введите пароль" autocomplete="current-password">
</div>
<button class="btn btn-primary btn-large" onclick="handleLogin()">Войти</button>
</div>
<!-- Форма регистрации -->
<div id="register-form" class="auth-form" style="display: none;">
<div class="form-group">
<label>Логин</label>
<input type="text" id="register-username" class="input" placeholder="Минимум 3 символа" autocomplete="username">
</div>
<div class="form-group">
<label>Пароль</label>
<input type="password" id="register-password" class="input" placeholder="Минимум 6 символов" autocomplete="new-password">
</div>
<div class="form-group">
<label>Повторите пароль</label>
<input type="password" id="register-password-confirm" class="input" placeholder="Повторите пароль" autocomplete="new-password">
</div>
<button class="btn btn-primary btn-large" onclick="handleRegister()">Зарегистрироваться</button>
</div>
<div class="auth-guest">
<span>или</span>
<button class="btn btn-outline" onclick="playAsGuest()">Играть как гость</button>
</div>
</div>
</div>
<!-- Главное меню -->
<div id="main-menu" class="screen">
<div class="glass-container menu-container">
<div class="logo">
<span class="logo-icon">🃏</span>
<h1>Texas Hold'em</h1>
<p class="subtitle">No-Limit Poker</p>
</div>
<!-- Информация о пользователе -->
<div id="user-info" class="user-info">
<span id="user-display-name">Гость</span>
<span id="user-role-badge" class="role-badge" style="display: none;">ADMIN</span>
<button class="btn btn-small btn-outline" onclick="handleLogout()">Выход</button>
</div>
<div class="menu-buttons">
<button class="btn btn-primary btn-large" onclick="showScreen('single-player-menu')">
<span class="btn-icon">🤖</span>
Одиночная игра
</button>
<button class="btn btn-secondary btn-large" onclick="showScreen('multiplayer-menu')">
<span class="btn-icon">👥</span>
Мультиплеер
</button>
<button class="btn btn-outline btn-large" onclick="showScreen('leaderboard-screen')">
<span class="btn-icon">🏆</span>
Таблица лидеров
</button>
</div>
<div class="settings-row">
<button class="btn btn-icon-only" onclick="toggleSound()" id="sound-toggle">
🔊
</button>
<button class="btn btn-icon-only" onclick="showScreen('settings-screen')">
⚙️
</button>
<!-- Кнопка админ-панели (только для админов) -->
<button class="btn btn-icon-only admin-only" onclick="showScreen('admin-screen')" style="display: none;" id="admin-btn">
👑
</button>
</div>
</div>
</div>
<!-- Меню одиночной игры -->
<div id="single-player-menu" class="screen">
<div class="glass-container menu-container">
<button class="btn-back" onclick="showScreen('main-menu')">← Назад</button>
<h2>Одиночная игра</h2>
<div class="form-group">
<label>Ваше имя</label>
<input type="text" id="sp-player-name" class="input" placeholder="Введите имя" value="Игрок">
</div>
<div class="form-group">
<label>Количество ботов</label>
<div class="btn-group">
<button class="btn btn-option active" data-value="1" onclick="selectOption(this, 'bot-count')">1</button>
<button class="btn btn-option" data-value="2" onclick="selectOption(this, 'bot-count')">2</button>
<button class="btn btn-option" data-value="3" onclick="selectOption(this, 'bot-count')">3</button>
<button class="btn btn-option" data-value="4" onclick="selectOption(this, 'bot-count')">4</button>
<button class="btn btn-option" data-value="5" onclick="selectOption(this, 'bot-count')">5</button>
</div>
</div>
<div class="form-group">
<label>Сложность ИИ</label>
<div class="btn-group difficulty-group">
<button class="btn btn-option active" data-value="1" onclick="selectOption(this, 'ai-difficulty')">
<span class="diff-icon">🎲</span>
<span class="diff-name">Новичок</span>
</button>
<button class="btn btn-option" data-value="2" onclick="selectOption(this, 'ai-difficulty')">
<span class="diff-icon">🎯</span>
<span class="diff-name">Опытный</span>
</button>
<button class="btn btn-option" data-value="3" onclick="selectOption(this, 'ai-difficulty')">
<span class="diff-icon">🧠</span>
<span class="diff-name">Эксперт</span>
</button>
</div>
</div>
<div class="form-group">
<label>Начальный стек</label>
<div class="btn-group">
<button class="btn btn-option" data-value="500" onclick="selectOption(this, 'starting-stack')">500</button>
<button class="btn btn-option active" data-value="1000" onclick="selectOption(this, 'starting-stack')">1000</button>
<button class="btn btn-option" data-value="2000" onclick="selectOption(this, 'starting-stack')">2000</button>
<button class="btn btn-option" data-value="5000" onclick="selectOption(this, 'starting-stack')">5000</button>
</div>
</div>
<button class="btn btn-primary btn-large" onclick="startSinglePlayer()">
Начать игру
</button>
</div>
</div>
<!-- Меню мультиплеера -->
<div id="multiplayer-menu" class="screen">
<div class="glass-container menu-container">
<button class="btn-back" onclick="showScreen('main-menu')">← Назад</button>
<h2>Мультиплеер</h2>
<div class="form-group">
<label>Ваше имя</label>
<input type="text" id="mp-player-name" class="input" placeholder="Введите имя" value="Игрок">
</div>
<div class="tabs">
<button class="tab active" onclick="switchTab('join-tab')">Присоединиться</button>
<button class="tab" onclick="switchTab('create-tab')">Создать комнату</button>
</div>
<div id="join-tab" class="tab-content active">
<div class="room-list" id="room-list">
<div class="room-list-loading">Подключение к серверу...</div>
</div>
<button class="btn btn-outline" onclick="refreshRooms()">🔄 Обновить</button>
</div>
<div id="create-tab" class="tab-content">
<div class="form-group">
<label>Название комнаты</label>
<input type="text" id="room-name" class="input" placeholder="Моя комната">
</div>
<div class="form-group">
<label>Блайнды</label>
<div class="btn-group">
<button class="btn btn-option active" data-value="5/10" onclick="selectOption(this, 'blinds')">5/10</button>
<button class="btn btn-option" data-value="10/20" onclick="selectOption(this, 'blinds')">10/20</button>
<button class="btn btn-option" data-value="25/50" onclick="selectOption(this, 'blinds')">25/50</button>
</div>
</div>
<div class="form-group">
<label>Макс. игроков</label>
<div class="btn-group">
<button class="btn btn-option" data-value="2" onclick="selectOption(this, 'max-players')">2</button>
<button class="btn btn-option" data-value="4" onclick="selectOption(this, 'max-players')">4</button>
<button class="btn btn-option active" data-value="6" onclick="selectOption(this, 'max-players')">6</button>
</div>
</div>
<button class="btn btn-primary btn-large" onclick="createRoom()">
Создать комнату
</button>
</div>
</div>
</div>
<!-- Лобби комнаты -->
<div id="room-lobby" class="screen">
<div class="glass-container lobby-container">
<button class="btn-back" onclick="leaveRoom()">← Выйти</button>
<h2 id="lobby-room-name">Комната</h2>
<!-- Блок для шаринга ссылки на комнату -->
<div class="room-share-section">
<div class="room-link-display">
<input type="text" id="room-link-input" class="input" readonly onclick="this.select()">
<button class="btn btn-secondary btn-icon-only" onclick="copyRoomLink()" title="Копировать ссылку">
📋
</button>
</div>
<div class="share-buttons">
<button class="btn btn-outline btn-small" onclick="shareToTelegram()">
<span>📱 Telegram</span>
</button>
<button class="btn btn-outline btn-small" onclick="shareToWhatsApp()">
<span>💬 WhatsApp</span>
</button>
<button class="btn btn-outline btn-small" onclick="shareGeneric()" id="share-generic-btn">
<span>🔗 Поделиться</span>
</button>
</div>
</div>
<div class="lobby-players" id="lobby-players">
<!-- Игроки будут добавлены динамически -->
</div>
<div class="lobby-info">
<span>Блайнды: <strong id="lobby-blinds">5/10</strong></span>
<span>Игроки: <strong id="lobby-player-count">1/6</strong></span>
</div>
<button class="btn btn-primary btn-large" id="start-game-btn" onclick="startMultiplayerGame()">
Начать игру
</button>
<div class="lobby-chat">
<div class="chat-messages" id="lobby-chat-messages"></div>
<div class="chat-input-row">
<input type="text" id="lobby-chat-input" class="input" placeholder="Сообщение..." onkeypress="handleLobbyChatKey(event)">
<button class="btn btn-primary" onclick="sendLobbyChat()"></button>
</div>
</div>
</div>
</div>
<!-- Игровой экран -->
<div id="game-screen" class="screen">
<div class="game-container">
<!-- Информация о столе -->
<div class="table-info">
<div class="pot-display glass-card">
<span class="pot-label">Банк</span>
<span class="pot-amount" id="pot-amount">0</span>
</div>
<div class="phase-display glass-card" id="game-phase">
Ожидание
</div>
</div>
<!-- Покерный стол -->
<div class="poker-table">
<div class="table-felt">
<!-- Общие карты -->
<div class="community-cards" id="community-cards">
<!-- Карты будут добавлены динамически -->
</div>
<!-- Позиции игроков -->
<div class="player-positions" id="player-positions">
<!-- Игроки будут добавлены динамически -->
</div>
</div>
</div>
<!-- Карты игрока -->
<div class="player-hand-container glass-card">
<div class="player-info-row">
<div class="player-name-display" id="player-name-display">Игрок</div>
<div class="player-balance-display">
<span class="balance-icon">💰</span>
<span class="balance-amount" id="player-balance">1000</span>
</div>
</div>
<div class="player-cards" id="player-cards">
<div class="card card-back"></div>
<div class="card card-back"></div>
</div>
<div class="hand-strength" id="hand-strength"></div>
</div>
<!-- Панель действий -->
<div class="action-panel glass-card" id="action-panel">
<div class="action-buttons">
<button class="btn btn-fold" onclick="playerAction('fold')">
Фолд
</button>
<button class="btn btn-check" onclick="playerAction('check')" id="btn-check">
Чек
</button>
<button class="btn btn-call" onclick="playerAction('call')" id="btn-call">
Колл <span id="call-amount"></span>
</button>
<button class="btn btn-bet" onclick="showBetSlider()" id="btn-bet">
Бет
</button>
<button class="btn btn-raise" onclick="showBetSlider()" id="btn-raise">
Рейз
</button>
<button class="btn btn-allin" onclick="playerAction('allin')">
All-In
</button>
</div>
<div class="bet-slider-container" id="bet-slider-container" style="display: none;">
<input type="range" id="bet-slider" class="bet-slider" min="0" max="1000" value="0" oninput="updateBetValue()">
<div class="bet-value-display">
<input type="number" id="bet-value" class="bet-input" value="0" onchange="updateSliderFromInput()">
</div>
<div class="bet-presets">
<button class="btn btn-small" onclick="setBetPreset(0.5)">½ Пот</button>
<button class="btn btn-small" onclick="setBetPreset(0.75)">¾ Пот</button>
<button class="btn btn-small" onclick="setBetPreset(1)">Пот</button>
</div>
<div class="bet-confirm">
<button class="btn btn-secondary" onclick="hideBetSlider()">Отмена</button>
<button class="btn btn-primary" onclick="confirmBet()">Подтвердить</button>
</div>
</div>
</div>
<!-- Чат в игре -->
<div class="game-chat glass-card" id="game-chat">
<div class="chat-header" onclick="toggleChat()">
💬 Чат
<span class="chat-toggle"></span>
</div>
<div class="chat-body">
<div class="chat-messages" id="game-chat-messages"></div>
<div class="chat-input-row">
<input type="text" id="game-chat-input" class="input" placeholder="Сообщение..." onkeypress="handleGameChatKey(event)">
<button class="btn btn-primary" onclick="sendGameChat()"></button>
</div>
</div>
</div>
<!-- Кнопки управления -->
<div class="game-controls">
<button class="btn btn-icon-only" onclick="toggleSound()">🔊</button>
<button class="btn btn-icon-only" onclick="leaveGame()">🚪</button>
</div>
<!-- Кнопка новой раздачи (для одиночной игры) -->
<button class="btn btn-primary btn-large new-hand-btn" id="new-hand-btn" style="display: none;" onclick="startNewHand()">
Новая раздача
</button>
</div>
</div>
<!-- Таблица лидеров -->
<div id="leaderboard-screen" class="screen">
<div class="glass-container menu-container">
<button class="btn-back" onclick="showScreen('main-menu')">← Назад</button>
<h2>🏆 Таблица лидеров</h2>
<div class="leaderboard-tabs">
<button class="tab active" onclick="switchLeaderboardTab('local')">Локальные</button>
<button class="tab" onclick="switchLeaderboardTab('global')">Глобальные</button>
</div>
<div class="leaderboard-list" id="leaderboard-list">
<!-- Записи будут добавлены динамически -->
</div>
<button class="btn btn-outline" onclick="clearLeaderboard()">Очистить записи</button>
</div>
</div>
<!-- Настройки -->
<div id="settings-screen" class="screen">
<div class="glass-container menu-container">
<button class="btn-back" onclick="showScreen('main-menu')">← Назад</button>
<h2>⚙️ Настройки</h2>
<div class="settings-list">
<div class="setting-item">
<span>Звуковые эффекты</span>
<label class="switch">
<input type="checkbox" id="setting-sound" checked onchange="updateSettings()">
<span class="slider"></span>
</label>
</div>
<div class="setting-item">
<span>Анимации</span>
<label class="switch">
<input type="checkbox" id="setting-animations" checked onchange="updateSettings()">
<span class="slider"></span>
</label>
</div>
<div class="setting-item">
<span>Показывать силу руки</span>
<label class="switch">
<input type="checkbox" id="setting-hand-strength" checked onchange="updateSettings()">
<span class="slider"></span>
</label>
</div>
<div class="setting-item">
<span>Автофолд при отключении</span>
<label class="switch">
<input type="checkbox" id="setting-autofold" checked onchange="updateSettings()">
<span class="slider"></span>
</label>
</div>
</div>
<h3 style="margin-top: 24px; margin-bottom: 16px;">🎴 Рубашка карт</h3>
<div class="card-back-settings">
<div class="card-back-preview">
<div class="card card-back" id="card-back-preview">
<div class="card-back-pattern"></div>
</div>
<span class="preview-label">Превью</span>
</div>
<div class="card-back-options">
<div class="form-group">
<label>Выберите стиль рубашки</label>
<div class="btn-group card-back-styles">
<button class="btn btn-option active" data-style="default" onclick="selectCardBack(this)">🎰 Классика</button>
<button class="btn btn-option" data-style="red" onclick="selectCardBack(this)">🔴 Красная</button>
<button class="btn btn-option" data-style="blue" onclick="selectCardBack(this)">🔵 Синяя</button>
<button class="btn btn-option" data-style="custom" onclick="selectCardBack(this)">🖼️ Своя</button>
</div>
</div>
<div class="form-group" id="custom-card-back-group" style="display: none;">
<label>Загрузить изображение</label>
<input type="file" id="card-back-file" class="input" accept="image/*" onchange="loadCustomCardBack(this)">
<small style="color: var(--text-muted); display: block; margin-top: 4px;">Рекомендуемый размер: 70×100 px</small>
</div>
<div class="form-group" id="card-back-url-group" style="display: none;">
<label>Или вставьте URL изображения</label>
<input type="text" id="card-back-url" class="input" placeholder="https://example.com/card-back.png" onchange="setCardBackUrl(this.value)">
</div>
</div>
</div>
<div class="form-group admin-only" id="server-url-group" style="display: none;">
<label>Сервер WebSocket</label>
<input type="text" id="server-url" class="input" value="ws://localhost:3000" onchange="updateSettings()">
</div>
<!-- LLM статус (только чтение для пользователей) -->
<div class="llm-status-box" id="llm-status-box">
<span class="llm-status-icon" id="llm-status-icon">🤖</span>
<span id="llm-status-text">LLM чат: загрузка...</span>
</div>
<!-- Кнопка настройки LLM для админа -->
<div class="admin-only" id="admin-llm-button-group" style="display: none; margin-top: 12px;">
<button class="btn btn-primary" onclick="showScreen('admin-screen')">
👑 Настроить LLM (Админ-панель)
</button>
</div>
<div style="margin-top: 16px;"></div>
<button class="btn btn-outline" onclick="resetSettings()">Сбросить настройки</button>
</div>
</div>
<!-- Админ-панель -->
<div id="admin-screen" class="screen">
<div class="glass-container admin-container">
<button class="btn-back" onclick="showScreen('main-menu')">← Назад</button>
<h2>👑 Админ-панель</h2>
<div class="admin-tabs">
<button class="btn btn-tab active" onclick="switchAdminTab('settings')">⚙️ Настройки</button>
<button class="btn btn-tab" onclick="switchAdminTab('logs')">📋 Логи</button>
<button class="btn btn-tab" onclick="switchAdminTab('users')">👥 Пользователи</button>
</div>
<!-- Вкладка настроек -->
<div id="admin-tab-settings" class="admin-tab-content">
<h3>🤖 Настройки LLM чата</h3>
<div class="settings-list">
<div class="setting-item">
<span>Включить LLM чат для всех</span>
<label class="switch">
<input type="checkbox" id="admin-llm-enabled" onchange="saveAdminSettings()">
<span class="slider"></span>
</label>
</div>
</div>
<div class="form-group">
<label>LLM провайдер</label>
<select id="admin-llm-provider" class="input" onchange="saveAdminSettings()">
<option value="ollama">Ollama</option>
<option value="lmstudio">LM Studio</option>
<option value="openai">OpenAI</option>
</select>
</div>
<div class="form-group">
<label>URL API</label>
<input type="text" id="admin-llm-url" class="input" value="http://localhost:11434" onchange="saveAdminSettings()">
</div>
<div class="form-group">
<label>Модель</label>
<input type="text" id="admin-llm-model" class="input" value="llama3.2" onchange="saveAdminSettings()">
</div>
<div class="form-group">
<label>API Key (для OpenAI)</label>
<input type="password" id="admin-llm-apikey" class="input" placeholder="sk-..." onchange="saveAdminSettings()">
</div>
<button class="btn btn-secondary" onclick="testAdminLLM()">🔗 Проверить подключение</button>
</div>
<!-- Вкладка логов -->
<div id="admin-tab-logs" class="admin-tab-content" style="display: none;">
<h3>📋 История действий</h3>
<div class="log-stats" id="log-stats">
<div class="stat-item">
<span class="stat-value" id="stat-total">0</span>
<span class="stat-label">Всего</span>
</div>
<div class="stat-item">
<span class="stat-value" id="stat-today">0</span>
<span class="stat-label">Сегодня</span>
</div>
</div>
<div class="log-filters">
<select id="log-filter-type" class="input" onchange="loadLogs()">
<option value="">Все действия</option>
<option value="login">Входы</option>
<option value="register">Регистрации</option>
<option value="room_created">Создание комнат</option>
<option value="chat_message">Сообщения чата</option>
<option value="game_action">Игровые действия</option>
</select>
<button class="btn btn-secondary" onclick="loadLogs()">🔄 Обновить</button>
</div>
<div class="log-table-container">
<table class="log-table" id="log-table">
<thead>
<tr>
<th>Время</th>
<th>Пользователь</th>
<th>Действие</th>
<th>Детали</th>
</tr>
</thead>
<tbody id="log-table-body">
</tbody>
</table>
</div>
<div class="log-pagination">
<button class="btn btn-small" onclick="loadLogs(currentLogPage - 1)" id="log-prev-btn">← Назад</button>
<span id="log-page-info">Страница 1</span>
<button class="btn btn-small" onclick="loadLogs(currentLogPage + 1)" id="log-next-btn">Вперёд →</button>
</div>
</div>
<!-- Вкладка пользователей -->
<div id="admin-tab-users" class="admin-tab-content" style="display: none;">
<h3>👥 Пользователи</h3>
<p style="color: var(--text-muted);">Раздел в разработке...</p>
</div>
</div>
</div>
<!-- Результаты раздачи -->
<div id="hand-result-modal" class="modal">
<div class="modal-content glass-container">
<h3 id="result-title">Результат</h3>
<div class="result-details" id="result-details"></div>
<button class="btn btn-primary" onclick="closeResultModal()">Продолжить</button>
</div>
</div>
<!-- Уведомления -->
<div class="notifications" id="notifications"></div>
<script src="game.js"></script>
<script src="ai.js"></script>
<script src="auth.js"></script>
<script src="main.js"></script>
</body>
</html>