<?php /** * The template for displaying a single Match */ get_header(); $match_id = get_the_ID(); // Получаем данные матча $home_team = get_post_meta($match_id, 'home_team', true) ?: 'Команда 1'; $away_team = get_post_meta($match_id, 'away_team', true) ?: 'Команда 2'; $home_score = get_post_meta($match_id, 'home_score', true) ?: '0'; $away_score = get_post_meta($match_id, 'away_score', true) ?: '0'; $match_date = get_post_meta($match_id, 'match_date', true); $match_time = get_post_meta($match_id, 'match_time', true) ?: '19:00'; $match_status = get_post_meta($match_id, 'match_status', true) ?: 'upcoming'; $match_minute = get_post_meta($match_id, 'match_minute', true) ?: '0'; $league = get_post_meta($match_id, 'match_league', true) ?: 'РПЛ'; $stadium = get_post_meta($match_id, 'match_stadium', true) ?: 'Стадион'; $video_code = get_post_meta($match_id, 'match_video_code', true); $rutube_video_id = get_post_meta($match_id, 'rutube_video_id', true); // ID видео на RUTUBE $vk_video_url = get_post_meta($match_id, 'vk_video_url', true); // Extract VK video ID from URL - extract owner_id and video_id $vk_video_id = ''; if ($vk_video_url) { // Handle video_ext.php?oid=-144147267&id=456244624 format if (preg_match('/video_ext\.php\?oid=(-?\d+)&id=(\d+)/', $vk_video_url, $m)) { $vk_video_id = $m[1] . '&id=' . $m[2]; } // Handle URLs like video--144147267_456244407 (double dash for negative owner_id) elseif (preg_match('/video(-+)(\d+)_(\d+)/', $vk_video_url, $m)) { $vk_video_id = '-' . $m[2] . '&id=' . $m[3]; } // Handle URLs like video-144147267_456244407 (single dash) elseif (preg_match('/video-(\d+)_(\d+)/', $vk_video_url, $m)) { $vk_video_id = '-' . $m[1] . '&id=' . $m[2]; } } // Логотипы $home_logo = get_team_logo_url($home_team); $away_logo = get_team_logo_url($away_team); function get_team_logo_url($team_name) { $teams = get_posts(['post_type' => 'team', 'title' => $team_name, 'posts_per_page' => 1]); if (!empty($teams) && has_post_thumbnail($teams[0]->ID)) { return get_the_post_thumbnail_url($teams[0]->ID, 'thumbnail'); } return null; } function get_team_permalink_by_name($team_name) { $teams = get_posts(['post_type' => 'team', 'title' => $team_name, 'posts_per_page' => 1]); if (!empty($teams)) return get_permalink($teams[0]->ID); return home_url('/team/' . sanitize_title($team_name) . '/'); } $home_team_url = get_team_permalink_by_name($home_team); $away_team_url = get_team_permalink_by_name($away_team); // Определяем ссылки для трансляции по лиге $stream_links = []; $rutube_category = 'sport'; // Категория RUTUBE по умолчанию $league_lower = mb_strtolower($league); if (strpos($league_lower, 'кхл') !== false || strpos($league_lower, 'хоккей') !== false) { $stream_links = [ ['title' => 'RUTUBE Хоккей', 'url' => 'https://rutube.ru/feeds/sport/hockey/', 'icon' => '🏒'], ['title' => 'Okko Спорт', 'url' => 'https://okko.tv/sport/khl', 'icon' => '🎬'], ]; $rutube_category = 'hockey'; } elseif (strpos($league_lower, 'ufc') !== false || strpos($league_lower, 'mma') !== false) { $stream_links = [ ['title' => 'RUTUBE MMA', 'url' => 'https://rutube.ru/feeds/sport/mma/', 'icon' => '🥊'], ['title' => 'UFC Fight Pass', 'url' => 'https://www.ufc.com/watch', 'icon' => '📺'], ]; $rutube_category = 'mma'; } elseif (strpos($league_lower, 'формула') !== false || strpos($league_lower, 'f1') !== false) { $stream_links = [ ['title' => 'RUTUBE F1', 'url' => 'https://rutube.ru/feeds/sport/formula1/', 'icon' => '🏎️'], ['title' => 'F1 TV', 'url' => 'https://www.formula1.com/en/f1tv.html', 'icon' => '🎬'], ]; $rutube_category = 'formula1'; } elseif (strpos($league_lower, 'бокс') !== false) { $stream_links = [ ['title' => 'RUTUBE Бокс', 'url' => 'https://rutube.ru/feeds/sport/boxing/', 'icon' => '🥊'], ['title' => 'Матч ТВ', 'url' => 'https://matchtv.ru/boxing', 'icon' => '📺'], ]; $rutube_category = 'boxing'; } elseif (strpos($league_lower, 'баскетбол') !== false || strpos($league_lower, 'nba') !== false) { $stream_links = [ ['title' => 'RUTUBE Баскетбол', 'url' => 'https://rutube.ru/feeds/sport/basketball/', 'icon' => '🏀'], ['title' => 'Матч ТВ', 'url' => 'https://matchtv.ru/basketball', 'icon' => '📺'], ]; $rutube_category = 'basketball'; } elseif (strpos($league_lower, 'теннис') !== false) { $stream_links = [ ['title' => 'RUTUBE Теннис', 'url' => 'https://rutube.ru/feeds/sport/tennis/', 'icon' => '🎾'], ['title' => 'Матч ТВ', 'url' => 'https://matchtv.ru/tennis', 'icon' => '📺'], ]; $rutube_category = 'tennis'; } elseif (strpos($league_lower, 'футбол') !== false || strpos($league_lower, 'рпл') !== false || strpos($league_lower, 'апл') !== false) { $stream_links = [ ['title' => 'RUTUBE Футбол', 'url' => 'https://rutube.ru/feeds/sport/football/', 'icon' => '⚽'], ['title' => 'Матч ТВ', 'url' => 'https://matchtv.ru/football', 'icon' => '📺'], ]; $rutube_category = 'football'; } else { $stream_links = [ ['title' => 'RUTUBE Спорт', 'url' => 'https://rutube.ru/feeds/sport/', 'icon' => '🏅'], ['title' => 'Матч ТВ', 'url' => 'https://matchtv.ru', 'icon' => '📺'], ]; } // Ссылка на прямые трансляции RUTUBE $rutube_live_url = 'https://rutube.ru/feeds/sport/live/'; ?> <div class="match-page"> <!-- Навигация --> <div class="match-nav"> <a href="<?php echo home_url('/match-center/'); ?>" class="match-nav__back">← Матч-центр</a> <span class="match-nav__date"><?php echo $match_date ? date('d.m.Y', strtotime($match_date)) : ''; ?></span> </div> <!-- Заголовок матча --> <div class="match-header"> <div class="match-header__status"> <?php if ($match_status === 'live') : ?> <span class="live-badge"><span class="live-dot"></span> LIVE</span> <span class="match-minute"><?php echo $match_minute; ?>'</span> <?php elseif ($match_status === 'finished') : ?> <span class="finished-badge">Завершён</span> <?php else : ?> <span class="upcoming-badge"> <?php echo $match_date ? date('d.m', strtotime($match_date)) : ''; ?> • <?php echo $match_time; ?> </span> <?php endif; ?> </div> <div class="match-scoreboard"> <a href="<?php echo $home_team_url; ?>" class="team-block team-block--home"> <div class="team-block__logo"> <?php if ($home_logo) : ?> <img src="<?php echo $home_logo; ?>" alt="<?php echo $home_team; ?>"> <?php else : ?> <div class="team-logo-placeholder"><?php echo mb_substr($home_team, 0, 1); ?></div> <?php endif; ?> </div> <div class="team-block__name"><?php echo $home_team; ?></div> </a> <div class="match-score"> <span class="match-score__home"><?php echo $home_score; ?></span> <span class="match-score__sep">:</span> <span class="match-score__away"><?php echo $away_score; ?></span> </div> <?php $match_time_display = get_post_meta($match_id, 'match_time_display', true); if ($match_status === 'live' && $match_time_display) : ?> <div class="match-time-live"><?php echo $match_time_display; ?></div> <?php endif; ?> <a href="<?php echo $away_team_url; ?>" class="team-block team-block--away"> <div class="team-block__name"><?php echo $away_team; ?></div> <div class="team-block__logo"> <?php if ($away_logo) : ?> <img src="<?php echo $away_logo; ?>" alt="<?php echo $away_team; ?>"> <?php else : ?> <div class="team-logo-placeholder"><?php echo mb_substr($away_team, 0, 1); ?></div> <?php endif; ?> </div> </a> </div> <div class="match-info"> <span>🏆 <?php echo $league; ?></span> <span>📍 <?php echo $stadium; ?></span> </div> </div> <!-- Табы --> <div class="match-tabs"> <button class="match-tab active" data-tab="stream">📺 Трансляция</button> <button class="match-tab" data-tab="chat">💬 Чат</button> <button class="match-tab" data-tab="events">📊 События</button> <button class="match-tab" data-tab="stats">📈 Статистика</button> </div> <!-- Контент: Трансляция (первая по умолчанию) --> <div class="match-content active" id="tab-stream"> <?php if (!empty($vk_video_id)) : ?> <!-- VK видео плеер (приоритетнее) --> <div class="vk-player" style="background:#000;border-radius:12px;overflow:hidden;margin-bottom:20px;"> <div class="vk-player__header" style="background:#1a1a2e;padding:12px 16px;"> <span style="color:#fff;font-weight:600;">🔴 VK Видео</span> </div> <div class="vk-player__embed" style="position:relative;padding-top:56.25%;"> <iframe src="https://vk.com/video_ext.php?oid=<?php echo htmlspecialchars($vk_video_id); ?>" width="100%" height="450" allow="autoplay; fullscreen" allowfullscreen style="position:absolute;top:0;left:0;width:100%;height:100%;border:none;"> </iframe> </div> </div> <?php elseif ($vk_video_url): ?> <!-- VK button hidden - iframe already shown above when vk_video_id is set <div style="background:#252540;padding:20px;border-radius:12px;text-align:center;margin-bottom:20px;"> <p style="color:#fff;margin-bottom:12px;">🎬 VK Видео</p> <a href="<?php echo esc_url($vk_video_url); ?>" target="_blank" style="background:#5181b8;color:#fff;padding:12px 24px;border-radius:8px;text-decoration:none;font-weight:600;">Открыть видео ВКонтакте</a> </div> --><?php elseif ($rutube_video_id) : ?> <!-- RUTUBE видео матча --> <div class="rutube-player"> <div class="rutube-player__header"> <span class="rutube-player__badge">🎬 Видео матча</span> </div> <div class="rutube-player__embed"> <iframe src="https://rutube.ru/play/embed/<?php echo esc_attr($rutube_video_id); ?>/" width="100%" height="450" allow="clipboard-write; autoplay" allowfullscreen> </iframe> </div> </div> <?php endif; ?> <!-- Кнопка поиска трансляции (только для админов) --> <?php if (current_user_can('manage_options')) : ?> <div class="admin-stream-controls"> <button class="find-stream-btn" data-match-id="<?php echo $match_id; ?>"> 🔍 Найти трансляцию на RUTUBE </button> <span class="find-stream-status"></span> <!-- Панель обновления счёта --> <div class="admin-score-panel"> <h4>📊 Обновить счёт</h4> <div class="score-inputs"> <input type="number" id="adminHomeScore" value="<?php echo $home_score; ?>" min="0" max="99"> <span>:</span> <input type="number" id="adminAwayScore" value="<?php echo $away_score; ?>" min="0" max="99"> </div> <div class="time-input"> <input type="text" id="adminMatchTime" value="<?php echo get_post_meta($match_id, 'match_time_display', true) ?: ''; ?>" placeholder="45'" maxlength="10"> </div> <button class="update-score-btn" data-match-id="<?php echo $match_id; ?>">💾 Сохранить</button> <span class="update-score-status"></span> </div> </div> <?php endif; ?> <?php if ($match_status === 'live' && $video_code) : ?> <!-- LIVE плеер --> <div class="live-player"> <div class="live-player__header"> <span class="live-player__badge"><span class="live-dot"></span> ПРЯМАЯ ТРАНСЛЯЦИЯ</span> <span class="live-player__viewers">👁 <?php echo rand(500, 5000); ?> смотрят</span> </div> <div class="live-player__video"> <?php echo $video_code; ?> </div> </div> <?php endif; ?> <!-- Блок трансляции --> <div class="stream-info"> <?php if ($match_status === 'upcoming') : ?> <div class="stream-info__header"> <span class="stream-info__icon">📺</span> <div class="stream-info__title">Где смотреть трансляцию</div> <div class="stream-info__time"> Начало: <?php echo $match_date ? date('d.m.Y', strtotime($match_date)) : ''; ?> в <?php echo $match_time; ?> </div> </div> <?php elseif ($match_status === 'finished') : ?> <div class="stream-info__header"> <span class="stream-info__icon">🎬</span> <div class="stream-info__title">Обзоры и повторы</div> </div> <?php else : ?> <div class="stream-info__header"> <span class="stream-info__icon">🔴</span> <div class="stream-info__title">Смотреть онлайн</div> </div> <?php endif; ?> <div class="stream-buttons"> <?php foreach ($stream_links as $link) : ?> <a href="<?php echo $link['url']; ?>" target="_blank" class="stream-btn"> <span class="stream-btn__icon"><?php echo $link['icon']; ?></span> <span class="stream-btn__title"><?php echo $link['title']; ?></span> </a> <?php endforeach; ?> </div> <!-- Прямые трансляции RUTUBE --> <div class="rutube-live-section"> <a href="<?php echo $rutube_live_url; ?>" target="_blank" class="rutube-live-btn"> <span class="rutube-live-btn__icon">🔴</span> <span class="rutube-live-btn__text"> <strong>RUTUBE</strong> <span>Прямые трансляции</span> </span> <span class="rutube-live-btn__arrow">→</span> </a> </div> <?php if ($match_status === 'upcoming') : ?> <div class="stream-reminder"> <button class="reminder-btn" data-match-id="<?php echo $match_id; ?>"> 🔔 Напомнить о трансляции </button> </div> <?php endif; ?> </div> </div> <!-- Контент: Чат --> <div class="match-content" id="tab-chat"> <div class="match-chat"> <div class="chat-messages" id="chatMessages"> <?php $comments = get_comments(['post_id' => $match_id, 'status' => 'approve', 'order' => 'ASC']); if ($comments) : foreach ($comments as $comment) : $avatar = get_avatar_url($comment->user_id ?: 0, ['size' => 40]); $time = date('H:i', strtotime($comment->comment_date)); ?> <div class="chat-message"> <img src="<?php echo esc_url($avatar); ?>" alt="" class="chat-message__avatar"> <div class="chat-message__content"> <div class="chat-message__header"> <span class="chat-message__author"><?php echo esc_html($comment->comment_author); ?></span> <span class="chat-message__time"><?php echo $time; ?></span> </div> <div class="chat-message__text"><?php echo esc_html($comment->comment_content); ?></div> </div> </div> <?php endforeach; else : ?> <div class="chat-empty"><p>💬 Начните обсуждение матча!</p></div> <?php endif; ?> </div> <form class="chat-form" id="chatForm"> <?php wp_nonce_field('match_chat_nonce', 'chat_nonce'); ?> <input type="hidden" name="match_id" value="<?php echo $match_id; ?>"> <input type="hidden" name="action" value="send_match_message"> <div class="chat-form__input-wrap"> <input type="text" name="message" id="chatInput" placeholder="Напишите сообщение..." autocomplete="off" required> <button type="submit" class="chat-form__send">➤</button> </div> </form> </div> </div> <!-- Контент: События --> <div class="match-content" id="tab-events"> <div class="events-timeline"> <?php // Auto-fetch events if not yet loaded $events = get_post_meta($match_id, '_match_events', true); if ( !$events && in_array($match_status, ['live', 'finished', 'FT', 'IN_PLAY']) ) { // Try to fetch from API if (function_exists('sj_ls_fetch_match_events')) { $fetched = sj_ls_fetch_match_events($match_id); if ($fetched) $events = wp_json_encode($fetched); } } if ($events) : $events_list = json_decode($events, true); if (is_array($events_list)) : foreach ($events_list as $event) : $team_class = $event['team'] === 'home' ? 'event-row--home' : 'event-row--away'; ?> <div class="event-row <?php echo $team_class; ?>"> <div class="event-row__time"><?php echo $event['minute']; ?>'</div> <div class="event-row__icon"><?php echo $event['icon']; ?></div> <div class="event-row__content"> <strong><?php echo $event['type']; ?></strong> <?php echo $event['player']; ?> </div> </div> <?php endforeach; endif; else : ?> <div class="no-data"><p>События матча будут добавлены позже</p></div> <?php endif; ?> </div> </div> <!-- Контент: Статистика --> <div class="match-content" id="tab-stats"> <?php $stats = get_post_meta($match_id, '_match_stats', true); $stats_data = $stats ? json_decode($stats, true) : null; if ($stats_data) : ?> <div class="stats-grid"> <?php foreach ($stats_data as $stat) : $total = $stat['home'] + $stat['away']; $home_pct = $total > 0 ? round($stat['home'] / $total * 100) : 50; ?> <div class="stat-row"> <div class="stat-row__value"><?php echo $stat['home']; ?></div> <div class="stat-row__center"> <div class="stat-row__label"><?php echo $stat['label']; ?></div> <div class="stat-row__bar"> <div class="stat-bar stat-bar--home" style="width: <?php echo $home_pct; ?>%"></div> <div class="stat-bar stat-bar--away" style="width: <?php echo 100 - $home_pct; ?>%"></div> </div> </div> <div class="stat-row__value"><?php echo $stat['away']; ?></div> </div> <?php endforeach; ?> </div> <?php else : ?> <div class="no-data"><p>Статистика будет доступна после матча</p></div> <?php endif; ?> </div> </div> <style> /* Match Page */ .match-page { max-width: 800px; margin: 0 auto; padding: 20px; } .match-nav { display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px; } .match-nav__back { color: #888; text-decoration: none; font-size: 14px; } .match-nav__back:hover { color: #ff4d4d; } .match-nav__date { color: #888; font-size: 14px; } /* Header */ .match-header { background: #1a1a2e; border-radius: 16px; padding: 24px; margin-bottom: 20px; border: 1px solid #2a2a3e; } .match-header__status { text-align: center; margin-bottom: 16px; } .live-badge { display: inline-flex; align-items: center; gap: 8px; background: #ff0000; color: #fff; padding: 6px 16px; border-radius: 20px; font-weight: 700; font-size: 14px; } .live-dot { width: 8px; height: 8px; background: #fff; border-radius: 50%; animation: pulse 1.5s infinite; } @keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.5; } } .match-minute { margin-left: 12px; color: #ff4d4d; font-weight: 700; } .finished-badge { background: #2a2a3e; color: #888; padding: 6px 16px; border-radius: 20px; font-weight: 700; } .upcoming-badge { background: #ff4d4d; color: #fff; padding: 6px 16px; border-radius: 20px; font-weight: 700; } /* Scoreboard */ .match-scoreboard { display: flex; justify-content: center; align-items: center; gap: 24px; margin-bottom: 16px; } .team-block { display: flex; flex-direction: column; align-items: center; gap: 8px; text-decoration: none; flex: 1; } .team-block__logo img { width: 64px; height: 64px; border-radius: 12px; } .team-logo-placeholder { width: 64px; height: 64px; background: linear-gradient(135deg, #ff4d4d, #ff8080); border-radius: 12px; display: flex; align-items: center; justify-content: center; font-size: 28px; font-weight: 800; color: #fff; } .team-block__name { font-size: 16px; font-weight: 700; color: #fff; text-align: center; } .match-score { display: flex; align-items: center; gap: 8px; font-size: 48px; font-weight: 900; color: #fff; } .match-score__sep { color: #444; } .match-time-live { color: #22c55e; font-size: 14px; font-weight: 600; margin-top: 4px; } .match-info { display: flex; justify-content: center; gap: 24px; color: #888; font-size: 13px; } /* Tabs */ .match-tabs { display: flex; gap: 8px; margin-bottom: 20px; flex-wrap: wrap; } .match-tab { padding: 12px 20px; background: #1a1a2e; border: 1px solid #2a2a3e; border-radius: 10px; color: #888; cursor: pointer; font-weight: 600; font-size: 14px; transition: all 0.2s; } .match-tab:hover, .match-tab.active { background: #ff4d4d; border-color: #ff4d4d; color: #fff; } .match-content { display: none; background: #1a1a2e; border-radius: 16px; padding: 20px; border: 1px solid #2a2a3e; } .match-content.active { display: block; } /* Stream Info */ .stream-info { text-align: center; padding: 20px; } .stream-info__header { margin-bottom: 24px; } .stream-info__icon { font-size: 48px; margin-bottom: 12px; } .stream-info__title { font-size: 20px; font-weight: 700; color: #fff; margin-bottom: 8px; } .stream-info__time { color: #ff4d4d; font-weight: 600; } .stream-buttons { display: flex; gap: 16px; justify-content: center; flex-wrap: wrap; margin-bottom: 24px; } .stream-btn { display: flex; flex-direction: column; align-items: center; gap: 8px; padding: 20px 32px; background: #252540; border: 1px solid #2a2a3e; border-radius: 12px; text-decoration: none; transition: all 0.2s; } .stream-btn:hover { border-color: #ff4d4d; transform: translateY(-2px); } .stream-btn__icon { font-size: 32px; } .stream-btn__title { color: #fff; font-weight: 600; } .stream-reminder { margin-top: 16px; } .reminder-btn { background: transparent; border: 1px solid #ff4d4d; color: #ff4d4d; padding: 12px 24px; border-radius: 10px; font-weight: 600; cursor: pointer; transition: all 0.2s; } .reminder-btn:hover { background: #ff4d4d; color: #fff; } /* Live Player */ .live-player { background: #000; border-radius: 12px; overflow: hidden; } .live-player__header { display: flex; justify-content: space-between; align-items: center; padding: 12px 16px; background: #1a1a2e; } .live-player__badge { display: flex; align-items: center; gap: 8px; color: #fff; font-weight: 700; font-size: 12px; text-transform: uppercase; } .live-player__viewers { color: #888; font-size: 13px; } .live-player__video { position: relative; padding-top: 56.25%; background: #000; } .live-player__video iframe { position: absolute; top: 0; left: 0; width: 100%; height: 100%; border: none; } /* Chat */ .match-chat { display: flex; flex-direction: column; height: 400px; border-radius: 12px; overflow: hidden; } .chat-messages { flex: 1; overflow-y: auto; padding: 16px; background: #252540; } .chat-message { display: flex; gap: 12px; margin-bottom: 12px; } .chat-message__avatar { width: 36px; height: 36px; border-radius: 50%; } .chat-message__content { flex: 1; } .chat-message__header { display: flex; align-items: center; gap: 8px; margin-bottom: 4px; } .chat-message__author { color: #fff; font-weight: 600; font-size: 14px; } .chat-message__time { color: #666; font-size: 12px; } .chat-message__text { color: #ccc; font-size: 14px; } .chat-empty { display: flex; align-items: center; justify-content: center; height: 100%; color: #666; } .chat-form { display: flex; padding: 12px; background: #1a1a2e; border-top: 1px solid #2a2a3e; } .chat-form__input-wrap { display: flex; flex: 1; background: #252540; border-radius: 24px; padding: 4px 16px; border: 1px solid #2a2a3e; } .chat-form__input-wrap:focus-within { border-color: #ff4d4d; } .chat-form input { flex: 1; background: transparent; border: none; outline: none; color: #fff; font-size: 14px; } .chat-form__send { background: #ff4d4d; border: none; color: #fff; padding: 8px 16px; border-radius: 20px; cursor: pointer; font-weight: 600; } /* Events */ .events-timeline { display: flex; flex-direction: column; gap: 8px; } .event-row { display: flex; align-items: center; gap: 12px; padding: 12px; background: #252540; border-radius: 8px; border-left: 3px solid transparent; } .event-row--home { border-left-color: #22c55e; } .event-row--away { border-left-color: #ff4d4d; } .event-row__time { color: #888; font-weight: 700; min-width: 40px; } .event-row__icon { font-size: 20px; } .event-row__content { color: #fff; } /* Stats */ .stats-grid { display: flex; flex-direction: column; gap: 12px; } .stat-row { display: flex; align-items: center; gap: 16px; } .stat-row__value { font-size: 20px; font-weight: 800; color: #fff; min-width: 40px; text-align: center; } .stat-row__center { flex: 1; } .stat-row__label { text-align: center; font-size: 13px; color: #888; margin-bottom: 8px; } .stat-row__bar { display: flex; height: 6px; border-radius: 3px; overflow: hidden; background: #252540; } .stat-bar--home { background: #22c55e; } .stat-bar--away { background: #ff4d4d; } .no-data { text-align: center; padding: 40px; color: #666; } /* Responsive */ @media (max-width: 600px) { .match-scoreboard { flex-direction: column; gap: 16px; } .match-score { font-size: 36px; } .team-block__logo img { width: 56px; height: 56px; } .team-logo-placeholder { width: 56px; height: 56px; font-size: 24px; } .match-info { flex-direction: column; gap: 8px; } .stream-buttons { flex-direction: column; } .stream-btn { flex-direction: row; justify-content: center; } } /* Admin controls */ .admin-stream-controls { background: #1a1a2e; border: 1px dashed #ff4d4d; border-radius: 12px; padding: 16px; margin-bottom: 20px; text-align: center; } .find-stream-btn { background: linear-gradient(135deg, #ff4d4d, #ff6b6b); border: none; color: #fff; padding: 12px 24px; border-radius: 10px; font-weight: 600; cursor: pointer; transition: all 0.2s; } .find-stream-btn:hover:not(:disabled) { transform: translateY(-2px); box-shadow: 0 4px 15px rgba(255,77,77,0.4); } .find-stream-btn:disabled { opacity: 0.6; cursor: not-allowed; } .find-stream-status { display: block; margin-top: 12px; font-size: 14px; } /* RUTUBE player */ .rutube-player { background: #000; border-radius: 12px; overflow: hidden; margin-bottom: 20px; } .rutube-player__header { background: #1a1a2e; padding: 12px 16px; } .rutube-player__badge { color: #fff; font-weight: 600; font-size: 14px; } .rutube-player__embed { position: relative; padding-top: 56.25%; } .rutube-player__embed iframe { position: absolute; top: 0; left: 0; width: 100%; height: 100%; border: none; } /* Admin score panel */ .admin-score-panel { margin-top: 20px; padding-top: 20px; border-top: 1px dashed #444; } .admin-score-panel h4 { margin: 0 0 12px; color: #fff; font-size: 14px; } .score-inputs { display: flex; align-items: center; gap: 10px; margin-bottom: 12px; } .score-inputs input { width: 60px; padding: 8px; text-align: center; font-size: 20px; font-weight: bold; background: #2a2a4e; border: 1px solid #444; border-radius: 8px; color: #fff; } .score-inputs span { font-size: 24px; color: #666; } .time-input { margin-bottom: 12px; } .time-input input { width: 100px; padding: 8px; text-align: center; background: #2a2a4e; border: 1px solid #444; border-radius: 8px; color: #fff; } .update-score-btn { background: linear-gradient(135deg, #22c55e, #16a34a); border: none; color: #fff; padding: 10px 20px; border-radius: 8px; font-weight: 600; cursor: pointer; transition: all 0.2s; } .update-score-btn:hover { transform: translateY(-2px); } .update-score-status { display: block; margin-top: 8px; font-size: 13px; } </style> <script> // Tab switching document.querySelectorAll('.match-tab').forEach(tab => { tab.addEventListener('click', function() { document.querySelectorAll('.match-tab').forEach(t => t.classList.remove('active')); document.querySelectorAll('.match-content').forEach(c => c.classList.remove('active')); this.classList.add('active'); document.getElementById('tab-' + this.dataset.tab).classList.add('active'); }); }); // Chat const chatForm = document.getElementById('chatForm'); const chatInput = document.getElementById('chatInput'); const chatMessages = document.getElementById('chatMessages'); if (chatForm) { chatForm.addEventListener('submit', function(e) { e.preventDefault(); const message = chatInput.value.trim(); if (!message) return; // Placeholder - добавляем сообщение локально const empty = chatMessages.querySelector('.chat-empty'); if (empty) empty.remove(); const msgHtml = ` <div class="chat-message"> <img src="https://placehold.co/36x36/333/fff?text=U" alt="" class="chat-message__avatar"> <div class="chat-message__content"> <div class="chat-message__header"> <span class="chat-message__author">Гость</span> <span class="chat-message__time">${new Date().toLocaleTimeString('ru-RU', {hour:'2-digit',minute:'2-digit'})}</span> </div> <div class="chat-message__text">${message.replace(/</g,'<')}</div> </div> </div> `; chatMessages.insertAdjacentHTML('beforeend', msgHtml); chatMessages.scrollTop = chatMessages.scrollHeight; chatInput.value = ''; }); chatMessages.scrollTop = chatMessages.scrollHeight; } // Найти трансляцию на RUTUBE const findStreamBtn = document.querySelector('.find-stream-btn'); if (findStreamBtn) { findStreamBtn.addEventListener('click', function() { const btn = this; const matchId = btn.dataset.matchId; const status = document.querySelector('.find-stream-status'); btn.disabled = true; btn.textContent = '⏳ Поиск...'; status.textContent = ''; fetch('<?php echo admin_url('admin-ajax.php'); ?>', { method: 'POST', headers: {'Content-Type': 'application/x-www-form-urlencoded'}, body: 'action=rutube_find_video&match_id=' + matchId }) .then(r => r.json()) .then(data => { if (data.success) { status.innerHTML = '<span style="color:#22c55e">✅ Видео найдено! Обновите страницу.</span>'; // Автообновление через 2 секунды setTimeout(() => location.reload(), 2000); } else { status.innerHTML = '<span style="color:#ff4d4d">❌ ' + (data.data || 'Видео не найдено') + '</span>'; btn.textContent = '🔍 Найти трансляцию на RUTUBE'; btn.disabled = false; } }) .catch(err => { status.innerHTML = '<span style="color:#ff4d4d">❌ Ошибка соединения</span>'; btn.textContent = '🔍 Найти трансляцию на RUTUBE'; btn.disabled = false; }); }); } // Обновление счёта (админ) const updateScoreBtn = document.querySelector('.update-score-btn'); if (updateScoreBtn) { updateScoreBtn.addEventListener('click', function() { const btn = this; const matchId = btn.dataset.matchId; const homeScore = document.getElementById('adminHomeScore').value; const awayScore = document.getElementById('adminAwayScore').value; const matchTime = document.getElementById('adminMatchTime').value; const status = document.querySelector('.update-score-status'); btn.disabled = true; btn.textContent = '⏳ Сохранение...'; fetch('<?php echo admin_url('admin-ajax.php'); ?>', { method: 'POST', headers: {'Content-Type': 'application/x-www-form-urlencoded'}, body: 'action=update_match_score&match_id=' + matchId + '&home_score=' + homeScore + '&away_score=' + awayScore + '&match_time=' + encodeURIComponent(matchTime) }) .then(r => r.json()) .then(data => { if (data.success) { status.innerHTML = '<span style="color:#22c55e">✅ Счёт обновлён!</span>'; // Обновляем табло document.querySelector('.match-score__home').textContent = homeScore; document.querySelector('.match-score__away').textContent = awayScore; } else { status.innerHTML = '<span style="color:#ff4d4d">❌ Ошибка</span>'; } btn.textContent = '💾 Сохранить'; btn.disabled = false; }) .catch(err => { status.innerHTML = '<span style="color:#ff4d4d">❌ Ошибка соединения</span>'; btn.textContent = '💾 Сохранить'; btn.disabled = false; }); }); } // Live-обновление счёта для live-матчей (function() { const matchStatus = '<?php echo $match_status; ?>'; const matchId = <?php echo $match_id; ?>; if (matchStatus !== 'live') return; const scoreHome = document.querySelector('.match-score__home'); const scoreAway = document.querySelector('.match-score__away'); if (!scoreHome || !scoreAway) return; // Обновление каждую минуту function updateScore() { fetch(`<?php echo rest_url('rutube/v1/live-score/'); ?>${matchId}`) .then(r => r.json()) .then(data => { if (data.home_score !== undefined) { scoreHome.textContent = data.home_score; } if (data.away_score !== undefined) { scoreAway.textContent = data.away_score; } }) .catch(err => console.log('Score update failed')); } // Запускаем обновление setInterval(updateScore, 60000); // каждую минуту updateScore(); // сразу при загрузке })(); </script> <?php get_footer(); ?>