Livematch / index.php
ipnshalaby5's picture
Upload 2 files
7ab779f verified
Raw
History Blame Contribute Delete
42.1 kB
<?php
// index.php
error_reporting(0);
ini_set('display_errors', 0);
if (isset($_GET['action']) && $_GET['action'] == 'get_json') {
header('Content-Type: application/json; charset=utf-8');
header('Access-Control-Allow-Origin: *');
if (isset($_GET['type']) && $_GET['type'] === 'live') {
// يمكنك تعديل رابط المباشر هنا اذا كان لديك API مخصص للمباشر بنفس هيكل الجديد
// حالياً سنستخدم نفس المنطق ولكن يفضل توحيد المصدر
// كمثال سنستخدم نفس الرابط ولكن يجب أن يكون لديك رابط مباشر،
// أو سنعتمد على جلب بيانات اليوم ونفلترها في الجافاسكربت (وهو الأضمن حالياً لعدم توفر رابط Live منفصل في طلبك)
$reqDate = date('Y-m-d');
$apiUrl = "https://yallalive24.com/api/match.php/match.php/matches_date_get/$reqDate?key=BlackCode_Secret_2026";
} else {
$reqDate = isset($_GET['date']) ? $_GET['date'] : '';
$reqDate = preg_replace('/[^0-9\-]/', '', $reqDate);
if(empty($reqDate)) $reqDate = date('Y-m-d');
// الرابط الجديد كما طلبته
$apiUrl = "https://yallalive24.com/api/match.php/match.php/matches_date_get/$reqDate?key=BlackCode_Secret_2026";
}
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $apiUrl);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_TIMEOUT, 15);
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36');
$response = curl_exec($ch);
if ($response === false) {
echo json_encode(['status' => false, 'message' => 'Curl Error: ' . curl_error($ch)]);
} else {
echo $response;
}
curl_close($ch);
exit;
}
?>
<!DOCTYPE html>
<html lang="ar" dir="rtl">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<meta name="theme-color" content="#000000">
<meta name="description" content="جدول مباريات اليوم، نتائج مباشرة وترتيب الفرق">
<title>مباريات اليوم - Black Code</title>
<link href="https://fonts.googleapis.com/css2?family=Cairo:wght@400;600;700;800&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/flatpickr/dist/flatpickr.min.css">
<style>
:root {
/* تم تغيير الخلفية للأسود */
--bg-body: #000000;
--bg-card: #16192;
--bg-header: #1f232e;
--text-white: #ffffff;
--text-gray: #8a9099;
--color-live: #e74c3c;
--color-break: #f39c12;
--color-cancelled: #ff4757;
--color-teal: #1affc6;
--color-success: #00e676;
--color-miss: #ff1744;
--bottom-nav-height: 60px;
--radius: 12px;
}
* {
box-sizing: border-box;
-webkit-tap-highlight-color: transparent;
outline: none;
user-select: none;
}
body {
font-family: 'Cairo', sans-serif;
background-color: var(--bg-body);
color: var(--text-white);
margin: 0;
padding: 0;
font-size: 12px;
padding-bottom: calc(var(--bottom-nav-height) + 20px);
overflow-x: hidden;
}
a { text-decoration: none; color: inherit; }
.main-wrapper { max-width: 500px; margin: 0 auto; min-height: 100vh; position: relative; }
.top-navbar {
display: flex; justify-content: space-between; align-items: center;
padding: 10px 15px; background-color: var(--bg-body);
position: sticky; top: 0; z-index: 50; border-bottom: 1px solid #1a1d26;
}
.nav-logo img { height: 24px; width: auto; pointer-events: none; }
.nav-controls { display: flex; align-items: center; gap: 8px; }
.nav-btn {
background: var(--bg-header); border: 1px solid #2a2e3b; color: #ccc;
width: 32px; height: 32px; border-radius: 8px; display: flex; align-items: center; justify-content: center;
font-size: 13px; cursor: pointer; transition: 0.2s;
}
.nav-btn:active { transform: scale(0.95); background: var(--color-teal); color: #000; }
.btn-live-wrapper {
position: relative;
display: flex;
align-items: center;
justify-content: center;
background: #191c24;
border: 1px solid #2c3140;
border-radius: 20px;
padding: 4px 12px;
cursor: pointer;
transition: 0.3s;
height: 32px;
}
.btn-live-wrapper.is-live-mode {
border-color: rgba(231, 76, 60, 0.5);
box-shadow: 0 0 10px rgba(231, 76, 60, 0.2);
}
.live-content {
display: flex;
align-items: center;
gap: 6px;
font-weight: 700;
font-size: 12px;
}
.live-text {
color: var(--color-live);
text-shadow: 0 0 8px rgba(231, 76, 60, 0.6);
}
.live-icon-svg {
width: 10px;
height: 10px;
fill: var(--color-live);
animation: livePulse 1.5s infinite;
}
.btn-live-wrapper.is-all-mode {
background: var(--bg-header);
border-color: #2a2e3b;
}
.btn-live-wrapper.is-all-mode .live-text {
color: #ccc;
text-shadow: none;
}
.btn-live-wrapper.is-all-mode .live-icon-svg {
display: none;
}
@keyframes livePulse {
0% { opacity: 1; transform: scale(1); }
50% { opacity: 0.5; transform: scale(0.8); }
100% { opacity: 1; transform: scale(1); }
}
.date-header-container { display: flex; align-items: center; justify-content: space-between; padding: 12px 15px 5px 15px; }
.date-display { font-size: 14px; font-weight: 700; color: #fff; }
.today-badge { font-size: 10px; background: var(--color-break); color: #000; padding: 2px 6px; border-radius: 4px; font-weight: bold; display: none; }
.matches-container { padding: 5px 10px 20px 10px; }
.champ-block { margin-bottom: 12px; animation: fadeUp 0.4s ease; }
.champ-header {
display: flex; align-items: center; background-color: var(--bg-header);
padding: 6px 10px; border-radius: var(--radius); margin-bottom: 5px;
border: 1px solid #252936; cursor: pointer; position: relative; height: 40px;
z-index: 2;
transition: background-color 0.2s;
}
.champ-header:active { background-color: #2a2e3b; }
.champ-header img { width: 18px; height: 18px; margin-left: 10px; object-fit: contain; }
.champ-title { font-weight: 700; color: #ddd; font-size: 11px; flex: 1; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.champ-actions { padding: 5px; color: #666; font-size: 14px; position: relative; z-index: 10; display: flex; align-items: center; cursor: pointer; }
.dropdown-menu { display: none; position: absolute; left: 0; top: 30px; background: #252a36; border: 1px solid #333; border-radius: 8px; box-shadow: 0 5px 20px rgba(0,0,0,0.6); width: 160px; z-index: 50; }
.dropdown-menu.show { display: block; animation: fadeIn 0.2s; }
.dropdown-item { padding: 10px; color: #ccc; font-size: 11px; border-bottom: 1px solid #2f3442; transition: 0.2s; cursor: pointer; display: flex; align-items: center; gap: 8px; }
.match-link { display: block; width: 100%; text-decoration: none; color: inherit; }
.match-card {
background-color: var(--bg-card);
border-radius: var(--radius);
margin-bottom: 8px;
border: 1px solid #1f232e;
position: relative;
cursor: pointer;
transition: background 0.2s ease, transform 0.1s;
}
.match-card:active { background-color: #20242e; transform: scale(0.99); }
.match-card.regular-layout {
display: flex;
align-items: center;
justify-content: space-between;
min-height: 55px;
padding: 5px 8px;
}
.regular-layout .team-name-box {
flex: 1;
font-size: 11px;
font-weight: 700;
color: #eee;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.regular-layout .home-name { text-align: left; padding-left: 5px; }
.regular-layout .away-name { text-align: right; padding-right: 5px; }
.regular-layout .logo-box { width: 30px; display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
.regular-layout .team-logo { width: 26px; height: 26px; object-fit: contain; }
.regular-layout .match-center {
width: 80px;
display: flex; flex-direction: column; align-items: center; justify-content: center;
flex-shrink: 0;
}
.match-card.penalty-layout {
display: flex;
align-items: flex-start;
justify-content: space-between;
padding: 12px 8px;
}
.penalty-layout .team-col {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
min-width: 0;
gap: 6px;
}
.penalty-layout .center-col {
width: 100px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: flex-start;
padding-top: 5px;
flex-shrink: 0;
}
.penalty-layout .team-top-row { display: flex; align-items: center; gap: 8px; width: 100%; }
.penalty-layout .team-col.home .team-top-row { flex-direction: row; justify-content: flex-start; }
.penalty-layout .team-col.away .team-top-row { flex-direction: row-reverse; justify-content: flex-start; }
.penalty-layout .team-logo { width: 32px; height: 32px; object-fit: contain; }
.penalty-layout .team-name { font-size: 12px; font-weight: 700; color: #eee; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pen-label { font-size: 9px; color: #888; margin-top: 4px; margin-bottom: 2px; }
.pen-score-box {
background: #232836;
border: 1px solid #353a4a;
border-radius: 6px;
padding: 3px 10px;
font-size: 13px;
font-weight: 800;
color: var(--color-teal);
display: flex;
align-items: center;
justify-content: center;
margin-top: 2px;
min-width: 45px;
}
.pen-dots-row { display: flex; align-items: center; gap: 4px; margin-top: 5px; height: 14px; }
.penalty-layout .team-col.home .pen-dots-row { justify-content: flex-start; padding-right: 5px; }
.penalty-layout .team-col.away .pen-dots-row { justify-content: flex-end; padding-left: 5px; }
.pen-icon { font-size: 11px; }
.pen-icon.scored { color: var(--color-success); filter: drop-shadow(0 0 2px rgba(0,230,118,0.3)); }
.pen-icon.missed { color: var(--color-miss); }
.upcoming-time { font-size: 12px; font-weight: 700; color: #fff; direction: ltr; }
.status-text {
font-size: 9px;
font-weight: 700;
color: var(--text-gray);
margin-bottom: 3px;
min-height: 12px;
order: 1;
transition: color 0.3s;
}
.score-container, .score-main {
display: flex; align-items: center; justify-content: center;
font-weight: 800; color: #fff; line-height: 1;
order: 2;
}
.score-container { font-size: 18px; gap: 5px; }
.score-main { font-size: 20px; gap: 8px; margin-bottom: 4px; }
.box-live {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 100%;
}
.status-live { color: var(--color-live); }
.status-break { color: var(--color-break); }
.status-cancelled { color: var(--color-cancelled); }
.status-ended { color: var(--text-gray); }
.blink-dot { display: inline-block; width: 6px; height: 6px; background-color: var(--color-live); border-radius: 50%; margin-left: 3px; animation: blinker 1s infinite; vertical-align: middle; }
@keyframes blinker { 50% { opacity: 0; } }
@keyframes fadeUp { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } }
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
.skeleton-block { margin-bottom: 15px; }
.skeleton-header { height: 40px; background: #1f232e; border-radius: 12px; margin-bottom: 8px; position: relative; overflow: hidden; }
.skeleton-card { height: 55px; background: #161922; border-radius: 12px; margin-bottom: 8px; position: relative; overflow: hidden; }
.skeleton-header::after, .skeleton-card::after {
content: ""; position: absolute; top: 0; left: 0; width: 100%; height: 100%;
background: linear-gradient(90deg, transparent, rgba(255,255,255,0.05), transparent);
animation: loading 1.5s infinite;
}
@keyframes loading { 0% { transform: translateX(-100%); } 100% { transform: translateX(100%); } }
.bottom-nav { position: fixed; bottom: 0; left: 0; width: 100%; height: var(--bottom-nav-height); background-color: #12141a; border-top: 1px solid #1f232e; display: flex; justify-content: space-around; align-items: center; z-index: 100; padding-bottom: env(safe-area-inset-bottom); }
.nav-item { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; color: #666; text-decoration: none; height: 100%; transition: 0.2s; }
.nav-item i { font-size: 18px; margin-bottom: 4px; }
.nav-item span { font-size: 10px; font-weight: 600; }
.nav-item.active { color: var(--color-teal); }
.modal-overlay { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0, 0, 0, 0.7); z-index: 999; display: flex; align-items: flex-end; justify-content: center; opacity: 0; visibility: hidden; transition: opacity 0.3s; }
.modal-overlay.active { opacity: 1; visibility: visible; }
.modal-content { background: #11131a; width: 100%; max-width: 500px; border-radius: 20px 20px 0 0; padding: 20px; transform: translateY(100%); transition: transform 0.3s ease-out; }
.modal-overlay.active .modal-content { transform: translateY(0); }
.modal-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px; }
.modal-title { font-size: 16px; font-weight: 700; color: #eee; }
.modal-close { font-size: 20px; color: #888; cursor: pointer; }
.filter-btn { width: 100%; background-color: var(--color-teal); color: #000; border: none; padding: 12px; border-radius: 12px; font-size: 14px; font-weight: 700; cursor: pointer; margin-top: 15px; }
.flatpickr-calendar.inline { width: 100% !important; background: transparent !important; border: none !important; box-shadow: none !important; }
.flatpickr-day { color: #fff !important; border-radius: 8px !important; }
.flatpickr-day.selected { background: var(--color-teal) !important; color: #000 !important; border: none !important; font-weight: 800 !important; }
.hidden { display: none !important; }
.no-matches { text-align: center; padding-top: 80px; color: var(--text-gray); }
.no-matches i { font-size: 40px; margin-bottom: 15px; opacity: 0.3; }
.fav-icon { color: #f1c40f; font-size: 12px; margin-left: 5px; display: none; }
.is-pinned .fav-icon { display: inline-block; }
/* تنسيق الحقوق */
.black-code-rights {
text-align: center;
padding: 20px 0;
margin-bottom: 10px;
color: #888;
font-family: 'Cairo', sans-serif;
font-size: 12px;
}
.black-code-rights a {
color: #ffffff;
font-weight: bold;
text-decoration: none;
font-family: sans-serif;
}
.black-code-rights a:hover {
color: var(--color-teal);
}
</style>
</head>
<body oncontextmenu="return false;" ondragstart="return false;" onselectstart="return false;">
<div class="main-wrapper">
<div class="top-navbar">
<div class="nav-logo"><img src="https://i.imgur.com/7J6w5wR.png" alt="Logo"></div>
<div class="nav-controls">
<div class="btn-live-wrapper is-live-mode" id="live-toggle-btn" onclick="toggleLiveMode()">
<div class="live-content">
<svg class="live-icon-svg" viewBox="0 0 24 24">
<circle cx="12" cy="12" r="10" />
</svg>
<span class="live-text" id="live-btn-text">مباشر</span>
</div>
</div>
<button class="nav-btn" onclick="changeDate(-1)"><i class="fa-solid fa-chevron-right"></i></button>
<button class="nav-btn" id="calendar-trigger"><i class="fa-regular fa-calendar"></i></button>
<button class="nav-btn" onclick="changeDate(1)"><i class="fa-solid fa-chevron-left"></i></button>
</div>
</div>
<div class="date-header-container">
<div class="date-display" id="date-label">--</div>
<div class="today-badge" id="today-badge">اليوم</div>
</div>
<div class="matches-container" id="matches-wrapper"></div>
<!-- قسم الحقوق -->
<div class="black-code-rights">
صنع بواسطة
<a href="https://t.me/Black_Code2" target="_blank">𝕭𝖑𝖆𝖈𝖐 𝕮𝖔𝖉𝖊</a>
</div>
</div>
<div class="bottom-nav">
<a href="#" class="nav-item active">
<i class="fa-solid fa-futbol"></i>
<span>المباريات</span>
</a>
<a href="stdieng.php" class="nav-item">
<i class="fa-solid fa-chart-simple"></i>
<span>الترتيب</span>
</a>
<a href="news.php" class="nav-item">
<i class="fa-regular fa-newspaper"></i>
<span>الأخبار</span>
</a>
<a href="#" class="nav-item">
<i class="fa-solid fa-bars"></i>
<span>المزيد</span>
</a>
</div>
<div class="modal-overlay" id="date-modal">
<div class="modal-content">
<div class="modal-header">
<div class="modal-close" onclick="closeModal()"><i class="fa-solid fa-xmark"></i></div>
<div class="modal-title">اختر التاريخ</div>
</div>
<div id="inline-calendar-container"></div>
<button class="filter-btn" onclick="applyDateFilter()">تطبيق الفلتر</button>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/flatpickr"></script>
<script src="https://npmcdn.com/flatpickr/dist/l10n/ar.js"></script>
<script>
document.addEventListener('keydown', function(e) {
if(e.ctrlKey && (e.key === 'c' || e.key === 'v' || e.key === 'u' || e.key === 's')) e.preventDefault();
if(e.keyCode == 123) e.preventDefault();
});
let userCurrentDate = new Date();
let tempSelectedDate = new Date();
let refreshInterval, timerInterval, calendarInstance;
let currentData = [];
let isLiveMode = false;
document.addEventListener('DOMContentLoaded', () => {
initCalendar();
updatePageContent();
document.getElementById('calendar-trigger').addEventListener('click', openModal);
document.getElementById('date-modal').addEventListener('click', (e) => {
if(e.target.id === 'date-modal') closeModal();
});
document.addEventListener('click', (e) => {
if (!e.target.closest('.champ-actions')) {
document.querySelectorAll('.dropdown-menu').forEach(menu => menu.classList.remove('show'));
}
});
});
function escapeHtml(text) {
if (!text) return "";
return text
.replace(/&/g, "&amp;")
.replace(/</g, "&lt;")
.replace(/>/g, "&gt;")
.replace(/"/g, "&quot;")
.replace(/'/g, "&#039;");
}
function goToLeagueDetails(leagueId, leagueTitle) {
window.location.href = `league-details.php?id=${leagueId}&title=${encodeURIComponent(leagueTitle)}`;
}
function toggleLiveMode() {
const btnWrapper = document.getElementById('live-toggle-btn');
const btnText = document.getElementById('live-btn-text');
if (!isLiveMode) {
isLiveMode = true;
btnWrapper.classList.remove('is-live-mode');
btnWrapper.classList.add('is-all-mode');
btnText.innerText = "الكل";
document.getElementById('date-label').innerText = "مباريات جارية الآن";
document.getElementById('today-badge').style.display = "none";
loadLiveMatches();
} else {
isLiveMode = false;
btnWrapper.classList.remove('is-all-mode');
btnWrapper.classList.add('is-live-mode');
btnText.innerText = "مباشر";
updatePageContent();
}
}
function initCalendar() {
calendarInstance = flatpickr("#inline-calendar-container", {
locale: "ar", inline: true, defaultDate: userCurrentDate, disableMobile: true, dateFormat: "Y-m-d",
onChange: function(selectedDates) { tempSelectedDate = selectedDates[0]; }
});
}
function openModal() { calendarInstance.setDate(userCurrentDate); tempSelectedDate = userCurrentDate; document.getElementById('date-modal').classList.add('active'); }
function closeModal() { document.getElementById('date-modal').classList.remove('active'); }
function applyDateFilter() {
if (isLiveMode) {
isLiveMode = false;
const btnWrapper = document.getElementById('live-toggle-btn');
const btnText = document.getElementById('live-btn-text');
btnWrapper.classList.remove('is-all-mode');
btnWrapper.classList.add('is-live-mode');
btnText.innerText = "مباشر";
}
userCurrentDate = tempSelectedDate;
updatePageContent();
closeModal();
}
function changeDate(offset) {
if(isLiveMode) {
toggleLiveMode();
return;
}
userCurrentDate.setDate(userCurrentDate.getDate() + offset);
updatePageContent();
}
function updatePageContent() {
updateDateLabel();
loadMatches(formatDateForAPI(userCurrentDate));
}
function updateDateLabel() {
const options = { weekday: 'long', day: 'numeric', month: 'long', year: 'numeric' };
document.getElementById('date-label').innerText = userCurrentDate.toLocaleDateString('ar-EG', options);
const today = new Date();
const isToday = (userCurrentDate.toDateString() === today.toDateString());
document.getElementById('today-badge').style.display = isToday ? 'inline-block' : 'none';
}
function formatDateForAPI(date) {
const offset = date.getTimezoneOffset();
const d = new Date(date.getTime() - (offset*60*1000));
return d.toISOString().split('T')[0];
}
function getLeaguePrefs() { return JSON.parse(localStorage.getItem('league_prefs') || '{}'); }
function setLeaguePref(id, type) {
let prefs = getLeaguePrefs();
if (type === 'normal') delete prefs[id]; else prefs[id] = type;
localStorage.setItem('league_prefs', JSON.stringify(prefs));
renderMatches(currentData);
}
function showSkeleton() {
let html = '';
for(let i=0; i<3; i++) {
html += `<div class="skeleton-block">
<div class="skeleton-header"></div>
<div class="skeleton-card"></div>
<div class="skeleton-card"></div>
</div>`;
}
document.getElementById('matches-wrapper').innerHTML = html;
}
function loadMatches(dateStr) {
showSkeleton();
clearInterval(refreshInterval); clearInterval(timerInterval);
fetch(`?action=get_json&date=${dateStr}`).then(res => res.json()).then(json => {
// تحديث: قراءة الهيكل الجديد للبيانات (json.data.data)
if(!json.data || !json.data.data || json.data.data.length === 0) {
document.getElementById('matches-wrapper').innerHTML = `<div class="no-matches"><i class="fa-regular fa-calendar-xmark"></i><p>لا توجد مباريات في هذا اليوم</p></div>`;
currentData = [];
} else {
currentData = json.data.data;
renderMatches(currentData);
if(dateStr === formatDateForAPI(new Date())) startLiveUpdates(dateStr, false);
}
}).catch(err => { console.error(err); document.getElementById('matches-wrapper').innerHTML = `<div class="no-matches"><p>حدث خطأ في الاتصال</p></div>`; });
}
function loadLiveMatches() {
showSkeleton();
clearInterval(refreshInterval); clearInterval(timerInterval);
fetch(`?action=get_json&type=live`).then(res => res.json()).then(json => {
// تحديث: قراءة الهيكل الجديد للبيانات (json.data.data)
if(!json.data || !json.data.data || json.data.data.length === 0) {
document.getElementById('matches-wrapper').innerHTML = `<div class="no-matches"><i class="fa-solid fa-satellite-dish"></i><p>لا توجد مباريات جارية الآن</p></div>`;
currentData = [];
} else {
currentData = json.data.data;
// تصفية المباريات المباشرة في حالة جلب كل المباريات
let liveMatches = currentData.filter(m => m.status != 0 && m.status != 10 && m.status != 4);
if(liveMatches.length === 0) {
// إذا لم نفلتر أو كان الرابط يعيد الكل، نعرض الكل أو نعتمد على الفلترة
// هنا سنعرض الكل كما يأتي من الرابط إذا لم تنجح الفلترة أو إذا كان الرابط مخصصاً
}
renderMatches(currentData);
startLiveUpdates(null, true);
}
}).catch(err => {
console.error(err);
document.getElementById('matches-wrapper').innerHTML = `<div class="no-matches"><p>حدث خطأ في الاتصال</p></div>`;
});
}
function renderMatches(matches) {
const grouped = {};
matches.forEach(m => {
if(!grouped[m.championship_id]) grouped[m.championship_id] = { info: m.championship, matches: [] };
grouped[m.championship_id].matches.push(m);
});
const prefs = getLeaguePrefs();
const champIds = Object.keys(grouped);
const topLeagues = [], normalLeagues = [], bottomLeagues = [];
champIds.forEach(id => {
const status = prefs[id] || 'normal';
if (status === 'top') topLeagues.push(id);
else if (status === 'bottom') bottomLeagues.push(id);
else normalLeagues.push(id);
});
const sortedIds = [...topLeagues, ...normalLeagues, ...bottomLeagues];
let html = '';
sortedIds.forEach(id => {
const grp = grouped[id];
const cImg = `https://imgs.ysscores.com/championship/48/${grp.info.image}`;
const safeTitle = escapeHtml(grp.info.title);
const safeTitleJs = safeTitle.replace(/'/g, "\\'");
const menuId = `menu-${id}`;
const currentStatus = prefs[id] || 'normal';
const isPinned = (currentStatus === 'top') ? 'is-pinned' : '';
let menuItems = '';
const itemTop = `<div class="dropdown-item" onclick="setLeaguePref('${id}', 'top')"><i class="fa-solid fa-arrow-up"></i> ضعه في البداية</div>`;
const itemBottom = `<div class="dropdown-item" onclick="setLeaguePref('${id}', 'bottom')"><i class="fa-solid fa-arrow-down"></i> ضعه في النهاية</div>`;
const itemNormal = `<div class="dropdown-item" onclick="setLeaguePref('${id}', 'normal')"><i class="fa-solid fa-rotate-left"></i> رجوع للطبيعي</div>`;
if (currentStatus === 'top') menuItems = itemNormal + itemBottom;
else if (currentStatus === 'bottom') menuItems = itemTop + itemNormal;
else menuItems = itemTop + itemBottom;
html += `<div class="champ-block ${isPinned}">
<div class="champ-header" onclick="goToLeagueDetails('${grp.info.url_id}', '${safeTitleJs}')">
<img src="${cImg}" onerror="this.src='https://via.placeholder.com/18'">
<span class="champ-title">${safeTitle} <i class="fa-solid fa-star fav-icon"></i></span>
<div class="champ-actions" onclick="toggleMenu(event, '${menuId}')">
<i class="fa-solid fa-ellipsis"></i>
<div class="dropdown-menu" id="${menuId}">${menuItems}</div>
</div>
</div>`;
grp.matches.forEach(m => { html += buildCard(m); });
html += `</div>`;
});
document.getElementById('matches-wrapper').innerHTML = html;
updateTimers();
timerInterval = setInterval(updateTimers, 1000);
}
function getPenaltiesDots(penaltiesArr) {
if (!penaltiesArr || penaltiesArr.length === 0) return '';
let html = '';
penaltiesArr.forEach(obj => {
const val = Object.values(obj)[0];
const cls = (val == 1) ? 'scored' : 'missed';
html += `<i class="fa-solid fa-futbol pen-icon ${cls}"></i>`;
});
return html;
}
function getPenaltiesScore(pensArr) {
let score = 0;
if(pensArr) {
pensArr.forEach(obj => { score += Object.values(obj)[0]; });
}
return score;
}
function buildCard(m) {
const hImg = `https://imgs.ysscores.com/teams/64/${m.home_team.image}`;
const aImg = `https://imgs.ysscores.com/teams/64/${m.away_team.image}`;
const homeName = escapeHtml(m.home_team.title);
const awayName = escapeHtml(m.away_team.title);
let timeStr;
if (m.match_timestamp && m.match_timestamp > 0) {
let dateObj = new Date(m.match_timestamp * 1000);
timeStr = dateObj.toLocaleTimeString('en-US', {hour: '2-digit', minute:'2-digit'});
} else { timeStr = m.match_time; }
timeStr = timeStr.replace('AM', 'ص').replace('PM', 'م');
let hasPens = false;
let homeDots = '', awayDots = '';
let penScoreBox = '', penLabel = '';
if (m.penalties && Object.keys(m.penalties).length > 0) {
const homeIdStr = m.home_team.row_id.toString();
const awayIdStr = m.away_team.row_id.toString();
const homePensArr = m.penalties[homeIdStr] || [];
const awayPensArr = m.penalties[awayIdStr] || [];
if (homePensArr.length > 0 || awayPensArr.length > 0) {
hasPens = true;
homeDots = getPenaltiesDots(homePensArr);
awayDots = getPenaltiesDots(awayPensArr);
let hPenScore = getPenaltiesScore(homePensArr);
let aPenScore = getPenaltiesScore(awayPensArr);
penLabel = `<div class="pen-label">ضربات جزاء</div>`;
penScoreBox = `<div class="pen-score-box">${hPenScore} - ${aPenScore}</div>`;
}
}
const upClass = (m.status == 0) ? '' : 'hidden';
const liveClass = (m.status != 0) ? '' : 'hidden';
const exTimeVal = m.ex_time ? m.ex_time : 0;
if (hasPens) {
return `<a href="match-details.php?id=${m.match_id}" class="match-link">
<div class="match-card penalty-layout" id="card-${m.match_id}"
data-status="${m.status}"
data-ht="${m.ht_time || 0}"
data-start="${m.match_timestamp || 0}"
data-ext="${exTimeVal}">
<div class="team-col home">
<div class="team-top-row">
<div class="logo-box"><img src="${hImg}" class="team-logo"></div>
<div class="team-name">${homeName}</div>
</div>
<div class="pen-dots-row">${homeDots}</div>
</div>
<div class="center-col">
<div class="box-upcoming ${upClass}">
<span class="upcoming-time">${timeStr}</span>
</div>
<div class="box-live ${liveClass}">
<div class="status-text" id="st-${m.match_id}">--</div>
<div class="score-main">
<span id="sh-${m.match_id}">${m.home_scores}</span>
<span>-</span>
<span id="sa-${m.match_id}">${m.away_scores}</span>
</div>
${penLabel}
${penScoreBox}
</div>
</div>
<div class="team-col away">
<div class="team-top-row">
<div class="logo-box"><img src="${aImg}" class="team-logo"></div>
<div class="team-name">${awayName}</div>
</div>
<div class="pen-dots-row">${awayDots}</div>
</div>
</div>
</a>`;
}
else {
return `<a href="match-details.php?id=${m.match_id}" class="match-link">
<div class="match-card regular-layout" id="card-${m.match_id}"
data-status="${m.status}"
data-ht="${m.ht_time || 0}"
data-start="${m.match_timestamp || 0}"
data-ext="${exTimeVal}">
<div class="team-name-box home-name">${homeName}</div>
<div class="logo-box"><img src="${hImg}" class="team-logo"></div>
<div class="match-center">
<div class="box-upcoming ${upClass}">
<span class="upcoming-time">${timeStr}</span>
</div>
<div class="box-live ${liveClass}">
<div class="status-text" id="st-${m.match_id}">--</div>
<div class="score-container">
<span id="sh-${m.match_id}">${m.home_scores}</span>
<span style="font-size:12px; color:#555;">-</span>
<span id="sa-${m.match_id}">${m.away_scores}</span>
</div>
</div>
</div>
<div class="logo-box"><img src="${aImg}" class="team-logo"></div>
<div class="team-name-box away-name">${awayName}</div>
</div>
</a>`;
}
}
function toggleMenu(event, menuId) {
event.stopPropagation();
event.preventDefault();
document.querySelectorAll('.dropdown-menu').forEach(m => { if(m.id !== menuId) m.classList.remove('show'); });
document.getElementById(menuId).classList.toggle('show');
}
function startLiveUpdates(dateStr, liveMode) {
refreshInterval = setInterval(() => {
let url = `?action=get_json`;
if (liveMode) {
url += `&type=live`;
} else {
url += `&date=${dateStr}`;
}
fetch(url).then(r => r.json()).then(json => {
// تحديث: قراءة الهيكل الجديد للبيانات (json.data.data)
if(json.data && json.data.data) {
updateMatchesDOM(json.data.data);
}
});
}, 15000);
}
function updateMatchesDOM(matches) {
matches.forEach(m => {
const card = document.getElementById(`card-${m.match_id}`);
if(!card) return;
card.setAttribute('data-status', m.status);
if(m.ht_time) card.setAttribute('data-ht', m.ht_time);
if(m.ex_time) card.setAttribute('data-ext', m.ex_time);
const sh = document.getElementById(`sh-${m.match_id}`);
const sa = document.getElementById(`sa-${m.match_id}`);
if(sh && sh.innerText != m.home_scores) sh.innerText = m.home_scores;
if(sa && sa.innerText != m.away_scores) sa.innerText = m.away_scores;
const upBox = card.querySelector('.box-upcoming');
const liveBox = card.querySelector('.box-live');
if(m.status == 0) {
if(upBox) upBox.classList.remove('hidden');
if(liveBox) liveBox.classList.add('hidden');
} else {
if(upBox) upBox.classList.add('hidden');
if(liveBox) liveBox.classList.remove('hidden');
}
});
currentData = matches;
}
function updateTimers() {
const now = Math.floor(Date.now() / 1000);
document.querySelectorAll('.match-card').forEach(card => {
const status = parseInt(card.getAttribute('data-status'));
if(status === 0) return;
const mid = card.id.replace('card-', '');
const ht = parseInt(card.getAttribute('data-ht'));
const start = parseInt(card.getAttribute('data-start'));
const exTime = parseInt(card.getAttribute('data-ext')) || 0;
const stEl = document.getElementById(`st-${mid}`);
if(!stEl) return;
stEl.className = "status-text";
if (status === 10 || status === 4 || status === 8) {
stEl.innerText = "انتهت";
stEl.classList.add("status-ended");
return;
}
else if (status === 14) {
stEl.innerText = "تأجلت";
stEl.classList.add("status-break");
return;
}
else if (status === 15) {
stEl.innerText = "أُلغيت";
stEl.className = "status-text status-cancelled";
return;
}
else if (!ht && start > 0 && (now - start) > (200*60)) {
stEl.innerText = "انتهت";
stEl.classList.add("status-ended");
return;
}
let txt = "";
let cls = "status-live";
let showDot = true;
let diffSec = (ht > 0) ? (now - ht) : 0;
let minutes = Math.floor(diffSec / 60);
switch (status) {
case 1:
if (minutes >= 45) {
let extra = minutes - 45;
txt = "45+" + (extra > 0 ? extra : 1);
} else {
txt = (minutes + 1) + "'";
}
break;
case 2:
txt = "استراحة";
cls = "status-break";
showDot = false;
break;
case 3:
minutes = 46 + minutes;
if (minutes >= 90) {
let extra = minutes - 90;
txt = "90+" + (extra > 0 ? extra : 1);
} else {
txt = minutes + "'";
}
break;
case 5:
minutes = 90 + minutes + 1;
if (minutes > 105) {
let extra = minutes - 105;
txt = "105+" + extra;
} else {
txt = minutes + "'";
}
break;
case 6:
minutes = 105 + minutes + 1;
if (minutes > 120) {
let extra = minutes - 120;
txt = "120+" + extra;
} else {
txt = minutes + "'";
}
break;
case 7:
txt = "ضربات جزاء";
cls = "status-live";
showDot = true;
break;
case 55: case 66:
txt = "استراحة";
cls = "status-break";
showDot = false;
break;
default:
let totalMin = (start > 0) ? Math.floor((now - start) / 60) : 0;
txt = totalMin + "'";
break;
}
if(txt !== "") {
if (showDot) stEl.innerHTML = `<span class="blink-dot"></span> ${txt}`;
else stEl.innerText = txt;
stEl.className = `status-text ${cls}`;
} else {
stEl.innerText = "";
}
});
}
</script>
</body>
</html>