Implemented search in the filter bar

develop
Jason Zhu 2023-04-17 22:52:54 +10:00
parent 10442f9dc8
commit 3281629dcf
5 changed files with 63 additions and 4 deletions

View File

@ -8,6 +8,7 @@ import {
setRegionOptions,
setSortOptions,
setTypeOptions,
setSearchInput,
} from 'features/Pokedex/pokedexSlice';
import { RegionPokemonRange } from 'features/Pokedex/types/slice';
import { useAppDispatch, useAppSelector } from 'app/hooks';
@ -141,6 +142,15 @@ const Filters = () => {
</select>
</div>
</div>
<div className="filter__items">
<div>
<div>SEARCH</div>
<input
type="text"
onChange={e => dispatch(setSearchInput(e.target.value))}
/>
</div>
</div>
</div>
</>
);

View File

@ -31,12 +31,22 @@ export const sortPokemonCardsByIdOrName = (
});
};
export const searchPokemonCardsByName = (
pokemonList: PokemonCardProps[],
searchInput: string,
) => {
return pokemonList.filter(pokemon =>
pokemon.name.toLowerCase().includes(searchInput.toLowerCase()),
);
};
const Pokedex = () => {
const isLoadingPokemons = useAppSelector(
state => state.pokedex.isLoadingPokemons,
);
const selectedType = useAppSelector(state => state.pokedex.selectedType);
const selectedSort = useAppSelector(state => state.pokedex.selectedSort);
const searchInput = useAppSelector(state => state.pokedex.searchInput);
const pokemonList = useAppSelector(state => state.pokedex.pokemonCardList);
@ -48,6 +58,10 @@ const Pokedex = () => {
filteredPokemonList,
selectedSort,
);
const searchedPokemonCardList = searchPokemonCardsByName(
sortedFilteredPokemonCardList,
searchInput,
);
return (
<>
@ -56,7 +70,7 @@ const Pokedex = () => {
<Loading />
) : (
<div className="all__pokemons">
{sortedFilteredPokemonCardList.map(pokemonCard => (
{searchedPokemonCardList.map(pokemonCard => (
<PokemonCard
key={pokemonCard.id}
id={pokemonCard.id}

View File

@ -1,6 +1,7 @@
import {
filterPokemonCardsByType,
sortPokemonCardsByIdOrName,
searchPokemonCardsByName,
} from 'features/Pokedex/Pokedex';
import { PokemonResponseData } from 'features/Pokedex/types/api';
import pokemon3_Venusaur from 'features/Pokedex/__test__/pokemon3_Venusaur.json';
@ -81,4 +82,32 @@ describe('pokedex Component', () => {
expect(sortedList).toEqual([pokemon4_Charmander, pokemon3_Venusaur]);
});
});
describe('searchPokemonByName works correctly', () => {
beforeEach(() => {
store = configureStore({
reducer: {
pokedex: pokedexSlice.reducer,
[pokedexApi.reducerPath]: pokedexApi.reducer,
},
middleware: getDefaultMiddleware =>
getDefaultMiddleware().concat(
pokedexApi.middleware,
listenerMiddleware.middleware,
),
});
});
const pokemonList: PokemonResponseData[] = [
pokemon3_Venusaur,
pokemon4_Charmander,
];
it('should search by name correctly', () => {
const searchName = 'char';
const searchedList = searchPokemonCardsByName(pokemonList, searchName);
expect(searchedList).toHaveLength(1);
expect(searchedList[0]).toEqual(pokemon4_Charmander);
});
});
});

View File

@ -50,6 +50,7 @@ const initialState: PokedexState = {
selectedRegion: '',
selectedType: '',
selectedSort: '',
searchInput: '',
isLoadingPokemons: true,
pokemonCardList: [],
};
@ -79,6 +80,9 @@ export const pokedexSlice: Slice<PokedexState> = createSlice({
) => {
state.sortOptions = action.payload;
},
setSearchInput: (state, action: PayloadAction<string>) => {
state.searchInput = action.payload;
},
setIsLoadingPokemons: (state, action: PayloadAction<boolean>) => {
state.isLoadingPokemons = action.payload;
},
@ -118,6 +122,7 @@ export const {
setRegionOptions,
setTypeOptions,
setSortOptions,
setSearchInput,
setIsLoadingPokemons,
} = pokedexSlice.actions;

View File

@ -2,12 +2,13 @@ import { PokemonResponseData } from './api';
import { PokemonCardProps } from '../PokemonCard';
export type PokedexState = {
selectedRegion: string;
regionOptions: RegionPokemonRange[];
selectedType: string;
typeOptions: string[];
selectedSort: string;
sortOptions: { name: string; value: string }[];
selectedRegion: string;
selectedType: string;
selectedSort: string;
searchInput: string;
isLoadingPokemons: boolean;
pokemonCardList: PokemonCardProps[];
};