Files
cm/templates/rooms.html
2026-02-02 19:18:25 +03:00

568 lines
22 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.
{% extends "base.html" %}
{% block title %}Комнаты - Капитал & Рынок{% endblock %}
{% block content %}
<div class="screen active">
<!-- Шапка -->
<div class="header">
<a href="{{ url_for('index') }}" class="back-button"></a>
<div class="logo-container">
<span class="logo-text" style="color: white; font-weight: bold; font-size: 1.2rem;">
💰 Комнаты
</span>
</div>
<div style="margin-left: auto;">
<span style="font-size: 0.9rem;">
{% if current_user.is_authenticated %}
{{ current_user.username }}
{% endif %}
</span>
</div>
</div>
<!-- Основной контент -->
<div class="container">
<!-- Поиск и создание комнаты -->
<div class="search-bar">
<input type="text" id="room-search" placeholder="Поиск комнат по названию..."
onkeyup="searchRooms()">
<button onclick="searchRooms()">🔍</button>
</div>
<button class="button" onclick="createRoom()" style="margin-bottom: 20px;">
Создать новую комнату
</button>
<!-- Доступные комнаты -->
<div class="card">
<h3>📢 Доступные комнаты</h3>
<div style="margin: 10px 0; color: var(--light-text); font-size: 0.9rem;">
{% if rooms %}
Найдено {{ rooms|length }} комнат
{% else %}
Нет доступных комнат
{% endif %}
</div>
<ul class="room-list" id="room-list">
{% if rooms %}
{% for room in rooms %}
<li class="room-item" onclick="joinRoom('{{ room.code }}')">
<div class="room-info">
<div class="room-avatar"
style="background-color: {% if room.status == 'waiting' %}#4caf50{% elif room.status == 'playing' %}#ff9800{% else %}#9e9e9e{% endif %};">
{{ room.player_count }}
</div>
<div style="flex: 1;">
<div style="display: flex; justify-content: space-between; align-items: center;">
<strong>{{ room.name }}</strong>
<span style="font-size: 0.8rem; color: var(--light-text);">
Месяц {{ room.current_month }}/{{ room.total_months }}
</span>
</div>
<div class="room-meta">
Создатель: {{ room.creator.username if room.creator else 'Система' }} •
Игроков: {{ room.player_count }}/{{ config.MAX_PLAYERS_PER_ROOM }}
</div>
{% if room.settings %}
<div style="margin-top: 3px;">
{% set settings = room.settings|from_json %}
{% if settings.allow_loans %}
<span style="background-color: #e3f2fd; color: #1976d2; padding: 2px 6px; border-radius: 10px; font-size: 0.75rem; margin-right: 5px;">Кредиты</span>
{% endif %}
{% if settings.allow_black_market %}
<span style="background-color: #f3e5f5; color: #7b1fa2; padding: 2px 6px; border-radius: 10px; font-size: 0.75rem;">Чёрный рынок</span>
{% endif %}
</div>
{% endif %}
</div>
</div>
<div class="room-status {{ room.status }}">
{% if room.status == 'waiting' %}
Ожидание
{% elif room.status == 'playing' %}
Игра идет
{% elif room.status == 'full' %}
Заполнена
{% else %}
{{ room.status }}
{% endif %}
</div>
</li>
{% endfor %}
{% else %}
<li style="text-align: center; padding: 20px; color: var(--light-text);">
<div style="font-size: 3rem; margin-bottom: 10px;">🏢</div>
<p>Пока нет доступных комнат</p>
<p style="font-size: 0.9rem;">Создайте первую комнату!</p>
</li>
{% endif %}
</ul>
</div>
<!-- Ваши комнаты -->
<div class="card">
<h3>⭐ Ваши комнаты</h3>
{% if user_rooms %}
<ul class="room-list" id="my-room-list">
{% for room in user_rooms %}
<li class="room-item" onclick="joinRoom('{{ room.code }}')">
<div class="room-info">
<div class="room-avatar" style="background-color: var(--primary-color);">
{{ room.player_count }}
</div>
<div style="flex: 1;">
<div style="display: flex; justify-content: space-between; align-items: center;">
<strong>{{ room.name }}</strong>
{% if room.creator_id == current_user.id %}
<span style="background-color: #fff3e0; color: #ef6c00; padding: 2px 8px; border-radius: 10px; font-size: 0.75rem;">Админ</span>
{% endif %}
</div>
<div class="room-meta">
Месяц {{ room.current_month }}/{{ room.total_months }} •
Игроков: {{ room.player_count }}/{{ config.MAX_PLAYERS_PER_ROOM }}
</div>
</div>
</div>
<div class="room-status {{ room.status }}">
{% if room.status == 'waiting' %}
Ожидание
{% elif room.status == 'playing' %}
В игре
{% else %}
{{ room.status }}
{% endif %}
</div>
</li>
{% endfor %}
</ul>
{% else %}
<div style="text-align: center; padding: 20px; color: var(--light-text);">
<div style="font-size: 3rem; margin-bottom: 10px;">👤</div>
<p>Вы пока не участвуете в комнатах</p>
<p style="font-size: 0.9rem;">Присоединитесь к существующей или создайте свою</p>
</div>
{% endif %}
</div>
<!-- Быстрые действия -->
<div class="card">
<h3>⚡ Быстрые действия</h3>
<div style="display: grid; grid-template-columns: repeat(2, 1fr); gap: 10px; margin-top: 15px;">
<button class="button secondary" onclick="createQuickRoom('Быстрая игра')">
Быстрая игра
</button>
<button class="button secondary" onclick="createQuickRoom('Для новичков')">
Для новичков
</button>
<button class="button secondary" onclick="createQuickRoom('Турнир')">
Турнир
</button>
<button class="button secondary" onclick="createQuickRoom('С друзьями')">
С друзьями
</button>
</div>
</div>
<!-- Статистика -->
{% if current_user.is_authenticated %}
<div class="card">
<h3>📊 Ваша статистика</h3>
<div style="display: grid; grid-template-columns: repeat(2, 1fr); gap: 15px; margin-top: 15px;">
<div style="text-align: center; padding: 15px; background-color: #f5f5f5; border-radius: var(--border-radius);">
<div style="font-size: 2rem; font-weight: bold; color: var(--primary-color);">{{
current_user.total_games }}
</div>
<div style="font-size: 0.9rem; color: var(--light-text);">Всего игр</div>
</div>
<div style="text-align: center; padding: 15px; background-color: #f5f5f5; border-radius: var(--border-radius);">
<div style="font-size: 2rem; font-weight: bold; color: var(--primary-color);">{{
current_user.games_won }}
</div>
<div style="font-size: 0.9rem; color: var(--light-text);">Побед</div>
</div>
<div style="text-align: center; padding: 15px; background-color: #f5f5f5; border-radius: var(--border-radius);">
<div style="font-size: 2rem; font-weight: bold; color: var(--primary-color);">
{% if current_user.total_games > 0 %}
{{ "%.1f"|format(current_user.games_won / current_user.total_games * 100) }}%
{% else %}
0%
{% endif %}
</div>
<div style="font-size: 0.9rem; color: var(--light-text);">Процент побед</div>
</div>
<div style="text-align: center; padding: 15px; background-color: #f5f5f5; border-radius: var(--border-radius);">
<div style="font-size: 2rem; font-weight: bold; color: var(--primary-color);">
{{ current_user.total_earnings|format_currency }}
</div>
<div style="font-size: 0.9rem; color: var(--light-text);">Заработано</div>
</div>
</div>
</div>
{% endif %}
</div>
</div>
<!-- Модальное окно создания комнаты -->
<div id="create-room-modal" class="modal-backdrop">
<div class="modal">
<h3>Создание комнаты</h3>
<form id="create-room-form" onsubmit="return submitRoomForm(event)">
<div class="input-group">
<label for="room-name">Название комнаты *</label>
<input type="text" id="room-name" name="name"
placeholder="Например: Быки и медведи" required>
</div>
<div class="input-group">
<label for="total-months">Длительность игры</label>
<select id="total-months" name="total_months">
<option value="6">6 месяцев (быстрая игра)</option>
<option value="12" selected>12 месяцев (стандартная)</option>
<option value="18">18 месяцев (продвинутая)</option>
<option value="24">24 месяца (экспертная)</option>
</select>
</div>
<div class="input-group">
<label for="start-capital">Стартовый капитал</label>
<input type="number" id="start-capital" name="start_capital"
value="100000" min="50000" max="1000000" step="10000">
</div>
<div class="input-group">
<label style="display: flex; align-items: center; gap: 10px;">
<input type="checkbox" id="allow-loans" name="allow_loans" checked>
<span>Разрешить кредиты</span>
</label>
</div>
<div class="input-group">
<label style="display: flex; align-items: center; gap: 10px;">
<input type="checkbox" id="allow-black-market" name="allow_black_market">
<span>Разрешить чёрный рынок</span>
</label>
</div>
<div class="input-group">
<label style="display: flex; align-items: center; gap: 10px;">
<input type="checkbox" id="private-room" name="private_room">
<span>Приватная комната (по приглашению)</span>
</label>
</div>
<div class="flex gap-2 mt-4">
<button type="submit" class="button success">Создать комнату</button>
<button type="button" onclick="hideCreateRoomModal()" class="button secondary">Отмена</button>
</div>
</form>
</div>
</div>
{% endblock %}
{% block scripts %}
<script>
// Глобальные переменные
let allRooms = [];
// Инициализация при загрузке
document.addEventListener('DOMContentLoaded', function() {
console.log('Rooms page loaded');
// Сохраняем все комнаты для поиска
const roomItems = document.querySelectorAll('.room-item');
allRooms = Array.from(roomItems).map(item => ({
name: item.querySelector('strong')?.textContent.toLowerCase() || '',
element: item
}));
// Подключение к комнате через WebSocket
if (typeof socket !== 'undefined') {
console.log('Socket connected, joining global room');
socket.emit('join_global_room');
}
});
// Поиск комнат
function searchRooms() {
const searchTerm = document.getElementById('room-search').value.toLowerCase();
const roomList = document.getElementById('room-list');
if (!roomList) return;
const rooms = roomList.querySelectorAll('.room-item');
rooms.forEach(room => {
const roomName = room.querySelector('strong')?.textContent.toLowerCase() || '';
if (roomName.includes(searchTerm) || searchTerm === '') {
room.style.display = 'flex';
} else {
room.style.display = 'none';
}
});
}
// Создание комнаты
function createRoom() {
console.log('Opening create room modal');
const modal = document.getElementById('create-room-modal');
if (modal) {
modal.classList.add('active');
document.getElementById('room-name').focus();
}
}
// Быстрое создание комнаты
function createQuickRoom(name) {
console.log('Creating quick room:', name);
// Создаем форму данных
const formData = new FormData();
formData.append('name', name);
formData.append('total_months', '12');
formData.append('start_capital', '100000');
formData.append('allow_loans', 'on');
formData.append('allow_black_market', 'off');
formData.append('private_room', 'off');
// Отправляем запрос
createRoomRequest(formData);
}
// Отправка формы создания комнаты
function submitRoomForm(event) {
console.log('Submitting room form');
event.preventDefault();
const form = document.getElementById('create-room-form');
const formData = new FormData(form);
createRoomRequest(formData);
return false;
}
// Функция для отправки запроса на создание комнаты
function createRoomRequest(formData) {
console.log('Sending create room request');
fetch('/room/create', {
method: 'POST',
body: formData,
headers: {
'Accept': 'application/json',
}
})
.then(response => {
console.log('Response status:', response.status);
console.log('Response headers:', response.headers.get('content-type'));
// Проверяем тип ответа
const contentType = response.headers.get('content-type');
if (contentType && contentType.includes('application/json')) {
return response.json();
} else {
return response.text().then(text => {
console.error('Expected JSON, got:', text.substring(0, 200));
throw new Error('Server returned HTML instead of JSON');
});
}
})
.then(data => {
console.log('Create room response:', data);
if (data.error) {
alert('Ошибка: ' + data.error);
} else if (data.redirect) {
// Редирект в лобби комнаты
window.location.href = data.redirect;
} else if (data.success) {
// Редирект по коду комнаты
window.location.href = `/room/${data.room_code}`;
} else {
alert('Неизвестный ответ от сервера');
}
})
.catch(error => {
console.error('Error creating room:', error);
alert('Ошибка при создании комнаты. Проверьте консоль для деталей.');
});
}
// Скрыть модальное окно
function hideCreateRoomModal() {
const modal = document.getElementById('create-room-modal');
if (modal) {
modal.classList.remove('active');
}
}
// Присоединение к комнате
function joinRoom(roomCode) {
console.log('Joining room:', roomCode);
window.location.href = `/room/${roomCode}`;
}
// Обновление статуса онлайн
function updateOnlineStatus() {
if (typeof socket !== 'undefined' && socket.connected) {
socket.emit('user_online', {
timestamp: new Date().toISOString()
});
}
}
// Периодическое обновление статуса
setInterval(updateOnlineStatus, 30000);
updateOnlineStatus();
// Обработка клавиши Escape для закрытия модального окна
document.addEventListener('keydown', function(event) {
if (event.key === 'Escape') {
hideCreateRoomModal();
}
});
// Закрытие модального окна при клике на фон
document.addEventListener('click', function(event) {
const modal = document.getElementById('create-room-modal');
if (modal && modal.classList.contains('active') && event.target === modal) {
hideCreateRoomModal();
}
});
</script>
<style>
/* Дополнительные стили для rooms.html */
.room-item {
cursor: pointer;
transition: all 0.3s ease;
border-radius: var(--border-radius);
margin: 5px 0;
padding: 12px;
border: 1px solid transparent;
}
.room-item:hover {
background-color: #f5f5f5;
border-color: var(--primary-color);
transform: translateX(5px);
}
.room-avatar {
width: 40px;
height: 40px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
color: white;
font-weight: bold;
font-size: 1.1rem;
margin-right: 12px;
flex-shrink: 0;
}
.room-status {
padding: 5px 10px;
border-radius: 15px;
font-size: 0.8rem;
font-weight: bold;
text-transform: uppercase;
white-space: nowrap;
}
.room-status.waiting {
background-color: #e3f2fd;
color: #1976d2;
}
.room-status.playing {
background-color: #fff3e0;
color: #ef6c00;
}
.room-status.full {
background-color: #ffebee;
color: #d32f2f;
}
.search-bar {
display: flex;
gap: 10px;
margin-bottom: 15px;
}
.search-bar input {
flex: 1;
padding: 12px;
border: 1px solid #ddd;
border-radius: var(--border-radius);
font-size: 1rem;
}
.search-bar button {
padding: 0 20px;
background-color: var(--primary-color);
color: white;
border: none;
border-radius: var(--border-radius);
cursor: pointer;
font-size: 1.1rem;
transition: background-color 0.3s;
}
.search-bar button:hover {
background-color: #0077b3;
}
.modal-backdrop {
display: none;
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.5);
align-items: center;
justify-content: center;
z-index: 1000;
}
.modal-backdrop.active {
display: flex;
}
.modal {
background-color: white;
border-radius: var(--border-radius);
padding: 20px;
max-width: 500px;
width: 90%;
max-height: 90vh;
overflow-y: auto;
box-shadow: 0 5px 20px rgba(0, 0, 0, 0.2);
}
@media (max-width: 480px) {
.room-item {
flex-direction: column;
align-items: flex-start;
}
.room-status {
align-self: flex-end;
margin-top: 10px;
}
.search-bar {
flex-direction: column;
}
.search-bar button {
width: 100%;
padding: 12px;
}
}
</style>
{% endblock %}