(lt.51)Practise project

(lt.51)Practise project

·

9 min read

Here we will learn step by step process to make a project
Stay tuned and follow the steps.

Step1: go to folder where you want to make this project and run the command.

Step 2:

select : react as framework and js as language

Step3:

Run the commands directed

Now you will see the below web page when try to run localhost:5173

step4:

Now create a folder Components
inside components create two folder named: search and pokedex

step5

Make a file search.jsx

now i will show what to write under these files

Pokedex.jsx

import React from 'react';
import Search1 from "../Search/Searchs";
import "./Pokedex.css";


function Pokedex()
{
    return(
        <div className='pokedex-wrapper'>
           <h1 id='pokedex-heading'>Pokedex</h1> 

        <Search1/> 
        {/* // this is the name that you import from the file*/}
        </div>
    )

}
export default Pokedex;

pokedex.css

.pokedex-wrapper
{
    display:  flex;
    flex-direction : column;

}

#pokedex-heading
{
    margin: 0 auto;
    letter-spacing: 5px;
}

search.css

.search-wrapper {
  margin: 0 auto;
}

#pokemon-name-search {
    margin: 2rem;
  width: 600px;
  padding: 1.5rem;
}

search.jsx

import './Search.css'

function Search() {
    return (
        <div className='search-wrapper'>

            < input id="pokemon-name-search" type="text" 
            placeholder="pokemon name...." />

        </div>
    );

}

export default Search;

app.jsx


import './App.css'
import Pokedex from './Components/Pokedex/Pokedex'

function App(){
  return (
    <>
    <Pokedex/>   

   </>
  )
}

export default App

I m attaching how your folders look like

step 6:

How to download lists of pokemon

Goto pokeapi

PokemonList.jsx

import { useState } from "react";
import { useEffect } from "react"

function PokemonList()
{
    const [x , setx] = useState(0);
    const [y , sety] = useState(0);

    useEffect(()=>
    {
        console.log("effect ")

    } ,[x]);


    return(
        <>
        <div>
            x : {x} <button onClick={() => setx(x+1)}> Inc </button>
        </div>
        <div>
            y : {y} <button onClick={() => sety(y+1)}> Inc </button>

        </div>
        </>
    )

}

export default PokemonList

Pokedex.jsx

import React from 'react';
import Search1 from "../Search/Searchs";
import "./Pokedex.css";
import PokemonList from '../PokemonList/PokemonList';


function Pokedex()
{
    return(
        <div className='pokedex-wrapper'>
           <h1 id='pokedex-heading'>Pokedex</h1> 

        <Search1/> 
        {/* // this is the name that you import from the file*/}
        <PokemonList/>
        </div>
    )

}
export default Pokedex;

Step7:

Now for downloading data we can either use fetch api or axios :
In this case we will use axios.

npm install axios

now the files will be:

PokemonList.jsx


import { useEffect } from "react"
import axios from 'axios'
import './PokemonList.css'

function PokemonList() {

    async function downloadPokemons() {
        const response = await axios.get('https://pokeapi.co/api/v2/pokemon')
        console.log(response.data)

    }
    useEffect(() => {
        downloadPokemons();

    }, []);


    return (
        <div className="pokemon-list-wrapper">
            Pokemon list
        </div>
    )

}

export default PokemonList

pokemonList.css

.pokemon-list-wrapper
{
    margin: 0 auto;
}

Step 8:

fetching details of pokemon and setting url
i have provided the code please go through it and try to understand it through searching by yourself it will help you

I m linking the updated code now:

PokemonList.css

.pokemon-list-wrapper
{
    margin: 2rem auto;
    display: flex;
    flex-direction: column;
    align-items: center;
}

.pokemon-wrapper
{

    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
    justify-content: space-evenly;
}

.pokemon-name-list-colour
{
    color: rgb(59, 17, 197);
    font-size: x-large;
    font-family: 'Lucida Sans', 'Lucida Sans Regular', 'Lucida Grande', 'Lucida Sans Unicode', Geneva, Verdana, sans-serif;

}

.button-control
{
    margin-left: 1rem;
    padding: 1rem 0.5rem;
    color: aqua;
}

PokemonList.jsx


import { useEffect } from "react"
import axios from 'axios'
import './PokemonList.css'
import { useState } from "react"
import Pokemon from "../Pokemon/Pokemon";

