bep40 commited on
Commit
74261c5
·
verified ·
1 Parent(s): de9f2e0

Upload static/match_detail.js

Browse files
Files changed (1) hide show
  1. static/match_detail.js +128 -79
static/match_detail.js CHANGED
@@ -1,6 +1,5 @@
1
  // === VNEWS — Match Detail UI ===
2
- // Renders match detail (preview, lineups, H2H) in the match overlay
3
- // Integrates with app_v2.js openMatch / loadMatchTab
4
 
5
  (function(){
6
  if(window._mdLoaded) return;
@@ -13,6 +12,16 @@
13
  s.textContent=`
14
  .md-sec{margin-bottom:14px}
15
  .md-sec-title{font-size:13px;font-weight:800;color:#5cb87a;margin-bottom:6px;padding-bottom:4px;border-bottom:1px solid #2a2a2a;display:flex;align-items:center;gap:6px}
 
 
 
 
 
 
 
 
 
 
16
  .md-preview-text{font-size:12px;color:#ccc;line-height:1.6;background:#1a1a1a;border-radius:8px;padding:10px;border-left:3px solid #2d8659;max-height:300px;overflow-y:auto}
17
  .md-lineups{display:grid;grid-template-columns:1fr 1fr;gap:10px}
18
  .md-team-box{background:#1a2a1f;border:1px solid #2a3a2a;border-radius:8px;padding:8px}
@@ -20,11 +29,29 @@
20
  .md-formation{font-size:9px;color:#888;text-align:center;margin-bottom:6px}
21
  .md-player-item{font-size:10px;color:#ccc;padding:2px 0;border-bottom:1px solid #1a2a1f}
22
  .md-h2h-item{display:flex;align-items:center;gap:6px;padding:6px;background:#1a1a1a;border-radius:6px;margin-bottom:3px;font-size:11px}
23
- .md-h2h-date{font-size:9px;color:#888;min-width:55px}
24
- .md-h2h-teams{flex:1;display:flex;align-items:center;gap:4px}
25
- .md-h2h-home{text-align:right;flex:1;color:#ddd}
26
- .md-h2h-away{text-align:left;flex:1;color:#ddd}
27
- .md-h2h-score{font-size:12px;font-weight:800;color:#f0c040;min-width:36px;text-align:center}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
28
  .md-no-data{color:#777;font-size:12px;padding:16px;text-align:center}
29
  .md-err{color:#e74c3c;font-size:12px;padding:16px;text-align:center}
30
  .mo-tab-detail{}
@@ -34,12 +61,11 @@
34
 
35
  function esc(s){return String(s||'').replace(/[&<>"']/g,function(m){return{'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;'}[m]})}
36
 
37
- // === 1. Override openMatch to always set _currentEventId and show detail tab first ===
38
  const _origOpenMatch = window.openMatch;
39
  window.openMatch = function(id){
40
  if(id) window._currentEventId = String(id);
41
  if(_origOpenMatch) _origOpenMatch.call(this, id);
42
- // Switch to detail tab
43
  setTimeout(function(){
44
  injectDetailTab();
45
  loadMatchTab('detail');
@@ -53,24 +79,19 @@
53
  if(_origLoadMatchTab) _origLoadMatchTab.call(this, tab);
54
  return;
55
  }
56
-
57
- // Update tab UI — highlight the Chi tiết tab
58
  document.querySelectorAll('.mo-tab').forEach(function(t){ t.classList.remove('active'); });
59
  document.querySelectorAll('.mo-tab').forEach(function(t){
60
  const txt = t.textContent || '';
61
  if(txt.includes('Chi tiết') || txt.includes('📋')) t.classList.add('active');
62
  });
63
-
64
  const el = document.getElementById('mo-body');
65
  if(!el) return;
66
  el.innerHTML = '<div class="md-no-data">⏳ Đang tải chi tiết trận đấu...</div>';
67
-
68
  const eventId = window._currentEventId;
69
  if(!eventId){
70
- el.innerHTML = '<div class="md-err">⚠️ Không tìm thấy mã trận đấu.<br><small>Hãy click vào một trận đấu cụ thể từ danh sách livescore.</small></div>';
71
  return;
72
  }
73
-
74
  try{
75
  const r = await fetch('/api/match/' + eventId + '/detail');
76
  if(!r.ok) throw new Error('API error ' + r.status);
@@ -86,92 +107,121 @@
86
  function renderMatchDetail(el, data){
87
  let h = '';
88
 
89
- // 1. Preview / Commentaries (raw HTML from bongda)
90
- if(data.commentaries_html && data.commentaries_html.length > 10){
91
- h += '<div class="md-sec"><div class="md-sec-title">📋 Thông tin trận đấu</div>';
92
- let clean = data.commentaries_html
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
93
  .replace(/<script[^>]*>[\s\S]*?<\/script>/gi, '')
94
  .replace(/<iframe[^>]*>[\s\S]*?<\/iframe>/gi, '')
95
  .replace(/<ins[^>]*>[\s\S]*?<\/ins>/gi, '');
96
- h += '<div class="md-preview-text">' + clean + '</div></div>';
97
- } else if(data.preview_text && data.preview_text.length > 0){
98
  h += '<div class="md-sec"><div class="md-sec-title">📋 Thông tin trận đấu</div>';
99
- h += '<div class="md-preview-text">' + data.preview_text.map(function(t){return esc(t);}).join('<br><br>') + '</div></div>';
100
  }
101
 
102
- // 2. Lineups (raw HTML)
103
- if(data.lineups_html && data.lineups_html.length > 10){
104
- h += '<div class="md-sec"><div class="md-sec-title"> Đội hình</div>';
105
- h += '<div>' + data.lineups_html.replace(/<script[^>]*>[\s\S]*?<\/script>/gi,'').replace(/<iframe[^>]*>[\s\S]*?<\/iframe>/gi,'') + '</div></div>';
106
- } else if(data.lineups && (data.lineups.home_players || data.lineups.away_players)){
107
- h += '<div class="md-sec"><div class="md-sec-title">⚽ Đội hình</div>';
108
- h += renderLineups(data.lineups) + '</div>';
 
 
 
 
 
 
 
 
 
 
109
  }
110
 
111
- // 3. H2H (raw HTML)
112
- if(data.h2h_html && data.h2h_html.length > 10){
113
- h += '<div class="md-sec"><div class="md-sec-title">🔄 Đối đầu (H2H)</div>';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
114
  h += '<div>' + data.h2h_html.replace(/<script[^>]*>[\s\S]*?<\/script>/gi,'').replace(/<iframe[^>]*>[\s\S]*?<\/iframe>/gi,'') + '</div></div>';
115
- } else if(data.h2h && data.h2h.length > 0){
116
- h += '<div class="md-sec"><div class="md-sec-title">🔄 Đối đầu (H2H)</div>';
117
- h += renderH2H(data.h2h) + '</div>';
118
  }
119
 
120
- // 4. Stats (raw HTML)
121
- if(data.stats_html && data.stats_html.length > 10){
122
- h += '<div class="md-sec"><div class="md-sec-title">📊 Thống </div>';
123
- h += '<div>' + data.stats_html.replace(/<script[^>]*>[\s\S]*?<\/script>/gi,'').replace(/<iframe[^>]*>[\s\S]*?<\/iframe>/gi,'') + '</div></div>';
 
 
 
 
 
 
 
 
 
 
 
 
124
  }
125
 
126
- // 5. Info
127
- if(data.info && Object.keys(data.info).length > 0){
128
- h += '<div class="md-sec"><div class="md-sec-title">📍 Thông tin</div>';
129
- h += '<div style="font-size:11px;color:#ccc;line-height:1.8;padding:8px;background:#1a1a1a;border-radius:8px">';
130
- if(data.info.date) h += '<div>📅 Ngày: <b>'+esc(data.info.date)+'</b></div>';
131
- if(data.info.time) h += '<div>🕐 Giờ: <b>'+esc(data.info.time)+'</b></div>';
132
- if(data.info.stadium) h += '<div>🏟 Sân: <b>'+esc(data.info.stadium)+'</b></div>';
133
- if(data.info.referee) h += '<div>👨‍⚖️ Trọng tài: <b>'+esc(data.info.referee)+'</b></div>';
134
- h += '</div></div>';
135
  }
136
 
137
  if(!h){
138
- h = '<div class="md-no-data">Chưa có chi tiết cho trận đấu này.<br><small style="color:#666">Dữ liệu sẽ cập nhật khi giải khởi tranh hoặc trận đấu bắt đầu.</small></div>';
139
  }
140
-
141
  el.innerHTML = h;
142
- // Prevent link navigation inside overlay
143
  el.querySelectorAll('a').forEach(function(a){ a.addEventListener('click', function(e){ e.preventDefault(); }); });
144
  }
145
 
146
- function renderLineups(l){
147
- let h='<div class="md-lineups">';
148
- h+='<div class="md-team-box"><div class="md-team-name">'+esc(l.home_team||'Đội nhà')+'</div>';
149
- if(l.formation) h+='<div class="md-formation">'+esc(l.formation)+'</div>';
150
- (l.home_players||[]).forEach(function(p,i){h+='<div class="md-player-item">'+(i+1)+'. '+esc(p)+'</div>';});
151
- if(l.home_subs&&l.home_subs.length){h+='<div style="font-size:9px;color:#888;margin-top:6px;font-style:italic">Dự bị:</div>';(l.home_subs||[]).forEach(function(p){h+='<div style="font-size:9px;color:#888">'+esc(p)+'</div>';});}
152
- h+='</div>';
153
- h+='<div class="md-team-box"><div class="md-team-name">'+esc(l.away_team||'Đội khách')+'</div>';
154
- if(l.away_formation) h+='<div class="md-formation">'+esc(l.away_formation)+'</div>';
155
- (l.away_players||[]).forEach(function(p,i){h+='<div class="md-player-item">'+(i+1)+'. '+esc(p)+'</div>';});
156
- if(l.away_subs&&l.away_subs.length){h+='<div style="font-size:9px;color:#888;margin-top:6px;font-style:italic">Dự bị:</div>';(l.away_subs||[]).forEach(function(p){h+='<div style="font-size:9px;color:#888">'+esc(p)+'</div>';});}
157
- h+='</div></div>';
158
- return h;
159
- }
160
-
161
- function renderH2H(matches){
162
- let h='';
163
- matches.forEach(function(m){
164
- h+='<div class="md-h2h-item">';
165
- h+='<span class="md-h2h-date">'+esc(m.date||'')+'</span>';
166
- h+='<span class="md-h2h-teams"><span class="md-h2h-home">'+esc(m.home||'')+'</span>';
167
- h+='<span class="md-h2h-score">'+esc(m.score||'vs')+'</span>';
168
- h+='<span class="md-h2h-away">'+esc(m.away||'')+'</span></span>';
169
- h+='</div>';
170
- });
171
  return h;
172
  }
173
 
174
- // === 4. Inject "Chi tiết" tab into overlay ===
175
  function injectDetailTab(){
176
  const tabs = document.querySelector('.mo-tabs');
177
  if(!tabs || document.querySelector('.mo-tab-detail')) return;
@@ -182,7 +232,7 @@
182
  tabs.insertBefore(d, tabs.firstChild);
183
  }
184
 
185
- // === 5. Intercept clicks in livescore to capture event_id ===
186
  document.addEventListener('click', function(e){
187
  const md = e.target.closest('.match-detail');
188
  if(!md) return;
@@ -194,7 +244,6 @@
194
  }
195
  }, true);
196
 
197
- // Try to inject tab on DOM ready
198
  if(document.readyState==='loading') document.addEventListener('DOMContentLoaded', function(){ setTimeout(injectDetailTab, 1000); });
199
  else setTimeout(injectDetailTab, 1000);
200
  })();
 
1
  // === VNEWS — Match Detail UI ===
2
+ // Renders match detail (pre-match info, lineups, H2H, form, stats) in the match overlay
 
3
 
4
  (function(){
5
  if(window._mdLoaded) return;
 
12
  s.textContent=`
13
  .md-sec{margin-bottom:14px}
14
  .md-sec-title{font-size:13px;font-weight:800;color:#5cb87a;margin-bottom:6px;padding-bottom:4px;border-bottom:1px solid #2a2a2a;display:flex;align-items:center;gap:6px}
15
+ .md-pre-match{background:linear-gradient(135deg,#1a2a1f,#0d1117);border:1px solid #2d8659;border-radius:10px;padding:12px;text-align:center;margin-bottom:12px}
16
+ .md-pre-league{font-size:9px;color:#5cb87a;font-weight:700;text-transform:uppercase;letter-spacing:1px;margin-bottom:6px}
17
+ .md-pre-teams{display:flex;align-items:center;justify-content:center;gap:12px}
18
+ .md-pre-team{display:flex;flex-direction:column;align-items:center;gap:4px;flex:1}
19
+ .md-pre-team img{width:32px;height:32px;object-fit:contain}
20
+ .md-pre-team span{font-size:11px;color:#ddd;text-align:center}
21
+ .md-pre-vs{font-size:18px;font-weight:900;color:#f0c040;min-width:40px;text-align:center}
22
+ .md-pre-info{display:flex;gap:12px;justify-content:center;margin-top:10px;flex-wrap:wrap}
23
+ .md-pre-info-item{font-size:10px;color:#aaa;display:flex;align-items:center;gap:3px}
24
+ .md-pre-info-item b{color:#ddd;font-size:11px}
25
  .md-preview-text{font-size:12px;color:#ccc;line-height:1.6;background:#1a1a1a;border-radius:8px;padding:10px;border-left:3px solid #2d8659;max-height:300px;overflow-y:auto}
26
  .md-lineups{display:grid;grid-template-columns:1fr 1fr;gap:10px}
27
  .md-team-box{background:#1a2a1f;border:1px solid #2a3a2a;border-radius:8px;padding:8px}
 
29
  .md-formation{font-size:9px;color:#888;text-align:center;margin-bottom:6px}
30
  .md-player-item{font-size:10px;color:#ccc;padding:2px 0;border-bottom:1px solid #1a2a1f}
31
  .md-h2h-item{display:flex;align-items:center;gap:6px;padding:6px;background:#1a1a1a;border-radius:6px;margin-bottom:3px;font-size:11px}
32
+ .md-h2h-date{font-size:9px;color:#888;min-width:55px;flex-shrink:0}
33
+ .md-h2h-league{font-size:8px;color:#666}
34
+ .md-h2h-teams{flex:1;display:flex;align-items:center;gap:4px;min-width:0}
35
+ .md-h2h-home{text-align:right;flex:1;color:#ddd;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
36
+ .md-h2h-away{text-align:left;flex:1;color:#ddd;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
37
+ .md-h2h-score{font-size:11px;font-weight:800;color:#f0c040;min-width:36px;text-align:center;flex-shrink:0}
38
+ .md-h2h-stats{display:flex;flex-direction:column;gap:4px}
39
+ .md-h2h-stat-row{display:flex;align-items:center;gap:8px;font-size:10px}
40
+ .md-h2h-stat-home{width:30px;text-align:right;color:#5cb87a;font-weight:700;flex-shrink:0}
41
+ .md-h2h-stat-label{flex:1;text-align:center;color:#888;font-size:9px}
42
+ .md-h2h-stat-away{width:30px;text-align:left;color:#e85d04;font-weight:700;flex-shrink:0}
43
+ .md-form-item{display:flex;align-items:center;gap:6px;padding:5px 6px;background:#1a1a1a;border-radius:6px;margin-bottom:2px;font-size:10px}
44
+ .md-form-result{padding:1px 5px;border-radius:3px;font-size:8px;font-weight:800;color:#fff;flex-shrink:0}
45
+ .md-form-result.T{background:#2d8659}
46
+ .md-form-result.B{background:#c0392b}
47
+ .md-form-result.H{background:#666}
48
+ .md-form-date{font-size:9px;color:#888;min-width:50px;flex-shrink:0}
49
+ .md-form-teams{flex:1;display:flex;align-items:center;gap:4px;min-width:0}
50
+ .md-form-home{text-align:right;flex:1;color:#ddd;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
51
+ .md-form-away{text-align:left;flex:1;color:#ddd;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
52
+ .md-form-score{font-size:10px;font-weight:700;color:#f0c040;min-width:30px;text-align:center;flex-shrink:0}
53
+ .md-form-section{margin-bottom:10px}
54
+ .md-form-team-label{font-size:11px;font-weight:700;color:#aaa;margin-bottom:4px}
55
  .md-no-data{color:#777;font-size:12px;padding:16px;text-align:center}
56
  .md-err{color:#e74c3c;font-size:12px;padding:16px;text-align:center}
57
  .mo-tab-detail{}
 
61
 
62
  function esc(s){return String(s||'').replace(/[&<>"']/g,function(m){return{'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;'}[m]})}
63
 
64
+ // === 1. Override openMatch to always set _currentEventId ===
65
  const _origOpenMatch = window.openMatch;
66
  window.openMatch = function(id){
67
  if(id) window._currentEventId = String(id);
68
  if(_origOpenMatch) _origOpenMatch.call(this, id);
 
69
  setTimeout(function(){
70
  injectDetailTab();
71
  loadMatchTab('detail');
 
79
  if(_origLoadMatchTab) _origLoadMatchTab.call(this, tab);
80
  return;
81
  }
 
 
82
  document.querySelectorAll('.mo-tab').forEach(function(t){ t.classList.remove('active'); });
83
  document.querySelectorAll('.mo-tab').forEach(function(t){
84
  const txt = t.textContent || '';
85
  if(txt.includes('Chi tiết') || txt.includes('📋')) t.classList.add('active');
86
  });
 
87
  const el = document.getElementById('mo-body');
88
  if(!el) return;
89
  el.innerHTML = '<div class="md-no-data">⏳ Đang tải chi tiết trận đấu...</div>';
 
90
  const eventId = window._currentEventId;
91
  if(!eventId){
92
+ el.innerHTML = '<div class="md-err">⚠️ Không tìm thấy mã trận đấu.</div>';
93
  return;
94
  }
 
95
  try{
96
  const r = await fetch('/api/match/' + eventId + '/detail');
97
  if(!r.ok) throw new Error('API error ' + r.status);
 
107
  function renderMatchDetail(el, data){
108
  let h = '';
109
 
110
+ // 0. Pre-match info card
111
+ const info = data.info || {};
112
+ if(info.home_team && info.away_team){
113
+ h += '<div class="md-pre-match">';
114
+ if(info.league) h += '<div class="md-pre-league">'+esc(info.league)+'</div>';
115
+ h += '<div class="md-pre-teams">';
116
+ h += '<div class="md-pre-team">';
117
+ if(info.home_logo) h += '<img src="'+esc(info.home_logo)+'" alt="">';
118
+ h += '<span>'+esc(info.home_team)+'</span></div>';
119
+ h += '<div class="md-pre-vs">VS</div>';
120
+ h += '<div class="md-pre-team">';
121
+ if(info.away_logo) h += '<img src="'+esc(info.away_logo)+'" alt="">';
122
+ h += '<span>'+esc(info.away_team)+'</span></div>';
123
+ h += '</div>';
124
+ if(info.date || info.time || info.stadium || info.referee){
125
+ h += '<div class="md-pre-info">';
126
+ if(info.date) h += '<span class="md-pre-info-item">📅 <b>'+esc(info.date)+'</b></span>';
127
+ if(info.time) h += '<span class="md-pre-info-item">🕐 <b>'+esc(info.time)+'</b></span>';
128
+ if(info.stadium) h += '<span class="md-pre-info-item">🏟 <b>'+esc(info.stadium)+'</b></span>';
129
+ if(info.referee) h += '<span class="md-pre-info-item">👨‍⚖️ <b>'+esc(info.referee)+'</b></span>';
130
+ h += '</div>';
131
+ }
132
+ h += '</div>';
133
+ } else if(data.pre_match_html){
134
+ let clean = data.pre_match_html
135
  .replace(/<script[^>]*>[\s\S]*?<\/script>/gi, '')
136
  .replace(/<iframe[^>]*>[\s\S]*?<\/iframe>/gi, '')
137
  .replace(/<ins[^>]*>[\s\S]*?<\/ins>/gi, '');
 
 
138
  h += '<div class="md-sec"><div class="md-sec-title">📋 Thông tin trận đấu</div>';
139
+ h += '<div class="md-preview-text">' + clean + '</div></div>';
140
  }
141
 
142
+ // 1. H2H Stats comparison
143
+ if(data.h2h_stats_parsed && Object.keys(data.h2h_stats_parsed).length > 0){
144
+ h += '<div class="md-sec"><div class="md-sec-title">📊 Thống kê đối đầu</div>';
145
+ h += '<div class="md-h2h-stats">';
146
+ const statLabels = data.h2h_stats_parsed;
147
+ for(const label in statLabels){
148
+ const s = statLabels[label];
149
+ h += '<div class="md-h2h-stat-row">';
150
+ h += '<span class="md-h2h-stat-home">'+esc(s.home)+'</span>';
151
+ h += '<span class="md-h2h-stat-label">'+esc(label)+'</span>';
152
+ h += '<span class="md-h2h-stat-away">'+esc(s.away)+'</span>';
153
+ h += '</div>';
154
+ }
155
+ h += '</div></div>';
156
+ } else if(data.h2h_stats_html && data.h2h_stats_html.length > 10){
157
+ h += '<div class="md-sec"><div class="md-sec-title">📊 Thống kê đối đầu</div>';
158
+ h += '<div>' + data.h2h_stats_html.replace(/<script[^>]*>[\s\S]*?<\/script>/gi,'').replace(/<iframe[^>]*>[\s\S]*?<\/iframe>/gi,'') + '</div></div>';
159
  }
160
 
161
+ // 2. H2H matches
162
+ if(data.h2h && data.h2h.length > 0){
163
+ h += '<div class="md-sec"><div class="md-sec-title">🔄 Lịch sử đối đầu</div>';
164
+ const h2hList = data.h2h.slice(0, 10);
165
+ h2hList.forEach(function(m){
166
+ h += '<div class="md-h2h-item">';
167
+ h += '<span class="md-h2h-date">'+esc(m.date||'')+'</span>';
168
+ if(m.league) h += '<span class="md-h2h-league">'+esc(m.league)+'</span>';
169
+ h += '<span class="md-h2h-teams">';
170
+ h += '<span class="md-h2h-home">'+esc(m.home||'')+'</span>';
171
+ h += '<span class="md-h2h-score">'+esc(m.score||'vs')+'</span>';
172
+ h += '<span class="md-h2h-away">'+esc(m.away||'')+'</span>';
173
+ h += '</span></div>';
174
+ });
175
+ h += '</div>';
176
+ } else if(data.h2h_html && data.h2h_html.length > 10){
177
+ h += '<div class="md-sec"><div class="md-sec-title">🔄 Lịch sử đối đầu</div>';
178
  h += '<div>' + data.h2h_html.replace(/<script[^>]*>[\s\S]*?<\/script>/gi,'').replace(/<iframe[^>]*>[\s\S]*?<\/iframe>/gi,'') + '</div></div>';
 
 
 
179
  }
180
 
181
+ // 3. Team form
182
+ if((data.home_form && data.home_form.length > 0) || (data.away_form && data.away_form.length > 0)){
183
+ h += '<div class="md-sec"><div class="md-sec-title">📈 Phong độ gần đây</div>';
184
+ if(data.home_form && data.home_form.length > 0){
185
+ h += '<div class="md-form-section">';
186
+ h += '<div class="md-form-team-label">🏠 Đội nhà</div>';
187
+ data.home_form.slice(0, 5).forEach(function(m){ h += renderFormItem(m); });
188
+ h += '</div>';
189
+ }
190
+ if(data.away_form && data.away_form.length > 0){
191
+ h += '<div class="md-form-section">';
192
+ h += '<div class="md-form-team-label">✈️ Đội khách</div>';
193
+ data.away_form.slice(0, 5).forEach(function(m){ h += renderFormItem(m); });
194
+ h += '</div>';
195
+ }
196
+ h += '</div>';
197
  }
198
 
199
+ // 4. Player performance stats
200
+ if(data.stats_html && data.stats_html.length > 10){
201
+ h += '<div class="md-sec"><div class="md-sec-title">🌟 Thông số cầu thủ</div>';
202
+ h += '<div>' + data.stats_html.replace(/<script[^>]*>[\s\S]*?<\/script>/gi,'').replace(/<iframe[^>]*>[\s\S]*?<\/iframe>/gi,'') + '</div></div>';
 
 
 
 
 
203
  }
204
 
205
  if(!h){
206
+ h = '<div class="md-no-data">Chưa có chi tiết cho trận đấu này.<br><small style="color:#666">Dữ liệu sẽ cập nhật khi giải khởi tranh hoặc trận đấu bắt đầu.</small></div>';
207
  }
 
208
  el.innerHTML = h;
 
209
  el.querySelectorAll('a').forEach(function(a){ a.addEventListener('click', function(e){ e.preventDefault(); }); });
210
  }
211
 
212
+ function renderFormItem(m){
213
+ let h = '<div class="md-form-item">';
214
+ if(m.result) h += '<span class="md-form-result '+esc(m.result)+'">'+esc(m.result)+'</span>';
215
+ h += '<span class="md-form-date">'+esc(m.date||'')+'</span>';
216
+ h += '<span class="md-form-teams">';
217
+ h += '<span class="md-form-home">'+esc(m.home||'')+'</span>';
218
+ h += '<span class="md-form-score">'+esc(m.score||'')+'</span>';
219
+ h += '<span class="md-form-away">'+esc(m.away||'')+'</span>';
220
+ h += '</span></div>';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
221
  return h;
222
  }
223
 
224
+ // === 4. Inject "Chi tiết" tab ===
225
  function injectDetailTab(){
226
  const tabs = document.querySelector('.mo-tabs');
227
  if(!tabs || document.querySelector('.mo-tab-detail')) return;
 
232
  tabs.insertBefore(d, tabs.firstChild);
233
  }
234
 
235
+ // === 5. Intercept clicks to capture event_id ===
236
  document.addEventListener('click', function(e){
237
  const md = e.target.closest('.match-detail');
238
  if(!md) return;
 
244
  }
245
  }, true);
246
 
 
247
  if(document.readyState==='loading') document.addEventListener('DOMContentLoaded', function(){ setTimeout(injectDetailTab, 1000); });
248
  else setTimeout(injectDetailTab, 1000);
249
  })();