Commit c54762c0 authored by Mahmoud Aglan's avatar Mahmoud Aglan

feat: complete tournament-detail.js i18n + add missing dictionary keys

Replace all 40+ remaining Arabic strings in tournament-detail.js.
Add tournament format/prizes/registration/standings/rounds keys
to both ar and en dictionaries.
Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
parent 344b3714
...@@ -640,6 +640,24 @@ const strings = { ...@@ -640,6 +640,24 @@ const strings = {
'tournament.live_matches': 'مباريات جارية', 'tournament.live_matches': 'مباريات جارية',
'tournament.no_match': 'لا توجد مباراة', 'tournament.no_match': 'لا توجد مباراة',
'spectate.watch': 'شاهد', 'spectate.watch': 'شاهد',
'tournament.format': 'النظام',
'tournament.time_control': 'الوقت',
'tournament.prizes': 'الجوائز',
'tournament.register_now': 'سجّل الآن',
'tournament.registering': 'جاري التسجيل...',
'tournament.registered': '✅ تم التسجيل',
'tournament.player_col': 'اللاعب',
'tournament.points_col': 'نقاط',
'tournament.buchholz_col': 'بوخ',
'tournament.rounds_not_started': 'لم تبدأ الجولات بعد',
'tournament.tap_to_expand': 'اضغط لعرض التقابلات',
'tournament.no_pairings': 'لا توجد تقابلات',
'tournament.play_btn': 'العب',
'tournament.no_games_yet': 'لم تلعب مباريات في هذه البطولة بعد',
'tournament.ready_matches': 'مباريات جاهزة',
'tournament.round_short': 'ج{n}',
'tournament.bye_point': 'إجازة — نقطة كاملة',
'tournament.prev_matches': 'المباريات السابقة',
'chess.rating': 'التصنيف', 'chess.rating': 'التصنيف',
'chess.rating_history': 'سجل التصنيف', 'chess.rating_history': 'سجل التصنيف',
'chess.highest': 'الأعلى', 'chess.highest': 'الأعلى',
...@@ -1307,6 +1325,24 @@ const strings = { ...@@ -1307,6 +1325,24 @@ const strings = {
'tournament.live_matches': 'Live Matches', 'tournament.live_matches': 'Live Matches',
'tournament.no_match': 'No match found', 'tournament.no_match': 'No match found',
'spectate.watch': 'Watch', 'spectate.watch': 'Watch',
'tournament.format': 'Format',
'tournament.time_control': 'Time',
'tournament.prizes': 'Prizes',
'tournament.register_now': 'Register Now',
'tournament.registering': 'Registering...',
'tournament.registered': '✅ Registered',
'tournament.player_col': 'Player',
'tournament.points_col': 'Points',
'tournament.buchholz_col': 'Buch.',
'tournament.rounds_not_started': 'Rounds not started yet',
'tournament.tap_to_expand': 'Tap to show pairings',
'tournament.no_pairings': 'No pairings',
'tournament.play_btn': 'Play',
'tournament.no_games_yet': 'No games played in this tournament yet',
'tournament.ready_matches': 'Ready Matches',
'tournament.round_short': 'R{n}',
'tournament.bye_point': 'Bye — full point',
'tournament.prev_matches': 'Previous Matches',
'chess.rating': 'Rating', 'chess.rating': 'Rating',
'chess.rating_history': 'Rating History', 'chess.rating_history': 'Rating History',
'chess.highest': 'Highest', 'chess.highest': 'Highest',
......
...@@ -109,24 +109,24 @@ async function loadInfo(content, tournamentId, el) { ...@@ -109,24 +109,24 @@ async function loadInfo(content, tournamentId, el) {
<div style="display:grid;grid-template-columns:1fr 1fr;gap:10px;margin-bottom:16px;"> <div style="display:grid;grid-template-columns:1fr 1fr;gap:10px;margin-bottom:16px;">
<div style="background:#1a1a2e;border-radius:10px;padding:12px;text-align:center;"> <div style="background:#1a1a2e;border-radius:10px;padding:12px;text-align:center;">
<div style="font-size:22px;font-weight:800;color:#E4AC38;">${data.player_count || 0}</div> <div style="font-size:22px;font-weight:800;color:#E4AC38;">${data.player_count || 0}</div>
<div style="font-size:11px;color:#64748b;">لاعبين</div> <div style="font-size:11px;color:#64748b;">${t('tournament.players')}</div>
</div> </div>
<div style="background:#1a1a2e;border-radius:10px;padding:12px;text-align:center;"> <div style="background:#1a1a2e;border-radius:10px;padding:12px;text-align:center;">
<div style="font-size:22px;font-weight:800;color:#3B82F6;">${data.rounds_total || data.swiss_rounds || '?'}</div> <div style="font-size:22px;font-weight:800;color:#3B82F6;">${data.rounds_total || data.swiss_rounds || '?'}</div>
<div style="font-size:11px;color:#64748b;">جولات</div> <div style="font-size:11px;color:#64748b;">${t('tournament.tab_rounds')}</div>
</div> </div>
<div style="background:#1a1a2e;border-radius:10px;padding:12px;text-align:center;"> <div style="background:#1a1a2e;border-radius:10px;padding:12px;text-align:center;">
<div style="font-size:22px;font-weight:800;color:#f8fafc;">${data.format || 'swiss'}</div> <div style="font-size:22px;font-weight:800;color:#f8fafc;">${data.format || 'swiss'}</div>
<div style="font-size:11px;color:#64748b;">النظام</div> <div style="font-size:11px;color:#64748b;">${t('tournament.format')}</div>
</div> </div>
<div style="background:#1a1a2e;border-radius:10px;padding:12px;text-align:center;"> <div style="background:#1a1a2e;border-radius:10px;padding:12px;text-align:center;">
<div style="font-size:22px;font-weight:800;color:#10B981;">${data.time_control || '?'}</div> <div style="font-size:22px;font-weight:800;color:#10B981;">${data.time_control || '?'}</div>
<div style="font-size:11px;color:#64748b;">الوقت</div> <div style="font-size:11px;color:#64748b;">${t('tournament.time_control')}</div>
</div> </div>
</div> </div>
${data.prize_pool_coins ? `<div style="background:#1a1a2e;border-radius:10px;padding:14px;text-align:center;margin-bottom:12px;"> ${data.prize_pool_coins ? `<div style="background:#1a1a2e;border-radius:10px;padding:14px;text-align:center;margin-bottom:12px;">
<div style="font-size:12px;color:#64748b;margin-bottom:4px;">الجوائز</div> <div style="font-size:12px;color:#64748b;margin-bottom:4px;">${t('tournament.prizes')}</div>
<div style="font-size:20px;font-weight:800;color:#E4AC38;">${data.prize_pool_coins} ${emoji('coin', '🪙', 20)}</div> <div style="font-size:20px;font-weight:800;color:#E4AC38;">${data.prize_pool_coins} ${emoji('coin', '🪙', 20)}</div>
</div>` : ''} </div>` : ''}
...@@ -135,25 +135,25 @@ async function loadInfo(content, tournamentId, el) { ...@@ -135,25 +135,25 @@ async function loadInfo(content, tournamentId, el) {
</div>` : ''} </div>` : ''}
${data.status === 'registration' ? ` ${data.status === 'registration' ? `
<button class="btn btn-primary w-full" id="register-btn" style="font-size:16px;padding:16px;">${emoji('swords', '⚔️', 16)} سجّل الآن</button> <button class="btn btn-primary w-full" id="register-btn" style="font-size:16px;padding:16px;">${emoji('swords', '⚔️', 16)} ${t('tournament.register_now')}</button>
` : ''} ` : ''}
`; `;
content.querySelector('#register-btn')?.addEventListener('click', async () => { content.querySelector('#register-btn')?.addEventListener('click', async () => {
const btn = content.querySelector('#register-btn'); const btn = content.querySelector('#register-btn');
btn.disabled = true; btn.disabled = true;
btn.textContent = 'جاري التسجيل...'; btn.textContent = t('tournament.registering');
try { try {
await net.post('tournaments.php', { action: 'register', tournament_id: tournamentId }); await net.post('tournaments.php', { action: 'register', tournament_id: tournamentId });
btn.textContent = '✅ تم التسجيل'; btn.textContent = t('tournament.registered');
btn.style.background = '#34D399'; btn.style.background = '#34D399';
} catch (e) { } catch (e) {
btn.textContent = e.message || 'فشل'; btn.textContent = e.message || t('common.failed');
btn.disabled = false; btn.disabled = false;
} }
}); });
} catch (e) { } catch (e) {
content.innerHTML = `<div style="text-align:center;color:#ef4444;padding:24px;">فشل تحميل البطولة</div>`; content.innerHTML = `<div style="text-align:center;color:#ef4444;padding:24px;">${t('common.error_load')}</div>`;
} }
} }
...@@ -163,16 +163,16 @@ async function loadStandings(content, tournamentId) { ...@@ -163,16 +163,16 @@ async function loadStandings(content, tournamentId) {
const standings = data.standings || []; const standings = data.standings || [];
if (standings.length === 0) { if (standings.length === 0) {
content.innerHTML = '<div style="text-align:center;color:#64748b;padding:32px;">لا توجد نتائج بعد — ستظهر بعد بدء الجولات</div>'; content.innerHTML = `<div style="text-align:center;color:#64748b;padding:32px;">${t('tournament.no_results')}</div>`;
return; return;
} }
content.innerHTML = ` content.innerHTML = `
<div style="display:flex;padding:6px 0;border-bottom:1px solid rgba(255,255,255,0.06);color:#64748b;font-size:11px;font-weight:600;"> <div style="display:flex;padding:6px 0;border-bottom:1px solid rgba(255,255,255,0.06);color:#64748b;font-size:11px;font-weight:600;">
<span style="width:30px;">#</span> <span style="width:30px;">#</span>
<span style="flex:1;">اللاعب</span> <span style="flex:1;">${t('tournament.player_col')}</span>
<span style="width:40px;text-align:center;">نقاط</span> <span style="width:40px;text-align:center;">${t('tournament.points_col')}</span>
<span style="width:40px;text-align:center;">بوخ</span> <span style="width:40px;text-align:center;">${t('tournament.buchholz_col')}</span>
</div> </div>
${standings.map((p, i) => ` ${standings.map((p, i) => `
<div class="standing-row"> <div class="standing-row">
...@@ -184,7 +184,7 @@ async function loadStandings(content, tournamentId) { ...@@ -184,7 +184,7 @@ async function loadStandings(content, tournamentId) {
`).join('')} `).join('')}
`; `;
} catch (e) { } catch (e) {
content.innerHTML = '<div style="text-align:center;color:#ef4444;">فشل تحميل الترتيب</div>'; content.innerHTML = `<div style="text-align:center;color:#ef4444;">${t('common.error_load')}</div>`;
} }
} }
...@@ -195,17 +195,17 @@ async function loadRounds(content, tournamentId) { ...@@ -195,17 +195,17 @@ async function loadRounds(content, tournamentId) {
const userId = store.get('auth.userId'); const userId = store.get('auth.userId');
if (rounds.length === 0) { if (rounds.length === 0) {
content.innerHTML = '<div style="text-align:center;color:#64748b;padding:32px;">لم تبدأ الجولات بعد</div>'; content.innerHTML = `<div style="text-align:center;color:#64748b;padding:32px;">${t('tournament.rounds_not_started')}</div>`;
return; return;
} }
content.innerHTML = rounds.map(r => ` content.innerHTML = rounds.map(r => `
<div style="margin-bottom:16px;"> <div style="margin-bottom:16px;">
<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:8px;"> <div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:8px;">
<span style="font-size:14px;font-weight:700;color:#f8fafc;">الجولة ${r.round_number}</span> <span style="font-size:14px;font-weight:700;color:#f8fafc;">${t('tournament.round', { n: r.round_number })}</span>
<span style="font-size:11px;padding:3px 8px;border-radius:99px;background:${r.status === 'completed' ? '#64748b' : r.status === 'in_progress' ? '#E4AC38' : '#3B82F6'};color:#000;font-weight:600;">${r.status === 'completed' ? 'منتهية' : r.status === 'in_progress' ? 'جارية' : 'قادمة'}</span> <span style="font-size:11px;padding:3px 8px;border-radius:99px;background:${r.status === 'completed' ? '#64748b' : r.status === 'in_progress' ? '#E4AC38' : '#3B82F6'};color:#000;font-weight:600;">${r.status === 'completed' ? t('tournament.completed') : r.status === 'in_progress' ? t('tournament.active') : t('tournament.upcoming')}</span>
</div> </div>
<div id="round-pairings-${r.id}" style="font-size:12px;color:#64748b;">اضغط لعرض التقابلات</div> <div id="round-pairings-${r.id}" style="font-size:12px;color:#64748b;">${t('tournament.tap_to_expand')}</div>
</div> </div>
`).join(''); `).join('');
...@@ -214,11 +214,11 @@ async function loadRounds(content, tournamentId) { ...@@ -214,11 +214,11 @@ async function loadRounds(content, tournamentId) {
if (el) { if (el) {
el.style.cursor = 'pointer'; el.style.cursor = 'pointer';
el.addEventListener('click', async () => { el.addEventListener('click', async () => {
el.textContent = 'جاري التحميل...'; el.textContent = t('common.loading');
try { try {
const pd = await net.get('swiss.php', { action: 'pairings', round_id: r.id }); const pd = await net.get('swiss.php', { action: 'pairings', round_id: r.id });
const pairings = pd.pairings || []; const pairings = pd.pairings || [];
if (pairings.length === 0) { el.textContent = 'لا توجد تقابلات'; return; } if (pairings.length === 0) { el.textContent = t('tournament.no_pairings'); return; }
el.innerHTML = pairings.map((p, idx) => { el.innerHTML = pairings.map((p, idx) => {
const playerA = p.player_a || p.white_id || ''; const playerA = p.player_a || p.white_id || '';
...@@ -231,7 +231,7 @@ async function loadRounds(content, tournamentId) { ...@@ -231,7 +231,7 @@ async function loadRounds(content, tournamentId) {
<span style="flex:1;font-size:12px;color:#f8fafc;">${p.white_name || p.player_a || '?'}</span> <span style="flex:1;font-size:12px;color:#f8fafc;">${p.white_name || p.player_a || '?'}</span>
<span style="padding:2px 8px;background:#1e1e3a;border-radius:4px;font-size:11px;font-weight:700;color:#E4AC38;">${p.result || 'vs'}</span> <span style="padding:2px 8px;background:#1e1e3a;border-radius:4px;font-size:11px;font-weight:700;color:#E4AC38;">${p.result || 'vs'}</span>
<span style="flex:1;text-align:left;font-size:12px;color:#f8fafc;">${p.black_name || p.player_b || '?'}</span> <span style="flex:1;text-align:left;font-size:12px;color:#f8fafc;">${p.black_name || p.player_b || '?'}</span>
${canPlay ? `<button class="play-pairing-btn" data-round-id="${r.id}" data-idx="${idx}" style="margin-right:8px;padding:4px 12px;background:#E4AC38;border:none;border-radius:6px;color:#000;font-weight:700;font-size:11px;cursor:pointer;">العب</button>` : ''} ${canPlay ? `<button class="play-pairing-btn" data-round-id="${r.id}" data-idx="${idx}" style="margin-right:8px;padding:4px 12px;background:#E4AC38;border:none;border-radius:6px;color:#000;font-weight:700;font-size:11px;cursor:pointer;">${t('tournament.play_btn')}</button>` : ''}
</div> </div>
`; `;
}).join(''); }).join('');
...@@ -244,13 +244,13 @@ async function loadRounds(content, tournamentId) { ...@@ -244,13 +244,13 @@ async function loadRounds(content, tournamentId) {
}); });
}); });
} catch (e) { } catch (e) {
el.textContent = 'فشل التحميل'; el.textContent = t('common.error_load');
} }
}); });
} }
}); });
} catch (e) { } catch (e) {
content.innerHTML = '<div style="text-align:center;color:#ef4444;">فشل تحميل الجولات</div>'; content.innerHTML = `<div style="text-align:center;color:#ef4444;">${t('common.error_load')}</div>`;
} }
} }
...@@ -268,7 +268,7 @@ async function loadMyGames(content, tournamentId) { ...@@ -268,7 +268,7 @@ async function loadMyGames(content, tournamentId) {
const allPending = (pendingData.pending || []).filter(p => p.tournament_id === tournamentId); const allPending = (pendingData.pending || []).filter(p => p.tournament_id === tournamentId);
if (games.length === 0 && allPending.length === 0) { if (games.length === 0 && allPending.length === 0) {
content.innerHTML = '<div style="text-align:center;color:#64748b;padding:32px;">لم تلعب مباريات في هذه البطولة بعد</div>'; content.innerHTML = `<div style="text-align:center;color:#64748b;padding:32px;">${t('tournament.no_games_yet')}</div>`;
return; return;
} }
...@@ -276,36 +276,36 @@ async function loadMyGames(content, tournamentId) { ...@@ -276,36 +276,36 @@ async function loadMyGames(content, tournamentId) {
// Pending matches first (with Play button) // Pending matches first (with Play button)
if (allPending.length > 0) { if (allPending.length > 0) {
html += `<div style="margin-bottom:14px;font-size:13px;font-weight:700;color:#E4AC38;">مباريات جاهزة</div>`; html += `<div style="margin-bottom:14px;font-size:13px;font-weight:700;color:#E4AC38;">${t('tournament.ready_matches')}</div>`;
html += allPending.map(p => { html += allPending.map(p => {
if (p.is_bye) { if (p.is_bye) {
return `<div class="pairing-row" style="border:1px solid #64748b;"> return `<div class="pairing-row" style="border:1px solid #64748b;">
<span style="font-size:12px;color:#64748b;">ج${p.round_number}</span> <span style="font-size:12px;color:#64748b;">${t('tournament.round_short', { n: p.round_number })}</span>
<span style="font-size:12px;color:#94a3b8;flex:1;margin:0 8px;">إجازة — نقطة كاملة</span> <span style="font-size:12px;color:#94a3b8;flex:1;margin:0 8px;">${t('tournament.bye_point')}</span>
<span style="font-size:11px;color:#34D399;">BYE ✓</span> <span style="font-size:11px;color:#34D399;">BYE ✓</span>
</div>`; </div>`;
} }
return `<div class="pairing-row" style="border:1px solid #E4AC38;"> return `<div class="pairing-row" style="border:1px solid #E4AC38;">
<span style="font-size:12px;color:#64748b;">ج${p.round_number}</span> <span style="font-size:12px;color:#64748b;">${t('tournament.round_short', { n: p.round_number })}</span>
<span style="font-size:12px;color:#f8fafc;flex:1;margin:0 8px;">vs ${p.opponent_name || 'خصم'}</span> <span style="font-size:12px;color:#f8fafc;flex:1;margin:0 8px;">vs ${p.opponent_name || t('common.opponent')}</span>
<button class="play-pending-btn" data-tid="${p.tournament_id}" data-rid="${p.round_id}" data-idx="${p.pairing_index}" style="padding:6px 16px;background:#E4AC38;border:none;border-radius:8px;color:#000;font-weight:700;font-size:12px;cursor:pointer;">العب</button> <button class="play-pending-btn" data-tid="${p.tournament_id}" data-rid="${p.round_id}" data-idx="${p.pairing_index}" style="padding:6px 16px;background:#E4AC38;border:none;border-radius:8px;color:#000;font-weight:700;font-size:12px;cursor:pointer;">${t('tournament.play_btn')}</button>
</div>`; </div>`;
}).join(''); }).join('');
} }
// Completed games // Completed games
if (games.length > 0) { if (games.length > 0) {
html += `<div style="margin-bottom:8px;margin-top:14px;font-size:13px;font-weight:700;color:#94a3b8;">المباريات السابقة</div>`; html += `<div style="margin-bottom:8px;margin-top:14px;font-size:13px;font-weight:700;color:#94a3b8;">${t('tournament.prev_matches')}</div>`;
html += games.map(g => { html += games.map(g => {
const isWhite = g.white_player_id === userId; const isWhite = g.white_player_id === userId;
let resultText = g.status; let resultText = g.status;
let resultColor = '#94a3b8'; let resultColor = '#94a3b8';
if (g.result === 'white_wins') { resultText = isWhite ? 'فوز' : 'خسارة'; resultColor = isWhite ? '#34D399' : '#ef4444'; } if (g.result === 'white_wins') { resultText = isWhite ? t('history.win') : t('history.loss'); resultColor = isWhite ? '#34D399' : '#ef4444'; }
else if (g.result === 'black_wins') { resultText = isWhite ? 'خسارة' : 'فوز'; resultColor = isWhite ? '#ef4444' : '#34D399'; } else if (g.result === 'black_wins') { resultText = isWhite ? t('history.loss') : t('history.win'); resultColor = isWhite ? '#ef4444' : '#34D399'; }
else if (g.result === 'draw') { resultText = 'تعادل'; resultColor = '#E4AC38'; } else if (g.result === 'draw') { resultText = t('history.draw'); resultColor = '#E4AC38'; }
return `<div class="pairing-row"> return `<div class="pairing-row">
<span style="font-size:12px;color:#64748b;">ج${g.tournament_round || '?'}</span> <span style="font-size:12px;color:#64748b;">${t('tournament.round_short', { n: g.tournament_round || '?' })}</span>
<span style="font-size:12px;color:#f8fafc;flex:1;margin:0 8px;">${g.result || g.status}</span> <span style="font-size:12px;color:#f8fafc;flex:1;margin:0 8px;">${g.result || g.status}</span>
<span style="font-size:11px;color:${resultColor};font-weight:600;">${resultText}</span> <span style="font-size:11px;color:${resultColor};font-weight:600;">${resultText}</span>
</div>`; </div>`;
...@@ -322,7 +322,7 @@ async function loadMyGames(content, tournamentId) { ...@@ -322,7 +322,7 @@ async function loadMyGames(content, tournamentId) {
}); });
}); });
} catch (e) { } catch (e) {
content.innerHTML = '<div style="text-align:center;color:#ef4444;">فشل التحميل</div>'; content.innerHTML = `<div style="text-align:center;color:#ef4444;">${t('common.error_load')}</div>`;
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment