|
| 1 | +import React, { Component } from 'react'; |
| 2 | +import { connect } from 'react-redux'; |
| 3 | +import PropTypes from 'prop-types'; |
| 4 | +import { Set, List } from 'immutable'; |
| 5 | +import { withRouter } from 'react-router'; |
| 6 | +import classNames from 'classnames'; |
| 7 | +import { withStyles } from '@material-ui/core/styles'; |
| 8 | +import CssBaseline from '@material-ui/core/CssBaseline'; |
| 9 | +import AppBar from '@material-ui/core/AppBar'; |
| 10 | +import Toolbar from '@material-ui/core/Toolbar'; |
| 11 | +import Styles from '../Styles'; |
| 12 | +import SpaceGrid from './space/SpaceGrid'; |
| 13 | +import Loader from './common/Loader'; |
| 14 | +import Main from './common/Main'; |
| 15 | +import { SPACES_NEARBY_MAIN_ID } from '../config/selectors'; |
| 16 | +import { searchSpacesByQuery } from '../utils/search'; |
| 17 | +import { getSpaces } from '../actions'; |
| 18 | + |
| 19 | +class FavoriteSpaces extends Component { |
| 20 | + static propTypes = { |
| 21 | + classes: PropTypes.shape({ |
| 22 | + root: PropTypes.string.isRequired, |
| 23 | + appBarShift: PropTypes.string.isRequired, |
| 24 | + menuButton: PropTypes.string.isRequired, |
| 25 | + hide: PropTypes.string.isRequired, |
| 26 | + drawer: PropTypes.string.isRequired, |
| 27 | + drawerPaper: PropTypes.string.isRequired, |
| 28 | + drawerHeader: PropTypes.string.isRequired, |
| 29 | + content: PropTypes.string.isRequired, |
| 30 | + contentShift: PropTypes.string.isRequired, |
| 31 | + settings: PropTypes.string.isRequired, |
| 32 | + }).isRequired, |
| 33 | + theme: PropTypes.shape({ |
| 34 | + direction: PropTypes.string.isRequired, |
| 35 | + }).isRequired, |
| 36 | + history: PropTypes.shape({ |
| 37 | + replace: PropTypes.func.isRequired, |
| 38 | + }).isRequired, |
| 39 | + spaces: PropTypes.instanceOf(Set).isRequired, |
| 40 | + activity: PropTypes.bool, |
| 41 | + favoriteSpaces: PropTypes.instanceOf(List).isRequired, |
| 42 | + searchQuery: PropTypes.string.isRequired, |
| 43 | + dispatchGetSpaces: PropTypes.func.isRequired, |
| 44 | + }; |
| 45 | + |
| 46 | + static defaultProps = { |
| 47 | + activity: false, |
| 48 | + }; |
| 49 | + |
| 50 | + state = { |
| 51 | + filteredSpaces: Set(), |
| 52 | + }; |
| 53 | + |
| 54 | + async componentDidMount() { |
| 55 | + const { dispatchGetSpaces } = this.props; |
| 56 | + await dispatchGetSpaces(); |
| 57 | + } |
| 58 | + |
| 59 | + componentDidUpdate({ |
| 60 | + spaces: prevSpaces, |
| 61 | + searchQuery: prevSearchQuery, |
| 62 | + favoriteSpaces: prevFavoriteSpaces, |
| 63 | + }) { |
| 64 | + const { spaces, searchQuery, favoriteSpaces } = this.props; |
| 65 | + if ( |
| 66 | + !spaces.equals(prevSpaces) || |
| 67 | + searchQuery !== prevSearchQuery || |
| 68 | + !favoriteSpaces.equals(prevFavoriteSpaces) |
| 69 | + ) { |
| 70 | + this.filterSpaces(); |
| 71 | + } |
| 72 | + } |
| 73 | + |
| 74 | + filterSpaces = () => { |
| 75 | + const { spaces, searchQuery, favoriteSpaces } = this.props; |
| 76 | + let filteredSpaces = searchSpacesByQuery(spaces, searchQuery); |
| 77 | + filteredSpaces = filteredSpaces.filter(({ id }) => |
| 78 | + favoriteSpaces.includes(id) |
| 79 | + ); |
| 80 | + this.setState({ filteredSpaces }); |
| 81 | + }; |
| 82 | + |
| 83 | + render() { |
| 84 | + const { classes, activity } = this.props; |
| 85 | + const { filteredSpaces } = this.state; |
| 86 | + |
| 87 | + if (activity) { |
| 88 | + return ( |
| 89 | + <div className={classNames(classes.root)} style={{ height: '100%' }}> |
| 90 | + <CssBaseline /> |
| 91 | + <AppBar position="fixed"> |
| 92 | + <Toolbar /> |
| 93 | + </AppBar> |
| 94 | + <main className="Main"> |
| 95 | + <Loader /> |
| 96 | + </main> |
| 97 | + </div> |
| 98 | + ); |
| 99 | + } |
| 100 | + |
| 101 | + return ( |
| 102 | + <Main |
| 103 | + showSearch |
| 104 | + handleOnSearch={this.handleOnSearch} |
| 105 | + id={SPACES_NEARBY_MAIN_ID} |
| 106 | + > |
| 107 | + <SpaceGrid spaces={filteredSpaces} showActions saved /> |
| 108 | + </Main> |
| 109 | + ); |
| 110 | + } |
| 111 | +} |
| 112 | + |
| 113 | +const mapStateToProps = ({ authentication, Space }) => ({ |
| 114 | + searchQuery: Space.get('searchQuery'), |
| 115 | + activity: Boolean(Space.getIn(['current', 'activity']).size), |
| 116 | + favoriteSpaces: authentication.getIn(['user', 'favoriteSpaces']), |
| 117 | + spaces: Space.get('saved'), |
| 118 | +}); |
| 119 | + |
| 120 | +const mapDispatchToProps = { |
| 121 | + dispatchGetSpaces: getSpaces, |
| 122 | +}; |
| 123 | + |
| 124 | +const ConnectedComponent = connect( |
| 125 | + mapStateToProps, |
| 126 | + mapDispatchToProps |
| 127 | +)(FavoriteSpaces); |
| 128 | + |
| 129 | +const StyledComponent = withStyles(Styles, { withTheme: true })( |
| 130 | + ConnectedComponent |
| 131 | +); |
| 132 | + |
| 133 | +export default withRouter(StyledComponent); |
0 commit comments