From 785788506028ad759dfdb13976a693124c1388ea Mon Sep 17 00:00:00 2001 From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com> Date: Tue, 15 Sep 2020 13:28:25 -0400 Subject: [PATCH 1/4] fix(SavedTripList): Add trip editing commands to saved trips list. --- lib/actions/user.js | 10 +++-- lib/components/user/saved-trip-editor.js | 41 +++++------------ lib/components/user/saved-trip-list.js | 56 +++++++++++++++++++----- lib/components/user/trip-summary-pane.js | 5 +-- 4 files changed, 64 insertions(+), 48 deletions(-) diff --git a/lib/actions/user.js b/lib/actions/user.js index b5c094073..61c43ffd7 100644 --- a/lib/actions/user.js +++ b/lib/actions/user.js @@ -128,10 +128,10 @@ export function createOrUpdateUser (userData) { /** * Updates a logged-in user's monitored trip, - * then, if that was successful, refreshes the redux monitoredTrips - * with the updated trip. + * then, if that was successful, alerts (optional) + * and refreshes the redux monitoredTrips with the updated trip. */ -export function createOrUpdateUserMonitoredTrip (tripData, isNew) { +export function createOrUpdateUserMonitoredTrip (tripData, isNew, silentOnSuccess) { return async function (dispatch, getState) { const { otp, user } = getState() const { otp_middleware: otpMiddleware = null } = otp.config.persistence @@ -148,7 +148,9 @@ export function createOrUpdateUserMonitoredTrip (tripData, isNew) { // TODO: improve the UI feedback messages for this. if (result.status === 'success' && result.data) { - alert('Your preferences have been saved.') + if (!silentOnSuccess) { + alert('Your preferences have been saved.') + } // Reload user's monitored trips after add/update. await dispatch(fetchUserMonitoredTrips(accessToken)) diff --git a/lib/components/user/saved-trip-editor.js b/lib/components/user/saved-trip-editor.js index d2cc9b21e..eb5124ea6 100644 --- a/lib/components/user/saved-trip-editor.js +++ b/lib/components/user/saved-trip-editor.js @@ -1,5 +1,4 @@ import React from 'react' -import { Button } from 'react-bootstrap' import StackedPaneDisplay from './stacked-pane-display' @@ -11,39 +10,19 @@ const SavedTripEditor = ({ monitoredTrip, onCancel, onComplete, - onDeleteTrip, panes }) => { if (monitoredTrip) { - let paneSequence - if (isCreating) { - paneSequence = [ - { - pane: panes.basics, - title: 'Trip information' - }, - { - pane: panes.notifications, - title: 'Trip notifications' - } - ] - } else { - paneSequence = [ - { - pane: panes.basics, - title: 'Trip overview' - }, - { - pane: panes.notifications, - title: 'Trip notifications' - }, - { - // TODO: Find a better place for this. - pane: () => , - title: 'Danger zone' - } - ] - } + const paneSequence = [ + { + pane: panes.basics, + title: 'Trip information' + }, + { + pane: panes.notifications, + title: 'Trip notifications' + } + ] return ( <> diff --git a/lib/components/user/saved-trip-list.js b/lib/components/user/saved-trip-list.js index 9969a5d3c..9fe3f328e 100644 --- a/lib/components/user/saved-trip-list.js +++ b/lib/components/user/saved-trip-list.js @@ -1,9 +1,11 @@ +import clone from 'clone' import React, { Component } from 'react' -import { Button, ButtonGroup } from 'react-bootstrap' +import { Button, ButtonGroup, Panel } from 'react-bootstrap' import { connect } from 'react-redux' import { withLoginRequired } from 'use-auth0-hooks' import * as uiActions from '../../actions/ui' +import * as userActions from '../../actions/user' import DesktopNav from '../app/desktop-nav' import LinkButton from './link-button' import TripSummaryPane from './trip-summary-pane' @@ -17,11 +19,32 @@ class SavedTripList extends Component { * Navigate to the saved trip's URL #/savedtrips/trip-id-123. * (There shouldn't be a need to encode the ids from Mongo.) */ - _handleTripSelect = trip => () => { + _handleEditTrip = trip => () => { const { id } = trip this.props.routeTo(`/savedtrips/${id}`) } + /** + * Pauses or resumes the specified trip. + */ + _handlePauseOrResumeMonitoring = trip => async () => { + const newTrip = clone(trip) + newTrip.isActive = !newTrip.isActive + + // Silent update of existing trip. + await this.props.createOrUpdateUserMonitoredTrip(newTrip, false, true) + } + + /** + * Deletes a trip from persistence + * and refetches the redux monitoredTrips for the logged-in user. + */ + _handleDeleteTrip = trip => async () => { + if (confirm('Would you like to remove this trip?')) { + await this.props.deleteUserMonitoredTrip(trip.id) + } + } + render () { const { trips } = this.props @@ -44,13 +67,24 @@ class SavedTripList extends Component { {accountLink}

My saved trips

Click on a saved trip below to modify it.

- - {trips.map((trip, index) => ( - - ))} - + + + + + + + + ))} ) } @@ -59,9 +93,9 @@ class SavedTripList extends Component {
{/* TODO: Do mobile view. */} -
+
{content} - +
) } @@ -76,6 +110,8 @@ const mapStateToProps = (state, ownProps) => { } const mapDispatchToProps = { + createOrUpdateUserMonitoredTrip: userActions.createOrUpdateUserMonitoredTrip, + deleteUserMonitoredTrip: userActions.deleteUserMonitoredTrip, routeTo: uiActions.routeTo } diff --git a/lib/components/user/trip-summary-pane.js b/lib/components/user/trip-summary-pane.js index eea9ba233..73041d971 100644 --- a/lib/components/user/trip-summary-pane.js +++ b/lib/components/user/trip-summary-pane.js @@ -19,8 +19,7 @@ class TripSummaryPane extends Component { ) return ( -
-

{monitoredTrip.tripName}

+ <>

@@ -34,7 +33,7 @@ class TripSummaryPane extends Component { : 'Disabled'}

-
+ ) } } From 6d80183239828d45d17d2508e4d584b16a32365f Mon Sep 17 00:00:00 2001 From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com> Date: Tue, 15 Sep 2020 13:44:37 -0400 Subject: [PATCH 2/4] refactor(SavedTripScreen): Remove unused methods. --- lib/components/user/saved-trip-screen.js | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/lib/components/user/saved-trip-screen.js b/lib/components/user/saved-trip-screen.js index 70932da42..9febb617c 100644 --- a/lib/components/user/saved-trip-screen.js +++ b/lib/components/user/saved-trip-screen.js @@ -87,19 +87,6 @@ class SavedTripScreen extends Component { this.props.routeTo('/savedtrips') } - /** - * Deletes a trip from persistence and returns to the saved trips screen. - */ - _handleDeleteTrip = async () => { - if (confirm('Would you like to remove this trip?')) { - const { deleteUserMonitoredTrip } = this.props - const { monitoredTrip } = this.state - await deleteUserMonitoredTrip(monitoredTrip.id) - - this._goToSavedTrips() - } - } - _handleSaveNewTrip = async () => { await this._updateMonitoredTrip() this._goToTripPlanner() @@ -199,7 +186,6 @@ class SavedTripScreen extends Component { monitoredTrip={monitoredTrip} onCancel={isCreating ? this._goToTripPlanner : this._goToSavedTrips} onComplete={isCreating ? this._handleSaveNewTrip : this._handleSaveTripEdits} - onDeleteTrip={this._handleDeleteTrip} panes={this._panes} /> @@ -224,7 +210,6 @@ const mapStateToProps = (state, ownProps) => { const mapDispatchToProps = { createOrUpdateUserMonitoredTrip: userActions.createOrUpdateUserMonitoredTrip, - deleteUserMonitoredTrip: userActions.deleteUserMonitoredTrip, routeTo: uiActions.routeTo } From 19709bed5ca9d77f7915003870a9f4c233ff33ca Mon Sep 17 00:00:00 2001 From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com> Date: Mon, 5 Oct 2020 14:58:53 -0400 Subject: [PATCH 3/4] refactor(SavedTripList): Address PR comments. --- lib/components/user/saved-trip-list.js | 154 ++++++++++++++----------- 1 file changed, 87 insertions(+), 67 deletions(-) diff --git a/lib/components/user/saved-trip-list.js b/lib/components/user/saved-trip-list.js index 9fe3f328e..42ba59247 100644 --- a/lib/components/user/saved-trip-list.js +++ b/lib/components/user/saved-trip-list.js @@ -1,6 +1,6 @@ import clone from 'clone' import React, { Component } from 'react' -import { Button, ButtonGroup, Panel } from 'react-bootstrap' +import { Button, ButtonGroup, Glyphicon, Panel } from 'react-bootstrap' import { connect } from 'react-redux' import { withLoginRequired } from 'use-auth0-hooks' @@ -12,95 +12,119 @@ import TripSummaryPane from './trip-summary-pane' import withLoggedInUserSupport from './with-logged-in-user-support' /** - * This component displays the list of saved trips for the logged-in user. + * This class manages events and rendering for one item in the saved trip list. */ -class SavedTripList extends Component { +class TripListItem extends Component { /** * Navigate to the saved trip's URL #/savedtrips/trip-id-123. * (There shouldn't be a need to encode the ids from Mongo.) */ - _handleEditTrip = trip => () => { - const { id } = trip - this.props.routeTo(`/savedtrips/${id}`) + _handleEditTrip = () => { + const { routeTo, trip } = this.props + routeTo(`/savedtrips/${trip.id}`) } /** * Pauses or resumes the specified trip. */ - _handlePauseOrResumeMonitoring = trip => async () => { + _handlePauseOrResumeMonitoring = () => { + const { createOrUpdateUserMonitoredTrip, trip } = this.props const newTrip = clone(trip) newTrip.isActive = !newTrip.isActive // Silent update of existing trip. - await this.props.createOrUpdateUserMonitoredTrip(newTrip, false, true) + createOrUpdateUserMonitoredTrip(newTrip, false, true) } /** - * Deletes a trip from persistence - * and refetches the redux monitoredTrips for the logged-in user. + * Deletes a trip from persistence. + * (The operation also refetches the redux monitoredTrips for the logged-in user.) */ - _handleDeleteTrip = trip => async () => { + _handleDeleteTrip = async () => { if (confirm('Would you like to remove this trip?')) { - await this.props.deleteUserMonitoredTrip(trip.id) + const { deleteUserMonitoredTrip, trip } = this.props + await deleteUserMonitoredTrip(trip.id) } } render () { - const { trips } = this.props - - // TODO: Improve navigation. - const accountLink =

Back to My Account

- let content - - if (!trips || trips.length === 0) { - content = ( - <> - {accountLink} -

You have no saved trips

-

Perform a trip search from the map first.

- - ) - } else { - // Stack the saved trip summaries. When the user clicks on one, they can edit that trip. - content = ( - <> - {accountLink} -

My saved trips

-

Click on a saved trip below to modify it.

- - {trips.map((trip, index) => ( - - - {trip.tripName} - - - - - - - - - - - ))} - - ) - } - + const { trip } = this.props return ( -
- {/* TODO: Do mobile view. */} - -
- {content} -
-
+ + + {trip.tripName} + + + + + + + + + + ) } } +// connect to the redux store +const itemMapStateToProps = () => {} + +const itemMapDispatchToProps = { + createOrUpdateUserMonitoredTrip: userActions.createOrUpdateUserMonitoredTrip, + deleteUserMonitoredTrip: userActions.deleteUserMonitoredTrip, + routeTo: uiActions.routeTo +} + +const ConnectedTripListItem = connect(itemMapStateToProps, itemMapDispatchToProps)(TripListItem) + +/** + * This component displays the list of saved trips for the logged-in user. + */ +const SavedTripList = ({ trips }) => { + // TODO: Improve navigation. + const accountLink =

Back to My Account

+ let content + + if (!trips || trips.length === 0) { + content = ( + <> + {accountLink} +

You have no saved trips

+

Perform a trip search from the map first.

+ + ) + } else { + // Stack the saved trip summaries. When the user clicks on one, they can edit that trip. + content = ( + <> + {accountLink} +

My saved trips

+ {trips.map((trip, index) => )} + + ) + } + + return ( +
+ {/* TODO: Do mobile view. */} + +
+ {content} +
+
+ ) +} + // connect to the redux store const mapStateToProps = (state, ownProps) => { @@ -109,11 +133,7 @@ const mapStateToProps = (state, ownProps) => { } } -const mapDispatchToProps = { - createOrUpdateUserMonitoredTrip: userActions.createOrUpdateUserMonitoredTrip, - deleteUserMonitoredTrip: userActions.deleteUserMonitoredTrip, - routeTo: uiActions.routeTo -} +const mapDispatchToProps = {} export default withLoggedInUserSupport( withLoginRequired(connect(mapStateToProps, mapDispatchToProps)(SavedTripList)), From 43d545a1dda5f9308667004d7562119533a3229c Mon Sep 17 00:00:00 2001 From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com> Date: Wed, 7 Oct 2020 12:45:10 -0400 Subject: [PATCH 4/4] refactor(SavedTripList): Update button text, move things around per PR comment. --- lib/components/user/saved-trip-list.js | 110 ++++++++++++------------- 1 file changed, 55 insertions(+), 55 deletions(-) diff --git a/lib/components/user/saved-trip-list.js b/lib/components/user/saved-trip-list.js index 42ba59247..a2f6879db 100644 --- a/lib/components/user/saved-trip-list.js +++ b/lib/components/user/saved-trip-list.js @@ -11,6 +11,59 @@ import LinkButton from './link-button' import TripSummaryPane from './trip-summary-pane' import withLoggedInUserSupport from './with-logged-in-user-support' +/** + * This component displays the list of saved trips for the logged-in user. + */ +const SavedTripList = ({ trips }) => { + // TODO: Improve navigation. + const accountLink =

Back to My Account

+ let content + + if (!trips || trips.length === 0) { + content = ( + <> + {accountLink} +

You have no saved trips

+

Perform a trip search from the map first.

+ + ) + } else { + // Stack the saved trip summaries. When the user clicks on one, they can edit that trip. + content = ( + <> + {accountLink} +

My saved trips

+ {trips.map((trip, index) => )} + + ) + } + + return ( +
+ {/* TODO: Do mobile view. */} + +
+ {content} +
+
+ ) +} + +// connect to the redux store + +const mapStateToProps = (state, ownProps) => { + return { + trips: state.user.loggedInUserMonitoredTrips + } +} + +const mapDispatchToProps = {} + +export default withLoggedInUserSupport( + withLoginRequired(connect(mapStateToProps, mapDispatchToProps)(SavedTripList)), + true +) + /** * This class manages events and rendering for one item in the saved trip list. */ @@ -59,8 +112,8 @@ class TripListItem extends Component {