From af890689291a4b898fcab19e4ddb646980536834 Mon Sep 17 00:00:00 2001 From: Jason Zhu Date: Sun, 19 Mar 2023 22:42:09 +1100 Subject: [PATCH] Implemented setSelectedType and setSelectedSort reducer in pokedexSlice, and getRegionList and getTypeList endpoints --- src/features/Pokedex/Filters/Filters.tsx | 86 ++++++++++++++++++++++-- src/features/Pokedex/Filters/index.ts | 1 + src/features/Pokedex/pokedexApi.ts | 42 +++++++++++- src/features/Pokedex/pokedexSlice.ts | 21 ++++-- 4 files changed, 138 insertions(+), 12 deletions(-) create mode 100644 src/features/Pokedex/Filters/index.ts diff --git a/src/features/Pokedex/Filters/Filters.tsx b/src/features/Pokedex/Filters/Filters.tsx index 63aaa6c..4cfab78 100644 --- a/src/features/Pokedex/Filters/Filters.tsx +++ b/src/features/Pokedex/Filters/Filters.tsx @@ -1,30 +1,104 @@ import React from 'react'; +import { + useGetRegionListQuery, + useGetTypeListQuery, +} from 'features/Pokedex/pokedexApi'; +import { + setSelectedRegion, + setSelectedType, + setSelectedSort, +} from 'features/Pokedex/pokedexSlice'; +import { useAppDispatch } from 'app/hooks'; + +const useGetSortOptions = () => { + const sortOptions = [ + { name: 'ID', value: 'id' }, + { name: 'Name', value: 'name' }, + ]; + return { data: sortOptions }; +}; const Filters = () => { + const dispatch = useAppDispatch(); + + const handleRegionChange = (event: React.ChangeEvent) => { + dispatch(setSelectedRegion(event.target.value)); + }; + const handleTypeChange = (event: React.ChangeEvent) => { + dispatch(setSelectedType(event.target.value)); + }; + const handleSortChange = (event: React.ChangeEvent) => { + dispatch(setSelectedSort(event.target.value)); + }; + + const { + data: regionsData, + error: regionsError, + isLoading: regionsLoading, + } = useGetRegionListQuery(); + const { + data: typesData, + error: typesError, + isLoading: typesLoading, + } = useGetTypeListQuery(); + const { data: sortOptions } = useGetSortOptions(); + return ( <>
REGION
- + {regionsLoading ? ( + + ) : ( + regionsData?.results.map(region => ( + + )) + )}
TYPE
- + {typesLoading ? ( + + ) : ( + typesData?.results.map(type => ( + + )) + )}
SORT BY
- + {sortOptions.map(option => ( + + ))}
diff --git a/src/features/Pokedex/Filters/index.ts b/src/features/Pokedex/Filters/index.ts new file mode 100644 index 0000000..c7b59bc --- /dev/null +++ b/src/features/Pokedex/Filters/index.ts @@ -0,0 +1 @@ +export * from './Filters'; diff --git a/src/features/Pokedex/pokedexApi.ts b/src/features/Pokedex/pokedexApi.ts index 40cfaa5..8fdcbd7 100644 --- a/src/features/Pokedex/pokedexApi.ts +++ b/src/features/Pokedex/pokedexApi.ts @@ -1,6 +1,30 @@ import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'; import type { PokemonProps as Pokemon } from './Pokemon'; +export interface Region { + name: string; + url: string; +} + +export interface Type { + name: string; + url: string; +} + +interface RegionResponse { + count: number; + next: string | null; + previous: string | null; + results: Region[]; +} + +interface TypeResponse { + count: number; + next: string | null; + previous: string | null; + results: Type[]; +} + export const pokedexApi = createApi({ reducerPath: 'pokedexApi', baseQuery: fetchBaseQuery({ baseUrl: 'https://pokeapi.co/api/v2/' }), @@ -8,7 +32,23 @@ export const pokedexApi = createApi({ getPokemonList: builder.query({ query: limit => `pokemon?limit=${limit}`, }), + getRegionList: builder.query({ + query: () => 'region', + }), + getTypeList: builder.query({ + query: () => 'type', + transformResponse: (response: RegionResponse) => { + return { + ...response, + results: [{ name: 'All Types', url: '' }, ...response.results], + }; + }, + }), }), }); -export const { useGetPokemonListQuery } = pokedexApi; +export const { + useGetPokemonListQuery, + useGetRegionListQuery, + useGetTypeListQuery, +} = pokedexApi; diff --git a/src/features/Pokedex/pokedexSlice.ts b/src/features/Pokedex/pokedexSlice.ts index de166a8..731a697 100644 --- a/src/features/Pokedex/pokedexSlice.ts +++ b/src/features/Pokedex/pokedexSlice.ts @@ -5,23 +5,34 @@ import type { RootState } from 'app/store'; import { PokemonProps as Pokemon } from './Pokemon'; interface PokedexState { - pokemonList: Pokemon[]; + selectedRegion: string; + selectedType: string; + selectedSort: string; } const initialState: PokedexState = { - pokemonList: [], + selectedRegion: '', + selectedType: '', + selectedSort: '', }; export const pokedexSlice = createSlice({ name: 'pokedex', initialState, reducers: { - setPokemonList: (state, action: PayloadAction) => { - state.pokemonList = action.payload; + setSelectedRegion: (state, action: PayloadAction) => { + state.selectedRegion = action.payload; + }, + setSelectedType: (state, action: PayloadAction) => { + state.selectedType = action.payload; + }, + setSelectedSort: (state, action: PayloadAction) => { + state.selectedSort = action.payload; }, }, }); -export const { setPokemonList } = pokedexSlice.actions; +export const { setSelectedRegion, setSelectedType, setSelectedSort } = + pokedexSlice.actions; export default pokedexSlice.reducer;