From ad2b0e34adcb622e49ec15fd566db52395b4b75d Mon Sep 17 00:00:00 2001 From: Tom Raithel Date: Tue, 21 Mar 2017 20:57:20 +0100 Subject: [PATCH] Finish search from header --- js/actions.js | 3 +- js/components/App.js | 2 +- js/components/Header.js | 39 ++++++++++++++++- js/components/PageOverview.js | 15 +++++-- js/components/Search.js | 79 ++++++++++++++++++++--------------- js/reducer.js | 2 + js/server.js | 3 +- 7 files changed, 101 insertions(+), 42 deletions(-) diff --git a/js/actions.js b/js/actions.js index 650f22b7..d0a7b00f 100644 --- a/js/actions.js +++ b/js/actions.js @@ -1,10 +1,11 @@ export const NAVIGATE = 'navigate'; const actions = { - navigate: (pageName, pushToHistory = true) => { + navigate: (pageName, pushToHistory = true, pageState = {}) => { return { type: NAVIGATE, pageName, + pageState, pushToHistory, }; }, diff --git a/js/components/App.js b/js/components/App.js index f11ee96f..b35d9556 100644 --- a/js/components/App.js +++ b/js/components/App.js @@ -26,6 +26,6 @@ function App(props) { } export default connect( - ({ items, releases, pageName }) => ({ items, releases, pageName }), + ({ items, releases, pageName, pageState }) => ({ items, releases, pageName, pageState }), actions )(App); diff --git a/js/components/Header.js b/js/components/Header.js index aed61525..c94aa685 100644 --- a/js/components/Header.js +++ b/js/components/Header.js @@ -1,16 +1,20 @@ import React from 'react'; import classNames from 'classnames'; +import { connect } from 'react-redux'; + import Branding from './Branding'; import Link from './Link'; import LogoLink from './LogoLink'; import Search from './Search'; import { getItemPageNames } from '../../common/config'; +import actions from '../actions'; class Header extends React.Component { constructor(...args) { super(...args); this.state = { searchOpen: false, + search: '', }; } @@ -26,9 +30,29 @@ class Header extends React.Component { }); } + handleSearchChange = (search) => { + this.setState({ + search, + }); + } + + handleSearchSubmit = () => { + this.props.navigate('overview', true, { + search: this.state.search, + }); + + this.setState({ + searchOpen: false, + search: '', + }); + } + handleOpenClick = (e) => { e.preventDefault(); this.openSearch(); + setTimeout(() => { + this.search.focus(); + }, 0); } render() { @@ -56,7 +80,14 @@ class Header extends React.Component { Search
- + { this.search = s; }} + />
@@ -65,4 +96,8 @@ class Header extends React.Component { } } -export default Header; + +export default connect( + undefined, + actions +)(Header); diff --git a/js/components/PageOverview.js b/js/components/PageOverview.js index baeb17d2..115b9ac1 100644 --- a/js/components/PageOverview.js +++ b/js/components/PageOverview.js @@ -18,14 +18,23 @@ const containsSearchTerm = (text = '', term = '') => { class PageOverview extends React.Component { - constructor(...args) { - super(...args); + constructor(props, ...args) { + super(props, ...args); this.state = { ring: rings[0], - search: '', + search: props.pageState.search || '', }; } + componentWillReceiveProps(nextProps) { + if (this.search !== nextProps.pageState.search) { + this.setState({ + ring: rings[0], + search: nextProps.pageState.search, + }); + } + } + handleRingClick = (ring) => (e) => { e.preventDefault(); diff --git a/js/components/Search.js b/js/components/Search.js index 9c42eb25..056d240d 100644 --- a/js/components/Search.js +++ b/js/components/Search.js @@ -1,41 +1,52 @@ import React from 'react'; import classNames from 'classnames'; -export default function Search({ value, onChange, onClose, open = false, onSubmit = () => {} }) { - const closable = typeof onClose === 'function'; +class Search extends React.Component { + focus() { + this.input.focus(); + } - const handleSubmit = (e) => { - e.preventDefault(); - onSubmit(); - }; + render() { + const { value, onChange, onClose, open = false, onSubmit = () => {} } = this.props; - const handleClose = (e) => { - e.preventDefault(); - onClose(); - } + const closable = typeof onClose === 'function'; + + const handleSubmit = (e) => { + e.preventDefault(); + onSubmit(); + }; - return ( -
- { onChange(e.target.value); }} - className="search__field" - placeholder="What are you looking for?" - /> - - - - { - closable && ( - - - - ) - } -
- ); + const handleClose = (e) => { + e.preventDefault(); + onClose(); + } + + return ( +
+ { onChange(e.target.value); }} + className="search__field" + placeholder="What are you looking for?" + ref={(input) => { this.input = input; }} + /> + + + + { + closable && ( + + + + ) + } +
+ ); + } } + +export default Search; diff --git a/js/reducer.js b/js/reducer.js index 31b3b7de..69c4aa5c 100644 --- a/js/reducer.js +++ b/js/reducer.js @@ -2,6 +2,7 @@ import { NAVIGATE } from './actions'; const initialState = { pageName: 'index', + pageState: {}, items: [], releases: [], }; @@ -12,6 +13,7 @@ const appReducer = (state = initialState, action = {}) => { return { ...state, pageName: action.pageName, + pageState: action.pageState, } break; default: diff --git a/js/server.js b/js/server.js index 73903a9f..931ac045 100644 --- a/js/server.js +++ b/js/server.js @@ -10,7 +10,8 @@ export const renderPage = (radar, pageName) => { // Create a new Redux store instance const store = createStore(appReducer, { ...radar, - pageName + pageName, + pageState: {}, }); // Render the component to a string