From e2433e12a190d7a86408a7537a0965a335e7b1c8 Mon Sep 17 00:00:00 2001 From: vista-man <524715@vistacollege.nl> Date: Thu, 27 Mar 2025 11:38:52 +0100 Subject: [PATCH] =?UTF-8?q?Refactor=20Pok=C3=A9mon=20detail=20display=20an?= =?UTF-8?q?d=20improve=20error=20handling=20in=20data=20fetching?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- v2/detail.html | 2 +- v2/get-pokemon.php | 67 +++++++----- v2/pokemon-detail.js | 27 +++-- v2/pokemon.js | 237 ++++--------------------------------------- v2/style.css | 4 + 5 files changed, 82 insertions(+), 255 deletions(-) diff --git a/v2/detail.html b/v2/detail.html index e07dfaa..c3c1c53 100644 --- a/v2/detail.html +++ b/v2/detail.html @@ -64,7 +64,7 @@
-

Move

+

Abilities

diff --git a/v2/get-pokemon.php b/v2/get-pokemon.php index 4007a3f..0e3e9c5 100644 --- a/v2/get-pokemon.php +++ b/v2/get-pokemon.php @@ -17,7 +17,10 @@ $conn = new mysqli($servername, $username, $password, $dbname); if ($conn->connect_error) { logMessage("Connection failed: " . $conn->connect_error); - die("Connection failed: " . $conn->connect_error); + header("Content-Type: application/json"); + http_response_code(500); + echo json_encode(["error" => "Database connection failed"]); + exit; } header("Cache-Control: max-age=86400"); // Cache for 24 hours @@ -25,7 +28,17 @@ header("Content-Type: application/json"); // Ensure JSON response if (isset($_GET['id'])) { $id = intval($_GET['id']); - $sql = "SELECT p.*, s.flavor_text, GROUP_CONCAT(t.name) AS types, GROUP_CONCAT(a.name) AS abilities, st.hp, st.attack, st.defense, st.sp_attack, st.sp_defense, st.speed + if ($id <= 0) { + logMessage("Invalid Pokémon ID: $id"); + echo json_encode(["error" => "Invalid Pokémon ID"]); + exit; + } + + $sql = "SELECT p.*, + COALESCE(s.flavor_text, '') AS flavor_text, + GROUP_CONCAT(DISTINCT t.name) AS types, + GROUP_CONCAT(DISTINCT a.name) AS abilities, + st.hp, st.attack, st.defense, st.sp_attack, st.sp_defense, st.speed FROM pokemon p LEFT JOIN species s ON p.id = s.pokemon_id LEFT JOIN pokemon_types pt ON p.id = pt.pokemon_id @@ -38,37 +51,41 @@ if (isset($_GET['id'])) { logMessage("Executing query: $sql"); $result = $conn->query($sql); - if ($result) { - if ($result->num_rows > 0) { - $pokemon = $result->fetch_assoc(); - $pokemon['types'] = explode(',', $pokemon['types']); - $pokemon['abilities'] = explode(',', $pokemon['abilities']); - logMessage("Query result: " . json_encode($pokemon)); - echo json_encode($pokemon); - } else { - logMessage("No Pokémon found for ID: $id"); - echo json_encode(["error" => "No Pokémon found"]); - } - } else { + if ($result === false) { logMessage("Error executing query: " . $conn->error); - echo json_encode(["error" => "Error fetching Pokémon data"]); + echo json_encode(["error" => "Error executing query"]); + exit; + } + + if ($result->num_rows > 0) { + $pokemon = $result->fetch_assoc(); + $pokemon['types'] = $pokemon['types'] ? explode(',', $pokemon['types']) : []; + $pokemon['abilities'] = $pokemon['abilities'] ? explode(',', $pokemon['abilities']) : []; + logMessage("Query result: " . json_encode($pokemon)); + echo json_encode($pokemon); + } else { + logMessage("No Pokémon found for ID: $id"); + echo json_encode(["error" => "No Pokémon found"]); } } else { - $sql = "SELECT * FROM pokemon"; + // Handle requests without an 'id' parameter + $sql = "SELECT id, name, height, weight, base_experience, image_url FROM pokemon"; logMessage("Executing query: $sql"); $result = $conn->query($sql); - if ($result) { - $pokemons = []; - while ($row = $result->fetch_assoc()) { - $pokemons[] = $row; - } - logMessage("Query result: " . json_encode($pokemons)); - echo json_encode($pokemons); - } else { + if ($result === false) { logMessage("Error executing query: " . $conn->error); - echo json_encode(["error" => "Error fetching Pokémon data"]); + echo json_encode(["error" => "Error executing query"]); + exit; } + + $pokemons = []; + while ($row = $result->fetch_assoc()) { + $pokemons[] = $row; + } + + logMessage("Query result: " . json_encode($pokemons)); + echo json_encode($pokemons); } $conn->close(); diff --git a/v2/pokemon-detail.js b/v2/pokemon-detail.js index cb0d5b9..440f2ec 100644 --- a/v2/pokemon-detail.js +++ b/v2/pokemon-detail.js @@ -25,6 +25,9 @@ async function loadPokemon(id) { 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" ); @@ -32,26 +35,22 @@ async function loadPokemon(id) { if (currentPokemonId === id) { displayPokemonDetails(pokemon); - document.querySelector(".body3-fonts.pokemon-description").textContent = - pokemon.flavor_text; + // 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.removeEventListener("click", navigatePokemon); - rightArrow.removeEventListener("click", navigatePokemon); + leftArrow.classList.toggle("hidden", id === 1); + rightArrow.classList.toggle("hidden", id === 1050); - if (id !== 1) { - leftArrow.addEventListener("click", () => { - navigatePokemon(id - 1); - }); - } - if (id !== 1050) { - rightArrow.addEventListener("click", () => { - navigatePokemon(id + 1); - }); - } + 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}`); } diff --git a/v2/pokemon.js b/v2/pokemon.js index 2e324bc..91295f8 100644 --- a/v2/pokemon.js +++ b/v2/pokemon.js @@ -3,52 +3,37 @@ const CACHE_DURATION = 24 * 60 * 60 * 1000; // 24 hours in milliseconds const listWrapper = document.querySelector(".list-wrapper"); const searchInput = document.querySelector("#search-input"); - const numberAscFilter = document.querySelector("#number-asc"); - const numberDescFilter = document.querySelector("#number-desc"); - const nameAscFilter = document.querySelector("#name-asc"); - const nameDescFilter = document.querySelector("#name-desc"); const notFoundMessage = document.querySelector("#not-found-message"); - const competitorsWrapper = document.querySelector("#competitors-wrapper"); let allPokemons = []; let filteredPokemons = []; document.addEventListener("DOMContentLoaded", () => { - const cachedData = localStorage.getItem("pokemons"); - const cacheTimestamp = localStorage.getItem("pokemons_timestamp"); - - if (cachedData && cacheTimestamp && (Date.now() - cacheTimestamp) < CACHE_DURATION) { - allPokemons = JSON.parse(cachedData); - console.log("Loaded Pokémon data from cache:", allPokemons); - filteredPokemons = allPokemons.filter(pokemon => !pokemon.deleted); - displayPokemons(filteredPokemons); - fetchCompetitors(); - } else { - fetchPokemons(); - } + fetchPokemons(); }); function fetchPokemons() { console.log("Fetching Pokémon data from server..."); fetch(`./get-pokemon.php`) - .then((response) => response.text()) - .then((text) => { - console.log("Server response:", text); - try { - const data = JSON.parse(text); - if (Array.isArray(data)) { - allPokemons = data; - localStorage.setItem("pokemons", JSON.stringify(allPokemons)); - localStorage.setItem("pokemons_timestamp", Date.now().toString()); - console.log("Fetched and cached Pokémon data:", allPokemons); - filteredPokemons = allPokemons.filter(pokemon => !pokemon.deleted); - displayPokemons(filteredPokemons); - fetchCompetitors(); - } else { - console.error("Unexpected response format:", data); - } - } catch (error) { - console.error("Error parsing JSON:", error); + .then((response) => { + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`); + } + return response.json(); + }) + .then((data) => { + if (data.error) { + console.error("Error from server:", data.error); + return; + } + + if (Array.isArray(data)) { + allPokemons = data; + console.log("Fetched Pokémon data:", allPokemons); + filteredPokemons = allPokemons; + displayPokemons(filteredPokemons); + } else { + console.error("Unexpected response format:", data); } }) .catch((error) => { @@ -56,28 +41,6 @@ }); } - async function fetchPokemonDataBeforeRedirect(id) { - try { - console.log(`Fetching data for Pokémon ID ${id} before redirect...`); - const response = await fetch(`./get-pokemon.php?id=${id}`); - const text = await response.text(); - console.log(`Response for Pokémon ID ${id}:`, text); - if (!text) { - throw new Error("Empty response from server"); - } - const pokemon = JSON.parse(text); - - if (pokemon.error) { - throw new Error(pokemon.error); - } - - return true; - } catch (error) { - console.error(`Failed to fetch Pokémon data before redirect for ID ${id}:`, error); - return false; - } - } - function displayPokemons(pokemons) { console.log("Displaying Pokémon data:", pokemons); listWrapper.innerHTML = ""; @@ -90,176 +53,20 @@

