Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add pokemon details modal #284

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
180 changes: 176 additions & 4 deletions assets/css/pokedex.css
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -104,6 +102,7 @@
flex-direction: row;
align-items: center;
justify-content: space-between;
width: 100%;
}

.pokemon .detail .types {
Expand Down Expand Up @@ -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%;
}
}
73 changes: 54 additions & 19 deletions assets/js/main.js
Original file line number Diff line number Diff line change
@@ -1,38 +1,71 @@
const pokemonList = document.getElementById('pokemonList')
const loadMoreButton = document.getElementById('loadMoreButton')
let pokemonButtons;

const maxRecords = 151
const limit = 10
let offset = 0;

function convertPokemonToLi(pokemon) {
return `
<li class="pokemon ${pokemon.type}">
<span class="number">#${pokemon.number}</span>
<span class="name">${pokemon.name}</span>

<div class="detail">
<ol class="types">
${pokemon.types.map((type) => `<li class="type ${type}">${type}</li>`).join('')}
</ol>

<img src="${pokemon.photo}"
alt="${pokemon.name}">
</div>
<li class="pokemon">
<button class="pokemonButton ${pokemon.type}">
<div class="pokemonNameAndId">
<span class="name">${pokemon.name}</span>
<span class="number">#${pokemon.number}</span>
</div>

<div class="detail">
<ol class="types">
${pokemon.types.map((type) => `<li class="type ${type}">${type}</li>`).join('')}
</ol>

<img src="${pokemon.photo}"
alt="${pokemon.name}">
</div>
</button>
</li>
`
}

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 <ol>
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 <ol> com as opções configuradas
observer.observe(pokemonList, config);


loadMoreButton.addEventListener('click', async () => {
offset += limit
const qtdRecordsWithNexPage = offset + limit

Expand All @@ -44,4 +77,6 @@ loadMoreButton.addEventListener('click', () => {
} else {
loadPokemonItens(offset, limit)
}
})
})


48 changes: 32 additions & 16 deletions assets/js/poke-api.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 [];
}
};
Loading