Last active
March 13, 2023 06:02
-
-
Save koolkishan/811d5b689408bedc27fbed240234b9a1 to your computer and use it in GitHub Desktop.
Pokedex Snippets
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| //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", | |
| }, | |
| ]; | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| .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; | |
| } | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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