Files
school/projects/year_01/challenge_08/pokedex/v2/pokemon-detail.js
2025-08-21 03:42:21 +02:00

255 lines
6.8 KiB
JavaScript

let currentPokemonId = null;
document.addEventListener("DOMContentLoaded", () => {
const MAX_POKEMONS = 1050;
const pokemonID = new URLSearchParams(window.location.search).get("id");
const id = parseInt(pokemonID, 10);
if (isNaN(id) || id < 1 || id > MAX_POKEMONS) {
console.error(`Invalid Pokémon ID: ${id}`);
return (window.location.href = "./index.html");
}
currentPokemonId = id;
loadPokemon(id);
});
async function loadPokemon(id) {
try {
console.log(`Loading data for Pokémon ID ${id}...`);
const pokemon = await fetch(`./get-pokemon.php?id=${id}`).then((res) =>
res.json()
);
if (pokemon.error) {
throw new Error(pokemon.error);
}
// Ensure the data is logged for debugging
console.log("Fetched Pokémon data:", pokemon);
const abilitiesWrapper = document.querySelector(
".pokemon-detail-wrap .pokemon-detail.move"
);
abilitiesWrapper.innerHTML = "";
if (currentPokemonId === id) {
displayPokemonDetails(pokemon);
// Ensure flavor text is updated
document.querySelector(".body3-fonts.pokemon-description").textContent =
pokemon.flavor_text || "No description available.";
// Update navigation arrows
const [leftArrow, rightArrow] = ["#leftArrow", "#rightArrow"].map((sel) =>
document.querySelector(sel)
);
leftArrow.classList.toggle("hidden", id === 1);
rightArrow.classList.toggle("hidden", id === 1050);
leftArrow.onclick = id > 1 ? () => navigatePokemon(id - 1) : null;
rightArrow.onclick = id < 1050 ? () => navigatePokemon(id + 1) : null;
// Update URL without reloading
window.history.pushState({}, "", `./detail.html?id=${id}`);
}
return true;
} catch (error) {
console.error("An error occurred while fetching Pokémon data:", error);
return (window.location.href = "./index.html");
}
}
async function navigatePokemon(id) {
currentPokemonId = id;
await loadPokemon(id);
}
const typeColors = {
normal: "#A8A878",
fire: "#F08030",
water: "#6890F0",
electric: "#F8D030",
grass: "#78C850",
ice: "#98D8D8",
fighting: "#C03028",
poison: "#A040A0",
ground: "#E0C068",
flying: "#A890F0",
psychic: "#F85888",
bug: "#A8B820",
rock: "#B8A038",
ghost: "#705898",
dragon: "#7038F8",
dark: "#705848",
steel: "#B8B8D0",
dark: "#EE99AC",
};
function setElementStyles(elements, cssProperty, value) {
elements.forEach((element) => {
element.style[cssProperty] = value;
});
}
function rgbaFromHex(hexColor) {
return [
parseInt(hexColor.slice(1, 3), 16),
parseInt(hexColor.slice(3, 5), 16),
parseInt(hexColor.slice(5, 7), 16),
].join(", ");
}
function setTypeBackgroundColor(pokemon) {
const mainType = pokemon.types[0];
const color = typeColors[mainType];
if (!color) {
console.warn(`Color not defined for type: ${mainType}`);
return;
}
const detailMainElement = document.querySelector(".detail-main");
setElementStyles([detailMainElement], "backgroundColor", color);
setElementStyles([detailMainElement], "borderColor", color);
setElementStyles(
document.querySelectorAll(".power-wrapper > p"),
"backgroundColor",
color
);
setElementStyles(
document.querySelectorAll(".stats-wrap p.stats"),
"color",
color
);
setElementStyles(
document.querySelectorAll(".stats-wrap .progress-bar"),
"color",
color
);
const rgbaColor = rgbaFromHex(color);
const styleTag = document.createElement("style");
styleTag.innerHTML = `
.stats-wrap .progress-bar::-webkit-progress-bar {
background-color: rgba(${rgbaColor}, 0.5);
}
.stats-wrap .progress-bar::-webkit-progress-value {
background-color: ${color};
}
`;
document.head.appendChild(styleTag);
}
function capitalizeFirstLetter(string) {
return string.charAt(0).toUpperCase() + string.slice(1).toLowerCase();
}
function createAndAppendElement(parent, tag, options = {}) {
const element = document.createElement(tag);
Object.keys(options).forEach((key) => {
element[key] = options[key];
});
parent.appendChild(element);
return element;
}
function displayPokemonDetails(pokemon) {
const { name, id, types, weight, height, abilities, hp, attack, defense, sp_attack, sp_defense, speed } = pokemon;
const capitalizePokemonName = capitalizeFirstLetter(name);
document.querySelector("title").textContent = capitalizePokemonName;
const detailMainElement = document.querySelector(".detail-main");
detailMainElement.classList.add(name.toLowerCase());
document.querySelector(".name-wrap .name").textContent =
capitalizePokemonName;
document.querySelector(
".pokemon-id-wrap .body2-fonts"
).textContent = `#${String(id).padStart(3, "0")}`;
const imageElement = document.querySelector(".detail-img-wrapper img");
imageElement.src = pokemon.image_url;
imageElement.alt = name;
const typeWrapper = document.querySelector(".power-wrapper");
typeWrapper.innerHTML = "";
types.forEach((type) => {
createAndAppendElement(typeWrapper, "p", {
className: `body3-fonts type ${type}`,
textContent: type,
});
});
document.querySelector(
".pokemon-detail-wrap .pokemon-detail p.body3-fonts.weight"
).textContent = `${weight / 10}kg`;
document.querySelector(
".pokemon-detail-wrap .pokemon-detail p.body3-fonts.height"
).textContent = `${height / 10}m`;
const abilitiesWrapper = document.querySelector(
".pokemon-detail-wrap .pokemon-detail.move"
);
abilities.forEach((ability) => {
createAndAppendElement(abilitiesWrapper, "p", {
className: "body3-fonts",
textContent: ability,
});
});
const statsWrapper = document.querySelector(".stats-wrapper");
statsWrapper.innerHTML = "";
const statNameMapping = {
hp: "HP",
attack: "ATK",
defense: "DEF",
sp_attack: "SATK",
sp_defense: "SDEF",
speed: "SPD",
};
const stats = { hp, attack, defense, sp_attack, sp_defense, speed };
Object.keys(stats).forEach((stat) => {
const statDiv = document.createElement("div");
statDiv.className = "stats-wrap";
statsWrapper.appendChild(statDiv);
createAndAppendElement(statDiv, "p", {
className: "body3-fonts stats",
textContent: statNameMapping[stat],
});
createAndAppendElement(statDiv, "p", {
className: "body3-fonts",
textContent: String(stats[stat]).padStart(3, "0"),
});
createAndAppendElement(statDiv, "progress", {
className: "progress-bar",
value: stats[stat],
max: 100,
});
});
setTypeBackgroundColor(pokemon);
}
function getEnglishFlavorText(pokemonSpecies) {
for (let entry of pokemonSpecies.flavor_text_entries) {
if (entry.language.name === "en") {
let flavor = entry.flavor_text.replace(/\f/g, " ");
return flavor;
}
}
return "";
}