From 9e9b7cef76438b4fe760191e76870bc1b27c9f5b Mon Sep 17 00:00:00 2001 From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com> Date: Tue, 2 Jun 2020 19:36:53 -0400 Subject: [PATCH] feat(saved trip): Add route and basic structure for saving trips. --- lib/components/app/responsive-webapp.js | 8 + lib/components/user/new-account-wizard.js | 1 + lib/components/user/save-trip-screen.js | 156 ++++++++++++++++++ lib/components/user/saved-trip-editor.js | 29 ++++ lib/components/user/saved-trip-wizard.js | 37 +++++ .../user/sequential-pane-display.js | 3 +- lib/components/user/trip-basics-pane.js | 5 + .../user/trip-notifications-pane.js | 5 + lib/components/user/trip-summary-pane.js | 5 + 9 files changed, 248 insertions(+), 1 deletion(-) create mode 100644 lib/components/user/save-trip-screen.js create mode 100644 lib/components/user/saved-trip-editor.js create mode 100644 lib/components/user/saved-trip-wizard.js create mode 100644 lib/components/user/trip-basics-pane.js create mode 100644 lib/components/user/trip-notifications-pane.js create mode 100644 lib/components/user/trip-summary-pane.js diff --git a/lib/components/app/responsive-webapp.js b/lib/components/app/responsive-webapp.js index d66d20621..b4f973f35 100644 --- a/lib/components/app/responsive-webapp.js +++ b/lib/components/app/responsive-webapp.js @@ -9,6 +9,7 @@ import { Route, Switch, withRouter } from 'react-router' import PrintLayout from './print-layout' import AfterSignInScreen from '../user/after-signin-screen' +import SaveTripScreen from '../user/save-trip-screen' import UserAccountScreen from '../user/user-account-screen' import withLoggedInUser from '../user/with-logged-in-user' import { setMapCenter, setMapZoom } from '../../actions/config' @@ -220,6 +221,13 @@ class RouterWrapper extends Component { return withLoggedInUser() }} /> + { + const props = this._combineProps(routerProps) + return withLoggedInUser() + }} + /> { return ( diff --git a/lib/components/user/save-trip-screen.js b/lib/components/user/save-trip-screen.js new file mode 100644 index 000000000..cf942f4dd --- /dev/null +++ b/lib/components/user/save-trip-screen.js @@ -0,0 +1,156 @@ +import PropTypes from 'prop-types' +import React, { Component } from 'react' +import { connect } from 'react-redux' +import { withLoginRequired } from 'use-auth0-hooks' + +import { addTrip, updateTrip } from '../../util/middleware' +import { routeTo } from '../../actions/ui' +import AppNav from '../app/app-nav' + +import SavedTripEditor from './saved-trip-editor' +import SavedTripWizard from './saved-trip-wizard' +import TripBasicsPane from './trip-basics-pane' +import TripNotificationsPane from './trip-notifications-pane' +import TripSummaryPane from './trip-summary-pane' + +/** + * This screen handles saving a trip from an OTP query for the logged-in user. + */ +class SaveTripScreen extends Component { + static propTypes = { + originalUrl: PropTypes.string + } + + static defaultProps = { + originalUrl: '/' + } + + constructor (props) { + super(props) + + this.state = { + // New trip: deep clone active trip to make edits. + monitoredTrip: {} + } + } + + _updateMonitoredTripState = newMonitoredTrip => { + const { monitoredTrip } = this.state + this.setState({ + monitoredTrip: { + ...monitoredTrip, + ...newMonitoredTrip + } + }) + } + + _updateMonitoredTrip = async () => { + const { auth, loggedInUser, persistence, wizard } = this.props + + if (persistence && persistence.otp_middleware) { + const { accessToken } = auth + const { id } = loggedInUser + const { monitoredTrip } = this.state + + // TODO: Change state of Save button. + + let result + if (wizard) { + result = await addTrip(persistence.otp_middleware, accessToken, monitoredTrip) + } else { + result = await updateTrip(persistence.otp_middleware, accessToken, monitoredTrip) + } + + // TODO: improve this. + if (result.status === 'success') { + alert('Your preferences have been saved.') + } else { + alert(`An error was encountered:\n${JSON.stringify(result)}`) + } + } + } + + _handleExit = () => { + const { originalUrl } = this.props + this.props.routeTo(originalUrl) + } + + _handleExitAndSave = async () => { + await this._updateMonitoredTrip() + this._handleExit() + } + + /** + * Hook monitoredTrip, onMonitoredTripChange on some panes upon rendering. + * This returns a new render function for the passed component + * that allows passing other props to it later if needed. + */ + _hookMonitoredTrip = Pane => props => { + const { monitoredTrip } = this.state + return ( + + ) + } + + // Make an index of pane components, so we don't render all panes at once on every render. + // Hook some panes to the monitoredTrip and onMonitoredTripChange props. + _panes = { + basics: this._hookMonitoredTrip(TripBasicsPane), + notifications: this._hookMonitoredTrip(TripNotificationsPane), + summary: this._hookMonitoredTrip(TripSummaryPane) + } + + // TODO: Update title bar during componentDidMount. + + render () { + const { monitoredTrip, wizard } = this.props + + let content + if (wizard) { + content = ( + + ) + } else { + content = ( + + ) + } + + return ( +
+ {/* TODO: Do mobile view. */} + +
+ {content} +
+
+ ) + } +} + +// connect to the redux store + +const mapStateToProps = (state, ownProps) => { + return { + loggedInUser: state.otp.user.loggedInUser, + persistence: state.otp.config.persistence + } +} + +const mapDispatchToProps = { + routeTo +} + +export default withLoginRequired(connect(mapStateToProps, mapDispatchToProps)(SaveTripScreen)) diff --git a/lib/components/user/saved-trip-editor.js b/lib/components/user/saved-trip-editor.js new file mode 100644 index 000000000..c97609aa6 --- /dev/null +++ b/lib/components/user/saved-trip-editor.js @@ -0,0 +1,29 @@ +import React from 'react' + +import StackedPaneDisplay from './stacked-pane-display' + +/** + * This component handles the existing account display. + */ +const SavedTripEditor = ({ onCancel, onComplete, panes }) => { + const paneSequence = [ + { + pane: panes.basics, + title: 'Trip information' + }, + { + pane: panes.notifications, + title: 'Trip notifications' + } + ] + + return ( + + ) +} + +export default SavedTripEditor diff --git a/lib/components/user/saved-trip-wizard.js b/lib/components/user/saved-trip-wizard.js new file mode 100644 index 000000000..a5ad2c5d4 --- /dev/null +++ b/lib/components/user/saved-trip-wizard.js @@ -0,0 +1,37 @@ +import React from 'react' + +import SequentialPaneDisplay from './sequential-pane-display' + +/** + * This component is the new account wizard. + */ +const SavedTripWizard = ({ onComplete, panes }) => { + const paneSequence = { + basics: { + nextId: 'notifications', + pane: panes.basics, + title: 'Trip information' + }, + notifications: { + nextId: 'summary', + pane: panes.notifications, + prevId: 'basics', + title: 'Trip notification preferences' + }, + summary: { + pane: panes.summary, + prevId: 'notifications', + title: 'Trip summary' + } + } + + return ( + + ) +} + +export default SavedTripWizard diff --git a/lib/components/user/sequential-pane-display.js b/lib/components/user/sequential-pane-display.js index 1de6b4d47..0caab78d5 100644 --- a/lib/components/user/sequential-pane-display.js +++ b/lib/components/user/sequential-pane-display.js @@ -15,6 +15,7 @@ const PaneContainer = styled.div` */ class SequentialPaneDisplay extends Component { static propTypes = { + initialPaneId: PropTypes.string.isRequired, onComplete: PropTypes.func.isRequired, paneSequence: PropTypes.object.isRequired } @@ -23,7 +24,7 @@ class SequentialPaneDisplay extends Component { super(props) this.state = { - activePaneId: 'terms' + activePaneId: props.initialPaneId } } diff --git a/lib/components/user/trip-basics-pane.js b/lib/components/user/trip-basics-pane.js new file mode 100644 index 000000000..056642320 --- /dev/null +++ b/lib/components/user/trip-basics-pane.js @@ -0,0 +1,5 @@ +import React from 'react' + +const TripBasicsPane = () =>
Trip basics!
+ +export default TripBasicsPane diff --git a/lib/components/user/trip-notifications-pane.js b/lib/components/user/trip-notifications-pane.js new file mode 100644 index 000000000..2e5183f71 --- /dev/null +++ b/lib/components/user/trip-notifications-pane.js @@ -0,0 +1,5 @@ +import React from 'react' + +const TripNotificationsPane = () =>
Trip notifications!
+ +export default TripNotificationsPane diff --git a/lib/components/user/trip-summary-pane.js b/lib/components/user/trip-summary-pane.js new file mode 100644 index 000000000..d99db4b31 --- /dev/null +++ b/lib/components/user/trip-summary-pane.js @@ -0,0 +1,5 @@ +import React from 'react' + +const TripSummaryPane = () =>
Trip summary!
+ +export default TripSummaryPane