Please check your email inbox and follow the link in the message to verify your email address before finishing your account setup. @@ -62,7 +73,8 @@ const mapStateToProps = () => { } const mapDispatchToProps = { - resendVerificationEmail: userActions.resendVerificationEmail + resendVerificationEmail: userActions.resendVerificationEmail, + routeTo: uiActions.routeTo } -export default connect(mapStateToProps, mapDispatchToProps)(VerifyEmailScreen) +export default connect(mapStateToProps, mapDispatchToProps)(VerifyEmailPane) diff --git a/lib/util/constants.js b/lib/util/constants.js index f1cb7bedc..34e2b6a09 100644 --- a/lib/util/constants.js +++ b/lib/util/constants.js @@ -7,7 +7,11 @@ export const PERSISTENCE_STRATEGY_OTP_MIDDLEWARE = 'otp_middleware' export const ACCOUNT_PATH = '/account' export const ACCOUNT_SETTINGS_PATH = `${ACCOUNT_PATH}/settings` export const TRIPS_PATH = `${ACCOUNT_PATH}/trips` +export const PLACES_PATH = `${ACCOUNT_PATH}/places` export const CREATE_ACCOUNT_PATH = `${ACCOUNT_PATH}/create` +export const CREATE_ACCOUNT_TERMS_PATH = `${CREATE_ACCOUNT_PATH}/terms` +export const CREATE_ACCOUNT_VERIFY_PATH = `${CREATE_ACCOUNT_PATH}/verify` +export const CREATE_ACCOUNT_PLACES_PATH = `${CREATE_ACCOUNT_PATH}/places` export const CREATE_TRIP_PATH = `${TRIPS_PATH}/new` // Gets the root URL, e.g. https://otp-instance.example.com:8080, computed once for all. diff --git a/lib/util/ui.js b/lib/util/ui.js index 58e4e1e1b..f947128f7 100644 --- a/lib/util/ui.js +++ b/lib/util/ui.js @@ -23,3 +23,24 @@ export function getCurrentRoute () { export const RETURN_TO_CURRENT_ROUTE = { returnTo: getCurrentRoute } + +/** + * Computes the Bootstrap error states based on Formik's validation props. + * @param {*} props The Formik props from which to extract the error states. + * @returns An object where each field is set to 'error' if the + * corresponding Formik props denote an error for that field. + */ +export function getErrorStates (props) { + const { errors, touched } = props + const errorStates = {} + Object.keys(errors).forEach(name => { + errorStates[name] = touched[name] && errors[name] && 'error' + }) + + return errorStates +} + +/** + * Browser navigate back. + */ +export const navigateBack = () => window.history.back() diff --git a/lib/util/user.js b/lib/util/user.js index 827896cd2..041a74368 100644 --- a/lib/util/user.js +++ b/lib/util/user.js @@ -1,4 +1,82 @@ - +/** + * Determines whether a loggedInUser is a new user + * that needs to complete the new account wizard. + */ export function isNewUser (loggedInUser) { return !loggedInUser.hasConsentedToTerms } + +// Helper functions to determine if +// a location is home or work. +export const isHome = loc => loc.type === 'home' +export const isWork = loc => loc.type === 'work' +export const isHomeOrWork = loc => isHome(loc) || isWork(loc) + +/** + * An index of common place types (excluding Home and Work), + * each type including a display name and the FontAwesome icon name. + * Add the supported place types below as needed. + */ +export const CUSTOM_PLACE_TYPES = { + custom: { + icon: 'map-marker', + name: 'Custom', + type: 'custom' + }, + dining: { + icon: 'cutlery', + name: 'Dining', + type: 'dining' + } +} + +/** + * The above, with Home and Work locations added. + */ +export const PLACE_TYPES = { + ...CUSTOM_PLACE_TYPES, + home: { + icon: 'home', + name: 'Home', + type: 'home' + }, + work: { + icon: 'briefcase', + name: 'Work', + type: 'work' + } +} + +// Defaults for home and work +const BLANK_HOME = { + ...PLACE_TYPES.home, + address: '' +} +const BLANK_WORK = { + ...PLACE_TYPES.work, + address: '' +} + +/** + * Moves the 'home' and 'work' locations of the provided user to the beginning of + * the savedLocations list, so they are always shown at the top of the FavoritePlacesPane. + * The name field is set to 'Home' and 'Work' regardless of the value that was persisted. + */ +export function positionHomeAndWorkFirst (userData) { + // Note: cloning is not necessary as the data is obtained from fetch. + const { savedLocations = [] } = userData + + const homeLocation = savedLocations.find(isHome) || BLANK_HOME + const workLocation = savedLocations.find(isWork) || BLANK_WORK + + homeLocation.name = BLANK_HOME.name + workLocation.name = BLANK_WORK.name + + const reorderedLocations = [ + homeLocation, + workLocation, + ...savedLocations.filter(loc => loc !== homeLocation && loc !== workLocation) + ] + + userData.savedLocations = reorderedLocations +}