function PokemonList() {
    const [pokemonList, setPokemonList] = useState([]);
    const [isLoading, setisloading] = useState(true);

    // const PokedexUrl = 'https://pokeapi.co/api/v2/pokemon'
    const [PokedexUrl, setPokedexUrl] = useState
       ('https://pokeapi.co/api/v2/pokemon')

    const [nextUrl , setNextUrl] =useState('');
    const [prevUrl , setPrevUrl] =useState('');


    async function downloadPokemons() {

     //as soon as download pokemons is called setisloading should be true
          setisloading(true)

        const response = await axios.get(PokedexUrl) //this will download 
                                                      //list of 20 pokemons


        const pokemonResults = response.data.results;//  we get the 
                                   //   array of pokemons from results
        console.log(response.data)
        setNextUrl(response.data.next);
        setPrevUrl(response.data.previous);

        // iterating over the array of pokemons and using their url
       // to create an arry of promises that will download these pokemons
        const pokemonResultPromise = pokemonResults.map((pokemon) =>
               axios.get(pokemon.url));

        // passing promise array to axios.all
        const pokemonData = await axios.all(pokemonResultPromise);
        console.log(pokemonData)// the pokemonData has all the 
       //detailed information of all the 20  pokemons 

        // saving data in pokemon list and iterating over data of 
          // each pokemon and extracting id name image types
        const res = pokemonData.map((pokeData) => {
            const pokemon = pokeData.data;
            return {
                id : pokemon.id,

                name: pokemon.name,

             image: (pokemon.sprites.other) ?
 pokemon.sprites.other.dream_world.front_default : pokemon.sprites.front_shiny,

              types: pokemon.types
            }
        });
        console.log(res)
        setPokemonList(res)

        setisloading(false);


    }
    useEffect(() => {
        downloadPokemons();

    }, [PokedexUrl]);


    return (
        <>
        <div className="pokemon-list-wrapper">
            <div className="pokemon-name-list-colour"> Pokemon list :  </div>
            <div className="pokemon-wrapper">
         {(isLoading) ? 'laoding' : pokemonList.map((p) => 
          <Pokemon name = {p.name} image ={p.image} key={p.id} />)
            }
            </div>
            <div className="button-control">
                <button  disabled={prevUrl ==null} onClick={()=>
                    setPokedexUrl(prevUrl)}>prev</button>
                <button disabled={nextUrl ==null} onClick={()=> 
                    setPokedexUrl(nextUrl)}>next</button>
            </div>

        </div>
        </>
    )

}

export default PokemonList

Pokemon.css

.pokemon
{ 

    flex-basis: 30%;
    height: 250px;
    width: 280px;
    align-items: center;
    display: flex;
    flex-direction: column;
}

.pokemon-name
{
    font-size:large;
    font-weight: 100;
    font-family:'Times New Roman', Times, serif;
    color: rgb(255, 0, 30);
}

.pokemon-image
{
   margin: 1rem;
    height: 180px;
    max-height: 80%;
}

.pokemon:hover
{
    background-color: rgb(180, 197, 197);
}

/* * {background-color: black} */

Pokemon.jsx

import './Pokemon.css'

function Pokemon({ name, image }) {
    return (
        <>
            <div className='pokemon'>
                <div className='pokemon-name'>{name}</div>
                <div><img className="pokemon-image" src={image}/></div>
            </div>

        </>
    )
}

export default Pokemon

Pokedex.css

.pokedex-wrapper
{
    display:  flex;
    flex-direction : column;

}

#pokedex-heading
{
    margin: 0 auto;
    letter-spacing: 5px;
    color: rgb(24, 222, 37);
}

Pokedex.jsx

import React from 'react';
import Search from "../Search/Searchs";
import "./Pokedex.css";
import PokemonList from '../PokemonList/PokemonList';


function Pokedex()
{
    return(
        <div className='pokedex-wrapper'>
           <h1 id='pokedex-heading'>Pokedex</h1> 

        <Search/> 
        <PokemonList/>
        </div>
    )

}
export default Pokedex;

search.css

.search-wrapper {
  margin: 0 auto;
}

#pokemon-name-search {
    margin: 2rem;
  width: 600px;
  padding: 1.5rem;
}

Search.jsx

import './Search.css'

function Search() {
    return (
        <div className='search-wrapper'>

            < input id="pokemon-name-search" type="text" 
            placeholder="pokemon name...." />

        </div>
    );

}

export default Search;

Step 9:

In this we will try to extract information of the pokemon we clicked

run this command inside your folder : npm i react -router -dom

make a folder in src named routes

