Compare commits

...

3 Commits

5 changed files with 63 additions and 69 deletions

View File

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

View File

@ -6,10 +6,8 @@ import {
setSelectedRegion,
setSelectedType,
setSelectedSort,
setRegionOptions,
setTypeOptions,
setSortOptions,
setSearchInput,
initializeFilterSlice,
} from './filterSlice';
import { useGetTypeListQuery } from 'app/services/pokeApi';
import { RegionPokemonRange } from './types/slice';
@ -31,61 +29,22 @@ 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 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 selectedType = useAppSelector(state => state.filter.selectedType);
const selectedSort = useAppSelector(state => state.filter.selectedSort);
const searchInput = useAppSelector(state => state.filter.searchInput);
const regionPokemonList = useAppSelector(state => state.filter.regionOptions);
const { data: fetchedRegionOptions } = useGetRegionOptions();
const { data: fetchedTypeOptions, isLoading: isFetchingTypeOptions } =
useGetTypeListQuery();
const { data: fetchedSortOptions } = useGetSortOptions();
const { isLoading: isFetchingTypeOptions } = useGetTypeListQuery();
useEffect(() => {
dispatch(setRegionOptions(fetchedRegionOptions));
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);
dispatch(initializeFilterSlice());
}, [dispatch]);
return (
<>
@ -101,7 +60,7 @@ const Filters = () => {
}}
value={selectedRegion}
>
{optionElements}
{createRegionPokemonListOptionElements(regionOptions)}
</select>
</div>
</div>
@ -116,9 +75,9 @@ const Filters = () => {
{isFetchingTypeOptions ? (
<option>Loading...</option>
) : (
fetchedTypeOptions?.results.map(type => (
<option key={type.name} value={type.name}>
{type.name}
typeOptions.map(type => (
<option key={type} value={type}>
{type}
</option>
))
)}
@ -134,7 +93,7 @@ const Filters = () => {
onChange={e => dispatch(setSelectedSort(e.target.value))}
value={selectedSort}
>
{fetchedSortOptions.map(option => (
{sortOptions.map(option => (
<option key={option.value} value={option.value}>
{option.name}
</option>

View File

@ -1,4 +1,9 @@
import { createSlice, PayloadAction, Slice } from '@reduxjs/toolkit';
import {
createAsyncThunk,
createSlice,
PayloadAction,
Slice,
} from '@reduxjs/toolkit';
import { FilterState } from './types/slice';
import { RegionPokemonRange } from './types/slice';
import { pokeApi } from 'app/services/pokeApi';
@ -15,6 +20,33 @@ const initialState: FilterState = {
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({
name: 'filter',
initialState,
@ -45,6 +77,15 @@ export const filterSlice: Slice<FilterState> = createSlice({
},
},
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(
pokeApi.endpoints.getTypeList.matchFulfilled,
(state, action) => {

View File

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

View File

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