Commit e8cfd6a8 by Endrew

Iniciando o projeto CRUD e estrutura de pastas

parents
<!DOCTYPE html>
<html lang="pt-BR">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Pokémon Team Builder</title>
<link rel="stylesheet" href="style.css">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600;700&display=swap"
rel="stylesheet">
</head>
<body>
<header>
Pokémon MEMV
</header>
<div class="container">
<!-- BOTÕES DOS TIMES -->
<div class="times">
<button class="time-btn active" onclick="trocarTime('Time 1', this)">
Time 1
</button>
<button class="time-btn" onclick="trocarTime('Time 2', this)">
Time 2
</button>
<button class="time-btn" onclick="trocarTime('Time 3', this)">
Time 3
</button>
<button class="time-btn" onclick="trocarTime('Time 4', this)">
Time 4
</button>
</div>
<!-- GRID -->
<div class="grid">
<!-- FORM -->
<div class="card">
<h2>Adicionar Pokémon</h2>
<form id="pokemonForm">
<input type="text" id="nome" placeholder="Digite o nome do Pokémon" autocomplete="off" required>
<input type="number" id="level" placeholder="Level" min="1" max="100" required>
<!-- ESCOLHER MEGA -->
<select id="usarMega">
<option value="nao">
Sem Mega Evolução
</option>
<option value="sim">
Utilizar Mega Evolução
</option>
</select>
<button type="submit">
Adicionar Pokémon
</button>
</form>
</div>
<!-- TIME -->
<div class="card">
<h2 id="tituloTime">
Time 1
</h2>
<div class="team-info" id="contador">
0 / 6 Pokémons
<br>
Mega Evolução: 0 / 1
</div>
<div class="pokemon-list" id="pokemonList">
</div>
</div>
</div>
</div>
<script>
/* ELEMENTOS */
const form = document.getElementById("pokemonForm");
const pokemonList = document.getElementById("pokemonList");
const contador = document.getElementById("contador");
const tituloTime = document.getElementById("tituloTime");
let timeAtual = "Time 1";
/* MEGAS */
const megaPokemons = {
venusaur:
"https://play.pokemonshowdown.com/sprites/xyani/venusaur-mega.gif",
charizard:
"https://play.pokemonshowdown.com/sprites/xyani/charizard-mega-x.gif",
blastoise:
"https://play.pokemonshowdown.com/sprites/xyani/blastoise-mega.gif",
gengar:
"https://play.pokemonshowdown.com/sprites/xyani/gengar-mega.gif",
lucario:
"https://play.pokemonshowdown.com/sprites/xyani/lucario-mega.gif",
salamence:
"https://play.pokemonshowdown.com/sprites/xyani/salamence-mega.gif",
rayquaza:
"https://play.pokemonshowdown.com/sprites/xyani/rayquaza-mega.gif",
mewtwo:
"https://play.pokemonshowdown.com/sprites/xyani/mewtwo-mega-y.gif",
tyranitar:
"https://play.pokemonshowdown.com/sprites/xyani/tyranitar-mega.gif",
metagross:
"https://play.pokemonshowdown.com/sprites/xyani/metagross-mega.gif"
};
/* TIMES */
const times = {
"Time 1": [],
"Time 2": [],
"Time 3": [],
"Time 4": []
};
/* TROCAR TIME */
function trocarTime(nomeTime, botao) {
timeAtual = nomeTime;
tituloTime.innerHTML = nomeTime;
document.querySelectorAll(".time-btn")
.forEach(btn => {
btn.classList.remove("active");
});
botao.classList.add("active");
renderizarPokemons();
}
/* ADICIONAR POKEMON */
form.addEventListener("submit", async function (e) {
e.preventDefault();
const nomeInput =
document.getElementById("nome")
.value
.toLowerCase()
.trim()
.replaceAll(" ", "-");
const level =
Number(document.getElementById("level").value);
const megaSelecionada =
document.getElementById("usarMega").value;
/* LEVEL */
if (level > 100) {
alert("O level máximo é 100!");
return;
}
/* TIME CHEIO */
if (times[timeAtual].length >= 6) {
alert("Seu time já possui 6 Pokémons!");
return;
}
try {
/* API */
const resposta =
await fetch(
`https://pokeapi.co/api/v2/pokemon/${nomeInput}`
);
if (!resposta.ok) {
alert("Pokémon não encontrado!");
return;
}
const dados = await resposta.json();
/* NOME */
const nome =
dados.name
.split("-")
.map(p =>
p.charAt(0).toUpperCase() + p.slice(1)
)
.join(" ");
/* TIPOS */
const tipo1 =
dados.types[0].type.name;
const tipo2 =
dados.types[1]
?
dados.types[1].type.name
:
"";
/* IMAGEM NORMAL */
const imagem =
dados.sprites.other["official-artwork"]
.front_default;
/* VERIFICAR MEGA */
const podeMega =
megaPokemons[dados.name];
/* ESCOLHER MEGA */
let usarMega = false;
if (
megaSelecionada === "sim"
&&
podeMega
) {
usarMega = true;
}
/* ERRO */
if (
megaSelecionada === "sim"
&&
!podeMega
) {
alert(
"Esse Pokémon não possui Mega Evolução!"
);
return;
}
/* LIMITAR 1 MEGA */
const jaTemMega =
times[timeAtual].some(p => p.mega);
if (usarMega && jaTemMega) {
alert(
"Seu time já possui uma Mega Evolução!"
);
return;
}
/* IMAGEM FINAL */
let imagemFinal = imagem;
/* IMAGEM MEGA */
if (usarMega) {
imagemFinal =
megaPokemons[dados.name];
}
/* POKEMON */
const pokemon = {
nome:
usarMega
?
`Mega ${nome}`
:
nome,
tipo1,
tipo2,
level,
imagem: imagemFinal,
mega: usarMega
};
times[timeAtual].push(pokemon);
renderizarPokemons();
form.reset();
}
catch (erro) {
alert("Erro ao buscar Pokémon!");
}
});
/* RENDERIZAR */
function renderizarPokemons() {
pokemonList.innerHTML = "";
const megaCount =
times[timeAtual]
.filter(p => p.mega).length;
contador.innerHTML =
`
${times[timeAtual].length} / 6 Pokémons
<br>
Mega Evolução: ${megaCount} / 1
`;
times[timeAtual].forEach((pokemon, index) => {
const card =
document.createElement("div");
card.classList.add("pokemon");
card.innerHTML = `
<div class="pokemon-left">
<img
src="${pokemon.imagem}"
alt="${pokemon.nome}"
>
<div class="pokemon-info">
<h3>
${pokemon.nome}
${pokemon.mega
?
`
<span class="mega-badge">
MEGA
</span>
`
:
""
}
</h3>
<p>
Tipo:
${pokemon.tipo1}
${pokemon.tipo2 ? " / " + pokemon.tipo2 : ""}
</p>
<p>
Level: ${pokemon.level}
</p>
</div>
</div>
<div class="pokemon-right">
<div class="tipos">
<span class="tipo">
${pokemon.tipo1}
</span>
${pokemon.tipo2
?
`
<span class="tipo">
${pokemon.tipo2}
</span>
`
:
""
}
</div>
<button
class="delete-btn"
onclick="removerPokemon(${index})"
>
Remover
</button>
</div>
`;
pokemonList.appendChild(card);
});
}
/* REMOVER */
function removerPokemon(index) {
times[timeAtual].splice(index, 1);
renderizarPokemons();
}
</script>
</body>
</html>
\ No newline at end of file
@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600;700&display=swap');
/* =========================================
RESET
========================================= */
*{
margin:0;
padding:0;
box-sizing:border-box;
font-family:'Poppins',sans-serif;
}
/* =========================================
BODY + CÉU
========================================= */
body{
min-height:100vh;
overflow-x:hidden;
color:white;
position:relative;
background:
linear-gradient(
to bottom,
#38bdf8 0%,
#7dd3fc 25%,
#bae6fd 55%,
#e0f2fe 100%
);
}
/* =========================================
NUVENS
========================================= */
body::before{
content:"";
position:fixed;
inset:0;
z-index:-2;
opacity:0.45;
background:
radial-gradient(circle at 10% 15%, white 0 55px, transparent 60px),
radial-gradient(circle at 18% 18%, white 0 40px, transparent 45px),
radial-gradient(circle at 26% 15%, white 0 55px, transparent 60px),
radial-gradient(circle at 70% 12%, white 0 65px, transparent 70px),
radial-gradient(circle at 78% 15%, white 0 45px, transparent 50px),
radial-gradient(circle at 86% 12%, white 0 65px, transparent 70px),
radial-gradient(circle at 40% 35%, white 0 70px, transparent 75px),
radial-gradient(circle at 50% 38%, white 0 50px, transparent 55px),
radial-gradient(circle at 60% 35%, white 0 70px, transparent 75px);
}
/* =========================================
BRILHO DO SOL
========================================= */
body::after{
content:"";
position:fixed;
top:-120px;
right:-120px;
width:350px;
height:350px;
border-radius:50%;
background:
radial-gradient(
circle,
rgba(255,255,255,0.95) 0%,
rgba(255,255,255,0.5) 40%,
transparent 75%
);
z-index:-3;
}
/* =========================================
HEADER
========================================= */
header{
width:100%;
padding:28px;
text-align:center;
font-size:45px;
font-weight:700;
letter-spacing:2px;
color:white;
background:
linear-gradient(
135deg,
#ef4444,
#dc2626,
#991b1b
);
border-bottom:6px solid #ffcb05;
box-shadow:
0 10px 30px rgba(0,0,0,0.25);
text-shadow:
0 0 10px rgba(0,0,0,0.3);
}
/* =========================================
CONTAINER
========================================= */
.container{
width:90%;
max-width:1450px;
margin:40px auto;
}
/* =========================================
TIMES
========================================= */
.times{
display:flex;
flex-wrap:wrap;
gap:15px;
margin-bottom:30px;
}
/* =========================================
BOTÕES DOS TIMES
========================================= */
.time-btn{
padding:14px 22px;
border:none;
border-radius:15px;
background:
linear-gradient(
135deg,
#ef4444,
#dc2626
);
color:white;
font-weight:700;
font-size:16px;
cursor:pointer;
transition:0.3s;
box-shadow:
0 6px 18px rgba(0,0,0,0.25);
}
.time-btn:hover{
transform:
translateY(-4px)
scale(1.05);
background:
linear-gradient(
135deg,
#ffcb05,
#f59e0b
);
color:#111827;
}
/* BOTÃO ATIVO */
.active{
background:
linear-gradient(
135deg,
#ffcb05,
#f59e0b
);
color:#111827;
}
/* =========================================
GRID
========================================= */
.grid{
display:grid;
grid-template-columns:1fr 1fr;
gap:35px;
}
/* =========================================
CARDS
========================================= */
.card{
background:
rgba(255,255,255,0.22);
backdrop-filter:blur(16px);
border:
2px solid rgba(255,255,255,0.35);
border-radius:30px;
padding:32px;
box-shadow:
0 15px 40px rgba(0,0,0,0.18);
}
/* =========================================
TITULOS
========================================= */
.card h2{
color:#991b1b;
font-size:34px;
margin-bottom:20px;
text-shadow:
0 2px 8px rgba(255,255,255,0.35);
}
/* =========================================
FORM
========================================= */
form{
display:flex;
flex-direction:column;
gap:18px;
}
/* =========================================
INPUTS
========================================= */
input,
select{
padding:16px;
border:none;
border-radius:14px;
background:
rgba(255,255,255,0.9);
color:#111827;
font-size:16px;
outline:none;
transition:0.3s;
box-shadow:
inset 0 2px 5px rgba(0,0,0,0.08);
}
option{
color:black;
}
/* FOCUS */
input:focus,
select:focus{
border:
2px solid #ef4444;
box-shadow:
0 0 18px rgba(239,68,68,0.45);
}
/* =========================================
BOTÃO PRINCIPAL
========================================= */
button{
padding:16px;
border:none;
border-radius:14px;
background:
linear-gradient(
135deg,
#ef4444,
#dc2626
);
color:white;
font-size:17px;
font-weight:700;
cursor:pointer;
transition:0.3s;
box-shadow:
0 6px 20px rgba(0,0,0,0.25);
}
button:hover{
transform:
scale(1.04);
background:
linear-gradient(
135deg,
#ffcb05,
#f59e0b
);
color:#111827;
}
/* =========================================
INFO TIME
========================================= */
.team-info{
margin-bottom:20px;
font-size:21px;
font-weight:700;
color:#111827;
}
/* =========================================
LISTA
========================================= */
.pokemon-list{
display:flex;
flex-direction:column;
gap:22px;
}
/* =========================================
CARD POKEMON
========================================= */
.pokemon{
background:
rgba(255,255,255,0.88);
border-radius:26px;
padding:22px;
display:flex;
justify-content:space-between;
align-items:center;
border:
2px solid rgba(255,255,255,0.4);
transition:0.35s;
box-shadow:
0 10px 30px rgba(0,0,0,0.15);
}
/* HOVER */
.pokemon:hover{
transform:
translateY(-5px)
scale(1.01);
background:white;
}
/* =========================================
LEFT
========================================= */
.pokemon-left{
display:flex;
align-items:center;
gap:18px;
}
/* =========================================
IMAGEM
========================================= */
.pokemon-left img{
width:130px;
height:130px;
object-fit:contain;
filter:
drop-shadow(0 0 12px rgba(0,0,0,0.22));
transition:0.3s;
}
.pokemon:hover img{
transform:
scale(1.08);
}
/* =========================================
INFO
========================================= */
.pokemon-info h3{
font-size:30px;
color:#b91c1c;
}
.pokemon-info p{
margin-top:6px;
color:#1f2937;
text-transform:capitalize;
font-weight:600;
}
/* =========================================
RIGHT
========================================= */
.pokemon-right{
display:flex;
flex-direction:column;
gap:14px;
align-items:flex-end;
}
/* =========================================
TIPOS
========================================= */
.tipos{
display:flex;
flex-wrap:wrap;
gap:10px;
}
/* =========================================
TIPO
========================================= */
.tipo{
padding:10px 16px;
border-radius:30px;
background:
linear-gradient(
135deg,
#ef4444,
#b91c1c
);
color:white;
font-size:14px;
font-weight:700;
text-transform:capitalize;
box-shadow:
0 4px 10px rgba(0,0,0,0.18);
}
/* =========================================
MEGA BADGE
========================================= */
.mega-badge{
background:
linear-gradient(
135deg,
#7c3aed,
#5b21b6
);
color:white;
padding:6px 12px;
border-radius:20px;
font-size:12px;
font-weight:700;
margin-left:10px;
box-shadow:
0 4px 10px rgba(0,0,0,0.2);
}
/* =========================================
BOTÃO REMOVER
========================================= */
.delete-btn{
background:
linear-gradient(
135deg,
#dc2626,
#991b1b
);
color:white;
padding:11px 18px;
border:none;
border-radius:12px;
font-weight:700;
cursor:pointer;
transition:0.3s;
}
.delete-btn:hover{
transform:
scale(1.05);
background:
linear-gradient(
135deg,
#991b1b,
#7f1d1d
);
}
/* =========================================
RESPONSIVO
========================================= */
@media(max-width:950px){
.grid{
grid-template-columns:1fr;
}
.pokemon{
flex-direction:column;
align-items:flex-start;
gap:20px;
}
.pokemon-right{
align-items:flex-start;
}
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment