Skip to content

Commit

Permalink
Merge pull request #19 from lizaklimova/search_page
Browse files Browse the repository at this point in the history
searchTypeSelector, searchParams
  • Loading branch information
lizaklimova authored Feb 10, 2024
2 parents 901b2bf + 852443e commit c491e04
Show file tree
Hide file tree
Showing 13 changed files with 260 additions and 40 deletions.
14 changes: 14 additions & 0 deletions src/components/MainTitle/MainTitle.styled.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import styled from 'styled-components';

export const PageTitle = styled.h2`
font-weight: 600;
font-size: 28px;
@media screen and (min-width: 768px) {
font-size: 32px;
}
@media screen and (min-width: 1440px) {
font-size: 44px;
}
`;
3 changes: 2 additions & 1 deletion src/components/MainTitle/MainTitle.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { FC } from 'react';
import { IMainTitleProps } from './mainTitleTypes';
import { PageTitle } from './MainTitle.styled';

const MainTitle: FC<IMainTitleProps> = ({ title }) => {
return <h2>{title}</h2>;
return <PageTitle>{title}</PageTitle>;
};

export default MainTitle;
10 changes: 9 additions & 1 deletion src/components/Search/SearchBar/SearchBar.styled.tsx
Original file line number Diff line number Diff line change
@@ -1 +1,9 @@
export {};
import styled from 'styled-components';

export const Container = styled.div`
display: flex;
flex-direction: column;
align-items: center;
gap: 24px;
margin-top: 50px;
`;
5 changes: 3 additions & 2 deletions src/components/Search/SearchBar/SearchBar.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import { FC } from 'react';
import SearchForm from 'components/SearchForm';
import SearchTypeSelector from '../SearchTypeSelector';
import { Container } from './SearchBar.styled';

const SearchBar: FC = () => {
return (
<div>
<Container>
<SearchForm />
<SearchTypeSelector />
</div>
</Container>
);
};

Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1,119 @@
export {};
import styled from 'styled-components';
import { FaAngleDown } from 'react-icons/fa6';

interface SelectProps {
$theme: string;
}

export const SelectWrap = styled.div`
display: flex;
align-items: center;
gap: 15px;
@media screen and (min-width: 768px) {
gap: 32px;
}
@media screen and (min-width: 1440px) {
gap: 18px;
}
`;

export const SelectName = styled.p`
font-weight: 500;
font-size: 12px;
line-height: 133%;
@media screen and (min-width: 768px) {
font-size: 14px;
}
@media screen and (min-width: 1440px) {
font-size: 18px;
}
`;

export const Select = styled.div<SelectProps>`
display: flex;
justify-content: space-between;
align-items: center;
width: 146px;
height: 34px;
border: ${({ $theme }) =>
$theme === 'light' ? 'none' : '1px solid var(--heroInput)'};
background-color: ${({ $theme }) =>
$theme === 'light' ? '#d9d9d928' : 'transparent'};
color: ${({ $theme }) => ($theme === 'light' ? '#23262a80' : '#fafafa7f')};
border-radius: 6px;
padding: 8px 14px;
font-size: 12px;
@media screen and (min-width: 768px) {
width: 175px;
height: 41px;
font-size: 14px;
padding: 10px 14px;
}
@media screen and (min-width: 1440px) {
width: 198px;
height: 49px;
padding: 14px;
}
`;

export const SelectContainer = styled.div`
position: relative;
`;

export const Options = styled.ul`
position: absolute;
top: 100%;
left: 0;
width: 100%;
background-color: var(--selectBg);
border-radius: 6px;
font-size: 12px;
padding: 8px 14px;
@media screen and (min-width: 768px) {
font-size: 14px;
padding: 10px 14px;
}
@media screen and (min-width: 1440px) {
padding: 14px;
}
`;

export const Option = styled.li`
display: flex;
align-items: center;
height: 23px;
opacity: 0.5;
transition: all 200ms ease-in-out;
&:hover {
opacity: 1;
}
@media screen and (min-width: 768px) {
height: 27px;
}
@media screen and (min-width: 1440px) {
height: 25px;
}
`;

export const ArrowDown = styled(FaAngleDown)`
color: var(--accentGreen);
width: 14px;
@media screen and (min-width: 768px) {
width: 20px;
}
@media screen and (min-width: 1440px) {
}
`;
59 changes: 57 additions & 2 deletions src/components/Search/SearchTypeSelector/SearchTypeSelector.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,62 @@
import { FC } from 'react';
import { FC, useState } from 'react';
import {
ArrowDown,
Option,
Options,
Select,
SelectContainer,
SelectName,
SelectWrap,
} from './SearchTypeSelector.styled';
import { useDispatch, useSelector } from 'react-redux';
import { updateSearchTypeAction } from '../../../redux/search/slice';
import { selectSearchType } from '../../../redux/search/selectors';
import useTheme from 'hooks/useTheme';