#${pokemon.id}

- ${pokemon.name} + ${pokemon.name}

${pokemon.name}

`; - listItem.addEventListener("click", async () => { - const success = await fetchPokemonDataBeforeRedirect(pokemon.id); - if (success) { - window.location.href = `./detail.html?id=${pokemon.id}`; - } else { - console.error(`Failed to fetch data for Pokémon ID: ${pokemon.id}`); - } - }); - listWrapper.appendChild(listItem); }); - lazyLoadImages(); - } - - function lazyLoadImages() { - console.log("Initializing lazy loading for images..."); - const images = document.querySelectorAll('.img-wrap img[data-src]'); - const config = { - root: null, - rootMargin: '0px', - threshold: 0.1 - }; - - let observer = new IntersectionObserver((entries, self) => { - entries.forEach(entry => { - if (entry.isIntersecting) { - preloadLowResImage(entry.target); - self.unobserve(entry.target); - } - }); - }, config); - - images.forEach(image => { - observer.observe(image); - }); - } - - function preloadLowResImage(img) { - const srcLow = img.getAttribute('data-src-low'); - if (!srcLow) { - return; - } - console.log("Preloading low-resolution image:", srcLow); - img.src = srcLow; - preloadHighResImage(img); - } - - function preloadHighResImage(img) { - const src = img.getAttribute('data-src'); - if (!src) { - return; - } - const highResImg = new Image(); - highResImg.src = src; - highResImg.onload = () => { - console.log("Preloading high-resolution image:", src); - setTimeout(() => { - img.src = src; - }, 2000); // Wait for 2 seconds before switching to high-resolution image - }; - } - - searchInput.addEventListener("keyup", handleSearch); - numberAscFilter.addEventListener("change", handleSort); - numberDescFilter.addEventListener("change", handleSort); - nameAscFilter.addEventListener("change", handleSort); - nameDescFilter.addEventListener("change", handleSort); - - function handleSearch() { - const searchTerm = searchInput.value.toLowerCase(); - console.log("Handling search with term:", searchTerm); - - filteredPokemons = allPokemons.filter((pokemon) => { - const pokemonID = pokemon.id.toString(); - const pokemonName = pokemon.name.toLowerCase(); - return (pokemonID.startsWith(searchTerm) || pokemonName.startsWith(searchTerm)) && !pokemon.deleted; - }); - - displayPokemons(filteredPokemons); - - if (filteredPokemons.length === 0) { + if (pokemons.length === 0) { notFoundMessage.style.display = "block"; } else { notFoundMessage.style.display = "none"; } } - - function handleSort() { - if (numberAscFilter.checked) { - filteredPokemons.sort((a, b) => a.id - b.id); - } else if (numberDescFilter.checked) { - filteredPokemons.sort((a, b) => b.id - a.id); - } else if (nameAscFilter.checked) { - filteredPokemons.sort((a, b) => a.name.localeCompare(b.name)); - } else if (nameDescFilter.checked) { - filteredPokemons.sort((a, b) => b.name.localeCompare(a.name)); - } - - displayPokemons(filteredPokemons); - } - - const closeButton = document.querySelector(".search-close-icon"); - closeButton.addEventListener("click", clearSearch); - - function clearSearch() { - console.log("Clearing search input and displaying all Pokémon..."); - searchInput.value = ""; - filteredPokemons = allPokemons.filter(pokemon => !pokemon.deleted); - displayPokemons(filteredPokemons); - notFoundMessage.style.display = "none"; - } - - function fetchCompetitors() { - console.log("Fetching competitors data from server..."); - fetch(`./get-competitors.php`) - .then((response) => { - if (!response.ok) { - throw new Error(`HTTP error! status: ${response.status}`); - } - return response.json(); - }) - .then((data) => { - if (data.error) { - console.error("Error from server:", data.error); - displayCompetitorsError(data.error); - } else { - displayCompetitors(data); - } - }) - .catch((error) => { - console.error("Error fetching competitors data:", error); - displayCompetitorsError("Failed to load competitors data. Please try again later."); - }); - } - - function displayCompetitorsError(message) { - const competitorsWrapper = document.querySelector("#competitors-wrapper"); - competitorsWrapper.innerHTML = `

${message}

`; - } - - function displayCompetitors(competitors) { - competitorsWrapper.innerHTML = ""; - - competitors.forEach((competitor) => { - const listItem = document.createElement("div"); - listItem.className = "list-item"; - listItem.innerHTML = ` -
-

User ID: ${competitor.user_id}

-
-
- ${competitor.name} -
-
-

${competitor.name}

-
-
-

Pokémon Count: ${competitor.pokemon_count}

-
- `; - - competitorsWrapper.appendChild(listItem); - }); - } })(); diff --git a/v2/style.css b/v2/style.css index 114acdb..b602299 100644 --- a/v2/style.css +++ b/v2/style.css @@ -79,6 +79,10 @@ input:focus-visible { display: none; } +.arrow.hidden { + display: none; +} + body { margin: 0; height: 100vh;