pokedex.css

.pokedex-wrapper
{
    display:  flex;
    flex-direction : column;

}

Pokedex.jsx

import React from 'react';
import Search from "../Search/Searchs";
import "./Pokedex.css";
import PokemonList from '../PokemonList/PokemonList';


function Pokedex()
{
    return(
        <div className='pokedex-wrapper'>


        <Search/> 
      <PokemonList/>
        </div>
    )

}
export default Pokedex;

Pkemon.css

.pokemon
{ 

    flex-basis: 30%;
    height: 250px;
    width: 280px;
    align-items: center;
    display: flex;
    flex-direction: column;
}

.pokemon-name
{
    font-size:large;
    font-weight: 100;
    font-family:'Times New Roman', Times, serif;
    color: rgb(255, 0, 30);
}

.pokemon-image
{
   margin: 1rem;
    height: 180px;
    max-height: 80%;
}

.pokemon:hover
{
    background-color: rgb(180, 197, 197);
}

/* * {background-color: black} */

Pokemon.jsx

import './Pokemon.css'
import { Link } from 'react-router-dom'

function Pokemon({ name, image , id }) {
    return (
        <>
            <div className='pokemon'>
                <Link to={`/pokemon/${id}`}>
                <div className='pokemon-name'>{name}</div>
                <div><img className='pokemon-image' src={image}/></div>
                </Link>
            </div>

        </>
    )
}

export default Pokemon

Pokemondetails.css

.pokemon-name
{
    font-size: larger;
    color: rgba(15, 157, 57, 0.962);
    text-align: center;
    font-family: Cambria, Cochin, Georgia, Times, 'Times New Roman', serif;
    font-weight: bolder;
}

.pokemon-types {
    border: 3px solid black;
    padding: 0.3rem; 
    display: flex;
    flex-direction: column;
    gap: 0.2rem; 
    background-color: antiquewhite;
    align-items: center;
    justify-content: center;
    text-align: center;
    margin: 1rem; /* Adds space outside the box */
}

.wid-height {
    color: crimson;
    display: flex;
    flex-direction: column;
    align-items: center; /* Centers items horizontally */
    justify-content: center; /* Centers items vertically */
    height: 100%; /* Ensure it takes full height of parent if needed */
}

PokemonDetails.jsx


import axios from "axios";
import { useState, useEffect } from "react";
import { useParams } from "react-router-dom";
import './PokemonDetails.css'

function PokemonDetails() {
    const { id } = useParams();
    const [pokemon, setPokemon] = useState({
        name: '',
        image: '',
        weight: 0,
        height: 0,
        types: []
    });

    async function downloadPokemon() {
        try {
            const response = await axios.get(`https://pokeapi.co/api/v2/pokemon/${id}`);
            setPokemon({
                name: response.data.name,
                image: response.data.sprites.other.dream_world.front_default,
                weight: response.data.weight,
                height: response.data.height,
                types: response.data.types.map((t) => t.type.name)
            });
        } catch (error) {
            console.error('Error fetching Pokémon data:', error);
        }
    }

    useEffect(() => {
        downloadPokemon();
    }, [id]);

    return (
        <div className="pokemon-details-wrapper">
            <div className="pokemon-name">Name: {pokemon.name}</div>
            <img className="pokemon-image" src={pokemon.image} alt={pokemon.name} />

           < div className="wid-height">
            <div >Height: {pokemon.height}</div>
            <div >Weight: {pokemon.weight}</div>
            </div>
            <div className="pokemon-types">
                {pokemon.types.length > 0 ? (
                    pokemon.types.map((t) => <div key={t}>{t}</div>)
                ) : (
                    <div>Loading types...</div>
                )}
            </div>
        </div>
    );
}

export default PokemonDetails;

PokemonList.css

.pokemon-list-wrapper
{
    margin: 2rem auto;
    display: flex;
    flex-direction: column;
    align-items: center;
}

.pokemon-wrapper
{

    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
    justify-content: space-evenly;
}

.pokemon-name-list-colour
{
    color: rgb(59, 17, 197);
    font-size: x-large;
    font-family: 'Lucida Sans', 'Lucida Sans Regular', 'Lucida Grande', 'Lucida Sans Unicode', Geneva, Verdana, sans-serif;

}

.button-control
{
    margin-left: 1rem;
    padding: 1rem 0.5rem;
    color: aqua;
}

Pokemonlist.jsx



