From 24e726dd3ad63be79ff1c3061b305321010f9d97 Mon Sep 17 00:00:00 2001 From: manue1 Date: Mon, 12 Jun 2017 11:21:40 -0500 Subject: [PATCH 1/5] Changes to location dropdown. - Remove commas from location input - Cities mode: hide county --- .../pages/get_started/get_started.component.js | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/shared/components/pages/get_started/get_started.component.js b/shared/components/pages/get_started/get_started.component.js index 3be00962..786abd05 100644 --- a/shared/components/pages/get_started/get_started.component.js +++ b/shared/components/pages/get_started/get_started.component.js @@ -212,7 +212,7 @@ class GetStartedComponent extends Panel { const get_started = this; const new_location = { input_location_mode: get_started.display_location_mode, - input_location: event.target.value, + input_location: get_started.display_location_mode === 1 ? event.target.value : event.target.value.replace(/,/g, ' '), }; get_started.setState({ @@ -227,7 +227,13 @@ class GetStartedComponent extends Panel { // debounce location suggestions by 500ms. get_started.$set_location_suggestions = setTimeout(() => { CalculatorApi.getAutoComplete(new_location) - .then((locations) => { + .then((l) => { + const locations = l; + if (new_location.input_location_mode === 2) { + locations.suggestions.forEach((s, i) => { + locations.suggestions[i] = s.replace(/,.*,/, ','); + }); + } get_started.setState({ locations, show_location_suggestions: true, From 130fc0ca06ded0e29e57501b25df3373bb396e4c Mon Sep 17 00:00:00 2001 From: manue1 Date: Mon, 12 Jun 2017 12:05:52 -0500 Subject: [PATCH 2/5] Make pie chart labels appear clickable. --- shared/components/common/graphs/graphs.scss | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/shared/components/common/graphs/graphs.scss b/shared/components/common/graphs/graphs.scss index 4ac93082..74f339fd 100644 --- a/shared/components/common/graphs/graphs.scss +++ b/shared/components/common/graphs/graphs.scss @@ -138,8 +138,12 @@ .d3-value-arc { text { - fill: black; + fill: #333; cursor:pointer; + &:hover { + fill: #555; + text-decoration: underline; + } } path { stroke: white; From 00ef4136958d2782336fdfa5efe88e472b9fc4d0 Mon Sep 17 00:00:00 2001 From: manue1 Date: Mon, 12 Jun 2017 16:35:51 -0500 Subject: [PATCH 3/5] Update default household size to be 3. - Set 3 as input_size parameter for retrieving defaults. - Remove 2.5 as search option on leaders page. - If user with input_size = 0 logs in, will be updated to 3. - Fix logout issues --- client/api/real/calculator.api.js | 7 +- server/assets/translations/en.json | 2 +- .../common/leaders/leaders.component.js | 2 +- .../get_started/get_started.component.js | 9 ++- .../settings/user/logout/logout.component.js | 7 +- .../user/sign_up/sign_up.component.js | 8 ++- shared/containers/auth.container.js | 1 + shared/lib/state_manager/state_manager.js | 2 +- shared/reducers/auth/auth.reducers.js | 70 +++++++++++-------- .../average_footprint.reducers.js | 2 +- 10 files changed, 65 insertions(+), 45 deletions(-) diff --git a/client/api/real/calculator.api.js b/client/api/real/calculator.api.js index 21706dec..f6fdfc1d 100644 --- a/client/api/real/calculator.api.js +++ b/client/api/real/calculator.api.js @@ -59,7 +59,12 @@ class CalculatorApi { }); } - // eg: location = {input_location: 06704, input_location_mode: 1, input_income: 1, input_size: 0} + /* eg: location = { + input_location: 06704, + input_location_mode: 1, + input_income: 1, + input_size: 3} + */ static getDefaultsAndResults(location) { const params = Object.assign({ op: 'get_defaults_and_results', diff --git a/server/assets/translations/en.json b/server/assets/translations/en.json index bbe72b51..276160f6 100644 --- a/server/assets/translations/en.json +++ b/server/assets/translations/en.json @@ -91,7 +91,7 @@ "label": "How many people live in your household?" }, "United States": "United States", - "average_household_size": "Avg (2.5)", + "average_household_size": "3 (Avg)", "restore_defaults": "Your answers are saved in browser storage.", "restore_defaults_button": "Click here to reset to defaults" }, diff --git a/shared/components/common/leaders/leaders.component.js b/shared/components/common/leaders/leaders.component.js index 26ffc66f..e4f6afc7 100644 --- a/shared/components/common/leaders/leaders.component.js +++ b/shared/components/common/leaders/leaders.component.js @@ -7,7 +7,7 @@ import footprintContainer, { footprintPropTypes } from 'shared/containers/footpr import template from './leaders.rt.html'; import loader from './loader.rt.html'; -const HOUSEHOLD_SIZES = [[1, '1'], [2, '2'], [0, 'Average'], [3, '3'], [4, '4'], [5, '5+']]; +const HOUSEHOLD_SIZES = [[1, '1'], [2, '2'], [3, '3 (Avg)'], [4, '4'], [5, '5+']]; class LeadersComponent extends Panel { diff --git a/shared/components/pages/get_started/get_started.component.js b/shared/components/pages/get_started/get_started.component.js index 786abd05..3f218c2d 100644 --- a/shared/components/pages/get_started/get_started.component.js +++ b/shared/components/pages/get_started/get_started.component.js @@ -8,7 +8,7 @@ import { setLocation } from 'api/user.api'; import footprintContainer, { footprintPropTypes } from 'shared/containers/footprint.container'; import template from './get_started.rt.html'; -const DEFAULT_LOCATION = { input_location_mode: 5, input_income: 1, input_size: 0 }; +const DEFAULT_LOCATION = { input_location_mode: 5, input_income: 1, input_size: 3 }; class GetStartedComponent extends Panel { @@ -186,7 +186,7 @@ class GetStartedComponent extends Panel { input_location_mode = 1; } - get_started.updateDefaults({ input_location: zipcode, input_location_mode }); + get_started.updateDefaults({ input_location: zipcode, input_location_mode, input_size: 3 }); if (get_started.user_authenticated) { @@ -273,10 +273,9 @@ class GetStartedComponent extends Panel { outer_width: get_started.slider_width, handle_r: 14, tick_labels: { - 0: get_started.t('get_started.average_household_size'), 1: '1', 2: '2', - 3: '3', + 3: get_started.t('get_started.average_household_size'), 4: '4', 5: '5+', }, @@ -289,7 +288,7 @@ class GetStartedComponent extends Panel { }); get_started.size_slider.drawData({ - abs_min: 0, + abs_min: 1, abs_max: 5, current_value: get_started.input_size, }); diff --git a/shared/components/pages/settings/user/logout/logout.component.js b/shared/components/pages/settings/user/logout/logout.component.js index 04ee4ee1..bfd34501 100644 --- a/shared/components/pages/settings/user/logout/logout.component.js +++ b/shared/components/pages/settings/user/logout/logout.component.js @@ -21,8 +21,11 @@ class LogoutComponent extends Translatable { submitLogout(event) { event.preventDefault(); this.props.resetAlerts(); - const response = window.FB.getLoginStatus(res => res); - (response && response.status === 'connected') ? window.FB.logout() : this.props.logout(); + if (window.FB) { + const response = window.FB.getLoginStatus(res => res); + if (response && response.status === 'connected') window.FB.logout(); + } + this.props.logout(); } componentDidMount() { diff --git a/shared/components/pages/settings/user/sign_up/sign_up.component.js b/shared/components/pages/settings/user/sign_up/sign_up.component.js index bea6dab0..895a3ce1 100644 --- a/shared/components/pages/settings/user/sign_up/sign_up.component.js +++ b/shared/components/pages/settings/user/sign_up/sign_up.component.js @@ -144,7 +144,7 @@ class SignUpComponent extends Panel { const sign_up = this; const new_location = { input_location_mode: 2, - input_location: event.target.value, + input_location: event.target.value.replace(/,/g, ' '), }; sign_up.setState({ @@ -159,7 +159,11 @@ class SignUpComponent extends Panel { // debounce location suggestions by 500ms. sign_up.$set_location_suggestions = setTimeout(() => { CalculatorApi.getAutoComplete(new_location) - .then((locations) => { + .then((l) => { + const locations = l; + locations.suggestions.forEach((s, i) => { + locations.suggestions[i] = s.replace(/,.*,/, ','); + }); sign_up.setState({ locations, show_location_suggestions: true, diff --git a/shared/containers/auth.container.js b/shared/containers/auth.container.js index c3e3f1c3..761932cb 100644 --- a/shared/containers/auth.container.js +++ b/shared/containers/auth.container.js @@ -8,6 +8,7 @@ const mapStateToProps = state => ({ auth: state.auth, ui: state.ui, location: state.location, + user_footprint: state.user_footprint, }); const mapDispatchToProps = dispatch => ({ diff --git a/shared/lib/state_manager/state_manager.js b/shared/lib/state_manager/state_manager.js index d29b957f..cb5d11a7 100644 --- a/shared/lib/state_manager/state_manager.js +++ b/shared/lib/state_manager/state_manager.js @@ -15,7 +15,7 @@ import uiReducers from 'shared/reducers/ui/ui.reducers'; import profileReducers from 'shared/reducers/profile/profile.reducers'; import { getLocalStorageItem } from '../utils/utils'; -const DEFAULT_LOCATION = { input_location_mode: 5, input_income: 1, input_size: 0 }; +const DEFAULT_LOCATION = { input_location_mode: 5, input_income: 1, input_size: 3 }; const CATEGORY_COLORS = { result_transport_total: '#0D7A3E', result_housing_total: '#45813C', diff --git a/shared/reducers/auth/auth.reducers.js b/shared/reducers/auth/auth.reducers.js index 3d704ab6..6281f9a2 100644 --- a/shared/reducers/auth/auth.reducers.js +++ b/shared/reducers/auth/auth.reducers.js @@ -9,7 +9,7 @@ import { setLocalStorageItem, getLocalStorageItem, tokenIsValid } from 'shared/l import { signup, login, loginFacebook, loggedIn, signedUp, logout, loggedOut, requestNewPassword, newPasswordRequested, authError, processActivation, verifyActivation, activationError, sendEmailConfirmation, resetPassword, resetPasswordSuccess, resetPasswordError } from './auth.actions'; -import { updatedFootprintComputed } from '../user_footprint/user_footprint.actions'; +import { updatedFootprintComputed, updateRemoteUserAnswers } from '../user_footprint/user_footprint.actions'; import { averageFootprintResetRequested } from '../average_footprint/average_footprint.actions'; import { pushAlert } from '../ui/ui.actions'; @@ -78,6 +78,9 @@ const ACTIONS = { }], }; + // existing users with household size == 0 -> update to 3 + if (parseInt(remote_answers.input_size, 10) === 0) remote_answers.input_size = 3; + if (Object.keys(remote_answers).length !== 0) { return loop( fromJS(updated), @@ -119,9 +122,6 @@ const ACTIONS = { }, [signedUp]: (state, api_response) => { - let updated; - let alert; - if (api_response.success) { const auth = { token: api_response.data.token, @@ -131,14 +131,14 @@ const ACTIONS = { setLocalStorageItem('auth', auth); - updated = state.setIn(['data', 'token'], auth.token) + const updated = state.setIn(['data', 'token'], auth.token) .setIn(['data', 'name'], auth.name) .setIn(['data', 'user_id'], auth.user_id) .set('loading', false) .set('received', true) .set('success', true); - alert = { + const alert = { id: 'shared', data: [{ needs_i18n: true, @@ -146,36 +146,44 @@ const ACTIONS = { message: 'success.sign_up', }], }; - } else { - let err; - alert = { - id: 'sign_up', - data: [], - }; - try { - err = JSON.parse(api_response.error); - alert.data.push({ - needs_i18n: true, - type: 'danger', - message: `errors.${Object.keys(err)[0]}.${Object.values(err)[0]}`, - }); - } catch (error) { - alert.data.push({ - needs_i18n: true, - type: 'danger', - message: 'errors.email.non-unique', - }); - } + return loop( + fromJS(updated), + Effects.batch([ + Effects.constant(pushAlert(alert)), + Effects.constant(updateRemoteUserAnswers()), + ]), + ); + } - updated = state.set('loading', false) - .set('received', true) - .set('success', false); + let err; + const alert = { + id: 'sign_up', + data: [], + }; + + try { + err = JSON.parse(api_response.error); + alert.data.push({ + needs_i18n: true, + type: 'danger', + message: `errors.${Object.keys(err)[0]}.${Object.values(err)[0]}`, + }); + } catch (error) { + alert.data.push({ + needs_i18n: true, + type: 'danger', + message: 'errors.email.non-unique', + }); } + const updated = state.set('loading', false) + .set('received', true) + .set('success', false); + return loop( - fromJS(updated), - Effects.constant(pushAlert(alert)), + fromJS(updated), + Effects.constant(pushAlert(alert)), ); }, diff --git a/shared/reducers/average_footprint/average_footprint.reducers.js b/shared/reducers/average_footprint/average_footprint.reducers.js index 5869a7d2..73605417 100644 --- a/shared/reducers/average_footprint/average_footprint.reducers.js +++ b/shared/reducers/average_footprint/average_footprint.reducers.js @@ -35,7 +35,7 @@ const ACTIONS = { if (!api_data.failed) { const updated = state.set('data', state.get('data').merge(api_data)) - .set('reset', false); + .set('reset', false); return loop( updated, From 05ecfba979f238e903237fc6aed8901a94e7a9e9 Mon Sep 17 00:00:00 2001 From: Danyel Cabello Date: Tue, 13 Jun 2017 01:37:58 -0500 Subject: [PATCH 4/5] Show county and state in sign up screen, get county and state from db and show in get started page --- server/assets/translations/en.json | 3 + .../get_started/get_started.component.js | 68 +++++++++++++++---- .../pages/get_started/get_started.scss | 2 +- .../user/sign_up/sign_up.component.js | 7 +- .../settings/user/sign_up/sign_up.rt.html | 18 +++++ .../pages/settings/user/sign_up/sign_up.scss | 5 +- shared/containers/footprint.container.js | 6 +- .../average_footprint.reducers.js | 4 +- shared/reducers/profile/profile.actions.js | 4 +- shared/reducers/profile/profile.reducers.js | 29 +++++--- 10 files changed, 113 insertions(+), 33 deletions(-) diff --git a/server/assets/translations/en.json b/server/assets/translations/en.json index 276160f6..169228b0 100644 --- a/server/assets/translations/en.json +++ b/server/assets/translations/en.json @@ -7,6 +7,9 @@ "email": "Email", "password": "Password", "city": "City", + "state":"State", + "country":"Country", + "county":"County", "input_location": "City", "public": "Yes, make my profile page public.", "enter_location": "Enter your location", diff --git a/shared/components/pages/get_started/get_started.component.js b/shared/components/pages/get_started/get_started.component.js index 3f218c2d..43075d7f 100644 --- a/shared/components/pages/get_started/get_started.component.js +++ b/shared/components/pages/get_started/get_started.component.js @@ -18,9 +18,11 @@ class GetStartedComponent extends Panel { get_started.initResizeListener(); get_started.state = { locations: {}, - input_location: get_started.userApiValue('input_location'), + input_location_zipcode: get_started.userApiValue('input_location'), + input_location:'', input_location_mode: parseInt(get_started.input_location_mode, 10), input_location_changed: false, + input_location_edited: false, input_location_mode_changed: get_started.props.ui.get('location_mode_changed'), show_location_suggestions: false, }; @@ -30,6 +32,9 @@ class GetStartedComponent extends Panel { const get_started = this; get_started.initializeSizeSlider(); get_started.initializeIncomeSlider(); + + const token = this.props.auth.getIn(['data', 'token']); + this.props.retrieveProfile({ user_id: this.user_id, token }); } componentDidUpdate() { @@ -59,16 +64,30 @@ class GetStartedComponent extends Panel { return this.state.input_location_mode_changed ? this.input_location_mode === 5 : false; } + get user_id() { + return this.props.auth.getIn(['data', 'user_id']); + } + get input_location_display() { const get_started = this; const display_location = get_started.props.ui.get('display_location'); if (get_started.country_mode) { return get_started.t('get_started.United States'); - } else if (display_location) { - return display_location; - } - return get_started.state.input_location; + } else if(get_started.state.input_location || get_started.state.input_location_edited){ + return get_started.state.input_location ; + } + switch(get_started.state.input_location_mode){ + case 1: + return get_started.state.input_location_zipcode; + case 2: + return get_started.props.profile.getIn(["data","city"]) + case 3: + return get_started.props.profile.getIn(["data","county"]) + case 4: + return get_started.props.profile.getIn(["data","state"]) + } + return ""; } get default_location() { @@ -164,10 +183,28 @@ class GetStartedComponent extends Panel { const get_started = this; const zipcode = event.target.dataset.zipcode; const suggestion = event.target.dataset.suggestion; - + + const index = get_started.state.locations.data.findIndex(l => l === zipcode); + const location_data = get_started.state.locations.selected_location[index]; + let input_location=""; + switch(get_started.state.input_location_mode){ + case 1: + input_location = zipcode; + break; + case 2: + input_location = location_data.city; + break; + case 3: + input_location = location_data.county; + break; + case 4: + input_location = location_data.state; + break; + } get_started.setState({ display_location: suggestion, - input_location: suggestion, + input_location_zipcode: zipcode, + input_location, show_location_suggestions: false, input_location_changed: true, }); @@ -186,13 +223,14 @@ class GetStartedComponent extends Panel { input_location_mode = 1; } - get_started.updateDefaults({ input_location: zipcode, input_location_mode, input_size: 3 }); - + get_started.updateDefaults({ + input_location:zipcode, + input_location_mode, + input_size: 3 + }); if (get_started.user_authenticated) { - const index = get_started.state.locations.data.findIndex(l => l === zipcode); - const location_data = get_started.state.locations.selected_location[index]; - + get_started.setUserLocation(location_data); } } @@ -203,7 +241,10 @@ class GetStartedComponent extends Panel { const user_location = location; user_location.country = 'us'; - return setLocation(user_location, token); + get_started.props.setLocation({userLocation:user_location, token, user_id:this.user_id} ); + get_started.setState({ + input_location_edited:false + }); } // called when input_location input changed. @@ -218,6 +259,7 @@ class GetStartedComponent extends Panel { get_started.setState({ input_location: event.target.value, show_location_suggestions: true, + input_location_edited:true }); if (get_started.$set_location_suggestions) { diff --git a/shared/components/pages/get_started/get_started.scss b/shared/components/pages/get_started/get_started.scss index ca82b52c..78a66174 100644 --- a/shared/components/pages/get_started/get_started.scss +++ b/shared/components/pages/get_started/get_started.scss @@ -1,4 +1,4 @@ -#location_suggestions_container { +#get_started #location_suggestions_container { position:relative; max-width: 404px; margin: 0 auto; diff --git a/shared/components/pages/settings/user/sign_up/sign_up.component.js b/shared/components/pages/settings/user/sign_up/sign_up.component.js index 895a3ce1..72015c3b 100644 --- a/shared/components/pages/settings/user/sign_up/sign_up.component.js +++ b/shared/components/pages/settings/user/sign_up/sign_up.component.js @@ -29,7 +29,10 @@ class SignUpComponent extends Panel { password: '', answers: '', city: '', - location: {}, + location: { + state:'', + country:'' + }, public: true, }; } @@ -47,7 +50,7 @@ class SignUpComponent extends Panel { } get input_location_display() { - return this.state.input_location; + return this.state.location.city; } paramValid(param) { diff --git a/shared/components/pages/settings/user/sign_up/sign_up.rt.html b/shared/components/pages/settings/user/sign_up/sign_up.rt.html index 104d1ac8..e3db5bc5 100644 --- a/shared/components/pages/settings/user/sign_up/sign_up.rt.html +++ b/shared/components/pages/settings/user/sign_up/sign_up.rt.html @@ -71,6 +71,24 @@ className="location-suggestion" onClick="{this.setLocation.bind(this)}">{suggestion} + +
+ + +
+
+ +