Skip to content

Commit

Permalink
Router, Search, Pokemon Info with Evo chains (#1)
Browse files Browse the repository at this point in the history
v1
  • Loading branch information
destinio authored Dec 2, 2024
1 parent 28cd227 commit 318173e
Show file tree
Hide file tree
Showing 14 changed files with 705 additions and 19 deletions.
49 changes: 48 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@
"classnames": "^2.5.1",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-icons": "^5.3.0"
"react-icons": "^5.3.0",
"react-router": "^7.0.1"
},
"devDependencies": {
"@eslint/js": "^9.13.0",
Expand Down
13 changes: 9 additions & 4 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,23 @@
import { Route, Routes } from 'react-router'
import './App.css'
import NavBar from './components/NavBar'
import TypeChecker from './pages/TypeChecker'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { ReactQueryDevtools } from '@tanstack/react-query-devtools'
import TypeChecker from './pages/TypeChecker'
import Search from './pages/Search'
import PokemonInfo from './pages/Pokemon'

const queryClient = new QueryClient()

function App() {
return (
<QueryClientProvider client={queryClient}>
<NavBar />
<div className='max-w-lg m-auto p-4'>
<TypeChecker />
</div>
<Routes>
<Route path='/' element={<TypeChecker />} />
<Route path='/search' element={<Search />} />
<Route path='/pokemon/:id' element={<PokemonInfo />} />
</Routes>
{process.env.NODE_ENV === 'development' && (
<ReactQueryDevtools initialIsOpen={false} />
)}
Expand Down
1 change: 0 additions & 1 deletion src/assets/react.svg

This file was deleted.

14 changes: 11 additions & 3 deletions src/components/NavBar.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,18 @@
import { FaGithub } from 'react-icons/fa'
import { FaGithub, FaSearch } from 'react-icons/fa'
import { FaCodeCompare } from 'react-icons/fa6'
import { Link } from 'react-router'

export default function NavBar() {
return (
<div className='max-w-lg m-auto p-4 flex justify-between items-center'>
<h1 className='text-2xl font-bold'>Pokemon Type Check</h1>
<nav className='text-3xl'>
<h1 className='text-2xl font-bold'>Pokemon Utils</h1>
<nav className='text-2xl flex gap-2'>
<Link to='/'>
<FaCodeCompare />
</Link>
<Link to='/search'>
<FaSearch />
</Link>
<a href='https://github.com/destinio/pokemon-type-checker'>
<FaGithub className='hover:scale-105 hover:text-sky-300' />
</a>
Expand Down
4 changes: 2 additions & 2 deletions src/components/TypeButtons.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ export default function TypeButtons() {

return (
<div className='grid grid-cols-4 gap-2'>
{pokemonTypes.map(p => (
{pokemonTypes.map((p, i) => (
<button
key={p.type}
key={`${i}`}
className={classNames(
'p-2 rounded-sm border border-black overflow-hidden text-xl hover:opacity-100 hover:scale-105',
{
Expand Down
9 changes: 7 additions & 2 deletions src/components/TypeIcon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ import {
import { MdStars } from 'react-icons/md'
import { useTypeChecker } from '../pages/TypeChecker/context/TypeCheckerProvider'

const pokemonTypes = [
// eslint-disable-next-line react-refresh/only-export-components
export const pokemonTypesIcons = [
{
type: 'normal',
color: '#AAAA99',
Expand Down Expand Up @@ -115,12 +116,16 @@ const pokemonTypes = [
},
]

export const getTypeByName = (name: string) => {
return pokemonTypesIcons.find(t => t.type === name) || pokemonTypesIcons[0]
}

interface ITypeIconProps {
type: string
}

export default function TypeIcon({ type }: ITypeIconProps) {
const pokemonType = pokemonTypes.find(t => t.type === type)
const pokemonType = pokemonTypesIcons.find(t => t.type === type)

const { setCurrentType } = useTypeChecker()

Expand Down
4 changes: 2 additions & 2 deletions src/components/TypeInfo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ export default function TypeInfo() {

return (
<div className='grid grid-cols-2 gap-4 p-6'>
{Object.entries(typeInfo.damage_relations).map(([key, value]) => (
<div key={key}>
{Object.entries(typeInfo.damage_relations).map(([key, value], i) => (
<div key={`${i}`}>
<h3 className='text-xl mb-2'>{convertInfoHeader(key)}</h3>
<div className='flex flex-wrap gap-4'>
{value.map((v: Info, i: number) => (
Expand Down
5 changes: 4 additions & 1 deletion src/main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@ import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import './index.css'
import App from './App.tsx'
import { BrowserRouter } from 'react-router'

createRoot(document.getElementById('root')!).render(
<StrictMode>
<App />
<BrowserRouter>
<App />
</BrowserRouter>
</StrictMode>,
)
85 changes: 85 additions & 0 deletions src/pages/Pokemon/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import { useQuery } from '@tanstack/react-query'
import { useParams } from 'react-router'
import { EvChainFull, renderEvChain } from '../../utils/renderEvChain'
import { PokemonFull } from './pokemon'
import { getTypeByName } from '../../components/TypeIcon'

export default function PokemonInfo() {
const { id } = useParams()

const { data, isLoading, isFetching } = useQuery({
queryKey: ['pokemon', id],
staleTime: 1000 * 60 * 60 * 24,
queryFn: async () => {
const response = await fetch(`https://pokeapi.co/api/v2/pokemon/${id}`)
const done = (await response.json()) as PokemonFull

const speciesResponse = await fetch(done.species.url)
const species = await speciesResponse.json()

const evChainUrl = species.evolution_chain.url

const evChainResponse = await fetch(evChainUrl)
const evChain = (await evChainResponse.json()) as EvChainFull

const returnData = {
...done,
evChain,
}

return returnData
},
})

if (isLoading || isFetching) {
return <div className='max-w-lg m-auto p-4'>Loading...</div>
}

if (!data) {
return <div className='max-w-lg m-auto p-4'>No Data!</div>
}

const { species, chains } = renderEvChain(data.evChain.chain)

const types = data.types.map(t => {
return getTypeByName(t.type.name)
})

return (
<div className='max-w-lg m-auto p-4 flex flex-col gap-8'>
<header
style={{
backgroundImage: `url('${data.sprites.other.home.front_default}')`,
color: types[0].color,
}}
className='bg-right bg-[length:200px] bg-no-repeat h-36 border-b-2 border-b-slate-700'
>
<h1 className='text-3xl font-bold mb-2'>{data.name}</h1>
<div className='mb-4'>Species: {species}</div>
<ul className='flex gap-2'>
{types.map((type, i) => (
<li
key={i}
style={{ color: type.color }}
className='flex gap-2 items-center text-2xl'
>
{type.icon}
</li>
))}
</ul>
</header>

<section>
<h2 className='text-2xl mb-4'>Evelution Chain(s)</h2>
<div>
<h4>Evelotion Chains:</h4>
<div>
{chains.map((chain, i) => (
<div key={i}>{chain}</div>
))}
</div>
</div>
</section>
</div>
)
}
Loading

0 comments on commit 318173e

Please sign in to comment.