bep40 commited on
Commit
f244fc1
·
verified ·
1 Parent(s): fde1e7c

Upload static/wc2026_v2.js with huggingface_hub

Browse files
Files changed (1) hide show
  1. static/wc2026_v2.js +148 -0
static/wc2026_v2.js ADDED
@@ -0,0 +1,148 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // === WORLD CUP 2026 - COMPLETE: all tabs + highlights + live refresh ===
2
+ let _wc2026Data=null;let _wcRefreshInterval=null;
3
+ const WC_TEAMS={'Mexico':'🇲🇽 Mexico','Colombia':'🇨🇴 Colombia','USA':'🇺🇸 Mỹ','United States':'🇺🇸 Mỹ','Brazil':'🇧🇷 Brazil','Argentina':'🇦🇷 Argentina','Germany':'🇩🇪 Đức','France':'🇫🇷 Pháp','Spain':'🇪🇸 Tây Ban Nha','England':'🏴󠁧󠁢󠁥󠁮󠁧󠁿 Anh','Portugal':'🇵🇹 Bồ Đào Nha','Netherlands':'🇳🇱 Hà Lan','Italy':'🇮🇹 Ý','Belgium':'🇧🇪 Bỉ','Croatia':'🇭🇷 Croatia','Uruguay':'🇺🇾 Uruguay','Japan':'🇯🇵 Nhật Bản','South Korea':'🇰🇷 Hàn Quốc','Korea Republic':'🇰🇷 Hàn Quốc','Australia':'🇦🇺 Úc','Saudi Arabia':'🇸🇦 Ả Rập Xê Út','Iran':'🇮🇷 Iran','Qatar':'🇶🇦 Qatar','Canada':'🇨🇦 Canada','Morocco':'🇲🇦 Morocco','Senegal':'🇸🇳 Senegal','Ecuador':'🇪🇨 Ecuador','Serbia':'🇷🇸 Serbia','Switzerland':'🇨🇭 Thụy Sĩ','Denmark':'🇩🇰 Đan Mạch','Poland':'🇵🇱 Ba Lan','Turkey':'🇹🇷 Thổ Nhĩ Kỳ','Türkiye':'🇹🇷 Thổ Nhĩ Kỳ','Ukraine':'🇺🇦 Ukraine','Egypt':'🇪🇬 Ai Cập','Nigeria':'🇳🇬 Nigeria','Cameroon':'🇨🇲 Cameroon','Ghana':'🇬🇭 Ghana','Tunisia':'🇹🇳 Tunisia','Algeria':'🇩🇿 Algeria','South Africa':'🇿🇦 Nam Phi','Indonesia':'🇮🇩 Indonesia','Vietnam':'🇻🇳 Việt Nam','China PR':'🇨🇳 Trung Quốc','New Zealand':'🇳🇿 New Zealand','Panama':'🇵🇦 Panama','Costa Rica':'🇨🇷 Costa Rica','Jamaica':'🇯🇲 Jamaica','Honduras':'🇭🇳 Honduras','Paraguay':'🇵🇾 Paraguay','Bolivia':'🇧🇴 Bolivia','Chile':'🇨🇱 Chile','Peru':'🇵🇪 Peru','Venezuela':'🇻🇪 Venezuela','Norway':'🇳🇴 Na Uy','Sweden':'🇸🇪 Thụy Điển','Austria':'🇦🇹 Áo','Scotland':'🏴󠁧󠁢󠁳󠁣󠁴󠁿 Scotland','Wales':'🏴󠁧󠁢󠁷󠁬󠁳󠁿 Xứ Wales','Ireland':'🇮🇪 Ireland','Romania':'🇷🇴 Romania','Hungary':'🇭🇺 Hungary','Greece':'🇬🇷 Hy Lạp','Uzbekistan':'🇺🇿 Uzbekistan','Iraq':'🇮🇶 Iraq','TBD':'🏳️ TBD'};
4
+ function _t(n){return WC_TEAMS[n]||WC_TEAMS[(n||'').trim()]||'🏴 '+n;}
5
+
6
+ const WC_CSS=`<style>
7
+ .wc-bxh{max-height:460px;overflow-y:auto;padding:2px;display:block}
8
+ .wc-bxh,.wc-bxh *{box-sizing:border-box!important;float:none!important;max-width:100%!important}
9
+ .wc-bxh script,.wc-bxh style,.wc-bxh ins,.wc-bxh iframe,.wc-bxh .info,.wc-bxh .btns,.wc-bxh .form{display:none!important}
10
+ .wc-bxh .title-table,.wc-bxh h6{display:block!important;background:#0b1a2a!important;color:#f0c040!important;font-size:11px!important;font-weight:800!important;padding:6px 8px!important;margin:8px 0 0!important;border-radius:5px 5px 0 0!important;border-bottom:1px solid #1a3a5a!important}
11
+ .wc-bxh .bxh-head{display:flex!important;align-items:center!important;padding:4px 6px!important;background:#0a1320!important;color:#6a9fca!important;font-size:9px!important;font-weight:700!important;border-bottom:1px solid #1a3a5a!important}
12
+ .wc-bxh .bxh-head .h-team{flex:1!important;text-align:left!important}
13
+ .wc-bxh .bxh-head .h-stat{flex:0 0 26px!important;text-align:center!important}
14
+ .wc-bxh .bxh-head .h-pts{flex:0 0 30px!important;text-align:center!important;color:#f0c040!important}
15
+ .wc-bxh .item{display:flex!important;align-items:center!important;padding:5px 6px!important;border-bottom:1px solid #10202f!important;background:transparent!important}
16
+ .wc-bxh .item:nth-child(even){background:#0a1320!important}
17
+ .wc-bxh .item .team{flex:1!important;display:flex!important;align-items:center!important;gap:5px!important;min-width:0!important;text-align:left!important}
18
+ .wc-bxh .item .team>span{flex:0 0 16px!important;color:#6a9fca!important;font-size:10px!important;text-align:center!important}
19
+ .wc-bxh .item .team a{flex:1!important;display:flex!important;align-items:center!important;gap:5px!important;min-width:0!important;color:#eee!important;text-decoration:none!important}
20
+ .wc-bxh .item .team a p{font-size:11px!important;color:#eee!important;white-space:nowrap!important;overflow:hidden!important;text-overflow:ellipsis!important;margin:0!important}
21
+ .wc-bxh .item .copy{display:flex!important;align-items:center!important;flex:0 0 auto!important}
22
+ .wc-bxh .item .copy>p{flex:0 0 26px!important;text-align:center!important;font-size:10px!important;color:#ccc!important;margin:0!important}
23
+ .wc-bxh .item .copy>p:last-of-type,.wc-bxh .item .copy>p:nth-last-child(2){flex:0 0 30px!important}
24
+ .wc-bxh .item .copy>p strong{color:#f0c040!important;font-weight:800!important}
25
+ .wc-bxh img{width:18px!important;height:18px!important;object-fit:contain!important;vertical-align:middle!important;display:inline-block!important;flex:0 0 18px!important}
26
+ .wc-bxh strong{color:#f0c040!important}
27
+ .wc-bxh a{color:#8ab4d8!important;text-decoration:none!important}
28
+ .wc-bxh table{width:100%!important;border-collapse:collapse!important;font-size:11px!important;display:table!important}
29
+ .wc-bxh th{background:#0b1a2a!important;color:#6a9fca!important;padding:5px 3px!important;font-size:9px!important;text-align:center!important}
30
+ .wc-bxh td{padding:4px 3px!important;border-bottom:1px solid #0d1a2a!important;font-size:10px!important;color:#ddd!important}
31
+ </style>`;
32
+
33
+ function switchWCTab(tab){
34
+ document.querySelectorAll('.wc-tab').forEach(t=>t.classList.remove('active'));
35
+ document.querySelectorAll('.wc-tab').forEach(t=>{if((tab==='news'&&t.textContent.includes('Tin'))||(tab==='fixtures'&&t.textContent.includes('Lịch'))||(tab==='standings'&&t.textContent.includes('BXH'))||(tab==='highlights'&&t.textContent.includes('Highlight'))||(tab==='stats'&&t.textContent.includes('Thống')))t.classList.add('active');});
36
+ const el=document.getElementById('wc-content');if(!el)return;
37
+ if(!_wc2026Data&&tab!=='highlights'){el.innerHTML='<div class="loading">Đang tải...</div>';return;}
38
+ if(tab==='news')renderWCNews(el);
39
+ else if(tab==='fixtures')renderWCFixtures(el);
40
+ else if(tab==='standings')renderWCStandings(el);
41
+ else if(tab==='highlights')renderWCHighlights(el);
42
+ else if(tab==='stats')renderWCStats(el);
43
+ }
44
+
45
+ // === NEWS ===
46
+ function renderWCNews(el){
47
+ const news=_wc2026Data.news||[];const road=_wc2026Data.road||[];
48
+ const combined=[];let ni=0,ri=0;
49
+ while(ni<news.length||ri<road.length){if(ni<news.length)combined.push({...news[ni++],_type:'news'});if(ri<road.length)combined.push({...road[ri++],_type:'road'});}
50
+ if(!combined.length){el.innerHTML='<div class="loading">Đang cập nhật...</div>';return;}
51
+ let h='<div class="wc-news-grid">';
52
+ combined.slice(0,20).forEach((a,i)=>{
53
+ const badge=a._type==='road'?'<span class="badge badge-wc">Đường tới WC</span>':'<span class="badge badge-fpt">Tin WC</span>';
54
+ h+=`<div class="wc-news-item" onclick="readArticle('${esc(a.link)}')"><div class="wc-news-img" id="wcimg-${i}">${a.img?`<img src="${esc(a.img)}" onerror="this.parentElement.innerHTML=''">`:''}</div><div class="wc-news-text">${badge}<div class="wc-news-title">${esc(a.title)}</div><div class="wc-news-via">${esc(a.source||'')}</div></div></div>`;
55
+ });
56
+ h+='</div>';el.innerHTML=h;
57
+ combined.slice(0,20).forEach((a,i)=>{if(a.img)return;fetch('/api/article?url='+encodeURIComponent(a.link)).then(r=>r.json()).then(d=>{if(d&&(d.og_image||d.img)){const x=document.getElementById('wcimg-'+i);if(x)x.innerHTML=`<img src="${esc(d.og_image||d.img)}" onerror="this.parentElement.innerHTML=''">`;}}).catch(()=>{});});
58
+ }
59
+
60
+ // === FIXTURES ===
61
+ function renderWCFixtures(el){
62
+ const d=_wc2026Data.fixtures||{};const matches=d.matches||[];
63
+ if(!matches.length){el.innerHTML='<div class="loading">Đang tải lịch thi đấu...</div>';return;}
64
+ const sorted=[...matches].sort((a,b)=>(a.date_utc||'').localeCompare(b.date_utc||''));
65
+ const byDate={};sorted.forEach(m=>{const day=m.date_vn?m.date_vn.split(' ').slice(1).join(' '):'TBD';if(!byDate[day])byDate[day]=[];byDate[day].push(m);});
66
+ let h='<div style="max-height:450px;overflow-y:auto;padding:2px">';
67
+ h+=`<div style="font-size:10px;color:#6a9fca;text-align:center;padding:3px">🏆 World Cup 2026 · ${d.total||104} trận · Giờ VN · 🔴 Livescore</div>`;
68
+ for(const[day,dm]of Object.entries(byDate)){
69
+ h+=`<div style="font-size:11px;font-weight:800;color:#f0c040;padding:6px 4px 2px;border-bottom:1px solid #1a3a5a">📅 ${esc(day)}</div>`;
70
+ dm.forEach(m=>{const live=m.status==='live',done=m.status==='finished';const bc=live?'#e74c3c':done?'#2d8659':'#1a3a5a';const time=m.date_vn?m.date_vn.split(' ')[0]:'';
71
+ h+=`<div style="padding:4px;margin:2px 0;border-left:3px solid ${bc};border-radius:3px;background:#0a1520"><div style="display:flex;justify-content:space-between;font-size:8px;color:#6a9fca"><span>🕐 ${esc(time)}${m.group?' · '+esc(m.group):''}</span>${m.location?`<span style="max-width:45%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap">🏟 ${esc(m.location)}</span>`:''}</div><div style="display:flex;align-items:center;gap:2px;margin-top:2px"><span style="flex:1;text-align:right;font-size:11px;color:#eee">${_t(m.home)}</span>${live?`<span style="min-width:44px;text-align:center;font-size:12px;font-weight:900;color:#e74c3c;background:#1a0808;padding:1px 4px;border-radius:3px">${esc(m.score)}</span>`:done?`<span style="min-width:44px;text-align:center;font-size:11px;font-weight:800;color:#4ade80">${esc(m.score)}</span>`:`<span style="min-width:44px;text-align:center;font-size:10px;color:#555">vs</span>`}<span style="flex:1;text-align:left;font-size:11px;color:#eee">${_t(m.away)}</span></div>${live?'<div style="text-align:center;font-size:8px;color:#e74c3c;font-weight:700">● LIVE</div>':''}</div>`;});
72
+ }
73
+ h+='</div>';el.innerHTML=h;
74
+ }
75
+
76
+ // === BXH ===
77
+ function renderWCStandings(el){
78
+ const d=_wc2026Data.standings||{};
79
+ if(d.html&&d.html.length>100){
80
+ el.innerHTML=WC_CSS+'<div class="wc-bxh">'+d.html+'</div>';
81
+ const box=el.querySelector('.wc-bxh');
82
+ if(box){
83
+ // Insert a column-header row right after each group title so stats are labeled
84
+ box.querySelectorAll('.title-table, h6').forEach(t=>{
85
+ if(t.nextElementSibling && t.nextElementSibling.classList.contains('bxh-head'))return;
86
+ const head=document.createElement('div');
87
+ head.className='bxh-head';
88
+ head.innerHTML='<span class="h-team">Đội</span><span class="h-stat">Tr</span><span class="h-stat">T</span><span class="h-stat">H</span><span class="h-stat">B</span><span class="h-stat">BT</span><span class="h-stat">BB</span><span class="h-pts">HS</span><span class="h-pts">Đ</span>';
89
+ t.insertAdjacentElement('afterend',head);
90
+ });
91
+ }
92
+ el.querySelectorAll('a').forEach(a=>a.addEventListener('click',e=>e.preventDefault()));
93
+ return;
94
+ }
95
+ // Self-calculate from fixtures
96
+ const fx=_wc2026Data.fixtures||{};const matches=fx.matches||[];
97
+ const gm=matches.filter(m=>m.group&&m.group.toLowerCase().includes('group'));
98
+ if(!gm.length){el.innerHTML='<div class="loading">BXH cập nhật khi giải bắt đầu 11/06/2026<br><small style="color:#6a9fca">🔴 Livescore tự động</small></div>';return;}
99
+ const groups={};gm.forEach(m=>{const g=m.group;if(!groups[g])groups[g]={};[m.home,m.away].forEach(t=>{if(!groups[g][t])groups[g][t]={p:0,w:0,d:0,l:0,gf:0,ga:0,pts:0};});if(m.home_score!=null&&m.away_score!=null){const hs=+m.home_score,as=+m.away_score;if(!isNaN(hs)&&!isNaN(as)){groups[g][m.home].p++;groups[g][m.away].p++;groups[g][m.home].gf+=hs;groups[g][m.home].ga+=as;groups[g][m.away].gf+=as;groups[g][m.away].ga+=hs;if(hs>as){groups[g][m.home].w++;groups[g][m.home].pts+=3;groups[g][m.away].l++;}else if(hs<as){groups[g][m.away].w++;groups[g][m.away].pts+=3;groups[g][m.home].l++;}else{groups[g][m.home].d++;groups[g][m.home].pts++;groups[g][m.away].d++;groups[g][m.away].pts++;}}}});
100
+ let h='<div style="max-height:450px;overflow-y:auto;padding:2px"><div style="font-size:10px;color:#6a9fca;text-align:center;padding:3px">🏆 BXH World Cup 2026 · 🔴 Livescore</div>';
101
+ Object.keys(groups).sort().forEach(g=>{const teams=Object.entries(groups[g]).map(([n,s])=>({name:n,...s,gd:s.gf-s.ga})).sort((a,b)=>b.pts-a.pts||b.gd-a.gd);h+=`<div style="font-size:11px;font-weight:800;color:#8ab4d8;padding:6px 4px 3px;margin-top:4px;border-bottom:1px solid #1a3a5a">${esc(g)}</div><table style="width:100%;border-collapse:collapse;font-size:10px;margin:2px 0"><tr style="background:#0b1a2a"><th style="text-align:left;padding:4px;color:#6a9fca">Đội</th><th style="color:#6a9fca;padding:3px">Tr</th><th style="color:#6a9fca;padding:3px">T</th><th style="color:#6a9fca;padding:3px">H</th><th style="color:#6a9fca;padding:3px">B</th><th style="color:#6a9fca;padding:3px">HS</th><th style="color:#f0c040;padding:3px;font-weight:800">Đ</th></tr>`;teams.forEach((t,i)=>{h+=`<tr style="background:${i<2?'#0a1a10':'transparent'}"><td style="padding:3px;color:#eee;white-space:nowrap">${_t(t.name)}</td><td style="text-align:center;padding:3px;color:#999">${t.p}</td><td style="text-align:center;color:#4ade80">${t.w}</td><td style="text-align:center;color:#fbbf24">${t.d}</td><td style="text-align:center;color:#f87171">${t.l}</td><td style="text-align:center;color:${t.gd>=0?'#4ade80':'#f87171'}">${t.gd>0?'+':''}${t.gd}</td><td style="text-align:center;color:#f0c040;font-weight:800">${t.pts}</td></tr>`;});h+='</table>';});
102
+ h+='</div>';el.innerHTML=h;
103
+ }
104
+
105
+ // === STATS ===
106
+ function renderWCStats(el){
107
+ const d=_wc2026Data.stats||{};
108
+ if(d.html&&d.html.length>100){el.innerHTML=WC_CSS+'<div class="wc-bxh">'+d.html+'</div>';el.querySelectorAll('a').forEach(a=>a.addEventListener('click',e=>e.preventDefault()));}
109
+ else el.innerHTML='<div class="loading">Thống kê cập nhật khi giải bắt đầu<br><small style="color:#6a9fca">Vua phá lưới · Kiến tạo · Thẻ phạt</small></div>';
110
+ }
111
+
112
+ // === HIGHLIGHTS (WC + Friendly from xemlaibongda.top) ===
113
+ async function renderWCHighlights(el){
114
+ el.innerHTML='<div class="loading">Đang tải highlight...</div>';
115
+ try{
116
+ // Load both WC and Friendly highlights
117
+ const[wc,fr]=await Promise.all([
118
+ fetch('/api/highlights/world-cup').then(r=>r.json()).catch(()=>[]),
119
+ fetch('/api/highlights/friendly').then(r=>r.json()).catch(()=>[])
120
+ ]);
121
+ // Keep per-league index so the clicked card maps to the correct video in its own league array
122
+ const all=[...(wc||[]).map((v,j)=>({...v,_league:'WC',_li:j})),...(fr||[]).map((v,j)=>({...v,_league:'Friendly',_li:j}))];
123
+ if(!all.length){el.innerHTML='<div class="loading">Chưa có highlight World Cup & Giao hữu</div>';return;}
124
+ let h='<div style="display:grid;grid-template-columns:repeat(2,1fr);gap:6px;max-height:450px;overflow-y:auto;padding:4px">';
125
+ all.slice(0,24).forEach((v,i)=>{
126
+ const league=v._league==='WC'?'world-cup':'friendly';
127
+ const badge=v._league==='WC'?'🌍 WC':'🤝 Friendly';
128
+ h+=`<div style="cursor:pointer;border-radius:6px;overflow:hidden;background:#0a1520" onclick="openHighlightFeed('${league}',${v._li},'${esc(v.link)}')">`;
129
+ h+=`<div style="position:relative;aspect-ratio:16/9;background:#1a2a3a">${v.img?`<img src="${esc(v.img)}" style="width:100%;height:100%;object-fit:cover">`:''}<div class="card-play">▶</div></div>`;
130
+ h+=`<div style="padding:4px 6px"><span style="font-size:8px;color:#f0c040">${badge}</span><div style="font-size:10px;color:#ccc;line-height:1.2;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden">${esc(v.title)}</div></div>`;
131
+ h+='</div>';
132
+ });
133
+ h+='</div>';el.innerHTML=h;
134
+ }catch(e){el.innerHTML='<div class="loading">Lỗi tải highlight</div>';}
135
+ }
136
+
137
+ // === LIVE AUTO-REFRESH (90s) ===
138
+ function startWCLiveRefresh(){
139
+ if(_wcRefreshInterval)clearInterval(_wcRefreshInterval);
140
+ _wcRefreshInterval=setInterval(async()=>{
141
+ if(!document.getElementById('view-home')?.classList.contains('active'))return;
142
+ try{
143
+ const data=await fetch('/api/wc2026').then(r=>r.json()).catch(()=>null);
144
+ if(data){_wc2026Data=data;const wcEl=document.getElementById('wc-content');if(wcEl){const tab=document.querySelector('.wc-tab.active');if(tab){const t=tab.textContent;if(t.includes('Tin'))renderWCNews(wcEl);else if(t.includes('Lịch'))renderWCFixtures(wcEl);else if(t.includes('BXH'))renderWCStandings(wcEl);else if(t.includes('Thống'))renderWCStats(wcEl);}}}
145
+ }catch(e){}
146
+ },90000);
147
+ }
148
+ setTimeout(startWCLiveRefresh,5000);