aboutsummaryrefslogtreecommitdiff
path: root/src/client/react/components
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/react/components')
-rw-r--r--src/client/react/components/container/Search.js21
-rw-r--r--src/client/react/components/container/View.js70
-rw-r--r--src/client/react/components/page/User.js2
3 files changed, 90 insertions, 3 deletions
diff --git a/src/client/react/components/container/Search.js b/src/client/react/components/container/Search.js
index 27b0563..9a99833 100644
--- a/src/client/react/components/container/Search.js
+++ b/src/client/react/components/container/Search.js
@@ -29,6 +29,12 @@ class Search extends React.Component {
this.props.dispatch(setUser(this.props.urlUser));
}
+ componentWillReceiveProps(nextProps) {
+ if (nextProps.urlUser !== this.props.urlUser) {
+ this.props.dispatch(setUser(nextProps.urlUser));
+ }
+ }
+
onFocus() {
this.setState({
hasFocus: true,
@@ -51,10 +57,18 @@ class Search extends React.Component {
case 'ArrowDown':
this.props.dispatch(changeSelectedResult(+1));
break;
- case 'Enter':
- if (this.props.selectedResult) {
- this.props.history.push(`/${this.props.selectedResult}`);
+ case 'Enter': {
+ const result = this.props.selectedResult || this.props.results[0];
+
+ if (result === this.props.urlUser) {
+ // 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(this.props.urlUser));
+ } else if (result) {
+ this.props.history.push(`/${result}`);
}
+ }
break;
default:
throw new Error('This should never happen... pls?');
@@ -100,6 +114,7 @@ class Search extends React.Component {
}
Search.propTypes = {
+ results: PropTypes.arrayOf(PropTypes.string).isRequired,
selectedResult: PropTypes.string,
urlUser: PropTypes.string,
isExactMatch: PropTypes.bool.isRequired,
diff --git a/src/client/react/components/container/View.js b/src/client/react/components/container/View.js
new file mode 100644
index 0000000..9bac66f
--- /dev/null
+++ b/src/client/react/components/container/View.js
@@ -0,0 +1,70 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import createDOMPurify from 'dompurify';
+import { connect } from 'react-redux';
+import { withRouter } from 'react-router-dom';
+
+import { fetchSchedule } from '../../actions/view';
+
+function cleanMeetingpointHTML(htmlStr) {
+ const DOMPurify = createDOMPurify(window);
+
+ return DOMPurify.sanitize(htmlStr, {
+ ADD_ATTR: ['rules'],
+ });
+}
+
+class View extends React.Component {
+ componentDidMount() {
+ if (!this.loadingFinished(this.props.user)) {
+ this.props.dispatch(fetchSchedule(this.props.user));
+ }
+ }
+
+ componentWillReceiveProps(nextProps) {
+ if (nextProps.user !== this.props.user && !this.loadingFinished(nextProps.user)) {
+ this.props.dispatch(fetchSchedule(nextProps.user));
+ }
+ }
+
+ loadingFinished(user) {
+ return this.props.schedules.hasOwnProperty(user) &&
+ this.props.schedules[user].state === 'finished';
+ }
+
+ render() {
+ if (!this.loadingFinished(this.props.user)) {
+ return (
+ <div>
+ Loading...
+ </div>
+ );
+ }
+
+ const cleanHTML = cleanMeetingpointHTML(this.props.schedules[this.props.user].htmlStr);
+
+ return (
+ // eslint-disable-next-line react/no-danger
+ <div dangerouslySetInnerHTML={{ __html: cleanHTML }} />
+ );
+ }
+}
+
+View.propTypes = {
+ user: PropTypes.string,
+ dispatch: PropTypes.func.isRequired,
+ schedules: PropTypes.objectOf(PropTypes.shape({
+ state: PropTypes.string.isRequired,
+ htmlStr: PropTypes.string,
+ })).isRequired,
+};
+
+View.defaultProps = {
+ user: null,
+};
+
+const mapStateToProps = state => ({
+ schedules: state.view.schedules,
+});
+
+export default withRouter(connect(mapStateToProps)(View));
diff --git a/src/client/react/components/page/User.js b/src/client/react/components/page/User.js
index 2ad65a6..ea8cd10 100644
--- a/src/client/react/components/page/User.js
+++ b/src/client/react/components/page/User.js
@@ -2,6 +2,7 @@ import React from 'react';
import PropTypes from 'prop-types';
import { Redirect } from 'react-router-dom';
import Search from '../container/Search';
+import View from '../container/View';
import users from '../../users';
const App = ({ match }) => {
@@ -15,6 +16,7 @@ const App = ({ match }) => {
return (
<div>
<Search urlUser={user} />
+ <View user={user} />
</div>
);
};