Trying to implement InfoDialogSlice and related api endpoints (app is running but infodialog is not showing)
parent
281eafc863
commit
8607a8f1ad
|
@ -59,6 +59,24 @@ describe('pokeApi', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('test getPokemonSpecies query', () => {
|
||||
test('visit https://pokeapi.co/api/v2/pokemon-species/6/', async () => {
|
||||
await store.dispatch(
|
||||
pokeApi.endpoints.getPokemonSpeciesFromUrl.initiate(
|
||||
'https://pokeapi.co/api/v2/pokemon-species/6/',
|
||||
),
|
||||
);
|
||||
|
||||
const pokemonSpecies =
|
||||
pokeApi.endpoints.getPokemonSpeciesFromUrl.select(
|
||||
'https://pokeapi.co/api/v2/pokemon-species/6/',
|
||||
)(store.getState()).data as PokemonSpeciesResponseData;
|
||||
expect(pokemonSpecies?.evolution_chain.url).toBe(
|
||||
'https://pokeapi.co/api/v2/evolution-chain/2/',
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('test getTypeList query', () => {
|
||||
test('visit https://pokeapi.co/api/v2/type should return correct data in list', async () => {
|
||||
await store.dispatch(pokeApi.endpoints.getTypeList.initiate());
|
||||
|
@ -88,6 +106,30 @@ describe('pokeApi', () => {
|
|||
).toBe('https://pokeapi.co/api/v2/pokemon-species/6/');
|
||||
});
|
||||
});
|
||||
|
||||
describe('test getEvolutionChainFromUrl query', () => {
|
||||
test('visit https://pokeapi.co/api/v2/evolution-chain/2/', async () => {
|
||||
await store.dispatch(
|
||||
pokeApi.endpoints.getEvolutionChainFromUrl.initiate(
|
||||
'https://pokeapi.co/api/v2/evolution-chain/2/',
|
||||
),
|
||||
);
|
||||
|
||||
const evolutionChainData =
|
||||
pokeApi.endpoints.getEvolutionChainFromUrl.select(
|
||||
'https://pokeapi.co/api/v2/evolution-chain/2/',
|
||||
)(store.getState()).data as EvolutionChainResponseData;
|
||||
expect(evolutionChainData?.chain.species.url).toBe(
|
||||
'https://pokeapi.co/api/v2/pokemon-species/4/',
|
||||
);
|
||||
expect(evolutionChainData?.chain.evolves_to[0].species.url).toBe(
|
||||
'https://pokeapi.co/api/v2/pokemon-species/5/',
|
||||
);
|
||||
expect(
|
||||
evolutionChainData?.chain.evolves_to[0].evolves_to[0].species.url,
|
||||
).toBe('https://pokeapi.co/api/v2/pokemon-species/6/');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('test helper functions', () => {
|
||||
|
|
|
@ -119,40 +119,25 @@ export const pokeApi = createApi({
|
|||
};
|
||||
},
|
||||
}),
|
||||
getPokemon: builder.query<PokemonResponseData, number>({
|
||||
query: Id => ({ url: `pokemon/${Id}` }),
|
||||
getPokemon: builder.query<PokemonResponseData, string | number>({
|
||||
query: IdOrName => ({ url: `pokemon/${IdOrName}` }),
|
||||
}),
|
||||
getPokemonSpecies: builder.query<PokemonSpeciesResponseData, number>({
|
||||
query: Id => ({ url: `pokemon-species/${Id}` }),
|
||||
}),
|
||||
getPokemonSpeciesFromUrl: builder.query<PokemonSpeciesResponseData, string>(
|
||||
{
|
||||
query: url => ({ url: `pokemon-species/${getIdFromUrl(url)}` }),
|
||||
},
|
||||
),
|
||||
getEvolutionChain: builder.query<EvolutionChainResponseData, number>({
|
||||
query: Id => ({ url: `evolution-chain/${Id}` }),
|
||||
}),
|
||||
getPokemonInfo: builder.query<string, number>({
|
||||
async queryFn(pokemonId, queryApi) {
|
||||
const pokemon: PokemonResponseData = await queryApi
|
||||
.dispatch(pokeApi.endpoints.getPokemon.initiate(pokemonId))
|
||||
.unwrap();
|
||||
|
||||
const pokemonSpecies: PokemonSpeciesResponseData = await queryApi
|
||||
.dispatch(
|
||||
pokeApi.endpoints.getPokemonSpecies.initiate(
|
||||
getIdFromUrl(pokemon.species.url),
|
||||
),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
const evolutionChain: EvolutionChainResponseData = await queryApi
|
||||
.dispatch(
|
||||
pokeApi.endpoints.getEvolutionChain.initiate(
|
||||
getIdFromUrl(pokemonSpecies.evolution_chain.url),
|
||||
),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
return { data: 'test' };
|
||||
getEvolutionChainFromUrl: builder.query<EvolutionChainResponseData, string>(
|
||||
{
|
||||
query: url => ({ url: `evolution-chain/${getIdFromUrl(url)}` }),
|
||||
},
|
||||
}),
|
||||
),
|
||||
}),
|
||||
});
|
||||
|
||||
|
@ -160,5 +145,7 @@ export const {
|
|||
useGetTypeListQuery,
|
||||
useGetPokemonQuery,
|
||||
useGetPokemonSpeciesQuery,
|
||||
useGetPokemonSpeciesFromUrlQuery,
|
||||
useGetEvolutionChainQuery,
|
||||
useGetEvolutionChainFromUrlQuery,
|
||||
} = pokeApi;
|
||||
|
|
|
@ -11,7 +11,7 @@ import EvolutionSpecies, {
|
|||
EvolutionSpeciesProps,
|
||||
} from 'components/EvolutionSpecies';
|
||||
|
||||
interface Stat {
|
||||
export interface Stat {
|
||||
stat__name: string;
|
||||
stat__value: number;
|
||||
}
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
export { default } from './InfoDialogComponent';
|
||||
export type { InfoDialogComponentProps } from './InfoDialogComponent';
|
||||
export * from './InfoDialogComponent';
|
||||
|
|
|
@ -13,11 +13,21 @@ export interface PokemonCardProps {
|
|||
types: string[];
|
||||
}
|
||||
|
||||
type PokemonCardPropsActionable = PokemonCardProps & {
|
||||
onClickAction: () => void;
|
||||
};
|
||||
|
||||
export function formatNumber(num: number) {
|
||||
return '#' + num.toString().padStart(3, '0');
|
||||
}
|
||||
|
||||
const PokemonCard = ({ id, name, image, types }: PokemonCardProps) => {
|
||||
const PokemonCard = ({
|
||||
id,
|
||||
name,
|
||||
image,
|
||||
types,
|
||||
onClickAction,
|
||||
}: PokemonCardPropsActionable) => {
|
||||
const finalColor = colorTypeGradients(types);
|
||||
|
||||
return (
|
||||
|
@ -38,6 +48,7 @@ const PokemonCard = ({ id, name, image, types }: PokemonCardProps) => {
|
|||
height="1em"
|
||||
width="1em"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
onClick={onClickAction}
|
||||
>
|
||||
<path d="M256 8C119.043 8 8 119.083 8 256c0 136.997 111.043 248 248 248s248-111.003 248-248C504 119.083 392.957 8 256 8zm0 110c23.196 0 42 18.804 42 42s-18.804 42-42 42-42-18.804-42-42 18.804-42 42-42zm56 254c0 6.627-5.373 12-12 12h-88c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h12v-64h-12c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h64c6.627 0 12 5.373 12 12v100h12c6.627 0 12 5.373 12 12v24z"></path>
|
||||
</svg>
|
||||
|
|
|
@ -19,32 +19,26 @@ const InfoDialog = ({ pokemonId }: InfoDialogProps) => {
|
|||
const dispatch = useAppDispatch();
|
||||
|
||||
const isOpen = useAppSelector(state => state.infoDialog.isOpen);
|
||||
const skipGetPokemonSpeciesQuery = useAppSelector(
|
||||
state => state.infoDialog.skipGetPokemonSpeciesQuery,
|
||||
);
|
||||
const skipGetEvolutionChainQuery = useAppSelector(
|
||||
state => state.infoDialog.skipGetEvolutionChainQuery,
|
||||
);
|
||||
const selectedPokemonId = useAppSelector(
|
||||
state => state.infoDialog.selectedPokemonId,
|
||||
const selectedInfoDialogDetails = useAppSelector(
|
||||
state => state.infoDialog.InfoDialogDetails,
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
<InfoDialogComponent
|
||||
openDialog={isOpen}
|
||||
id={selectedPokemonId}
|
||||
name={}
|
||||
types={}
|
||||
genera={}
|
||||
image={}
|
||||
height={}
|
||||
weight={}
|
||||
genderRatio={}
|
||||
description={}
|
||||
abilities={}
|
||||
stats={}
|
||||
evolutionChain={}
|
||||
id={selectedInfoDialogDetails.id}
|
||||
name={selectedInfoDialogDetails.name}
|
||||
types={selectedInfoDialogDetails.types}
|
||||
genera={selectedInfoDialogDetails.genera}
|
||||
image={selectedInfoDialogDetails.image}
|
||||
height={selectedInfoDialogDetails.height}
|
||||
weight={selectedInfoDialogDetails.weight}
|
||||
genderRatio={selectedInfoDialogDetails.genderRatio}
|
||||
description={selectedInfoDialogDetails.description}
|
||||
abilities={selectedInfoDialogDetails.abilities}
|
||||
stats={selectedInfoDialogDetails.stats}
|
||||
evolutionChain={selectedInfoDialogDetails.evolutionChain}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
|
|
|
@ -0,0 +1,193 @@
|
|||
import {
|
||||
constructEvolutionChainFromResponse,
|
||||
findEnglishGenera,
|
||||
findFirstEnglishFlavorText,
|
||||
} from './infoDialogSlice';
|
||||
|
||||
const bulbasaurEvolutionChainResponseData = {
|
||||
chain: {
|
||||
evolves_to: [
|
||||
{
|
||||
species: {
|
||||
name: 'ivysaur',
|
||||
url: 'https://pokeapi.co/api/v2/pokemon-species/2/',
|
||||
},
|
||||
evolves_to: [
|
||||
{
|
||||
species: {
|
||||
name: 'venusaur',
|
||||
url: 'https://pokeapi.co/api/v2/pokemon-species/3/',
|
||||
},
|
||||
evolves_to: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
species: {
|
||||
name: 'bulbasaur',
|
||||
url: 'https://pokeapi.co/api/v2/pokemon-species/1/',
|
||||
},
|
||||
},
|
||||
};
|
||||
const charmanderEvolutionChainResponseData = {
|
||||
chain: {
|
||||
evolves_to: [
|
||||
{
|
||||
species: {
|
||||
name: 'charmeleon',
|
||||
url: 'https://pokeapi.co/api/v2/pokemon-species/5/',
|
||||
},
|
||||
evolves_to: [
|
||||
{
|
||||
species: {
|
||||
name: 'charizard',
|
||||
url: 'https://pokeapi.co/api/v2/pokemon-species/6/',
|
||||
},
|
||||
evolves_to: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
species: {
|
||||
name: 'charmander',
|
||||
url: 'https://pokeapi.co/api/v2/pokemon-species/4/',
|
||||
},
|
||||
},
|
||||
};
|
||||
const bulbasaurGenera = {
|
||||
genera: [
|
||||
{
|
||||
genus: 'たねポケモン',
|
||||
language: {
|
||||
name: 'ja-Hrkt',
|
||||
url: 'https://pokeapi.co/api/v2/language/1/',
|
||||
},
|
||||
},
|
||||
{
|
||||
genus: '씨앗포켓몬',
|
||||
language: {
|
||||
name: 'ko',
|
||||
url: 'https://pokeapi.co/api/v2/language/3/',
|
||||
},
|
||||
},
|
||||
{
|
||||
genus: 'Seed Pokémon',
|
||||
language: {
|
||||
name: 'en',
|
||||
url: 'https://pokeapi.co/api/v2/language/9/',
|
||||
},
|
||||
},
|
||||
{
|
||||
genus: 'たねポケモン',
|
||||
language: {
|
||||
name: 'ja',
|
||||
url: 'https://pokeapi.co/api/v2/language/11/',
|
||||
},
|
||||
},
|
||||
{
|
||||
genus: '种子宝可梦',
|
||||
language: {
|
||||
name: 'zh-Hans',
|
||||
url: 'https://pokeapi.co/api/v2/language/12/',
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
const flavor_text_entries = [
|
||||
{
|
||||
flavor_text:
|
||||
'A strange seed was\nplanted on its\nback at birth.\fThe plant sprouts\nand grows with\nthis POKéMON.',
|
||||
language: {
|
||||
name: 'en',
|
||||
url: 'https://pokeapi.co/api/v2/language/9/',
|
||||
},
|
||||
version: {
|
||||
name: 'red',
|
||||
url: 'https://pokeapi.co/api/v2/version/1/',
|
||||
},
|
||||
},
|
||||
{
|
||||
flavor_text:
|
||||
'A strange seed was\nplanted on its\nback at birth.\fThe plant sprouts\nand grows with\nthis POKéMON.',
|
||||
language: {
|
||||
name: 'en',
|
||||
url: 'https://pokeapi.co/api/v2/language/9/',
|
||||
},
|
||||
version: {
|
||||
name: 'blue',
|
||||
url: 'https://pokeapi.co/api/v2/version/2/',
|
||||
},
|
||||
},
|
||||
{
|
||||
flavor_text:
|
||||
'It can go for days\nwithout eating a\nsingle morsel.\fIn the bulb on\nits back, it\nstores energy.',
|
||||
language: {
|
||||
name: 'en',
|
||||
url: 'https://pokeapi.co/api/v2/language/9/',
|
||||
},
|
||||
version: {
|
||||
name: 'yellow',
|
||||
url: 'https://pokeapi.co/api/v2/version/3/',
|
||||
},
|
||||
},
|
||||
{
|
||||
flavor_text:
|
||||
'うまれたときから せなかに\nふしぎな タネが うえてあって\nからだと ともに そだつという。',
|
||||
language: {
|
||||
name: 'ja-Hrkt',
|
||||
url: 'https://pokeapi.co/api/v2/language/1/',
|
||||
},
|
||||
version: {
|
||||
name: 'x',
|
||||
url: 'https://pokeapi.co/api/v2/version/23/',
|
||||
},
|
||||
},
|
||||
{
|
||||
flavor_text:
|
||||
'태어났을 때부터 등에\n이상한 씨앗이 심어져 있으며\n몸과 함께 자란다고 한다.',
|
||||
language: {
|
||||
name: 'ko',
|
||||
url: 'https://pokeapi.co/api/v2/language/3/',
|
||||
},
|
||||
version: {
|
||||
name: 'x',
|
||||
url: 'https://pokeapi.co/api/v2/version/23/',
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
describe('test infoDialogSlice', () => {
|
||||
describe('test utility functions', () => {
|
||||
test('constructEvolutionChainFromResponse works correctly for bulbasaur', () => {
|
||||
const evolutionChain = constructEvolutionChainFromResponse(
|
||||
bulbasaurEvolutionChainResponseData,
|
||||
);
|
||||
expect(evolutionChain.length).toBe(3);
|
||||
expect(evolutionChain[0]).toBe('bulbasaur');
|
||||
expect(evolutionChain[1]).toBe('ivysaur');
|
||||
expect(evolutionChain[2]).toBe('venusaur');
|
||||
});
|
||||
|
||||
test('constructEvolutionChainFromResponse works correctly for charmander', () => {
|
||||
const evolutionChain = constructEvolutionChainFromResponse(
|
||||
charmanderEvolutionChainResponseData,
|
||||
);
|
||||
expect(evolutionChain.length).toBe(3);
|
||||
expect(evolutionChain[0]).toBe('charmander');
|
||||
expect(evolutionChain[1]).toBe('charmeleon');
|
||||
expect(evolutionChain[2]).toBe('charizard');
|
||||
});
|
||||
|
||||
test('findEnglishGenera works correctly for bulbasaur', () => {
|
||||
const englishGenera = findEnglishGenera(bulbasaurGenera.genera);
|
||||
expect(englishGenera?.genus).toBe('Seed Pokémon');
|
||||
});
|
||||
|
||||
test('findEnglishFlavorTextForRed works correctly for species 1', () => {
|
||||
const englishFlavorText = findFirstEnglishFlavorText(flavor_text_entries);
|
||||
expect(englishFlavorText).toBe(
|
||||
'A strange seed was\nplanted on its\nback at birth.\fThe plant sprouts\nand grows with\nthis POKéMON.',
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
|
@ -1,28 +1,167 @@
|
|||
import { createSlice } from '@reduxjs/toolkit';
|
||||
import { createAsyncThunk, createSlice } from '@reduxjs/toolkit';
|
||||
import type { Slice, PayloadAction } from '@reduxjs/toolkit';
|
||||
import { buildDevCheckHandler } from '@reduxjs/toolkit/dist/query/core/buildMiddleware/devMiddleware';
|
||||
import { useAppSelector } from '../../app/hooks';
|
||||
import { pokeApi } from '../../app/services/pokeApi';
|
||||
import { PokemonResponseData } from '../../types/api';
|
||||
|
||||
import { pokeApi } from 'app/services/pokeApi';
|
||||
import { EvolutionSpeciesProps } from 'components/EvolutionSpecies';
|
||||
import { Stat } from 'components/InfoDialogComponent';
|
||||
import {
|
||||
EvolutionChain,
|
||||
EvolutionChainResponseData,
|
||||
FlavorTextEntry,
|
||||
generaItem,
|
||||
PokemonResponseData,
|
||||
PokemonSpeciesResponseData,
|
||||
} from 'types/api';
|
||||
|
||||
type InfoDiaglogDetails = {
|
||||
id: number;
|
||||
name: string;
|
||||
genera: string;
|
||||
image: string;
|
||||
types: string[];
|
||||
height: number;
|
||||
weight: number;
|
||||
genderRatio: number;
|
||||
description: string;
|
||||
abilities: string[];
|
||||
stats: Stat[];
|
||||
evolutionChain: EvolutionSpeciesProps[];
|
||||
};
|
||||
|
||||
const initialInfoDialogDetails: InfoDiaglogDetails = {
|
||||
id: 0,
|
||||
name: '',
|
||||
genera: '',
|
||||
image: '',
|
||||
types: [],
|
||||
height: 0,
|
||||
weight: 0,
|
||||
genderRatio: 0,
|
||||
description: '',
|
||||
abilities: [],
|
||||
stats: [],
|
||||
evolutionChain: [],
|
||||
};
|
||||
|
||||
export type InfoDialogStateProps = {
|
||||
isOpen: boolean;
|
||||
skipGetPokemonSpeciesQuery: boolean;
|
||||
skipGetEvolutionChainQuery: boolean;
|
||||
selectedPokemonId: number;
|
||||
pokemonSpeciesIdToFetch: number;
|
||||
evolutionChainIdToFetch: number;
|
||||
InfoDialogDetails: InfoDiaglogDetails;
|
||||
};
|
||||
|
||||
export const initialState: InfoDialogStateProps = {
|
||||
isOpen: false,
|
||||
skipGetPokemonSpeciesQuery: false,
|
||||
skipGetEvolutionChainQuery: false,
|
||||
selectedPokemonId: 0,
|
||||
pokemonSpeciesIdToFetch: 0,
|
||||
evolutionChainIdToFetch: 0,
|
||||
InfoDialogDetails: initialInfoDialogDetails,
|
||||
};
|
||||
|
||||
// create a function named constructNameOfEvolutionChainFromResponse to
|
||||
// iterate though EvolutionChainResponseData recursively and add name to result
|
||||
export const constructEvolutionChainFromResponse = (
|
||||
response: EvolutionChainResponseData,
|
||||
) => {
|
||||
const result: string[] = [];
|
||||
const addEvolutionSpeciesProps = (evo: EvolutionChain) => {
|
||||
result.push(evo.species.name);
|
||||
evo.evolves_to.forEach(evo => {
|
||||
addEvolutionSpeciesProps(evo);
|
||||
});
|
||||
};
|
||||
|
||||
addEvolutionSpeciesProps(response.chain);
|
||||
return result;
|
||||
};
|
||||
|
||||
export const findEnglishGenera = (generaItem: generaItem[]) =>
|
||||
generaItem.find(genera => genera.language.name === 'en');
|
||||
|
||||
export const findFirstEnglishFlavorText = (
|
||||
flavorTextEntries: FlavorTextEntry[],
|
||||
): string => {
|
||||
const englishFlavorTextItems = flavorTextEntries.filter(
|
||||
flavorText => flavorText.language.name === 'en',
|
||||
);
|
||||
if (englishFlavorTextItems) {
|
||||
return englishFlavorTextItems[0].flavor_text;
|
||||
} else {
|
||||
return 'Error';
|
||||
}
|
||||
};
|
||||
|
||||
export const constructPokemonInfoFromResponses = (
|
||||
fetchedPokemon: PokemonResponseData,
|
||||
fetchedPokemonSpecies: PokemonSpeciesResponseData,
|
||||
evolutionChain: EvolutionSpeciesProps[],
|
||||
): InfoDiaglogDetails => {
|
||||
return {
|
||||
id: fetchedPokemon.id,
|
||||
name: fetchedPokemon.name,
|
||||
genera: findEnglishGenera(fetchedPokemonSpecies.genera)?.genus || '',
|
||||
image: fetchedPokemon.sprites.other.dream_world.front_default,
|
||||
types: fetchedPokemon.types.map(type => type.type.name),
|
||||
height: fetchedPokemon.height,
|
||||
weight: fetchedPokemon.weight,
|
||||
genderRatio: fetchedPokemonSpecies.gender_rate - 1,
|
||||
description: findFirstEnglishFlavorText(
|
||||
fetchedPokemonSpecies.flavor_text_entries,
|
||||
),
|
||||
abilities: fetchedPokemon.abilities.map(ability => ability.ability.name),
|
||||
stats: fetchedPokemon.stats.map(stat => ({
|
||||
stat__name: stat.stat.name,
|
||||
stat__value: stat.base_stat,
|
||||
})),
|
||||
evolutionChain: evolutionChain,
|
||||
};
|
||||
};
|
||||
|
||||
export const fetchSelectedPokemonInfo = createAsyncThunk(
|
||||
'infoDialog/fetchSelectedPokemonInfo',
|
||||
async (pokemonId: number, thunkAPI) => {
|
||||
const { data: selectedPokemon } = await pokeApi.useGetPokemonQuery(
|
||||
pokemonId,
|
||||
);
|
||||
if (selectedPokemon && selectedPokemon.species) {
|
||||
const { data: selectedPokemonSpecies } =
|
||||
await pokeApi.useGetPokemonSpeciesFromUrlQuery(
|
||||
selectedPokemon.species.url,
|
||||
);
|
||||
if (selectedPokemonSpecies && selectedPokemonSpecies.evolution_chain) {
|
||||
const { data: selectedPokemonEvolutionChain } =
|
||||
await pokeApi.useGetEvolutionChainFromUrlQuery(
|
||||
selectedPokemonSpecies.evolution_chain.url,
|
||||
);
|
||||
if (selectedPokemonEvolutionChain) {
|
||||
const evolutionChainNames = constructEvolutionChainFromResponse(
|
||||
selectedPokemonEvolutionChain,
|
||||
);
|
||||
// for each name in evolutionChain, fetch the pokemon
|
||||
const evolutionChain: EvolutionSpeciesProps[] = [];
|
||||
evolutionChainNames.map(async name => {
|
||||
const { data: evolutionChainPokemon } =
|
||||
await pokeApi.useGetPokemonQuery(name);
|
||||
if (evolutionChainPokemon) {
|
||||
evolutionChain.push({
|
||||
types: evolutionChainPokemon.types.map(type => type.type.name),
|
||||
name: evolutionChainPokemon.name,
|
||||
image_url:
|
||||
evolutionChainPokemon.sprites.other.dream_world.front_default,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
const selectedPokemonInfo = constructPokemonInfoFromResponses(
|
||||
selectedPokemon,
|
||||
selectedPokemonSpecies,
|
||||
evolutionChain,
|
||||
);
|
||||
|
||||
return selectedPokemonInfo;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
},
|
||||
);
|
||||
|
||||
export const infoDialogSlice: Slice<InfoDialogStateProps> = createSlice({
|
||||
name: 'infoDialog',
|
||||
initialState,
|
||||
|
@ -30,38 +169,17 @@ export const infoDialogSlice: Slice<InfoDialogStateProps> = createSlice({
|
|||
setIsOpen: (state, action: PayloadAction<boolean>) => {
|
||||
state.isOpen = action.payload;
|
||||
},
|
||||
setSkipGetPokemonSpeciesQuery: (state, action: PayloadAction<boolean>) => {
|
||||
state.skipGetPokemonSpeciesQuery = action.payload;
|
||||
},
|
||||
setSkipGetEvolutionChainQuery: (state, action: PayloadAction<boolean>) => {
|
||||
state.skipGetEvolutionChainQuery = action.payload;
|
||||
},
|
||||
setSelectedPokemonId: (state, action: PayloadAction<number>) => {
|
||||
state.selectedPokemonId = action.payload;
|
||||
},
|
||||
setPokemonSpeciesIdToFetch: (state, action: PayloadAction<number>) => {
|
||||
state.pokemonSpeciesIdToFetch = action.payload;
|
||||
},
|
||||
setEvolutionChainIdToFetch: (state, action: PayloadAction<number>) => {
|
||||
state.evolutionChainIdToFetch = action.payload;
|
||||
},
|
||||
extraReducers: builder => {
|
||||
builder.addCase(fetchSelectedPokemonInfo.fulfilled, (state, action) => {
|
||||
if (action.payload) {
|
||||
state.InfoDialogDetails = action.payload;
|
||||
state.isOpen = true;
|
||||
}
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
export const {
|
||||
setIsOpen,
|
||||
setSkipGetPokemonSpeciesQuery,
|
||||
setSkipGetEvolutionChainQuery,
|
||||
setSelectedPokemonId,
|
||||
setPokemonSpeciesIdToFetch,
|
||||
setEvolutionChainIdToFetch,
|
||||
} = infoDialogSlice.actions;
|
||||
export const { setIsOpen } = infoDialogSlice.actions;
|
||||
|
||||
export default infoDialogSlice.reducer;
|
||||
|
||||
const fetchSelectedPokemonInfo = () => async (dispatch: any, getState: any) => {
|
||||
dispatch(setIsOpen(true));
|
||||
const selectedPokemonId = getState().InfoDialog.selectedPokemonId;
|
||||
const { data: selectedPokemon } =
|
||||
pokeApi.useGetPokemonQuery(selectedPokemonId);
|
||||
};
|
||||
|
|
|
@ -4,6 +4,7 @@ import Loading from 'components/Loading';
|
|||
|
||||
import { useAppSelector, useAppDispatch } from 'app/hooks';
|
||||
import { fetchPokemonsInTheRegion } from './pokedexSlice';
|
||||
import { fetchSelectedPokemonInfo } from '../InfoDialog/infoDialogSlice';
|
||||
|
||||
export const filterPokemonCardsByType = (
|
||||
pokemonList: PokemonCardProps[],
|
||||
|
@ -90,6 +91,9 @@ const Pokedex = ({
|
|||
name={pokemonCard.name}
|
||||
image={pokemonCard.image}
|
||||
types={pokemonCard.types}
|
||||
onClickAction={() =>
|
||||
dispatch(fetchSelectedPokemonInfo(pokemonCard.id))
|
||||
}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
|
|
|
@ -61,11 +61,25 @@ export interface PokemonResponseData {
|
|||
};
|
||||
}
|
||||
|
||||
export type generaItem = {
|
||||
genus: string;
|
||||
language: nameUrlPair;
|
||||
};
|
||||
|
||||
export type FlavorTextEntry = {
|
||||
flavor_text: string;
|
||||
language: nameUrlPair;
|
||||
version: nameUrlPair;
|
||||
};
|
||||
|
||||
export type PokemonSpeciesResponseData = {
|
||||
// many fields are ignored
|
||||
genera: generaItem[];
|
||||
evolution_chain: {
|
||||
url: string;
|
||||
};
|
||||
gender_rate: number;
|
||||
flavor_text_entries: FlavorTextEntry[];
|
||||
};
|
||||
|
||||
export type EvolutionChain = {
|
||||
|
|
Loading…
Reference in New Issue