This commit is contained in:
starified
2026-04-21 22:03:19 -04:00
parent 36e2d11f2e
commit 08bf320b57
4681 changed files with 566542 additions and 0 deletions

106
public/player.js Normal file
View File

@@ -0,0 +1,106 @@
const MODE_LABELS = {
vanilla: "Vanilla",
mace: "Mace",
axe: "Axe",
sword: "Sword",
smp: "SMP",
diamondsmp: "Diamond SMP",
uhc: "UHC",
pot: "Pot",
nethop: "Neth OP",
cart: "Cart",
};
const MODE_ICON_PATH = {
vanilla: "assets/gamemodes/smaller-vanilla-pvp.png",
mace: "assets/gamemodes/mace-pvp.png",
axe: "assets/gamemodes/axe-pvp.png",
sword: "assets/gamemodes/sword-pvp.png",
smp: "assets/gamemodes/smp.png",
diamondsmp: "assets/gamemodes/diamond-smp.png",
uhc: "assets/gamemodes/uhc.png",
pot: "assets/gamemodes/pot-pvp.png",
nethop: "assets/gamemodes/neth-op.png",
cart: "assets/gamemodes/cart-pvp.png",
};
function getAvatarUrl(username) {
return `https://render.crafty.gg/3d/bust/${encodeURIComponent(username)}`;
}
const profileCardEl = document.getElementById("profileCard");
const profileLoadingEl = document.getElementById("profileLoading");
const profileErrorEl = document.getElementById("profileError");
const profileAvatarEl = document.getElementById("profileAvatar");
const profileUsernameEl = document.getElementById("profileUsername");
const profilePositionEl = document.getElementById("profilePosition");
const profilePointsEl = document.getElementById("profilePoints");
const profileTiersEl = document.getElementById("profileTiers");
const closeBtnEl = document.getElementById("closeBtn");
function getUserFromQuery() {
const params = new URLSearchParams(window.location.search);
return params.get("user");
}
function showError(message) {
profileErrorEl.classList.remove("hidden");
profileErrorEl.textContent = message;
}
function renderProfile(player) {
profileAvatarEl.src = getAvatarUrl(player.username);
profileAvatarEl.alt = `${player.username} avatar`;
profileUsernameEl.textContent = player.username;
profilePositionEl.textContent = `#${player.position}`;
profilePointsEl.textContent = String(player.totalPoints);
const tiers = Object.entries(player.tiers || {})
.map(
([mode, tier]) => `
<article class="profile-tier">
<img src="${MODE_ICON_PATH[mode]}" alt="${MODE_LABELS[mode] || mode}" />
<h3>${MODE_LABELS[mode] || mode}</h3>
<p>${tier || "-"}</p>
</article>
`
)
.join("");
profileTiersEl.innerHTML = tiers;
profileCardEl.classList.remove("hidden");
}
async function loadProfile() {
const username = getUserFromQuery();
if (!username) {
profileLoadingEl.classList.add("hidden");
showError("Missing username. Open from the ranking page.");
return;
}
try {
const response = await fetch(`/api/players/${encodeURIComponent(username)}`, {
headers: { Accept: "application/json" },
});
if (!response.ok) {
throw new Error(`Failed (${response.status})`);
}
const player = await response.json();
renderProfile(player);
} catch (_error) {
showError("Failed to load profile.");
} finally {
profileLoadingEl.classList.add("hidden");
}
}
closeBtnEl.addEventListener("click", () => {
window.location.href = "index.html";
});
loadProfile();