const SearchTypeSelector: FC = () => {
return <div></div>;
const dispatch = useDispatch();
const searchType = useSelector(selectSearchType);
const { theme } = useTheme();

const [isOpen, setIsOpen] = useState(false);

const onSearchTypeChange = (event: React.MouseEvent<HTMLLIElement>) => {
const value = event.currentTarget.dataset.value;

dispatch(updateSearchTypeAction(value));
closeDropdown();
};

const openDropdown = () => {
setIsOpen(true);
};

const closeDropdown = () => {
setIsOpen(false);
};

return (
<SelectWrap>
<SelectName>Search by:</SelectName>
<SelectContainer>
<Select onClick={openDropdown} $theme={theme}>
{searchType === 'query' ? 'Title' : 'Ingredients'}
<ArrowDown />
</Select>

{isOpen && (
<Options>
<Option data-value="query" onClick={onSearchTypeChange}>
Title
</Option>
<Option data-value="ingredient" onClick={onSearchTypeChange}>
Ingredients
</Option>
</Options>
)}
</SelectContainer>
</SelectWrap>
);
};

export default SearchTypeSelector;
9 changes: 5 additions & 4 deletions src/components/SearchForm/SearchForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import { Formik } from 'formik';
import useTheme from 'hooks/useTheme';
import { SearchButton, SearchInput, StyledForm } from './SearchForm.styled';
import { useDispatch, useSelector } from 'react-redux';
import { selectSearchQuery } from '../../redux/searchQuery/selectors';
import { updateSearchQueryAction } from '../../redux/searchQuery/slice';
import { selectSearchQuery } from '../../redux/search/selectors';
import { updateSearchQueryAction } from '../../redux/search/slice';

const SearchForm: FC = () => {
const { theme } = useTheme();
Expand All @@ -15,14 +15,15 @@ const SearchForm: FC = () => {
const dispatch = useDispatch();

const handleSearch = () => {
if (pathname === '/main' && query.trim().length) {
if (pathname === '/main' && query.length) {
navigate('/search');
}

console.log(query);
};

const handleChange = (event: ChangeEvent<HTMLInputElement>) => {
dispatch(updateSearchQueryAction(event.target.value));
dispatch(updateSearchQueryAction(event.target.value.trim()));
};

return (
Expand Down
17 changes: 16 additions & 1 deletion src/pages/SearchPage.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,23 @@
import MainTitle from 'components/MainTitle/MainTitle';
import SearchBar from 'components/Search/SearchBar';
import { FC } from 'react';
import { FC, useEffect } from 'react';
import { useSelector } from 'react-redux';
import { useSearchParams } from 'react-router-dom';
import { selectSearchQuery, selectSearchType } from '../redux/search/selectors';

const SearchPage: FC = () => {
const query = useSelector(selectSearchQuery);
const type = useSelector(selectSearchType);
const [searchParams, setSearchParams] = useSearchParams();

useEffect(() => {
if (!query.length) {
setSearchParams({});
} else {
setSearchParams({ [type]: query, page: '1' });
}
}, [query, type, setSearchParams]);

return (
<>
<MainTitle title={'Search'} />
Expand Down
5 changes: 5 additions & 0 deletions src/redux/search/selectors.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { RootState } from 'redux/store';

export const selectSearchQuery = (state: RootState) => state.search.searchQuery;

export const selectSearchType = (state: RootState) => state.search.searchType;
28 changes: 28 additions & 0 deletions src/redux/search/slice.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { createSlice } from '@reduxjs/toolkit';

export interface SearchState {
searchQuery: string;
searchType: 'query' | 'ingredient';
}

const searchInitialState: SearchState = {
searchQuery: '',
searchType: 'query',
};

const searchSlice = createSlice({
name: 'search',
initialState: searchInitialState,
reducers: {
updateSearchQueryAction(state, action) {
state.searchQuery = action.payload;
},
updateSearchTypeAction(state, action) {
state.searchType = action.payload;
},
},
});

export const { updateSearchQueryAction, updateSearchTypeAction } =
searchSlice.actions;
export const searchReducer = searchSlice.reducer;
4 changes: 0 additions & 4 deletions src/redux/searchQuery/selectors.ts

This file was deleted.

22 changes: 0 additions & 22 deletions src/redux/searchQuery/slice.ts

This file was deleted.

4 changes: 2 additions & 2 deletions src/redux/store.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
} from 'redux-persist';
import storage from 'redux-persist/lib/storage';
import { authReducer } from './auth/slice';
import { searchQueryReducer } from './searchQuery/slice';
import { searchReducer } from './search/slice';

const authPersistConfig = {
key: 'auth',
Expand All @@ -22,7 +22,7 @@ const authPersistConfig = {
const persistedReducer = persistReducer(authPersistConfig, authReducer);
const rootReducer = combineReducers({
auth: persistedReducer,
searchQuery: searchQueryReducer,
search: searchReducer,
});

export const store = configureStore({
Expand Down

0 comments on commit c491e04

Please sign in to comment.