Skip to content

jpbast/pokedex

Repository files navigation

Pokémon App

Here you can know better the Pokémons you like!

You can visit https://jpbast-pokedex.vercel.app/ for checking it on production

How to run the app

Make sure you are using Node version >=18.x.

On your terminal, run:

yarn install

Then:

yarn dev

Finally, the app should be running at:

http://localhost:3000

Pages

For checking all the content within the app, you can visit the following pages:

  • Home page (/)
  • Pokémon detail (/:name)

Home page

On the top of the page we have a search input where you can find a specific Pokémon by its name or id. The search is only triggered if you hit Enter or the Search button. If the Pokémon exists, it will be displayed below replacing the list. If it does not exist, a error message will be displayed.

If you have searched for a Pokémon but want to display the list again, simply erase the input value or hit the Pokémon logo.

To improve performance, the list was implemented with Infinite Scroll. Pokémons are loaded every 20 as you scroll through the page. For better user experience, a Skeleton is displayed for each card every time a request is ongoing. If you scrolls too much and decide to return to the top, just hit the floating button on the bottom right.

To access detailed Pokémon info, just click on the card and you be sent to another page.

Pokémon detail

Here you can find a more detailed information about the Pokémon you want. The entire page's color scheme is dynamic and it depends on the Pokémon color type.

The entire page is responsive just like the Home page.

Technical details

Main technologies

  • React with Vite
  • TypeScript
  • TanStack Query
  • Tailwind
  • Ant Design
  • Axios
  • ESLint
  • Prettier

Data and cache

In order to improve performance, user and development experience, I decided to go with TanStack Query. All requests are handled by the following custom hooks:

  • usePokemonList: this hook gets all the Pokémon data needed on the home page and it's ready to use with infinite scroll. All the data needed is fetched here and then parsed to make it easier to consume through the components

  • usePokemon: used for building the detail page and for getting the result from the search input.

Cache and overall performance were the main concerns so both hooks were developed with it in mind. usePokemon has the same queryKey used on the usePokemonList, so the detail page is fully built consuming the cache if it exists. The opposite might also happen: if you first visit Pikachu page, for example, and then navigate to the list, Pikachu information will be pulled from the cache.

Navigation between pages is pretty fast since no new requests are made. Page refresh is also pretty fast since it pulls the data from cache if it exists.

Search input

In order to prevent unnecessary renders and requests, the search input was built using ref. I've added a state to display the single card and trigger the search request, but that's it.

Routes

The app router was built with React Router Dom.

Error handling

Every error is handled by the Error Boundary and the React Router Dom. If an unexpected error or a response error from the requests happens, a error page is displayed. This page has a button so you can reload the app.

For not found pages I created another page component that is quite similar to the error page.

If a searched Pokémon is not found, this is the feedback you'll see

Styles

Most of the styles and components were made with Tailwind and Ant Design.

For the fonts, the whole app is consuming the Google Inter. For improving performance and avoiding layout shift, I downloaded the .ttf files inside the /assets folder and loaded it from there.

Furthermore, every component and page is responsive.

For the animations, you can find it on the skeletons and the stats bar filling up on the detail page

Linting

The linting is being handled by ESLint and Prettier with some rules I usually set. I also added Husky for checking lint errors when I commit.

Project structure

  • src/assets: font files and Pokémons type icons
  • src/components: visual components
  • src/hooks: custom hooks for managing the API requests
  • src/layouts: app containers
  • src/pages: all app pages
  • src/router: React Router Dom setup
  • src/styles: global styles
  • src/typings: most important types used multiple types
  • src/utils: utility functions and axios setup