Skip to content

Commit

Permalink
feat: pokemon details page display
Browse files Browse the repository at this point in the history
  • Loading branch information
felixtanhm committed May 7, 2024
1 parent 51ca86c commit 05d3144
Show file tree
Hide file tree
Showing 7 changed files with 188 additions and 46 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,15 @@ function App() {
const urlPath = useLocation().pathname.split("/")[1];
const root = document.getElementById("root");
const [darkMode, setDarkMode] = useState(
window.matchMedia("(prefers-color-scheme: dark)").matches
window.matchMedia("(prefers-color-scheme: dark)").matches,
);

darkMode ? root.classList.add("dark") : root.classList.remove("dark");

return (
<DarkModeContext.Provider value={{ darkMode, setDarkMode }}>
<div>
<NavBar route={urlPath} toggleDarkMode={setDarkMode} />
<Outlet />
</div>
<NavBar route={urlPath} toggleDarkMode={setDarkMode} />
<Outlet />
</DarkModeContext.Provider>
);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
import PokeList from "./PokeList";

function Home() {
return (
<div>
<PokeList />
</div>
);
return <PokeList />;
}

export default Home;
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,11 @@ function PokeCard({ pokemon }) {
console.log(dexId);
}

function displayPokemon(e, dexId) {
console.log(e);
console.log(dexId);
navigate(`/pokemon/${dexId}`);
}

return (
<div
className="flex cursor-pointer flex-col items-center rounded-md bg-gray-200 p-4 dark:bg-gray-500/20"
onClick={(e) => {
displayPokemon(e, pokemon.dexId);
onClick={() => {
navigate(`/pokemon/${pokemon.dexId}`);
}}
>
<div className="absolute self-end">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,25 +1,179 @@
import { useParams } from "react-router-dom";
import { useState } from "react";
import PokeType from "./PokeType";
import capitalise from "../utils/capitalise";
import { HeartIcon as HeartIconOutline } from "@heroicons/react/24/outline";
import { HeartIcon as HeartIconSolid } from "@heroicons/react/24/solid";

function PokeDetails() {
const params = useParams();
const endpoint = "http://localhost:3000/pokemon/" + params.pokemonId;
const [currPokemon, setCurrPokemon] = useState(null);
const [state, setState] = useState("loading");

function toggleFavorite(e, dexId) {
e.stopPropagation();
console.log(dexId);
}

async function fetchPokemon() {
try {
const response = await fetch(endpoint);
const result = await response.json();
const response = await fetch(
`http://localhost:3000/pokemon/${params.dexId}`,
);

if (!response.ok) {
let errorMessage = `Failed to fetch data. Status: ${response.status}`;
if (response.statusText) {
errorMessage += `, Message: ${response.statusText}`;
}
throw new Error(errorMessage);
}

console.log(result);
const result = await response.json();
setCurrPokemon(result);
setState("success");
} catch (error) {
console.log(error);
setState("error");
}
}

fetchPokemon();
if (!currPokemon) fetchPokemon();

return (
<div>
<div>Main Details</div>
<div>Pokemon: {params.pokemonId}</div>
<div className="flex flex-col items-center gap-4 p-4 pb-12 sm:p-6 lg:p-8 dark:bg-gray-800">
{state === "error" && <p className="h-screen">Error para</p>}
{state === "loading" && !currPokemon && (
<p className="h-screen">Loading...</p>
)}
{currPokemon && (
<>
{/* Buttons */}
<div className="flex w-full justify-between gap-4 md:w-96">
<button className="w-20 rounded-md bg-gray-200 px-3 py-2 text-sm font-medium text-gray-900 hover:bg-gray-100 dark:bg-gray-500/20 dark:text-gray-300 dark:hover:bg-gray-700">
Previous
</button>
<button
type="button"
className="w-32 rounded-md bg-gray-200 px-3 py-2 text-sm font-medium text-gray-900 hover:bg-gray-100 dark:bg-gray-500/20 dark:text-gray-300 dark:hover:bg-gray-700"
onClick={(e) => {
toggleFavorite(e, currPokemon.dexId);
}}
>
<span className="sr-only">Favorite Pokemon</span>
<HeartIconOutline className="h-6 w-full" aria-hidden="true" />
</button>
<button className="w-20 rounded-md bg-gray-200 px-3 py-2 text-sm font-medium text-gray-900 hover:bg-gray-100 dark:bg-gray-500/20 dark:text-gray-300 dark:hover:bg-gray-700">
Next
</button>
</div>
<img
className="mt-6 min-w-28 max-w-24"
src={currPokemon.avatar}
></img>
{/* Name and Types */}
<div className="flex w-full flex-col items-center gap-4 p-2 md:w-96">
<h1 className="text-3xl font-bold text-gray-900 dark:text-gray-300">
{capitalise(currPokemon.name)}
</h1>
<div className="flex gap-2">
{currPokemon.types.map((type) => {
return <PokeType key={type} type={capitalise(type)} />;
})}
</div>
</div>
{/* Details */}
<div className="grid w-full grid-cols-2 gap-x-6 gap-y-4 rounded-md bg-gray-200 p-4 md:w-96 dark:bg-gray-500/20">
<div>
<p className="text-lg font-bold text-gray-900 dark:text-gray-300">
Height:
</p>
<p className="font-medium text-gray-900 dark:text-gray-300">
{currPokemon.details.height / 10 + " m"}
</p>
</div>
<div>
<p className="text-lg font-bold text-gray-900 dark:text-gray-300">
Weight:
</p>
<p className="font-medium text-gray-900 dark:text-gray-300">
{currPokemon.details.weight / 10 + " kg"}
</p>
</div>
<div>
<p className="text-lg font-bold text-gray-900 dark:text-gray-300">
Abilities:
</p>
<p className="font-medium text-gray-900 dark:text-gray-300">
{currPokemon.details.abilities
.map((ability) => {
return capitalise(ability);
})
.join(", ")}
</p>
</div>
<div>
<p className="text-lg font-bold text-gray-900 dark:text-gray-300">
Gender:
</p>
<p className="font-medium text-gray-900 dark:text-gray-300">
{currPokemon.details.has_gender ? "♂️ / ♀️" : ""}
</p>
</div>
</div>
{/* Stats */}
<div className="grid w-full grid-cols-2 gap-x-6 gap-y-2 rounded-md bg-gray-200 p-4 md:w-96 dark:bg-gray-500/20">
<div>
<p className="text-md font-bold text-gray-900 dark:text-gray-300">
HP:
</p>
<p className="font-medium text-gray-900 dark:text-gray-300">
{currPokemon.details.hp}
</p>
</div>
<div>
<p className="text-md font-bold text-gray-900 dark:text-gray-300">
Attack:
</p>
<p className="font-medium text-gray-900 dark:text-gray-300">
{currPokemon.details.attack}
</p>
</div>
<div>
<p className="text-md font-bold text-gray-900 dark:text-gray-300">
Defense:
</p>
<p className="font-medium text-gray-900 dark:text-gray-300">
{currPokemon.details.defense}
</p>
</div>
<div>
<p className="text-md font-bold text-gray-900 dark:text-gray-300">
Special Attack:
</p>
<p className="font-medium text-gray-900 dark:text-gray-300">
{currPokemon.details.special_attack}
</p>
</div>
<div>
<p className="text-md font-bold text-gray-900 dark:text-gray-300">
Special Defense:
</p>
<p className="font-medium text-gray-900 dark:text-gray-300">
{currPokemon.details.special_defense}
</p>
</div>
<div>
<p className="text-md font-bold text-gray-900 dark:text-gray-300">
Speed:
</p>
<p className="font-medium text-gray-900 dark:text-gray-300">
{currPokemon.details.speed}
</p>
</div>
</div>
</>
)}
</div>
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@ function PokeList() {
const [list, setList] = useState(null);
const [state, setState] = useState("loading");
const [error, setError] = useState(null);
console.log("list");

console.log(list);
async function fetchList(currData) {
try {
const nextId = currData.length;
const nextId = currData.length
? currData[currData.length - 1]?.dexId
: currData.length;

const response = await fetch(
`http://localhost:3000/pokemon?cursor=${nextId}`,
);
Expand Down Expand Up @@ -39,34 +40,33 @@ function PokeList() {
}
}

if (state === "error") {
return <p>error</p>;
}

if (!list) {
fetchList([]);
}

return (
<div className="flex flex-col items-center gap-8 p-4 pb-12 sm:p-6 lg:p-8 dark:bg-gray-800">
{state === "loading" && !list && <p>Loading...</p>}
{state === "error" && <p className="h-screen">Error</p>}
{state === "loading" && !list && <p className="h-screen">Loading...</p>}
{list && (
<>
<div className="grid w-full max-w-7xl grid-cols-2 gap-4 sm:grid-cols-4 lg:grid-cols-6">
{list.data.map((item) => {
return <PokeCard pokemon={item} key={item._id}></PokeCard>;
})}
</div>
<button
className="w-fit min-w-32 rounded-md bg-gray-200 px-3 py-2 text-sm font-medium text-gray-900 hover:bg-gray-300 dark:hover:bg-gray-100"
disabled={state === "loading"}
onClick={(e) => {
setState("loading");
fetchList(list.data);
}}
>
{state === "loading" ? "Loading..." : "Load More"}
</button>
{list.data.length < 151 && (
<button
className="w-fit min-w-32 rounded-md bg-gray-200 px-3 py-2 text-sm font-medium text-gray-900 hover:bg-gray-300 dark:hover:bg-gray-100"
disabled={state === "loading"}
onClick={() => {
setState("loading");
fetchList(list.data);
}}
>
{state === "loading" ? "Loading..." : "Load More"}
</button>
)}
</>
)}
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ const router = createBrowserRouter(
createRoutesFromElements(
<Route path="/" element={<App />}>
<Route index element={<Home text="home" />}></Route>
<Route path="pokemon/:pokemonId" element={<PokeDetails />}></Route>
<Route path="pokemon/:dexId" element={<PokeDetails />}></Route>
<Route path="favorites" element={<Test text="favs" />}></Route>
</Route>,
),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export default {
ice: "#98D8D8",
fairy: "#F0B6BC",
poison: "#A040A0",
psychic: "#F8588",
psychic: "#F85888",
dark: "#705848",
fighting: "#C03028",
dragon: "#7038F8",
Expand Down

0 comments on commit 05d3144

Please sign in to comment.