Implemented search in the filter bar
parent
10442f9dc8
commit
3281629dcf
|
@ -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>
|
||||
</>
|
||||
);
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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[];
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue