Spaces:
Running
Running
Upload static/match_detail.js with huggingface_hub
Browse files- static/match_detail.js +20 -23
static/match_detail.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
| 1 |
-
// === VNEWS — Match Detail UI (v5-
|
| 2 |
-
// Uses /api/proxy/bongda for fast server-side scraping
|
| 3 |
(function(){
|
| 4 |
if(window._mdLoadedV5) return;
|
| 5 |
window._mdLoadedV5 = true;
|
|
@@ -60,24 +59,27 @@
|
|
| 60 |
window.loadMatchTab=async function(tab){
|
| 61 |
if(tab!=='detail'){if(window._origLoadMatchTab)window._origLoadMatchTab.call(this,tab);return;}
|
| 62 |
document.querySelectorAll('.mo-tab').forEach(t=>t.classList.remove('active'));
|
| 63 |
-
document.querySelectorAll('.mo-tab').forEach(t=>{const txt=t.textContent||'';if(txt.includes('Chi tiết')||txt.includes('📋')||txt.includes('Thống kê')||txt.includes('Diễn biến'))t.classList.add('active');});
|
| 64 |
const el=document.getElementById('mo-body');
|
| 65 |
if(!el)return;
|
| 66 |
el.innerHTML='<div class="mdv5-no-data"><div style="display:inline-block;width:20px;height:20px;border:2px solid #333;border-top-color:#5cb87a;border-radius:50%;animation:mdv5spin .8s linear infinite"></div><div style="margin-top:8px">Đang tải...</div></div>';
|
| 67 |
const eventId=window._currentEventId;
|
|
|
|
| 68 |
if(!eventId){el.innerHTML='<div class="mdv5-warn">⚠️ Không tìm thấy mã trận đấu.</div>';return;}
|
| 69 |
|
| 70 |
try{
|
| 71 |
-
const
|
|
|
|
|
|
|
|
|
|
| 72 |
const data = await r.json();
|
| 73 |
if(data.found && data.info && data.info.home_team){
|
| 74 |
-
el.innerHTML = '<div class="mdv5-source">📡 Dữ liệu
|
| 75 |
renderMatchDetail(el, data);
|
| 76 |
}else{
|
| 77 |
-
el.innerHTML = '<div class="mdv5-warn">⚠️ Không thể tải dữ liệu.<br>Event ID: ' + esc(String(eventId)) + '<br><a href="https://bongda.com.vn/tran-dau/' + eventId + '
|
| 78 |
}
|
| 79 |
}catch(e){
|
| 80 |
-
el.innerHTML = '<div class="mdv5-warn">⚠️ Lỗi
|
| 81 |
}
|
| 82 |
};
|
| 83 |
|
|
@@ -85,7 +87,6 @@
|
|
| 85 |
const info=data.info||{};
|
| 86 |
let h='';
|
| 87 |
|
| 88 |
-
// Header
|
| 89 |
h+='<div class="mdv5-header"><div class="mdv5-teams">';
|
| 90 |
h+='<div class="mdv5-team">';
|
| 91 |
if(info.home_logo)h+='<img src="' + esc(info.home_logo) + '" alt="' + esc(info.home_team) + '">';
|
|
@@ -95,16 +96,14 @@
|
|
| 95 |
if(info.status_label){
|
| 96 |
const sl=info.status_label;let cls='finished';
|
| 97 |
if(sl==='LIVE'||sl==='H1'||sl==='H2')cls='live';
|
| 98 |
-
if(sl==='HT'||sl==='Nghỉ')cls='halftime';
|
| 99 |
h+='<span class="mdv5-status ' + cls + '">' + esc(sl) + '</span>';
|
| 100 |
}
|
| 101 |
h+='</div><div class="mdv5-team">';
|
| 102 |
if(info.away_logo)h+='<img src="' + esc(info.away_logo) + '" alt="' + esc(info.away_team) + '">';
|
| 103 |
h+='<span>' + esc(info.away_team) + '</span></div></div></div>';
|
| 104 |
|
| 105 |
-
// Tabs
|
| 106 |
const hasEvents=data.events&&data.events.length>0;
|
| 107 |
-
const hasStats=
|
| 108 |
|
| 109 |
if(hasStats||hasEvents){
|
| 110 |
h+='<div class="mdv5-tabs">';
|
|
@@ -113,10 +112,8 @@
|
|
| 113 |
h+='</div>';
|
| 114 |
}
|
| 115 |
|
| 116 |
-
// Stats tab
|
| 117 |
if(hasStats){
|
| 118 |
h+='<div id="mdv5-tab-stats" class="mdv5-tab-content" style="display:' + (hasEvents?'none':'block') + '">';
|
| 119 |
-
|
| 120 |
if(data.h2h_stats_parsed){
|
| 121 |
h+='<div class="mdv5-sec"><div class="mdv5-sec-title">📊 Tỷ lệ đối đầu</div>';
|
| 122 |
for(const label in data.h2h_stats_parsed){
|
|
@@ -125,12 +122,10 @@
|
|
| 125 |
}
|
| 126 |
h+='</div>';
|
| 127 |
}
|
| 128 |
-
|
| 129 |
if(data.prediction){
|
| 130 |
h+='<div class="mdv5-pred"><div class="mdv5-pred-title">🎯 Dự đoán</div><div class="mdv5-pred-teams">';
|
| 131 |
h+='<span>' + esc(data.prediction.home_name || '') + '</span><span class="mdv5-pred-vs">' + esc(data.prediction.result || 'VS') + '</span><span>' + esc(data.prediction.away_name || '') + '</span></div></div>';
|
| 132 |
}
|
| 133 |
-
|
| 134 |
if(data.recent_matches){
|
| 135 |
h+='<div class="mdv5-sec"><div class="mdv5-sec-title">📋 Kết quả gần nhất</div>';
|
| 136 |
data.recent_matches.slice(0,6).forEach(m=>{
|
|
@@ -141,7 +136,6 @@
|
|
| 141 |
h+='</div>';
|
| 142 |
}
|
| 143 |
|
| 144 |
-
// Events tab
|
| 145 |
if(hasEvents){
|
| 146 |
h+='<div id="mdv5-tab-events" class="mdv5-tab-content" style="display:' + (hasStats?'none':'block') + '">';
|
| 147 |
h+='<div class="mdv5-sec"><div class="mdv5-sec-title">��� Diễn biến trận đấu</div><div class="mdv5-timeline">';
|
|
@@ -155,9 +149,9 @@
|
|
| 155 |
const badge=isHome?'<span class="mdv5-ev-team home">HOME</span>':'<span class="mdv5-ev-team away">AWAY</span>';
|
| 156 |
let icon='', title='', detail='';
|
| 157 |
|
| 158 |
-
if(ev.type==='goal'){icon='⚽';title='BÀN THẮNG';detail=esc(ev.
|
| 159 |
-
else if(ev.type==='redcard'){icon='🟥';title='THỺ ĐỎ';detail=esc(ev.
|
| 160 |
-
else if(ev.type==='yellowcard'){icon='🟨';title='THỺ VÀNG';detail=esc(ev.
|
| 161 |
else if(ev.type==='substitution'){icon='↔️';title='THAY ĐỔI';detail=esc(ev.players);}
|
| 162 |
else{icon='•';detail=esc(ev.players);}
|
| 163 |
|
|
@@ -191,15 +185,18 @@
|
|
| 191 |
}
|
| 192 |
|
| 193 |
document.addEventListener('click',e=>{
|
| 194 |
-
const md=e.target.closest('.match-detail');
|
| 195 |
if(!md)return;
|
| 196 |
-
const link=md.querySelector('
|
| 197 |
if(link){
|
| 198 |
const href=link.getAttribute('href')||'';
|
| 199 |
-
const m=href.match(/\/tran-dau\/(\d+)\//);
|
| 200 |
if(m){
|
| 201 |
window._currentEventId=m[1];
|
| 202 |
-
window.
|
|
|
|
|
|
|
|
|
|
| 203 |
}
|
| 204 |
}
|
| 205 |
},true);
|
|
|
|
| 1 |
+
// === VNEWS — Match Detail UI (v5-stable)
|
|
|
|
| 2 |
(function(){
|
| 3 |
if(window._mdLoadedV5) return;
|
| 4 |
window._mdLoadedV5 = true;
|
|
|
|
| 59 |
window.loadMatchTab=async function(tab){
|
| 60 |
if(tab!=='detail'){if(window._origLoadMatchTab)window._origLoadMatchTab.call(this,tab);return;}
|
| 61 |
document.querySelectorAll('.mo-tab').forEach(t=>t.classList.remove('active'));
|
|
|
|
| 62 |
const el=document.getElementById('mo-body');
|
| 63 |
if(!el)return;
|
| 64 |
el.innerHTML='<div class="mdv5-no-data"><div style="display:inline-block;width:20px;height:20px;border:2px solid #333;border-top-color:#5cb87a;border-radius:50%;animation:mdv5spin .8s linear infinite"></div><div style="margin-top:8px">Đang tải...</div></div>';
|
| 65 |
const eventId=window._currentEventId;
|
| 66 |
+
const slug=window._currentSlug;
|
| 67 |
if(!eventId){el.innerHTML='<div class="mdv5-warn">⚠️ Không tìm thấy mã trận đấu.</div>';return;}
|
| 68 |
|
| 69 |
try{
|
| 70 |
+
const url = slug
|
| 71 |
+
? '/api/proxy/bongda?event_id=' + eventId + '&slug=' + encodeURIComponent(slug)
|
| 72 |
+
: '/api/proxy/bongda?event_id=' + eventId;
|
| 73 |
+
const r = await fetch(url, {signal: AbortSignal.timeout(25000)});
|
| 74 |
const data = await r.json();
|
| 75 |
if(data.found && data.info && data.info.home_team){
|
| 76 |
+
el.innerHTML = '<div class="mdv5-source">📡 Dữ liệu server-side nhanh</div>';
|
| 77 |
renderMatchDetail(el, data);
|
| 78 |
}else{
|
| 79 |
+
el.innerHTML = '<div class="mdv5-warn">⚠️ Không thể tải dữ liệu.<br>Event ID: ' + esc(String(eventId)) + '<br><a href="https://bongda.com.vn/tran-dau/' + eventId + '" target="_blank">Xem trên bongda.com.vn</a></div>';
|
| 80 |
}
|
| 81 |
}catch(e){
|
| 82 |
+
el.innerHTML = '<div class="mdv5-warn">⚠️ Lỗi: ' + esc(e.message) + '</div>';
|
| 83 |
}
|
| 84 |
};
|
| 85 |
|
|
|
|
| 87 |
const info=data.info||{};
|
| 88 |
let h='';
|
| 89 |
|
|
|
|
| 90 |
h+='<div class="mdv5-header"><div class="mdv5-teams">';
|
| 91 |
h+='<div class="mdv5-team">';
|
| 92 |
if(info.home_logo)h+='<img src="' + esc(info.home_logo) + '" alt="' + esc(info.home_team) + '">';
|
|
|
|
| 96 |
if(info.status_label){
|
| 97 |
const sl=info.status_label;let cls='finished';
|
| 98 |
if(sl==='LIVE'||sl==='H1'||sl==='H2')cls='live';
|
|
|
|
| 99 |
h+='<span class="mdv5-status ' + cls + '">' + esc(sl) + '</span>';
|
| 100 |
}
|
| 101 |
h+='</div><div class="mdv5-team">';
|
| 102 |
if(info.away_logo)h+='<img src="' + esc(info.away_logo) + '" alt="' + esc(info.away_team) + '">';
|
| 103 |
h+='<span>' + esc(info.away_team) + '</span></div></div></div>';
|
| 104 |
|
|
|
|
| 105 |
const hasEvents=data.events&&data.events.length>0;
|
| 106 |
+
const hasStats=data.h2h_stats_parsed||data.prediction||data.recent_matches;
|
| 107 |
|
| 108 |
if(hasStats||hasEvents){
|
| 109 |
h+='<div class="mdv5-tabs">';
|
|
|
|
| 112 |
h+='</div>';
|
| 113 |
}
|
| 114 |
|
|
|
|
| 115 |
if(hasStats){
|
| 116 |
h+='<div id="mdv5-tab-stats" class="mdv5-tab-content" style="display:' + (hasEvents?'none':'block') + '">';
|
|
|
|
| 117 |
if(data.h2h_stats_parsed){
|
| 118 |
h+='<div class="mdv5-sec"><div class="mdv5-sec-title">📊 Tỷ lệ đối đầu</div>';
|
| 119 |
for(const label in data.h2h_stats_parsed){
|
|
|
|
| 122 |
}
|
| 123 |
h+='</div>';
|
| 124 |
}
|
|
|
|
| 125 |
if(data.prediction){
|
| 126 |
h+='<div class="mdv5-pred"><div class="mdv5-pred-title">🎯 Dự đoán</div><div class="mdv5-pred-teams">';
|
| 127 |
h+='<span>' + esc(data.prediction.home_name || '') + '</span><span class="mdv5-pred-vs">' + esc(data.prediction.result || 'VS') + '</span><span>' + esc(data.prediction.away_name || '') + '</span></div></div>';
|
| 128 |
}
|
|
|
|
| 129 |
if(data.recent_matches){
|
| 130 |
h+='<div class="mdv5-sec"><div class="mdv5-sec-title">📋 Kết quả gần nhất</div>';
|
| 131 |
data.recent_matches.slice(0,6).forEach(m=>{
|
|
|
|
| 136 |
h+='</div>';
|
| 137 |
}
|
| 138 |
|
|
|
|
| 139 |
if(hasEvents){
|
| 140 |
h+='<div id="mdv5-tab-events" class="mdv5-tab-content" style="display:' + (hasStats?'none':'block') + '">';
|
| 141 |
h+='<div class="mdv5-sec"><div class="mdv5-sec-title">��� Diễn biến trận đấu</div><div class="mdv5-timeline">';
|
|
|
|
| 149 |
const badge=isHome?'<span class="mdv5-ev-team home">HOME</span>':'<span class="mdv5-ev-team away">AWAY</span>';
|
| 150 |
let icon='', title='', detail='';
|
| 151 |
|
| 152 |
+
if(ev.type==='goal'){icon='⚽';title='BÀN THẮNG';detail=esc(ev.players);}
|
| 153 |
+
else if(ev.type==='redcard'){icon='🟥';title='THỺ ĐỎ';detail=esc(ev.players);}
|
| 154 |
+
else if(ev.type==='yellowcard'){icon='🟨';title='THỺ VÀNG';detail=esc(ev.players);}
|
| 155 |
else if(ev.type==='substitution'){icon='↔️';title='THAY ĐỔI';detail=esc(ev.players);}
|
| 156 |
else{icon='•';detail=esc(ev.players);}
|
| 157 |
|
|
|
|
| 185 |
}
|
| 186 |
|
| 187 |
document.addEventListener('click',e=>{
|
| 188 |
+
const md=e.target.closest('.match-detail, .match-item');
|
| 189 |
if(!md)return;
|
| 190 |
+
const link=md.querySelector('a[href*="tran-dau"]');
|
| 191 |
if(link){
|
| 192 |
const href=link.getAttribute('href')||'';
|
| 193 |
+
const m=href.match(/\/tran-dau\/(\d+)\/(?:centre|preview)\/(.+)/);
|
| 194 |
if(m){
|
| 195 |
window._currentEventId=m[1];
|
| 196 |
+
window._currentSlug=m[2];
|
| 197 |
+
}else{
|
| 198 |
+
const m2=href.match(/\/tran-dau\/(\d+)/);
|
| 199 |
+
if(m2)window._currentEventId=m2[1];
|
| 200 |
}
|
| 201 |
}
|
| 202 |
},true);
|