Compare commits
3 Commits
54bf00e22c
...
bde86898e2
Author | SHA1 | Date | |
---|---|---|---|
bde86898e2 | |||
4a13b56c98 | |||
2513d4365f |
@ -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/';
|
||||
|
@ -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>
|
||||
|
@ -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) => {
|
||||
|
@ -76,7 +76,7 @@ const Pokedex = ({
|
||||
|
||||
useEffect(() => {
|
||||
dispatch(fetchPokemonsInTheRegion(selectedRegion));
|
||||
}, [selectedRegion]);
|
||||
}, [dispatch, selectedRegion]);
|
||||
|
||||
return (
|
||||
<>
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user