diff --git a/src/Home.js b/src/Home.js
index afa7452a0..8a97f772e 100644
--- a/src/Home.js
+++ b/src/Home.js
@@ -1,4 +1,4 @@
-import "./App.css";
+import "../../App.css";
import { useState, useEffect } from "react";
import { NavLink } from "react-router-dom";
@@ -6,27 +6,44 @@ function Home() {
const [text, setText] = useState("");
const [isReady, setIsReady] = useState(false);
+ const InputHandler = (event) => {
+ setText(event.target.value);
+ if (event.target.value === "Ready!") {
+ setIsReady(true);
+ }
+ if (event.target.value !== "Ready!"){
+ setIsReady(false)
+ }
+ };
+
return (
);
}
export default Home;
+
diff --git a/src/PokeDex.js b/src/PokeDex.js
index c7b071b04..4487f992d 100644
--- a/src/PokeDex.js
+++ b/src/PokeDex.js
@@ -1,13 +1,64 @@
-import "./App.css";
-import { useState, useEffect } from "react";
-import ReactLoading from "react-loading";
-import axios from "axios";
-import Modal from "react-modal";
+import './App.css';
+import { useState, useEffect } from 'react';
+import ReactLoading from 'react-loading';
+import axios from 'axios';
+import Modal from 'react-modal';
+
+import DetailCard from './components/DetailCard';
+import ThumbnailCard from './components/ThumbnailCard';
+import { MdNavigateNext, MdNavigateBefore } from 'react-icons/md';
function PokeDex() {
- const [pokemons, setPokemons] = useState([]);
- const [pokemonDetail, setPokemonDetail] = useState(null);
- const [isLoading, setIsLoading] = useState(false);
+ const [pokemons, setPokemons] = useState([]);
+ const [currentPokemonList, setCurrentPokemonList] = useState([]);
+ const [pokemonDetail, setPokemonDetail] = useState(null);
+ const [isLoading, setIsLoading] = useState(true);
+ const [nextLink, setNextLink] = useState('');
+ const [prevLink, setPrevLink] = useState('');
+ const [search, setSearch] = useState('');
+ const [notfound, setNotfound] = useState(false);
+ const [pokemonApi, setPokemonApi] = useState('https://pokeapi.co/api/v2/pokemon');
+
+ useEffect(() => {
+ axios.get(pokemonApi).then((response) => {
+ console.log(response);
+ setPokemons(response.data.results);
+ setCurrentPokemonList(response.data.results);
+ setNextLink(response.data.next);
+ setPrevLink(response.data.previous);
+ });
+ setIsLoading(false);
+ }, [pokemonApi]);
+
+ useEffect(() => {
+ if (search === '') {
+ setPokemons(currentPokemonList);
+ setNotfound(false);
+ } else {
+ const searchedPokemon = currentPokemonList.filter((value) => {
+ return value.name.toLowerCase().includes(search.toLowerCase());
+ });
+ if (searchedPokemon.length > 0) {
+ setNotfound(false);
+ setPokemons(searchedPokemon);
+ } else {
+ setNotfound(true);
+ }
+ }
+ }, [search, currentPokemonList]);
+
+ const handleChange = (e) => setSearch(e.target.value);
+
+ const onClickPokemon = (url) => {
+ axios.get(url).then((response) => {
+ console.log(response.data);
+ setPokemonDetail(response.data);
+ });
+ };
+
+ const onClickNext = () => setPokemonApi(nextLink);
+
+ const onClickPrev = () => setPokemonApi(prevLink);
const customStyles = {
content: {
@@ -31,10 +82,13 @@ function PokeDex() {
Requirement:
- Call this api:https://pokeapi.co/api/v2/pokemon to get pokedex, and show a list of pokemon name.
+ Call this api:https://pokeapi.co/api/v2/pokemon to get pokedex,
+ and show a list of pokemon name.
Implement React Loading and show it during API call
- when hover on the list item , change the item color to yellow.
+
+ when hover on the list item , change the item color to yellow.
+
when clicked the list item, show the modal below
Add a search bar on top of the bar for searching, search will run
@@ -42,7 +96,10 @@ function PokeDex() {
Implement sorting and pagingation
Commit your codes after done
- If you do more than expected (E.g redesign the page / create a chat feature at the bottom right). it would be good.
+
+ If you do more than expected (E.g redesign the page / create a
+ chat feature at the bottom right). it would be good.
+
@@ -56,15 +113,43 @@ function PokeDex() {
<>
- Implement loader here
+
>
) : (
<>
- Welcome to pokedex !
- Implement Pokedex list here
- >
+ Welcome to pokedex !
+
+
+
+
+
+ {notfound && Couldn't find the searched pokemon!
}
+ {pokemons && (
+
+ {pokemons.map((pokemon, index) => (
+ onClickPokemon(pokemon.url)} name={pokemon.name} />
+ ))}
+
+ )}
+ >
)}
{pokemonDetail && (
@@ -76,7 +161,8 @@ function PokeDex() {
}}
style={customStyles}
>
-
+
+ {/*
Requirement:
show the sprites front_default as the pokemon image
@@ -85,9 +171,12 @@ function PokeDex() {
required in tabular format
Create a bar chart based on the stats above
- Create a buttton to download the information generated in this modal as pdf. (images and chart must be included)
+
+ Create a buttton to download the information generated in this
+ modal as pdf. (images and chart must be included)
+
-
+
*/}
)}
diff --git a/src/components/DetailCard.css b/src/components/DetailCard.css
new file mode 100644
index 000000000..3afe87f24
--- /dev/null
+++ b/src/components/DetailCard.css
@@ -0,0 +1,84 @@
+.card-container {
+ width: 80vw;
+ height: auto;
+}
+
+.pokemon-name {
+ font-size: xx-large;
+ font-weight: bold;
+ line-height: 0%;
+ text-transform: capitalize;
+}
+
+.top-content {
+ display: grid;
+}
+
+.pokemon-img {
+ width: 100%;
+ max-height: 200px;
+ object-fit: cover;
+}
+
+table {
+ width: 100%;
+ text-align: left;
+ padding: 5px;
+ border: 1px aliceblue solid;
+}
+
+td, th {
+ text-transform: capitalize;
+}
+
+.table-wrapper {
+ display: flex;
+ align-items: center;
+}
+
+.barchart-wrapper {
+ width: 100%;
+ padding-top: 20px;
+ margin: 0 auto;
+}
+
+.bar-box {
+ background-color: #302e2e;
+ width: 150px;
+ height: 6px;
+}
+
+.progress-bar {
+ background-color: yellow;
+ height: 6px;
+}
+
+button {
+ padding: 5px;
+ background-color: yellow;
+ color: black;
+ margin-top: 20px;
+}
+
+@media only screen and (min-width: 770px) {
+ .card-container {
+ width: 600px;
+ }
+ .top-content {
+ grid-template-columns: 50% 50%;
+ }
+ .pokemon-img {
+ width: 80%;
+ height: auto;
+ max-height: none;
+ object-fit: cover;
+ }
+
+ .barchart-wrapper {
+ padding-top: 0;
+ }
+
+ .bar-box {
+ width: 200px;
+ }
+}
diff --git a/src/components/DetailCard.jsx b/src/components/DetailCard.jsx
new file mode 100644
index 000000000..9245cc3fd
--- /dev/null
+++ b/src/components/DetailCard.jsx
@@ -0,0 +1,62 @@
+import React, { useRef } from "react";
+import './DetailCard.css';
+import { useReactToPrint } from "react-to-print";
+
+const DetailCard = (props) => {
+ const printRef = useRef(null); // ref to point when print pdf is triggered
+ const name = props?.detail?.name;
+ const image = props?.detail?.sprites?.front_default;
+ const detailStats = props?.detail?.stats;
+
+ const onDownloadPdf = useReactToPrint({
+ content: () => printRef.current
+ });
+
+ const renderStatsTable = (stats) => (
+
+
+
+ Name
+ Base Stats
+
+ {stats.map((stat, index) => (
+
+ {stat.stat.name}
+ {stat.base_stat}
+
+ ))}
+
+
+ );
+
+ const renderBarChart = (stats) => (
+
+
+ {stats.map((stat, index) => (
+
+ {stat.stat.name}
+
+
+
+
+ ))}
+
+
+ );
+
+ return (
+
+
{name}
+
+
+ {renderStatsTable(detailStats)}
+
+ {renderBarChart(detailStats)}
+
Download As PDF
+
+ );
+};
+
+export default DetailCard;
diff --git a/src/components/ThumbnailCard.css b/src/components/ThumbnailCard.css
new file mode 100644
index 000000000..146f1b0ae
--- /dev/null
+++ b/src/components/ThumbnailCard.css
@@ -0,0 +1,64 @@
+.item-card {
+ width: 100px;
+ height: 135px;
+ margin-bottom: 20px;
+ text-align: center;
+ display: grid;
+ border: 1px white solid;
+ border-radius: 10px;
+ color: aliceblue;
+ cursor: pointer;
+}
+.item-card:hover {
+ background-color: yellow;
+ color: black;
+}
+
+.img-box {
+ width: 100px;
+ height: 100px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+
+.item-img {
+ width: 80px;
+ height: 80px;
+}
+.item-img:hover {
+ width: 100px;
+ height: 100px;
+}
+
+.item-name {
+ font-size: 16px;
+ padding-bottom: 8px;
+ font-weight: bold;
+ text-transform: capitalize;
+}
+
+@media only screen and (min-width: 770px) {
+ .item-card {
+ width: 200px;
+ height: 250px;
+ }
+
+ .img-box {
+ width: 200px;
+ height: 200px;
+ }
+
+ .item-img {
+ width: 150px;
+ height: 150px;
+ }
+ .item-img:hover {
+ width: 200px;
+ height: 200px;
+ }
+
+ .item-name {
+ font-size: 20px;
+ }
+ }
\ No newline at end of file
diff --git a/src/components/ThumbnailCard.jsx b/src/components/ThumbnailCard.jsx
new file mode 100644
index 000000000..6da6b7f53
--- /dev/null
+++ b/src/components/ThumbnailCard.jsx
@@ -0,0 +1,15 @@
+import React from 'react'
+import './ThumbnailCard.css'
+
+const ThumbnailCard = (props) => {
+ return (
+
+
+
+
+
{props.name}
+
+ )
+}
+
+export default ThumbnailCard
\ No newline at end of file