import { useEffect } from "react"
import axios from 'axios'
import './PokemonList.css'
import { useState } from "react"
import Pokemon from "../Pokemon/Pokemon";

function PokemonList() {
    const [pokemonList, setPokemonList] = useState([]);
    const [isLoading, setisloading] = useState(true);

    // const PokedexUrl = 'https://pokeapi.co/api/v2/pokemon'
    const [PokedexUrl, setPokedexUrl] = useState ('https://pokeapi.co/api/v2/pokemon')

    const [nextUrl , setNextUrl] =useState('');
    const [prevUrl , setPrevUrl] =useState('');


    async function downloadPokemons() {

          //as soon as download pokemons is calling setisloading should be true
          setisloading(true)

        const response = await axios.get(PokedexUrl) //this will download list of 20 pokemons


        const pokemonResults = response.data.results;//  we get the array of pokemons from results
        console.log(response.data)
        setNextUrl(response.data.next);
        setPrevUrl(response.data.previous);

        // iterating over the array of pokemons and using their url to create an arry of promises that will download these pokemons
        const pokemonResultPromise = pokemonResults.map((pokemon) => axios.get(pokemon.url));

        // passing promise array to axios.all
        const pokemonData = await axios.all(pokemonResultPromise);
        console.log(pokemonData)// the pokemonData has all the detailed information of all the 20  pokemons 

        // saving data in pokemon list and iterating over data of each pokemon and extracting id name image types
        const res = pokemonData.map((pokeData) => {
            const pokemon = pokeData.data;
            return {
                id : pokemon.id,

                name: pokemon.name,

                image: (pokemon.sprites.other) ? pokemon.sprites.other.dream_world.front_default : pokemon.sprites.front_shiny,

                types: pokemon.types
            }
        });
        console.log(res)
        setPokemonList(res)

        setisloading(false);


    }
    useEffect(() => {
        downloadPokemons();

    }, [PokedexUrl]);


    return (
        <>
        <div className="pokemon-list-wrapper">
            <div className="pokemon-name-list-colour"> Pokemon list :  </div>
            <div className="pokemon-wrapper">
            {(isLoading) ? 'laoding' : pokemonList.map((p) => <Pokemon name = {p.name} image ={p.image} key={p.id} id ={p.id}/>)
            }
            </div>
            <div className="button-control">
                <button  disabled={prevUrl ==null} onClick={()=> setPokedexUrl(prevUrl)}>prev</button>
                <button disabled={nextUrl ==null} onClick={()=> setPokedexUrl(nextUrl)}>next</button>
            </div>

        </div>
        </>
    )

}

export default PokemonList

Search.css

.search-wrapper {
  margin: 0 auto;
}

#pokemon-name-search {
    margin: 2rem;
  width: 600px;
  padding: 1.5rem;
}

Search.jsx

import './Search.css'

function Search() {
    return (
        <div className='search-wrapper'>

            < input id="pokemon-name-search" type="text" 
            placeholder="pokemon name...." />

        </div>
    );

}

export default Search;

CustomRoutes.jsx

import {Route, Routes} from "react-router-dom"
import PokemonDetails from "../Components/PokemonDetails/PokemonDetails"
import Pokedex from "../Components/Pokedex/Pokedex"

function CustomRoutes()
{
    return(
        <Routes>
            {/* // giving a route component inside route */}
            {/* Keep in remember whenever we are giving any component it should be wrapped inside the </> */}
            <Route path = "/" element ={<Pokedex/>}/>
            <Route path ="/pokemon/:id" element ={<PokemonDetails/>}/>
        </Routes>
    )

}

export default CustomRoutes

App.jsx


import './App.css'
import Pokedex from './Components/Pokedex/Pokedex'
import CustomRoutes from './routes/CustomRoutes'
import { Link } from 'react-router-dom'

function App(){
  return (
    <div className='outer'>
    <h1 id='pokedex-heading'>
      <Link to ="/">Pokedex</Link></h1>
    <CustomRoutes/>   

   </div>
  )
}

export default App

main.jsx

import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App.jsx'
import './index.css'
import {BrowserRouter} from 'react-router-dom'

ReactDOM.createRoot(document.getElementById('root')).render(
  <BrowserRouter>
    <App />

  </BrowserRouter>

)

this is how your folder should look like

Tip: Please try to run and try different things in this code

lt.50https://hashnode.com/post/clyo82sue000909mh0zz9byar

Did you find this article valuable?

Support himanshu by becoming a sponsor. Any amount is appreciated!