From 406986eccea577aa3c868e4fef1a8247367199c1 Mon Sep 17 00:00:00 2001 From: Jeffrey Date: Wed, 3 Jun 2020 14:50:34 -0700 Subject: [PATCH 1/5] created reducer for searchbar and search results. created types for searchbar reducer. created the redux action to toggle searchbar --- src/actions/search.js | 5 +++++ src/actions/types.js | 1 + .../navbarUserUtils.component.jsx | 1 + src/reducers/index.js | 2 ++ src/reducers/searchProducts.js | 19 +++++++++++++++++++ 5 files changed, 28 insertions(+) create mode 100644 src/actions/search.js create mode 100644 src/reducers/searchProducts.js diff --git a/src/actions/search.js b/src/actions/search.js new file mode 100644 index 0000000..aecbb51 --- /dev/null +++ b/src/actions/search.js @@ -0,0 +1,5 @@ +import { TOGGLE_SEARCHBAR } from './types'; + +export const toggleSearchbar = () => (dispatch) => { + dispatch({ type: TOGGLE_SEARCHBAR }); +}; diff --git a/src/actions/types.js b/src/actions/types.js index 4036d6b..966bf10 100644 --- a/src/actions/types.js +++ b/src/actions/types.js @@ -10,3 +10,4 @@ export const AUTH_ERROR = 'AUTH_ERROR'; export const REGISTER_FAIL = 'REGISTER_FAIL'; export const LOGIN_SUCCESS = 'LOGIN_SUCCESS'; export const LOGIN_FAIL = 'LOGIN_FAIL'; +export const TOGGLE_SEARCHBAR = 'TOGGLE_SEARCHBAR'; diff --git a/src/components/NavbarUserUtils/navbarUserUtils.component.jsx b/src/components/NavbarUserUtils/navbarUserUtils.component.jsx index 1becd8a..897445f 100644 --- a/src/components/NavbarUserUtils/navbarUserUtils.component.jsx +++ b/src/components/NavbarUserUtils/navbarUserUtils.component.jsx @@ -20,6 +20,7 @@ const NavbarUserUtils = ({ toggleModal, authorized, signOutUser }) => { src={searchIcon} alt="search icon" /> + {authorized === false ? (

Log In diff --git a/src/reducers/index.js b/src/reducers/index.js index f2777e5..a998f8c 100644 --- a/src/reducers/index.js +++ b/src/reducers/index.js @@ -1,12 +1,14 @@ import counterReducer from './Counter'; import loggedReducer from './isLogged'; import modalReducer from './modalDisplay'; +import productSearchReducer from './searchProducts'; import { combineReducers } from 'redux'; const allReducers = combineReducers({ counter: counterReducer, isLogged: loggedReducer, modalDisplay: modalReducer, + searchProducts: productSearchReducer, }); export default allReducers; diff --git a/src/reducers/searchProducts.js b/src/reducers/searchProducts.js new file mode 100644 index 0000000..9ea80b6 --- /dev/null +++ b/src/reducers/searchProducts.js @@ -0,0 +1,19 @@ +import { TOGGLE_SEARCHBAR } from '../actions/types'; + +const initialState = { + toggleSearchbar: false, + searchResults: [], +}; + +const searchProducts = (state = initialState, action) => { + const { type, payload } = action; + + switch (type) { + case TOGGLE_SEARCHBAR: + return { ...state, toggleSearchbar: !state.toggleSearchbar }; + default: + return { ...state }; + } +}; + +export default searchProducts; From dc558a39a7387391bf49db139275d11607422d40 Mon Sep 17 00:00:00 2001 From: Jeffrey Date: Wed, 3 Jun 2020 20:21:52 -0700 Subject: [PATCH 2/5] styled search bar to look like mock up --- .../navbarUserUtils.component.jsx | 52 ++++++++++++++---- .../navbarUserUtils.styles.css | 54 ++++++++++++++++++- src/reducers/searchProducts.js | 4 +- 3 files changed, 98 insertions(+), 12 deletions(-) diff --git a/src/components/NavbarUserUtils/navbarUserUtils.component.jsx b/src/components/NavbarUserUtils/navbarUserUtils.component.jsx index 897445f..cd3a56a 100644 --- a/src/components/NavbarUserUtils/navbarUserUtils.component.jsx +++ b/src/components/NavbarUserUtils/navbarUserUtils.component.jsx @@ -10,16 +10,47 @@ import LoginModal from '../LoginModal/LoginModal'; import { connect } from 'react-redux'; import { toggleModal } from '../../actions/modalDisplay'; import { signOutUser } from '../../actions/isLogged'; +import { toggleSearchbar } from '../../actions/search'; -const NavbarUserUtils = ({ toggleModal, authorized, signOutUser }) => { +const NavbarUserUtils = ({ + toggleModal, + authorized, + signOutUser, + toggleSearchbar, + displaySearchbar, +}) => { return (

- search icon + {displaySearchbar ? ( + <> +
+
+ +
+ +
+
+ search icon +
+ + ) : ( + search icon + )} {authorized === false ? (

@@ -38,9 +69,12 @@ const NavbarUserUtils = ({ toggleModal, authorized, signOutUser }) => { const mapStateToProps = (state) => { return { authorized: state.isLogged.authorized, + displaySearchbar: state.searchProducts.displaySearchbar, }; }; -export default connect(mapStateToProps, { toggleModal, signOutUser })( - NavbarUserUtils -); +export default connect(mapStateToProps, { + toggleModal, + signOutUser, + toggleSearchbar, +})(NavbarUserUtils); diff --git a/src/components/NavbarUserUtils/navbarUserUtils.styles.css b/src/components/NavbarUserUtils/navbarUserUtils.styles.css index 747b07d..602f75a 100644 --- a/src/components/NavbarUserUtils/navbarUserUtils.styles.css +++ b/src/components/NavbarUserUtils/navbarUserUtils.styles.css @@ -1,7 +1,7 @@ .navbar-user-utils-icon { margin: 0; display: inline; - padding: 10px; + padding: 20px; } .navbar-user-utils-icon:hover { @@ -11,5 +11,57 @@ .navbar-user-utils { display: flex; + flex-direction: row; justify-content: flex-end; + max-height: 65px; +} + +.searchForm { + display: flex; + flex-direction: row; + justify-content: flex-end; + /* max-height: 44px; */ + max-width: 400px; +} + +.searchSelector { + background-color: #b7b7b7; + border-radius: 12px 0px 0px 12px; + height: 43px; + width: auto; + font-size: 1rem; + text-align: center; + color: #707070; + border: 0px; + padding-right: 5px; + + /* arrow */ + -moz-appearance: none; + -webkit-appearance: none; + appearance: none; + background-image: linear-gradient(45deg, transparent 50%, gray 50%), + linear-gradient(135deg, gray 50%, transparent 50%), + linear-gradient(to right, #ccc, #ccc); + background-position: calc(100% - 20px) calc(1em + 2px), + calc(100% - 15px) calc(1em + 2px), calc(100% - 2.5em) 0.5em; + background-size: 5px 5px, 5px 5px, 0px 1.5em; + background-repeat: no-repeat; +} + +.searchInput { + width: 300px; + height: 40px; + border: 0px; +} + +.graySearch { + background-color: #b7b7b7; + max-height: 100%; + height: 43px; + border-radius: 0px 12px 12px 0px; + transform: translateY(10px); +} + +.searchIcon { + padding: 10px 20px 20px 10px; } diff --git a/src/reducers/searchProducts.js b/src/reducers/searchProducts.js index 9ea80b6..0fa5792 100644 --- a/src/reducers/searchProducts.js +++ b/src/reducers/searchProducts.js @@ -1,7 +1,7 @@ import { TOGGLE_SEARCHBAR } from '../actions/types'; const initialState = { - toggleSearchbar: false, + displaySearchbar: false, searchResults: [], }; @@ -10,7 +10,7 @@ const searchProducts = (state = initialState, action) => { switch (type) { case TOGGLE_SEARCHBAR: - return { ...state, toggleSearchbar: !state.toggleSearchbar }; + return { ...state, displaySearchbar: !state.displaySearchbar }; default: return { ...state }; } From e37600feb0cb7e554224d55ff464f928861a8439 Mon Sep 17 00:00:00 2001 From: Jeffrey Date: Thu, 4 Jun 2020 01:05:07 -0700 Subject: [PATCH 3/5] added functionality to search that allows users to filter through products. display will render conditionally dpending on search results --- src/actions/search.js | 19 ++- src/actions/types.js | 2 + src/components/App.js | 20 ++- .../navbarUserUtils.component.jsx | 145 ++++++++++++------ .../navbarUserUtils.styles.css | 4 + src/reducers/searchProducts.js | 11 +- 6 files changed, 145 insertions(+), 56 deletions(-) diff --git a/src/actions/search.js b/src/actions/search.js index aecbb51..54c5f23 100644 --- a/src/actions/search.js +++ b/src/actions/search.js @@ -1,5 +1,22 @@ -import { TOGGLE_SEARCHBAR } from './types'; +import { TOGGLE_SEARCHBAR, SEARCH_PRODUCTS, IS_SEARCHING } from './types'; +import axios from 'axios'; export const toggleSearchbar = () => (dispatch) => { dispatch({ type: TOGGLE_SEARCHBAR }); }; + +export const searchProducts = (searchInput) => async (dispatch) => { + const { data } = await axios.get('http://localhost:5005/data/all'); + + const filteredData = data.filter((obj) => + Object.keys(obj).some((key) => + obj[key].toLowerCase().includes(searchInput.toLowerCase()) + ) + ); + + dispatch({ type: SEARCH_PRODUCTS, payload: filteredData }); +}; + +export const searchStateToggle = () => (dispatch) => { + dispatch({ type: IS_SEARCHING }); +}; diff --git a/src/actions/types.js b/src/actions/types.js index 966bf10..921254d 100644 --- a/src/actions/types.js +++ b/src/actions/types.js @@ -11,3 +11,5 @@ export const REGISTER_FAIL = 'REGISTER_FAIL'; export const LOGIN_SUCCESS = 'LOGIN_SUCCESS'; export const LOGIN_FAIL = 'LOGIN_FAIL'; export const TOGGLE_SEARCHBAR = 'TOGGLE_SEARCHBAR'; +export const SEARCH_PRODUCTS = 'SEARCH_PRODUCTS'; +export const IS_SEARCHING = 'IS_SEARCHING'; diff --git a/src/components/App.js b/src/components/App.js index 7c92aba..7ff68e5 100644 --- a/src/components/App.js +++ b/src/components/App.js @@ -62,6 +62,7 @@ class App extends React.Component { render() { // Grab counter from redux state // const counter = useSelector(state => state.isLogged); + const { isSearching, searchResults } = this.props; return ( {/*

{this.counter}

@@ -70,9 +71,15 @@ class App extends React.Component {
- {this.state.data.map((info) => ( - - ))} + {isSearching && searchResults.length === 0 &&

No matches!

} + + {isSearching + ? searchResults.map((info) => ( + + )) + : this.state.data.map((info) => ( + + ))}