<style>
.spl-fixtures-wrap {
font-family: Arial, sans-serif;
max-width: 700px;
margin: 0 auto;
}
.spl-fixtures-wrap[dir="rtl"] { font-family: 'Segoe UI', Tahoma, Arial, sans-serif; }
.spl-section-title {
font-size: 18px;
font-weight: 700;
color: #1a1a2e;
margin-bottom: 14px;
}
.spl-day-group { margin-bottom: 20px; }
.spl-day-label {
font-size: 12px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.8px;
color: #1a6b3c;
margin-bottom: 8px;
padding-bottom: 4px;
border-bottom: 2px solid #e8f5ee;
}
.spl-fixture-card {
background: #fff;
border-radius: 10px;
box-shadow: 0 2px 8px rgba(0,0,0,0.07);
margin-bottom: 8px;
padding: 12px 16px;
display: flex;
align-items: center;
gap: 10px;
}
.spl-fixture-time {
font-size: 12px;
color: #888;
min-width: 45px;
text-align: center;
flex-shrink: 0;
}
.spl-fixture-teams {
flex: 1;
display: flex;
align-items: center;
gap: 8px;
justify-content: space-between;
}
.spl-team-block {
display: flex;
align-items: center;
gap: 6px;
flex: 1;
}
.spl-team-block.away { justify-content: flex-end; flex-direction: row-reverse; }
[dir="rtl"] .spl-team-block { flex-direction: row-reverse; }
[dir="rtl"] .spl-team-block.away { flex-direction: row; justify-content: flex-start; }
.spl-team-block img { width: 26px; height: 26px; object-fit: contain; flex-shrink: 0; }
.spl-team-name {
font-size: 13px;
font-weight: 600;
color: #222;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
max-width: 120px;
}
.spl-vs-box {
background: #f4f4f4;
color: #888;
font-size: 13px;
font-weight: 700;
padding: 6px 12px;
border-radius: 8px;
min-width: 50px;
text-align: center;
flex-shrink: 0;
}
.spl-loading { text-align: center; padding: 30px; color: #888; font-size: 14px; }
.spl-updated { font-size: 11px; color: #aaa; margin-top: 8px; text-align: right; }
[dir="rtl"] .spl-updated { text-align: left; }
@media (max-width: 480px) {
.spl-team-name { max-width: 70px; font-size: 11px; }
.spl-fixture-card { padding: 10px 8px; gap: 6px; }
}
</style>
<div class="spl-fixtures-wrap" id="spl-fixtures-root">
<div class="spl-section-title" id="spl-fix-title">...</div>
<div id="spl-fixtures-content">
<div class="spl-loading" id="spl-fix-loading">...</div>
</div>
<div class="spl-updated" id="spl-fixtures-updated"></div>
</div>
<script>
(function() {
var I18N = {
fr: {
title: 'Prochains Matchs',
loading: 'Chargement du calendrier...',
error: 'Données temporairement indisponibles.',
updated: 'Mis à jour : ',
today: "Aujourd'hui",
tomorrow:'Demain',
days: ['Dim','Lun','Mar','Mer','Jeu','Ven','Sam'],
months: ['Jan','Fév','Mar','Avr','Mai','Jun','Jul','Aoû','Sep','Oct','Nov','Déc'],
dir: 'ltr'
},
en: {
title: 'Upcoming Matches',
loading: 'Loading fixtures...',
error: 'Data temporarily unavailable.',
updated: 'Updated: ',
today: 'Today',
tomorrow:'Tomorrow',
days: ['Sun','Mon','Tue','Wed','Thu','Fri','Sat'],
months: ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'],
dir: 'ltr'
},
ar: {
title: 'المباريات القادمة',
loading: 'جاري تحميل المباريات...',
error: 'البيانات غير متوفرة مؤقتاً.',
updated: 'آخر تحديث: ',
today: 'اليوم',
tomorrow:'غداً',
days: ['الأحد','الاثنين','الثلاثاء','الأربعاء','الخميس','الجمعة','السبت'],
months: ['يناير','فبراير','مارس','أبريل','مايو','يونيو','يوليو','أغسطس','سبتمبر','أكتوبر','نوفمبر','ديسمبر'],
dir: 'rtl'
}
};
function detectLang() {
var lang = document.documentElement.lang || '';
lang = lang.toLowerCase().split('-')[0].split('_')[0];
return I18N[lang] ? lang : 'fr';
}
var lang = detectLang();
var t = I18N[lang];
var root = document.getElementById('spl-fixtures-root');
root.setAttribute('dir', t.dir);
document.getElementById('spl-fix-title').textContent = t.title;
document.getElementById('spl-fix-loading').textContent = t.loading;
function teamLogo(team) {
var logos = team.logos || [];
if (logos.length) return logos[0].href;
var tid = team.id || '';
return tid ? 'https://a.espncdn.com/i/teamlogos/soccer/500/' + tid + '.png' : '';
}
function formatDayLabel(dateStr) {
var d = new Date(dateStr + 'T12:00:00');
var today = new Date(); today.setHours(0,0,0,0);
var diff = Math.round((d - today) / 86400000);
if (diff === 0) return t.today;
if (diff === 1) return t.tomorrow;
return t.days[d.getDay()] + ' ' + d.getDate() + ' ' + t.months[d.getMonth()];
}
function loadFixtures() {
var today = new Date();
var end = new Date(today); end.setDate(end.getDate() + 60);
var fmt = function(d) { return d.getFullYear() + ('0'+(d.getMonth()+1)).slice(-2) + ('0'+d.getDate()).slice(-2); };
var url = 'https://site.api.espn.com/apis/site/v2/sports/soccer/ksa.1/scoreboard?limit=100&dates=' + fmt(today) + '-' + fmt(end);
fetch(url)
.then(function(r) { return r.json(); })
.then(function(data) {
var matches = [];
(data.events || []).forEach(function(evt) {
var comp = (evt.competitions || [{}])[0];
var competitors = comp.competitors || [];
var status = (comp.status || {}).type || {};
if (status.completed) return;
var home = competitors.find(function(c) { return c.homeAway === 'home'; }) || {};
var away = competitors.find(function(c) { return c.homeAway === 'away'; }) || {};
var homeTeam = home.team || {};
var awayTeam = away.team || {};
matches.push({
date: (evt.date || '').substring(0, 10),
time: (evt.date || '').substring(11, 16),
homeTeam: homeTeam.displayName || '',
homeLogo: teamLogo(homeTeam),
awayTeam: awayTeam.displayName || '',
awayLogo: teamLogo(awayTeam)
});
});
matches.sort(function(a,b) { return a.date.localeCompare(b.date); });
matches = matches.slice(0, 20);
if (!matches.length) {
document.getElementById('spl-fixtures-content').innerHTML = '<div class="spl-loading">' + t.error + '</div>';
return;
}
var groups = {};
matches.forEach(function(m) {
if (!groups[m.date]) groups[m.date] = [];
groups[m.date].push(m);
});
var html = '';
Object.keys(groups).sort().forEach(function(date) {
html += '<div class="spl-day-group"><div class="spl-day-label">' + formatDayLabel(date) + '</div>';
groups[date].forEach(function(m) {
var homeClass = t.dir === 'rtl' ? 'spl-team-block away' : 'spl-team-block';
var awayClass = t.dir === 'rtl' ? 'spl-team-block' : 'spl-team-block away';
html += '<div class="spl-fixture-card">'
+ '<div class="spl-fixture-time">' + m.time + '</div>'
+ '<div class="spl-fixture-teams">'
+ '<div class="' + homeClass + '">'
+ '<img src="' + m.homeLogo + '" alt="' + m.homeTeam + '" onerror="this.style.display=\'none\'">'
+ '<span class="spl-team-name">' + m.homeTeam + '</span></div>'
+ '<div class="spl-vs-box">VS</div>'
+ '<div class="' + awayClass + '">'
+ '<img src="' + m.awayLogo + '" alt="' + m.awayTeam + '" onerror="this.style.display=\'none\'">'
+ '<span class="spl-team-name">' + m.awayTeam + '</span></div>'
+ '</div></div>';
});
html += '</div>';
});
document.getElementById('spl-fixtures-content').innerHTML = html;
var now = new Date();
document.getElementById('spl-fixtures-updated').textContent =
t.updated + now.toLocaleDateString() + ' ' + now.toLocaleTimeString([], {hour:'2-digit', minute:'2-digit'});
})
.catch(function() {
document.getElementById('spl-fixtures-content').innerHTML = '<div class="spl-loading">' + t.error + '</div>';
});
}
loadFixtures();
setInterval(loadFixtures, 5 * 60 * 1000);
})();
</script>