diff --git a/assets/css/pokedex.css b/assets/css/pokedex.css
index 59eef2bde..0af8a2cd3 100644
--- a/assets/css/pokedex.css
+++ b/assets/css/pokedex.css
@@ -82,18 +82,16 @@
display: flex;
flex-direction: column;
margin: .5rem;
- padding: 1rem;
- border-radius: 1rem;
}
-.pokemon .number {
+.pokemon .pokemonNameAndId .number {
color: #000;
opacity: .3;
text-align: right;
font-size: .625rem;
}
-.pokemon .name {
+.pokemon .pokemonNameAndId .name {
text-transform: capitalize;
color: #fff;
margin-bottom: .25rem;
@@ -104,6 +102,7 @@
flex-direction: row;
align-items: center;
justify-content: space-between;
+ width: 100%;
}
.pokemon .detail .types {
@@ -146,20 +145,193 @@
border-radius: 1rem;
}
+.pokemonButton {
+ display: flex;
+ flex-direction: column;
+ flex-wrap: wrap;
+ padding: 1rem;
+ width: 100%;
+ border: none;
+ border-radius: 1rem;
+ cursor: pointer;
+}
+
+.pokemonNameAndId {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ width: 100%;
+ margin: 0px;
+}
+
+.modal {
+ display: none;
+ position: fixed;
+ z-index: 1;
+ padding-top: 100px;
+ left: 0;
+ top: 0;
+ width: 100%;
+ height: 100%;
+ overflow: auto;
+ }
+
+ .modal-content {
+ display: flex;
+ flex-direction: column;
+ flex-wrap: nowrap;
+ align-items: center;
+ justify-content: center;
+ box-shadow: rgba(0, 0, 0, 0.19) 0px 10px 20px, rgba(0, 0, 0, 0.23) 0px 6px 6px;
+ margin: auto;
+ padding: 1rem;
+ border: none;
+ border-radius: 2rem;
+ width: 20%;
+ height: 80%;
+ }
+
+ .modal-content > span {
+ width: 15%;
+ }
+
+ .stats-content {
+ display: flex;
+ flex-flow: column nowrap;
+ justify-content: center;
+ align-items: center;
+ width: 100%;
+ }
+
+ #pokemonName {
+ font-family: "Anton", sans-serif;
+ font-weight: 400;
+ font-style: normal;
+ color: white;
+ text-transform: uppercase;
+ margin: 1rem 0 0;
+ }
+
+ .stats-content > img {
+ width: 100%;
+ background-color: #fff;
+ box-shadow: rgba(14, 30, 37, 0.12) 0px 2px 4px 0px, rgba(14, 30, 37, 0.32) 0px 2px 16px 0px;
+ border-radius: 50%;
+ }
+
+ .stats-content > h2 {
+ color: white;
+ text-transform: capitalize;
+ font-family: "Anton", sans-serif;
+ font-weight: 400;
+ font-style: normal;
+ font-size: 1.25rem;
+ }
+
+ .pokemon-stats {
+ display: flex;
+ flex-flow: row nowrap;
+ align-items: center;
+ justify-content: space-around;
+ width: 100%;
+ }
+
+ .stats {
+ display: flex;
+ flex-flow: column nowrap;
+ justify-content: center;
+ align-items: center;
+ background-color: #fff;
+ border-radius: 0.625rem;
+ min-width: 3.5rem;
+ padding: 5px
+ }
+
+ .stats > span:first-child {
+ color: #6a6262;
+ font-size: 0.625rem;
+ }
+
+ .stats > span:last-child {
+ color: #000;
+ font-size: 1.25rem;
+ font-weight: 700;
+ }
+
+ /* The Close Button */
+ .close {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ color: #4f4e4e;
+ float: right;
+ font-size: 2rem;
+ border: 2px solid #4f4e4e;
+ border-radius: 50%;
+ font-weight: bold;
+ }
+
+ .close:hover,
+ .close:focus {
+ color: #000;
+ text-decoration: none;
+ border: 2px solid #000;
+ cursor: pointer;
+ }
+
@media screen and (min-width: 380px) {
.pokemons {
grid-template-columns: 1fr 1fr;
}
+
+ .modal-content {
+ width: 60%;
+ margin: 0 auto;
+ }
+
+ #pokemonName {
+ font-size: 1.25rem;
+ }
+
+ .stats-content > img {
+ width: 80%;
+ }
}
@media screen and (min-width: 576px) {
.pokemons {
grid-template-columns: 1fr 1fr 1fr;
}
+
+ .modal-content {
+ width: 40%;
+ margin: 0 auto;
+ }
+
+ #pokemonName {
+ font-size: 1.5rem;
+ }
+
+ .stats-content > img {
+ width: 70%;
+ }
}
@media screen and (min-width: 992px) {
.pokemons {
grid-template-columns: 1fr 1fr 1fr 1fr;
}
+
+ .modal-content {
+ width: 20%;
+ margin: 0 auto;
+ }
+
+ #pokemonName {
+ font-size: 2rem;
+ }
+
+ .stats-content > img {
+ width: 100%;
+ }
}
\ No newline at end of file
diff --git a/assets/js/main.js b/assets/js/main.js
index bcaa24508..9ebe35364 100644
--- a/assets/js/main.js
+++ b/assets/js/main.js
@@ -1,5 +1,6 @@
const pokemonList = document.getElementById('pokemonList')
const loadMoreButton = document.getElementById('loadMoreButton')
+let pokemonButtons;
const maxRecords = 151
const limit = 10
@@ -7,32 +8,64 @@ let offset = 0;
function convertPokemonToLi(pokemon) {
return `
-
- #${pokemon.number}
- ${pokemon.name}
-
-
-
- ${pokemon.types.map((type) => `- ${type}
`).join('')}
-
-
-
-
+
+
`
}
-function loadPokemonItens(offset, limit) {
- pokeApi.getPokemons(offset, limit).then((pokemons = []) => {
- const newHtml = pokemons.map(convertPokemonToLi).join('')
- pokemonList.innerHTML += newHtml
- })
+async function loadPokemonItens(offset, limit) {
+ try {
+ const pokemons = await pokeApi.getPokemons(offset, limit);
+ const newHtml = pokemons.map(convertPokemonToLi).join('');
+ pokemonList.innerHTML += newHtml;
+ return pokemons;
+ } catch (error) {
+ console.error('Error loading Pokemon items:', error);
+ }
+}
+
+function getPokemonButtons () {
+ const pokemonButtons = document.querySelectorAll('.pokemonButton')
+ return pokemonButtons
}
loadPokemonItens(offset, limit)
-loadMoreButton.addEventListener('click', () => {
+const observer = new MutationObserver(function(mutations) {
+ mutations.forEach(function(mutation) {
+ // Verifica se houve alterações no conteúdo do elemento
+ if (mutation.type === 'childList') {
+ // O conteúdo da lista ordenada foi modificado
+ pokemonButtons = getPokemonButtons()
+ pokemonButtons.forEach(addPokemonButtonClickHandler);
+ // Aqui você pode fazer o que precisar em resposta às alterações no conteúdo da lista
+ }
+ });
+});
+
+// Configura as opções para observar alterações no conteúdo da lista ordenada
+const config = { childList: true, subtree: true };
+
+// Inicia a observação no elemento com as opções configuradas
+observer.observe(pokemonList, config);
+
+
+loadMoreButton.addEventListener('click', async () => {
offset += limit
const qtdRecordsWithNexPage = offset + limit
@@ -44,4 +77,6 @@ loadMoreButton.addEventListener('click', () => {
} else {
loadPokemonItens(offset, limit)
}
-})
\ No newline at end of file
+})
+
+
diff --git a/assets/js/poke-api.js b/assets/js/poke-api.js
index 38fbfd465..4dac36684 100644
--- a/assets/js/poke-api.js
+++ b/assets/js/poke-api.js
@@ -13,23 +13,39 @@ function convertPokeApiDetailToPokemon(pokeDetail) {
pokemon.type = type
pokemon.photo = pokeDetail.sprites.other.dream_world.front_default
+ pokemon.alternativePhoto = pokeDetail.sprites.other.home.front_default
+ pokemon.stats = pokeDetail.stats;
return pokemon
}
-pokeApi.getPokemonDetail = (pokemon) => {
- return fetch(pokemon.url)
- .then((response) => response.json())
- .then(convertPokeApiDetailToPokemon)
-}
-
-pokeApi.getPokemons = (offset = 0, limit = 5) => {
- const url = `https://pokeapi.co/api/v2/pokemon?offset=${offset}&limit=${limit}`
-
- return fetch(url)
- .then((response) => response.json())
- .then((jsonBody) => jsonBody.results)
- .then((pokemons) => pokemons.map(pokeApi.getPokemonDetail))
- .then((detailRequests) => Promise.all(detailRequests))
- .then((pokemonsDetails) => pokemonsDetails)
-}
+pokeApi.getPokemonDetail = async (pokemon) => {
+ try {
+ const response = await fetch(pokemon.url);
+ const pokeDetail = await response.json();
+ const convertedPokemon = convertPokeApiDetailToPokemon(pokeDetail);
+ return convertedPokemon;
+ } catch (error) {
+ console.error('Error fetching Pokemon detail:', error);
+ return null; // Ou outra maneira de lidar com o erro, como lançar uma exceção
+ }
+};
+
+
+pokeApi.getPokemons = async (offset = 0, limit = 5) => {
+ const url = `https://pokeapi.co/api/v2/pokemon?offset=${offset}&limit=${limit}`;
+
+ try {
+ const response = await fetch(url);
+ const jsonBody = await response.json();
+ const pokemons = jsonBody.results;
+
+ const detailRequests = pokemons.map(pokemon => pokeApi.getPokemonDetail(pokemon));
+ const pokemonsDetails = await Promise.all(detailRequests);
+
+ return pokemonsDetails;
+ } catch (error) {
+ console.error('Error fetching Pokemon data:', error);
+ return [];
+ }
+};
diff --git a/assets/js/pokemon-modal.js b/assets/js/pokemon-modal.js
new file mode 100644
index 000000000..f3f3cd9e4
--- /dev/null
+++ b/assets/js/pokemon-modal.js
@@ -0,0 +1,66 @@
+const modal = document.getElementById("myModal");
+const span = document.getElementsByClassName("close")[0];
+
+async function createModal(pokemonDetail) {
+ const modalContent = document.getElementsByClassName('modal-content');
+ modalContent[0].classList.add(`${pokemonDetail.type}`);
+ modal.style.display = "block";
+
+ const content = document.createElement('div');
+ content.classList.add('stats-content');
+ content.innerHTML = `
+ ${pokemonDetail.name}
+
+ About
+
+
+ HP
+ ${pokemonDetail.stats[0].base_stat}
+
+
+ Attack
+ ${pokemonDetail.stats[1].base_stat}
+
+
+ Defense
+ ${pokemonDetail.stats[2].base_stat}
+
+
+ Speed
+ ${pokemonDetail.stats[5].base_stat}
+
+
+ `
+ modalContent[0].appendChild(content);
+
+ span.onclick = function() {
+ modal.style.display = "none";
+ modalContent[0].removeChild(content)
+ modalContent[0].classList.remove(`${pokemonDetail.type}`);
+ }
+
+ window.onclick = function(event) {
+ if (event.target == modal) {
+ modal.style.display = "none";
+ modalContent[0].removeChild(content)
+ modalContent[0].classList.remove(`${pokemonDetail.type}`);
+ }
+ }
+}
+
+// Adiciona um manipulador de evento de clique a cada botão Pokémon
+function addPokemonButtonClickHandler(pokemonButton) {
+ pokemonButton.addEventListener('click', async () => {
+ const pokemonName = pokemonButton.querySelector('.name').innerHTML;
+ try {
+ const pokemonDetail = await pokeApi.getPokemonDetail({
+ url: `https://pokeapi.co/api/v2/pokemon/${pokemonName}`
+ });
+ if (pokemonDetail) {
+ await createModal(pokemonDetail);
+ }
+ } catch (error) {
+ console.error('Error loading Pokemon detail:', error);
+ }
+ });
+}
diff --git a/assets/js/pokemon-model.js b/assets/js/pokemon-model.js
index b0d17bb90..3120639a8 100644
--- a/assets/js/pokemon-model.js
+++ b/assets/js/pokemon-model.js
@@ -5,4 +5,6 @@ class Pokemon {
type;
types = [];
photo;
+ alternativePhoto;
+ stats = [];
}
diff --git a/index.html b/index.html
index 1a017821d..2ba92f19b 100644
--- a/index.html
+++ b/index.html
@@ -15,7 +15,7 @@
-
+
@@ -37,9 +37,17 @@ Pokedex
+
+
+
+