diff options
Diffstat (limited to 'src/client/react')
-rw-r--r-- | src/client/react/components/container/RoomFinder.js | 9 | ||||
-rw-r--r-- | src/client/react/components/container/Search.js | 9 | ||||
-rw-r--r-- | src/client/react/components/container/View.js | 39 | ||||
-rw-r--r-- | src/client/react/components/container/WeekSelector.js | 6 | ||||
-rw-r--r-- | src/client/react/components/page/User.js | 6 | ||||
-rw-r--r-- | src/client/react/lib/url.js | 83 | ||||
-rw-r--r-- | src/client/react/store/selectors.js | 4 |
7 files changed, 35 insertions, 121 deletions
diff --git a/src/client/react/components/container/RoomFinder.js b/src/client/react/components/container/RoomFinder.js index b4af8cb..e502250 100644 --- a/src/client/react/components/container/RoomFinder.js +++ b/src/client/react/components/container/RoomFinder.js @@ -19,14 +19,13 @@ */ import { connect } from 'react-redux'; -import { withRouter } from 'react-router-dom'; import { shiftRoom } from '../../store/actions'; -import { userFromMatch } from '../../lib/url'; +import { selectUser } from '../../store/selectors'; import RoomFinder from '../presentational/RoomFinder'; -const mapStateToProps = (state, { match }) => { - const user = userFromMatch(match); +const mapStateToProps = (state) => { + const user = selectUser(state); return { key: user, @@ -40,4 +39,4 @@ const mapDispatchToProps = dispatch => ({ onHide: () => dispatch({ type: 'ROOM_FINDER/HIDE' }), }); -export default withRouter(connect(mapStateToProps, mapDispatchToProps)(RoomFinder)); +export default connect(mapStateToProps, mapDispatchToProps)(RoomFinder); diff --git a/src/client/react/components/container/Search.js b/src/client/react/components/container/Search.js index 73919d3..ca2e372 100644 --- a/src/client/react/components/container/Search.js +++ b/src/client/react/components/container/Search.js @@ -20,14 +20,13 @@ import { connect } from 'react-redux'; -import { withRouter } from 'react-router-dom'; import Search from '../presentational/Search'; import { setUser as setUserAction } from '../../store/actions'; -import { userFromLocation } from '../../lib/url'; import users from '../../users'; +import { selectUser } from '../../store/selectors'; -const mapStateToProps = (state, { location }) => { - const currentUser = userFromLocation(location); +const mapStateToProps = (state) => { + const currentUser = selectUser(state); const selectedUser = state.search && state.search.selected; let searchText; let isExactMatch; @@ -63,4 +62,4 @@ const mapDispatchToProps = dispatch => ({ }), }); -export default withRouter(connect(mapStateToProps, mapDispatchToProps)(Search)); +export default connect(mapStateToProps, mapDispatchToProps)(Search); diff --git a/src/client/react/components/container/View.js b/src/client/react/components/container/View.js index 407a7de..2ec2dbd 100644 --- a/src/client/react/components/container/View.js +++ b/src/client/react/components/container/View.js @@ -21,9 +21,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import { connect } from 'react-redux'; -import { withRouter } from 'react-router-dom'; - -import { userFromMatch, weekFromLocation } from '../../lib/url'; +import { selectUser, selectWeek } from '../../store/selectors'; import extractSchedule from '../../lib/extractSchedule'; import Schedule from '../presentational/Schedule'; @@ -37,8 +35,8 @@ class View extends React.Component { })).isRequired, // react-router - match: PropTypes.object.isRequired, - location: PropTypes.object.isRequired, + user: PropTypes.string.isRequired, + week: PropTypes.number.isRequired, // redux dispatch: PropTypes.func.isRequired, @@ -48,20 +46,14 @@ class View extends React.Component { this.fetchScheduleIfNeeded(); } - componentDidUpdate() { - this.fetchScheduleIfNeeded(); - } - fetchScheduleIfNeeded() { const { + user, + week, schedules, - match, - location, dispatch, } = this.props; - const user = userFromMatch(match); - const week = weekFromLocation(location); const schedule = extractSchedule(schedules, user, week); if (schedule.state === 'NOT_REQUESTED') { @@ -90,13 +82,11 @@ class View extends React.Component { render() { const { + user, + week, schedules, - match, - location, } = this.props; - const user = userFromMatch(match); - const week = weekFromLocation(location); const schedule = extractSchedule(schedules, user, week); switch (schedule.state) { @@ -111,8 +101,15 @@ class View extends React.Component { } } -const mapStateToProps = state => ({ - schedules: state.schedules, -}); +const mapStateToProps = (state) => { + const user = selectUser(state); + const week = selectWeek(state); + return { + key: `${user}:${week}`, + user, + week, + schedules: state.schedules, + }; +}; -export default withRouter(connect(mapStateToProps)(View)); +export default connect(mapStateToProps)(View); diff --git a/src/client/react/components/container/WeekSelector.js b/src/client/react/components/container/WeekSelector.js index c3f03f1..eeba0e7 100644 --- a/src/client/react/components/container/WeekSelector.js +++ b/src/client/react/components/container/WeekSelector.js @@ -21,12 +21,12 @@ import { connect } from 'react-redux'; import { withRouter } from 'react-router-dom'; import { shiftWeek } from '../../store/actions'; -import { weekFromLocation } from '../../lib/url'; +import { selectWeek } from '../../store/selectors'; import WeekSelector from '../presentational/WeekSelector'; -const mapStateToProps = (state, { location }) => ({ - week: weekFromLocation(location), +const mapStateToProps = state => ({ + week: selectWeek(state), }); const mapDispatchToProps = dispatch => ({ diff --git a/src/client/react/components/page/User.js b/src/client/react/components/page/User.js index af14188..1ad6149 100644 --- a/src/client/react/components/page/User.js +++ b/src/client/react/components/page/User.js @@ -25,9 +25,9 @@ import { Redirect } from 'react-router-dom'; import { Elevation } from 'rmwc/Elevation'; import Search from '../container/Search'; import View from '../container/View'; -import { userFromMatch } from '../../lib/url'; import WeekSelector from '../container/WeekSelector'; import RoomFinder from '../container/RoomFinder'; +import { selectUser } from '../../store/selectors'; import './User.scss'; @@ -70,8 +70,8 @@ class UserPage extends React.Component { } } -const mapStateToProps = (state, { match }) => ({ - user: userFromMatch(match), +const mapStateToProps = state => ({ + user: selectUser(state), }); export default connect(mapStateToProps)(UserPage); diff --git a/src/client/react/lib/url.js b/src/client/react/lib/url.js deleted file mode 100644 index bb5b483..0000000 --- a/src/client/react/lib/url.js +++ /dev/null @@ -1,83 +0,0 @@ -/** - * Copyright (C) 2018 Noah Loomans - * - * This file is part of rooster.hetmml.nl. - * - * rooster.hetmml.nl is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * rooster.hetmml.nl is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with rooster.hetmml.nl. If not, see <http://www.gnu.org/licenses/>. - * - */ - -import moment from 'moment'; -import queryString from 'query-string'; -import users from '../users'; -import purifyWeek from './purifyWeek'; - -export function userFromMatch(match) { - const user = `${match.params.type}/${match.params.value}`; - - if (!users.allIds.includes(user)) { - return null; - } - - return user; -} - -export function userFromLocation(location) { - const match = location.pathname.match(/^\/([stcr])\/([-0-9a-zA-Z]+)/); - if (!match) return null; - - const user = `${match[1]}/${match[2]}`; - if (!users.allIds.includes(user)) return null; - - return user; -} - -export function weekFromLocation(location) { - const weekStr = queryString.parse(location.search).week; - - if (!weekStr) { - return moment().week(); - } - - return purifyWeek(parseInt(weekStr, 10)); -} - -export function makeSetUser(history) { - return (userId) => { - const query = history.location.search; - history.push(`/${userId}${query}`); - }; -} - -export function makeSetWeek(history) { - return (week) => { - const query = queryString.stringify({ - ...queryString.parse(history.location.search), - week, - }); - - history.push(`${history.location.pathname}?${query}`); - }; -} - -export function makeUpdateQuery(history) { - return function updateQuery(newQuery) { - const query = queryString.stringify({ - ...queryString.parse(history.location.search), - ...newQuery, - }); - - history.push(`${history.location.pathname}?${query}`); - }; -} diff --git a/src/client/react/store/selectors.js b/src/client/react/store/selectors.js index 8264cdb..2567107 100644 --- a/src/client/react/store/selectors.js +++ b/src/client/react/store/selectors.js @@ -1,5 +1,6 @@ import moment from 'moment'; import queryString from 'query-string'; +import isNaN from 'lodash/isNaN'; import purifyWeek from '../lib/purifyWeek'; import users from '../users'; @@ -21,8 +22,9 @@ export function selectCurrentWeek(store) { export function selectWeek(store) { const { location } = store.router; const weekStr = queryString.parse(location.search).week; + const week = parseInt(weekStr, 10); - if (!weekStr) { + if (isNaN(week)) { return selectCurrentWeek(store); } |