Skip to content

Instantly share code, notes, and snippets.

@koolkishan
Last active March 13, 2023 06:02
Show Gist options
  • Select an option

  • Save koolkishan/811d5b689408bedc27fbed240234b9a1 to your computer and use it in GitHub Desktop.

Select an option

Save koolkishan/811d5b689408bedc27fbed240234b9a1 to your computer and use it in GitHub Desktop.
Pokedex Snippets
//Navbar Routes
const navigationRoutes = [
{
name: "Search",
route: "/search",
},
{
name: "Compare",
route: "/compare",
},
{
name: "Pokemon",
route: "/pokemon",
},
{
name: "My List",
route: "/list",
},
{
name: "About",
route: "/about",
},
];
Import all Images Code
const fetchImages = (context: string) => {
const images = {};
const cache = {};
function importAll(r) {
r.keys().forEach((key) => (cache[key] = r(key)));
}
importAll(context);
Object.entries(cache).forEach((module: string[]) => {
let key = module[0].split("");
key.splice(0, 2);
key.splice(-4, 4);
images[[key.join("")]] = module[1];
});
return images;
};
export const images = fetchImages(
require.context("../assets/pokemons/shiny", false, /\.(png|jpe?g|svg)$/)
);
export const defaultImages = fetchImages(
require.context("../assets/pokemons/default", false, /\.(png|jpe?g|svg)$/)
);
// Pokemon Types
import bug from "../assets/types/bug.png";
import dark from "../assets/types/dark.svg";
import dragon from "../assets/types/dragon.png";
import electric from "../assets/types/electric.svg";
import fairy from "../assets/types/fairy.svg";
import fighting from "../assets/types/fighting.svg";
import fire from "../assets/types/fire.png";
import flying from "../assets/types/flying.png";
import ghost from "../assets/types/ghost.png";
import grass from "../assets/types/grass.png";
import ground from "../assets/types/ground.svg";
import ice from "../assets/types/ice.svg";
import normal from "../assets/types/normal.svg";
import poison from "../assets/types/poison.svg";
import psychic from "../assets/types/psychic.svg";
import rock from "../assets/types/rock.svg";
import steel from "../assets/types/steel.svg";
import water from "../assets/types/water.svg";
const Bug = "bug";
const Dark = "dark";
const Dragon = "dragon";
const Electric = "electric";
const Fairy = "fairy";
const Fighting = "fighting";
const Fire = "fire";
const Flying = "flying";
const Ghost = "ghost";
const Grass = "grass";
const Ground = "ground";
const Ice = "ice";
const Normal = "normal";
const Poison = "poison";
const Psychic = "psychic";
const Rock = "rock";
const Steel = "steel";
const Water = "water";
export const pokemonTypes = {
bug: {
image: bug,
strength: [Grass, Psychic, Dark],
weakness: [Fighting, Flying, Poison, Ghost, Steel, Fire, Fairy],
resistance: [Fighting, Ground, Grass],
vulnerable: [Flying, Rock, Fire],
},
dark: {
image: dark,
strength: [Ghost, Psychic],
weakness: [Fighting, Dark, Fairy],
resistance: [Ghost, Psychic, Dark],
vulnerable: [Fighting, Bug, Fairy],
},
dragon: {
image: dragon,
strength: [Dragon],
weakness: [Steel, Fairy],
resistance: [Fire, Water, Grass, Electric],
vulnerable: [Ice, Dragon, Fairy],
},
electric: {
image: electric,
strength: [Flying, Water],
weakness: [Ground, Grass, Electric, Dragon],
resistance: [Flying, Steel, Electric],
vulnerable: [Ground],
},
fairy: {
image: fairy,
strength: [Fighting, Dragon, Dark],
weakness: [Poison, Steel, Fire],
resistance: [Fighting, Bug, Dragon, Dark],
vulnerable: [Poison, Steel],
},
fighting: {
image: fighting,
strength: [Normal, Rock, Steel, Ice, Dark],
weakness: [Flying, Poison, Psychic, Bug, Ghost, Fairy],
resistance: [Rock, Bug, Dark],
vulnerable: [Flying, Psychic, Fairy],
},
fire: {
image: fire,
strength: [Bug, Steel, Grass, Ice],
weakness: [Rock, Fire, Water, Dragon],
resistance: [Bug, Steel, Fire, Grass, Ice],
vulnerable: [Ground, Rock, Water],
},
flying: {
image: flying,
strength: [Fighting, Bug, Grass],
weakness: [Rock, Steel, Electric],
resistance: [Fighting, Ground, Bug, Grass],
vulnerable: [Rock, Electric, Ice],
},
ghost: {
image: ghost,
strength: [Ghost, Psychic],
weakness: [Normal, Dark],
resistance: [Normal, Fighting, Poison, Bug],
vulnerable: [Ghost, Dark],
},
grass: {
image: grass,
strength: [Ground, Rock, Water],
weakness: [Flying, Poison, Bug, Steel, Fire, Grass, Dragon],
resistance: [Ground, Water, Grass, Electric],
vulnerable: [Flying, Poison, Bug, Fire, Ice],
},
ground: {
image: ground,
strength: [Poison, Rock, Steel, Fire, Electric],
weakness: [Flying, Bug, Grass],
resistance: [Poison, Rock, Electric],
vulnerable: [Water, Grass, Ice],
},
ice: {
image: ice,
strength: [Flying, Ground, Grass, Dragon],
weakness: [Steel, Fire, Water, Ice],
resistance: [Ice],
vulnerable: [Fighting, Rock, Steel, Fire],
},
normal: {
image: normal,
strength: [],
weakness: [Rock, Ghost, Steel],
resistance: [Ghost],
vulnerable: [Fighting],
},
poison: {
image: poison,
strength: [Grass, Fairy],
weakness: [Poison, Ground, Rock, Ghost, Steel],
resistance: [Fighting, Poison, Grass, Fairy],
vulnerable: [Ground, Psychic],
},
psychic: {
image: psychic,
strength: [Fighting, Poison],
weakness: [Steel, Psychic, Dark],
resistance: [Fighting, Psychic],
vulnerable: [Bug, Ghost, Dark],
},
rock: {
image: rock,
strength: [Flying, Bug, Fire, Ice],
weakness: [Fighting, Ground, Steel],
resistance: [Normal, Flying, Poison, Fire],
vulnerable: [Fighting, Ground, Steel, Water, Grass],
},
steel: {
image: steel,
strength: [Rock, Ice, Fairy],
weakness: [Steel, Fire, Water, Electric],
resistance: [
Normal,
Flying,
Poison,
Rock,
Bug,
Steel,
Grass,
Psychic,
Ice,
Dragon,
Fairy,
],
vulnerable: [Fighting, Ground, Fire],
},
water: {
image: water,
strength: [Ground, Rock, Fire],
weakness: [Water, Grass, Dragon],
resistance: [Steel, Fire, Water, Ice],
vulnerable: [Grass, Electric],
},
};
// Pokemon.tsx
import React, { useEffect, useCallback } from "react";
import Wrapper from "../sections/Wrapper";
import { useParams } from "react-router-dom";
import { useAppDispatch } from "../app/hooks";
import axios from "axios";
import { pokemonRoute, pokemonSpeciesRoute } from "../utils/Constants";
import { defaultImages, images } from "../utils/getPokemonImages";
import { extractColors } from "extract-colors";
function Pokemon() {
const params = useParams();
const dispatch = useAppDispatch();
const getRecursiveEvolution: any = useCallback(
(evolutionChain: any, level: number, evolutionData: any) => {
if (!evolutionChain.evolves_to.length) {
return evolutionData.push({
pokemon: {
...evolutionChain.species,
url: evolutionChain.species.url.replace(
"pokemon-species",
"pokemon"
),
},
level,
});
}
evolutionData.push({
pokemon: {
...evolutionChain.species,
url: evolutionChain.species.url.replace("pokemon-species", "pokemon"),
},
level,
});
return getRecursiveEvolution(
evolutionChain.evolves_to[0],
level + 1,
evolutionData
);
},
[]
);
const getEvolutionData = useCallback(
(evolutionChain: any) => {
const evolutionData: any[] = [];
getRecursiveEvolution(evolutionChain, 1, evolutionData);
return evolutionData;
},
[getRecursiveEvolution]
);
const getPokemonInfo = useCallback(
async (image: string) => {
const { data } = await axios.get(`${pokemonRoute}/${params.id}`);
const { data: dataEncounters } = await axios.get(
data.location_area_encounters
);
const {
data: {
evolution_chain: { url: evolutionURL },
},
} = await axios.get(`${pokemonSpeciesRoute}/${data.id}`);
const { data: evolutionData } = await axios.get(evolutionURL);
const encounters: string[] = [];
dataEncounters.forEach((encounter: any) => {
encounters.push(
encounter.location_area.name.toUpperCase().split("-").join(" ")
);
});
console.log({ data });
const pokemonAbilities: { abilities: string[]; moves: string[] } = {
abilities: data.abilities.map(
({ ability }: { ability: { name: string } }) => ability.name
),
moves: data.moves.map(
({ move }: { move: { name: string } }) => move.name
),
};
const evolution = getEvolutionData(evolutionData.chain);
const evolutionLevel = evolution.find(
({ pokemon }) => pokemon.name === data.name
).level;
console.log({
id: data.id,
name: data.name,
types: data.types.map(
({ type: { name } }: { type: { name: string } }) => name
),
image,
stats: data.stats.map(
({
stat,
base_stat,
}: {
stat: { name: string };
base_stat: number;
}) => ({
name: stat.name,
value: base_stat,
})
),
encounters,
evolutionLevel,
evolution,
pokemonAbilities,
});
},
[getEvolutionData, params.id]
);
useEffect(() => {
const imageElemet = document.createElement("img");
// @ts-ignore
imageElemet.src = images[params.id];
if (!imageElemet.src) {
// @ts-ignore
imageElemet.src = defaultImages[params.id];
}
const options = {
pixels: 10000,
distance: 1,
splitPower: 10,
colorValidator: (red: number, green: number, blue: number, alpha = 255) =>
alpha > 250,
saturationDistance: 0.2,
lightnessDistance: 0.2,
hueDistance: 0.083333333,
};
const getColor = async () => {
const color = await extractColors(imageElemet.src, options);
const root = document.documentElement;
root.style.setProperty("--accent-color", color[0].hex.split('"')[0]);
};
getColor();
getPokemonInfo(imageElemet.src);
}, [params, getPokemonInfo]);
return <div>Pokemon</div>;
}
export default Wrapper(Pokemon);
// Tabbing Structure
export const pokemonTabs = {
description: "description",
evolution: "evolution",
locations: "locations",
moves: "moves",
};
const routes = [
{
name: pokemonTabs.description,
value: "Description",
},
{
name: pokemonTabs.evolution,
value: "Evolution",
},
{
name: pokemonTabs.locations,
value: "Catching",
},
{
name: pokemonTabs.moves,
value: "Capable Moves",
},
];
.details {
position: absolute;
top: 1rem;
left: 1rem;
color: white;
padding: 1rem;
width: 25rem;
text-transform: uppercase;
&::before {
height: 0.3rem;
width: 9rem;
content: "";
background-color: var(--accent-color);
position: absolute;
top: 0;
left: 0;
}
.name {
margin-bottom: 1rem;
}
button {
position: absolute;
right: 1rem;
bottom: -2rem;
padding: 0.8rem 0.8rem;
background-color: transparent;
border: 0.1rem solid var(--accent-color);
outline: none;
color: white;
text-transform: uppercase;
font-weight: 700;
letter-spacing: 0.1rem;
}
background: linear-gradient(
$bg-color ($dot-space - $dot-size),
transparent 1%
)
center,
$dot-color;
}
.stats {
position: absolute;
left: 1rem;
bottom: 8rem;
ul {
list-style-type: none;
display: flex;
flex-direction: column;
gap: 1rem;
li {
color: white;
text-align: right;
text-transform: uppercase;
letter-spacing: 0.1rem;
display: flex;
justify-content: flex-end;
align-items: center;
gap: 1rem;
progress {
transition: 2s ease-in-out;
width: 0;
height: 100%;
-webkit-appearance: none;
appearance: none;
&::-webkit-progress-bar {
border-radius: 1rem;
height: 0.3rem;
background-color: transparent;
}
&::-webkit-progress-value {
border-radius: 1rem;
background-color: var(--accent-color);
}
}
}
}
}
.battle-stats {
ul {
list-style-type: none;
display: flex;
flex-direction: column;
gap: 0.5rem;
letter-spacing: 0.1rem;
li {
display: grid;
grid-template-columns: max-content 80%;
gap: 0.5rem;
}
}
position: absolute;
bottom: 3rem;
right: 2rem;
color: white;
padding: 1rem;
width: 30rem;
&::before {
height: 0.3rem;
width: 9rem;
content: "";
background-color: var(--accent-color);
position: absolute;
top: 0;
left: 0;
}
.name {
margin-bottom: 1rem;
}
.add-pokemon {
position: absolute;
right: -1rem;
bottom: -2rem;
padding: 0.8rem 0.8rem;
background-color: transparent;
border: 0.1rem solid var(--accent-color);
outline: none;
color: white;
text-transform: uppercase;
font-weight: 700;
letter-spacing: 0.1rem;
cursor: pointer;
transition: 0.2s ease-in-out;
&:hover {
background-color: var(--accent-color);
}
}
background: linear-gradient(
$bg-color ($dot-space - $dot-size),
transparent 1%
)
center,
$dot-color;
}
import React, { useEffect } from "react";
import { pokemonTypes } from "../utils";
import { useAppDispatch } from "../app/hooks";
import { addPokemonToList } from "../app/reducers/addPokemonToList";
import { setPokemonTab } from "../app/slices/AppSlice";
import { pokemonTabs } from "../utils/constants";
import { currentPokemonType, pokemonStatsType } from "../utils/types";
export default function Info({
data,
}: {
data: currentPokemonType | undefined;
}) {
const dispatch = useAppDispatch();
useEffect(() => {
const progressBars = document.querySelectorAll("progress");
progressBars.forEach((progressBar) => {
progressBar.style.width = "10rem";
});
}, []);
const createStatsArray = (types: string[], statType: string) => {
const statsSet = new Set();
types.forEach((type: string) => {
// @ts-ignore
pokemonTypes[type][statType].forEach((stat: string) => {
if (!statsSet.has(stat)) {
statsSet.add(stat[0].toUpperCase() + stat.slice(1));
}
});
});
return Array.from(statsSet);
};
return (
<>
<div className="details">
<h1 className="name">{data?.name}</h1>
<h3>Type: {data?.types.join(" - ")}</h3>
<h3>Evolution: {data?.evolutionLevel}</h3>
<button onClick={() => dispatch(setPokemonTab(pokemonTabs.evolution))}>
See next evolution
</button>
</div>
<div className="stats">
<ul>
{data?.stats.map((stat: pokemonStatsType) => {
return (
<li key={stat.name}>
{stat.name}: {stat.value}
<progress max={100} value={stat.value} />
</li>
);
})}
</ul>
</div>
<div className="battle-stats">
{
<ul>
<li>
<span>Strengths:</span>
<span>
{createStatsArray(
data?.types as unknown as string[],
"strength"
).join(", ")}
</span>
</li>
<li>
<span>Weakness:</span>
<span>
{createStatsArray(
data?.types as unknown as string[],
"weakness"
).join(", ")}
</span>
</li>
<li>
<span>Resistant:</span>
<span>
{createStatsArray(
data?.types as unknown as string[],
"resistance"
).join(", ")}
</span>
</li>
<li>
<span>Vulnerable:</span>
<span>
{createStatsArray(
data?.types as unknown as string[],
"vulnerable"
).join(", ")}
</span>
</li>
</ul>
}
<button
onClick={() => dispatch(addPokemonToList(data!))}
className="add-pokemon"
>
Add Pokemon
</button>
</div>
</>
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment