Compare commits

..

No commits in common. "bde86898e2eb9fc6f10578555bebf201bde61cae" and "54bf00e22c967d25cd586b4822e5e9bd07ef59ac" have entirely different histories.

5 changed files with 69 additions and 63 deletions

View File

@ -2,7 +2,6 @@ import {
fetchBaseQuery, fetchBaseQuery,
FetchArgs, FetchArgs,
createApi, createApi,
BaseQueryApi,
} from '@reduxjs/toolkit/query/react'; } from '@reduxjs/toolkit/query/react';
import { import {
RegionListResponseData, RegionListResponseData,
@ -10,7 +9,6 @@ import {
PokemonResponseData, PokemonResponseData,
EvolutionChainResponseData, EvolutionChainResponseData,
PokemonSpeciesResponseData, PokemonSpeciesResponseData,
nameUrlPair,
} from 'types/api'; } from 'types/api';
export interface pokeApiFullListFetchArgs extends FetchArgs { export interface pokeApiFullListFetchArgs extends FetchArgs {
@ -21,7 +19,12 @@ interface PokeAPIPaginatedResponse {
count: number; count: number;
next: string | null; next: string | null;
previous: string | null; previous: string | null;
results: nameUrlPair[]; results: any[];
}
interface PokeAPIFullListResponse {
count: number;
results: any[];
} }
export const getIdFromUrl = (url: string) => { export const getIdFromUrl = (url: string) => {
@ -30,7 +33,7 @@ export const getIdFromUrl = (url: string) => {
}; };
async function fetchAllPages(url: string | null) { async function fetchAllPages(url: string | null) {
const allResults: nameUrlPair[] = []; const allResults: any[] = [];
while (url) { while (url) {
const response = await fetch(url); const response = await fetch(url);
@ -47,7 +50,7 @@ export const paginationBaseQuery = (baseUrl: string) =>
export const pokeApiAllPagesCustomBaseQuery = async ( export const pokeApiAllPagesCustomBaseQuery = async (
args: pokeApiFullListFetchArgs, args: pokeApiFullListFetchArgs,
api: BaseQueryApi, api: any,
extra: any, extra: any,
baseUrl: string, baseUrl: string,
) => { ) => {
@ -59,17 +62,19 @@ export const pokeApiAllPagesCustomBaseQuery = async (
data.results = data.results.concat(allResults); data.results = data.results.concat(allResults);
} }
result.data = { const fullListReponse: PokeAPIFullListResponse = {
count: data.count, count: data.count,
results: data.results, results: data.results,
}; };
result.data = fullListReponse;
} }
return result; return result;
}; };
export const pokeApiBaseQuery = async ( export const pokeApiBaseQuery = async (
args: pokeApiFullListFetchArgs, args: pokeApiFullListFetchArgs,
api: BaseQueryApi, api: any,
extra: any, extra: any,
) => { ) => {
const baseUrl = 'https://pokeapi.co/api/v2/'; const baseUrl = 'https://pokeapi.co/api/v2/';

View File

@ -6,8 +6,10 @@ import {
setSelectedRegion, setSelectedRegion,
setSelectedType, setSelectedType,
setSelectedSort, setSelectedSort,
setRegionOptions,
setTypeOptions,
setSortOptions,
setSearchInput, setSearchInput,
initializeFilterSlice,
} from './filterSlice'; } from './filterSlice';
import { useGetTypeListQuery } from 'app/services/pokeApi'; import { useGetTypeListQuery } from 'app/services/pokeApi';
import { RegionPokemonRange } from './types/slice'; import { RegionPokemonRange } from './types/slice';
@ -29,22 +31,61 @@ export const createRegionPokemonListOptionElements = (
}); });
}; };
export const useGetRegionOptions = () => {
const data: RegionPokemonRange[] = [
{ region: 'kanto', startId: 1, endId: 151 },
{ region: 'johto', startId: 152, endId: 251 },
{ region: 'hoenn', startId: 252, endId: 386 },
{ region: 'sinnoh', startId: 387, endId: 493 },
{ region: 'unova', startId: 494, endId: 649 },
{ region: 'kalos', startId: 650, endId: 721 },
{ region: 'alola', startId: 722, endId: 809 },
{ region: 'galar', startId: 810, endId: 898 },
];
return { data: data };
};
const useGetSortOptions = () => {
const data = [
{ name: 'ID', value: 'id' },
{ name: 'Name', value: 'name' },
];
return { data: data };
};
const Filters = () => { const Filters = () => {
const dispatch = useAppDispatch(); const dispatch = useAppDispatch();
const typeOptions = useAppSelector(state => state.filter.typeOptions);
const sortOptions = useAppSelector(state => state.filter.sortOptions);
const regionOptions = useAppSelector(state => state.filter.regionOptions);
const selectedRegion = useAppSelector(state => state.filter.selectedRegion); const selectedRegion = useAppSelector(state => state.filter.selectedRegion);
const selectedType = useAppSelector(state => state.filter.selectedType); const selectedType = useAppSelector(state => state.filter.selectedType);
const selectedSort = useAppSelector(state => state.filter.selectedSort); const selectedSort = useAppSelector(state => state.filter.selectedSort);
const searchInput = useAppSelector(state => state.filter.searchInput); const searchInput = useAppSelector(state => state.filter.searchInput);
const { isLoading: isFetchingTypeOptions } = useGetTypeListQuery(); const regionPokemonList = useAppSelector(state => state.filter.regionOptions);
const { data: fetchedRegionOptions } = useGetRegionOptions();
const { data: fetchedTypeOptions, isLoading: isFetchingTypeOptions } =
useGetTypeListQuery();
const { data: fetchedSortOptions } = useGetSortOptions();
useEffect(() => { useEffect(() => {
dispatch(initializeFilterSlice()); dispatch(setRegionOptions(fetchedRegionOptions));
}, [dispatch]); dispatch(setSortOptions(fetchedSortOptions));
dispatch(setSelectedRegion(fetchedRegionOptions[0].region));
dispatch(setSelectedSort(fetchedSortOptions[0].value));
}, []);
useEffect(() => {
if (!isFetchingTypeOptions && fetchedTypeOptions) {
dispatch(setTypeOptions(fetchedTypeOptions.results));
dispatch(setSelectedType(fetchedTypeOptions.results[0].name));
}
}, [isFetchingTypeOptions]);
const optionElements =
createRegionPokemonListOptionElements(regionPokemonList);
return ( return (
<> <>
@ -60,7 +101,7 @@ const Filters = () => {
}} }}
value={selectedRegion} value={selectedRegion}
> >
{createRegionPokemonListOptionElements(regionOptions)} {optionElements}
</select> </select>
</div> </div>
</div> </div>
@ -75,9 +116,9 @@ const Filters = () => {
{isFetchingTypeOptions ? ( {isFetchingTypeOptions ? (
<option>Loading...</option> <option>Loading...</option>
) : ( ) : (
typeOptions.map(type => ( fetchedTypeOptions?.results.map(type => (
<option key={type} value={type}> <option key={type.name} value={type.name}>
{type} {type.name}
</option> </option>
)) ))
)} )}
@ -93,7 +134,7 @@ const Filters = () => {
onChange={e => dispatch(setSelectedSort(e.target.value))} onChange={e => dispatch(setSelectedSort(e.target.value))}
value={selectedSort} value={selectedSort}
> >
{sortOptions.map(option => ( {fetchedSortOptions.map(option => (
<option key={option.value} value={option.value}> <option key={option.value} value={option.value}>
{option.name} {option.name}
</option> </option>

View File

@ -1,9 +1,4 @@
import { import { createSlice, PayloadAction, Slice } from '@reduxjs/toolkit';
createAsyncThunk,
createSlice,
PayloadAction,
Slice,
} from '@reduxjs/toolkit';
import { FilterState } from './types/slice'; import { FilterState } from './types/slice';
import { RegionPokemonRange } from './types/slice'; import { RegionPokemonRange } from './types/slice';
import { pokeApi } from 'app/services/pokeApi'; import { pokeApi } from 'app/services/pokeApi';
@ -20,33 +15,6 @@ const initialState: FilterState = {
searchInput: '', searchInput: '',
}; };
export const initializeFilterSlice = createAsyncThunk(
'filter/initializeFilterSlice',
async (_args, thunkAPI) => {
const dispatch = thunkAPI.dispatch;
const regionOptions = [
{ region: 'kanto', startId: 1, endId: 151 },
{ region: 'johto', startId: 152, endId: 251 },
{ region: 'hoenn', startId: 252, endId: 386 },
{ region: 'sinnoh', startId: 387, endId: 493 },
{ region: 'unova', startId: 494, endId: 649 },
{ region: 'kalos', startId: 650, endId: 721 },
{ region: 'alola', startId: 722, endId: 809 },
{ region: 'galar', startId: 810, endId: 898 },
];
dispatch(pokeApi.endpoints.getTypeList.initiate());
const sortOptions = [
{ name: 'ID', value: 'id' },
{ name: 'Name', value: 'name' },
];
return { regionOptions, sortOptions };
},
);
export const filterSlice: Slice<FilterState> = createSlice({ export const filterSlice: Slice<FilterState> = createSlice({
name: 'filter', name: 'filter',
initialState, initialState,
@ -77,15 +45,6 @@ export const filterSlice: Slice<FilterState> = createSlice({
}, },
}, },
extraReducers: builder => { extraReducers: builder => {
builder.addCase(initializeFilterSlice.fulfilled, (state, action) => {
if (action.payload) {
state.regionOptions = action.payload.regionOptions;
state.sortOptions = action.payload.sortOptions;
state.selectedRegion = action.payload.regionOptions[0].region;
state.selectedSort = action.payload.sortOptions[0].value;
}
});
builder.addMatcher( builder.addMatcher(
pokeApi.endpoints.getTypeList.matchFulfilled, pokeApi.endpoints.getTypeList.matchFulfilled,
(state, action) => { (state, action) => {

View File

@ -76,7 +76,7 @@ const Pokedex = ({
useEffect(() => { useEffect(() => {
dispatch(fetchPokemonsInTheRegion(selectedRegion)); dispatch(fetchPokemonsInTheRegion(selectedRegion));
}, [dispatch, selectedRegion]); }, [selectedRegion]);
return ( return (
<> <>

View File

@ -37,6 +37,7 @@ export interface PokemonResponseData {
base_experience: number; base_experience: number;
forms: nameUrlPair[]; forms: nameUrlPair[];
height: number; height: number;
held_items: any[];
id: number; id: number;
is_default: boolean; is_default: boolean;
location_area_encounters: string; location_area_encounters: string;