diff options
author | Noah Loomans <noahloomans@gmail.com> | 2018-02-09 17:04:12 +0100 |
---|---|---|
committer | Noah Loomans <noahloomans@gmail.com> | 2018-02-09 17:04:12 +0100 |
commit | 6926de1108b1a084e133d5f8363f080d7c20a99f (patch) | |
tree | ce27ac5a024e6a0e342037d3ea03ddf7ca6c3c82 /src/client/react/components/container | |
parent | 8d5bccc8984618c9282e9592882835819306fa07 (diff) |
Use classes instead of stateless functions for Components
Diffstat (limited to 'src/client/react/components/container')
-rw-r--r-- | src/client/react/components/container/HelpBox.js | 33 | ||||
-rw-r--r-- | src/client/react/components/container/Results.js | 103 | ||||
-rw-r--r-- | src/client/react/components/container/Search.js | 34 | ||||
-rw-r--r-- | src/client/react/components/container/View.js | 29 | ||||
-rw-r--r-- | src/client/react/components/container/WeekSelector.js | 66 |
5 files changed, 137 insertions, 128 deletions
diff --git a/src/client/react/components/container/HelpBox.js b/src/client/react/components/container/HelpBox.js index a74b43c..effe4f5 100644 --- a/src/client/react/components/container/HelpBox.js +++ b/src/client/react/components/container/HelpBox.js @@ -2,26 +2,37 @@ import React from 'react'; import PropTypes from 'prop-types'; import { connect } from 'react-redux'; -const HelpBox = ({ results, searchText }) => { - if (results.length > 0 || searchText !== '') { - return <div />; +class HelpBox extends React.Component { + static propTypes = { + // redux + results: PropTypes.arrayOf(PropTypes.string).isRequired, + searchText: PropTypes.string.isRequired, } - return ( - <div className="help-box"> - <div className="arrow" /> - <div className="bubble"> - Voer hier een docentafkorting, klas, leerlingnummer of lokaalnummer in. + render() { + if (this.props.results.length > 0 || this.props.searchText !== '') { + return <div />; + } + + return ( + <div className="help-box"> + <div className="arrow" /> + <div className="bubble"> + Voer hier een docentafkorting, klas, leerlingnummer of lokaalnummer in. + </div> </div> - </div> - ); -}; + ); + } +} HelpBox.propTypes = { + // redux results: PropTypes.arrayOf(PropTypes.string).isRequired, searchText: PropTypes.string.isRequired, }; +HelpBox.propTypes + const mapStateToProps = state => ({ results: state.search.results, searchText: state.search.searchText, diff --git a/src/client/react/components/container/Results.js b/src/client/react/components/container/Results.js index f65c0c8..41030e7 100644 --- a/src/client/react/components/container/Results.js +++ b/src/client/react/components/container/Results.js @@ -9,66 +9,61 @@ import { setUser } from '../../actions/search'; import { userFromMatch } from '../../lib/url'; import Result from '../presentational/Result'; -const Results = ({ - results, - searchText, - selectedResult, - match, - history, - dispatch, -}) => { - const user = userFromMatch(match); +class Results extends React.Component { + static propTypes = { + results: PropTypes.arrayOf(PropTypes.string).isRequired, + searchText: PropTypes.string.isRequired, + selectedResult: PropTypes.string, - const isExactMatch = - user != null && - searchText === users.byId[user].value; + // react-router + match: PropTypes.object.isRequired, + history: PropTypes.object.isRequired, - return ( - <div - className={classnames('search__results', { - 'search__results--has-results': !isExactMatch && results.length > 0, - })} - style={{ - minHeight: isExactMatch ? 0 : results.length * 54, - }} - > - {!isExactMatch && results.map(userId => ( - <Result - key={userId} - userId={userId} - isSelected={userId === selectedResult} - onClick={() => { - if (userId === user) { - // EDGE CASE: The user is set if the user changes, but it doesn't - // change if the result is already the one we are viewing. - // Therefor, we need to dispatch the SET_USER command manually. - dispatch(setUser(user)); - } else { - history.push(`/${userId}`); - } - }} - /> - ))} - </div> - ); -}; + // redux + dispatch: PropTypes.func.isRequired, + }; -Results.propTypes = { - results: PropTypes.arrayOf(PropTypes.string).isRequired, - searchText: PropTypes.string.isRequired, - selectedResult: PropTypes.string, + static defaultProps = { + selectedResult: null, + }; - // react-router - match: PropTypes.object.isRequired, - history: PropTypes.object.isRequired, + render() { + const user = userFromMatch(this.props.match); - // redux - dispatch: PropTypes.func.isRequired, -}; + const isExactMatch = + user != null && + this.props.searchText === users.byId[user].value; -Results.defaultProps = { - selectedResult: null, -}; + return ( + <div + className={classnames('search__results', { + 'search__results--has-results': !isExactMatch && this.props.results.length > 0, + })} + style={{ + minHeight: isExactMatch ? 0 : this.props.results.length * 54, + }} + > + {!isExactMatch && this.props.results.map(userId => ( + <Result + key={userId} + userId={userId} + isSelected={userId === this.props.selectedResult} + onClick={() => { + if (userId === user) { + // EDGE CASE: The user is set if the user changes, but it doesn't + // change if the result is already the one we are viewing. + // Therefor, we need to dispatch the SET_USER command manually. + this.props.dispatch(setUser(user)); + } else { + this.props.history.push(`/${userId}`); + } + }} + /> + ))} + </div> + ); + } +} const mapStateToProps = state => ({ results: state.search.results, diff --git a/src/client/react/components/container/Search.js b/src/client/react/components/container/Search.js index 8ca386c..44f2ba1 100644 --- a/src/client/react/components/container/Search.js +++ b/src/client/react/components/container/Search.js @@ -14,6 +14,23 @@ import Results from './Results'; import IconFromUserType from '../presentational/IconFromUserType'; class Search extends React.Component { + static propTypes = { + results: PropTypes.arrayOf(PropTypes.string).isRequired, + selectedResult: PropTypes.string, + searchText: PropTypes.string.isRequired, + + // react-router + match: PropTypes.object.isRequired, + history: PropTypes.object.isRequired, + + // redux + dispatch: PropTypes.func.isRequired, + }; + + static defaultProps = { + selectedResult: null, + }; + constructor(props) { super(props); @@ -132,23 +149,6 @@ class Search extends React.Component { } } -Search.propTypes = { - results: PropTypes.arrayOf(PropTypes.string).isRequired, - selectedResult: PropTypes.string, - searchText: PropTypes.string.isRequired, - - // react-router - match: PropTypes.object.isRequired, - history: PropTypes.object.isRequired, - - // redux - dispatch: PropTypes.func.isRequired, -}; - -Search.defaultProps = { - selectedResult: null, -}; - const mapStateToProps = state => ({ results: state.search.results, searchText: state.search.searchText, diff --git a/src/client/react/components/container/View.js b/src/client/react/components/container/View.js index f919dbc..96611d5 100644 --- a/src/client/react/components/container/View.js +++ b/src/client/react/components/container/View.js @@ -11,6 +11,20 @@ import Schedule from '../presentational/Schedule'; import Loading from '../presentational/Loading'; class View extends React.Component { + static propTypes = { + schedules: PropTypes.objectOf(PropTypes.objectOf(PropTypes.shape({ + state: PropTypes.string.isRequired, + htmlStr: PropTypes.string, + }))).isRequired, + + // react-router + match: PropTypes.object.isRequired, + location: PropTypes.object.isRequired, + + // redux + dispatch: PropTypes.func.isRequired, + }; + componentDidMount() { this.fetchScheduleIfNeeded(); } @@ -49,7 +63,6 @@ class View extends React.Component { switch (schedule.state) { case 'NOT_REQUESTED': - return <Loading />; case 'FETCHING': return <Loading />; case 'FINISHED': @@ -60,20 +73,6 @@ class View extends React.Component { } } -View.propTypes = { - schedules: PropTypes.objectOf(PropTypes.objectOf(PropTypes.shape({ - state: PropTypes.string.isRequired, - htmlStr: PropTypes.string, - }))).isRequired, - - // react-router - match: PropTypes.object.isRequired, - location: PropTypes.object.isRequired, - - // redux - dispatch: PropTypes.func.isRequired, -}; - const mapStateToProps = state => ({ schedules: state.view.schedules, }); diff --git a/src/client/react/components/container/WeekSelector.js b/src/client/react/components/container/WeekSelector.js index b8b5c2b..002128b 100644 --- a/src/client/react/components/container/WeekSelector.js +++ b/src/client/react/components/container/WeekSelector.js @@ -10,46 +10,50 @@ import ArrowForwardIcon from 'react-icons/lib/md/arrow-forward'; import purifyWeek from '../../lib/purifyWeek'; import { weekFromLocation } from '../../lib/url'; -function weekName(week) { - const currentWeek = moment().week(); - - if (currentWeek === week) { - return `Huidige week • ${week}`; - } else if (currentWeek + 1 === week) { - return `Volgende week • ${week}`; - } else if (currentWeek - 1 === week) { - return `Vorige week • ${week}`; - } +class WeekSelector extends React.Component { + static propTypes = { + // react-router + location: PropTypes.object.isRequired, + history: PropTypes.object.isRequired, + }; - return `Week ${week}`; -} + getWeekText() { + const week = weekFromLocation(this.props.location); -const WeekSelector = ({ location, history }) => { - const week = weekFromLocation(location); + const currentWeek = moment().week(); + + if (currentWeek === week) { + return `Huidige week • ${week}`; + } else if (currentWeek + 1 === week) { + return `Volgende week • ${week}`; + } else if (currentWeek - 1 === week) { + return `Vorige week • ${week}`; + } + + return `Week ${week}`; + } + + updateWeek(change) { + const week = weekFromLocation(this.props.location); - const updateWeek = (change) => { const newWeek = purifyWeek(week + change); const isCurrentWeek = moment().week() === newWeek; const query = queryString.stringify({ week: isCurrentWeek ? undefined : newWeek, }); - history.push(`${location.pathname}?${query}`); - }; + this.props.history.push(`${this.props.location.pathname}?${query}`); + } - return ( - <div className="week-selector"> - <button onClick={() => updateWeek(-1)}><ArrowBackIcon /></button> - <div className="text">{weekName(week)}</div> - <button onClick={() => updateWeek(+1)}><ArrowForwardIcon /></button> - </div> - ); -}; - -WeekSelector.propTypes = { - // react-router - location: PropTypes.object.isRequired, - history: PropTypes.object.isRequired, -}; + render() { + return ( + <div className="week-selector"> + <button onClick={() => this.updateWeek(-1)}><ArrowBackIcon /></button> + <div className="text">{this.getWeekText()}</div> + <button onClick={() => this.updateWeek(+1)}><ArrowForwardIcon /></button> + </div> + ); + } +} export default withRouter(WeekSelector); |