62 lines
2.0 KiB
JavaScript
62 lines
2.0 KiB
JavaScript
document.addEventListener("DOMContentLoaded", () => {
|
|
loadLeaderboard();
|
|
});
|
|
|
|
function loadLeaderboard() {
|
|
fetch('Leaderboard.php')
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
if (data.status === "success") {
|
|
renderLeaderboard(data.leaderboard);
|
|
}
|
|
})
|
|
.catch(error => console.error("Error loading leaderboard:", error));
|
|
}
|
|
|
|
function renderLeaderboard(players) {
|
|
const listContainer = document.getElementById('leaderboardList');
|
|
if (!listContainer) return; // Safety check
|
|
|
|
listContainer.innerHTML = ""; // Hapus data dummy statis
|
|
|
|
players.forEach((player, index) => {
|
|
const rank = index + 1;
|
|
let rankClass = 'rank-other';
|
|
|
|
// Tentukan styling berdasarkan ranking
|
|
if (rank === 1) rankClass = 'rank-1';
|
|
else if (rank === 2) rankClass = 'rank-2';
|
|
else if (rank === 3) rankClass = 'rank-3';
|
|
|
|
// Format angka skor dengan koma (contoh: 1,000)
|
|
// Fallback jika score tidak valid
|
|
const scoreVal = parseInt(player.score) || 0;
|
|
const formattedScore = new Intl.NumberFormat().format(scoreVal);
|
|
|
|
const itemHtml = `
|
|
<li class="leaderboard-item ${rankClass}">
|
|
<div class="rank-badge">${rank}</div>
|
|
<div class="player-info">
|
|
<div class="player-name">${escapeHtml(player.username)}</div>
|
|
</div>
|
|
<div class="player-score">
|
|
<div class="score-value">${formattedScore}</div>
|
|
<div class="score-label">Points</div>
|
|
</div>
|
|
</li>
|
|
`;
|
|
|
|
listContainer.insertAdjacentHTML('beforeend', itemHtml);
|
|
});
|
|
}
|
|
|
|
// Mencegah XSS attack (keamanan tambahan)
|
|
function escapeHtml(text) {
|
|
if (!text) return text;
|
|
return text
|
|
.replace(/&/g, "&")
|
|
.replace(/</g, "<")
|
|
.replace(/>/g, ">")
|
|
.replace(/"/g, """)
|
|
.replace(/'/g, "'");
|
|
} |