From 58a2c20a878d9ed6ecbb37dd743bc6787ff55e7a Mon Sep 17 00:00:00 2001
From: Blaine Price <1wbprice@gmail.com>
Date: Wed, 5 Jul 2017 19:15:31 -0400
Subject: [PATCH 1/5] Create LocationForm component and Redux functions, which
search for a user's location using an address or HTML5 geolocation.
---
api/controllers/GeolocationController.js | 28 +++++
api/controllers/SurveyController.js | 2 +-
api/controllers/index.js | 1 +
config/routes.js | 5 +
frontend/js/components/atoms/Hr.js | 25 ++++
.../js/components/ecosystems/LocationForm.js | 84 +++++++++++++
frontend/js/components/environments/Home.js | 15 ++-
.../components/environments/SurveySelector.js | 35 ++++++
frontend/js/components/organisms/TextField.js | 45 +++++++
.../js/redux/actions/pick-survey-actions.js | 113 +++++++++++++++++-
.../js/redux/reducers/pick-survey-reducer.js | 58 ++++++++-
frontend/js/routes.js | 6 +-
frontend/styles/alert.scss | 1 +
frontend/styles/hr.scss | 24 ++++
frontend/styles/location-form.scss | 13 ++
frontend/styles/style.scss | 5 +-
frontend/styles/text-field.scss | 33 +++++
package.json | 1 +
.../controllers/GeolocationController.test.js | 9 ++
19 files changed, 493 insertions(+), 10 deletions(-)
create mode 100644 api/controllers/GeolocationController.js
create mode 100644 frontend/js/components/atoms/Hr.js
create mode 100644 frontend/js/components/ecosystems/LocationForm.js
create mode 100644 frontend/js/components/environments/SurveySelector.js
create mode 100644 frontend/js/components/organisms/TextField.js
create mode 100644 frontend/styles/hr.scss
create mode 100644 frontend/styles/location-form.scss
create mode 100644 frontend/styles/text-field.scss
create mode 100644 test/integration/controllers/GeolocationController.test.js
diff --git a/api/controllers/GeolocationController.js b/api/controllers/GeolocationController.js
new file mode 100644
index 0000000..13a7074
--- /dev/null
+++ b/api/controllers/GeolocationController.js
@@ -0,0 +1,28 @@
+'use strict';
+
+const Controller = require('trails-controller');
+const fetch = require('isomorphic-fetch');
+const GOOGLE_API_KEY = process.env.GOOGLE_API_KEY;
+const geocodingUrl = 'https://maps.googleapis.com/maps/api/geocode/json';
+
+/**
+ * @module GeolocationController
+ * @description A controller for handling Geolocation requests.
+ */
+module.exports = class GeolocationController extends Controller {
+
+ get(request, reply) {
+ const address = JSON.stringify(request.query.address);
+
+ fetch(`${geocodingUrl}?address=${address}&key=${GOOGLE_API_KEY}`)
+ .then((response) => response.json())
+ .then((response) => {
+ reply(response);
+ })
+ .catch((error) => {
+ reply(error);
+ });
+ }
+
+};
+
diff --git a/api/controllers/SurveyController.js b/api/controllers/SurveyController.js
index 240e6ac..697e192 100644
--- a/api/controllers/SurveyController.js
+++ b/api/controllers/SurveyController.js
@@ -11,7 +11,7 @@ module.exports = class SurveyController extends Controller {
getSurveyByLatLng(request, reply) {
- const coordinates = request.query.coordinates;
+ const coordinates = JSON.parse(request.query.coordinates);
this.app.services.SurveyService.getSurveyByLatLng(coordinates.latitude,
coordinates.longitude)
diff --git a/api/controllers/index.js b/api/controllers/index.js
index 62cdbac..30419e1 100644
--- a/api/controllers/index.js
+++ b/api/controllers/index.js
@@ -8,3 +8,4 @@ exports.CategoryController = require('./CategoryController');
exports.QuestionController = require('./QuestionController');
exports.SurveyResultController = require('./SurveyResultController');
exports.SurveyController = require('./SurveyController');
+exports.GeolocationController = require('./GeolocationController')
diff --git a/config/routes.js b/config/routes.js
index f340622..feacc65 100644
--- a/config/routes.js
+++ b/config/routes.js
@@ -111,5 +111,10 @@ module.exports = [
method: ['GET'],
path: '/api/v1/default/info',
handler: 'DefaultController.info'
+ },
+ {
+ method: ['GET'],
+ path: '/api/v1/geolocation',
+ handler: 'GeolocationController.get'
}
];
diff --git a/frontend/js/components/atoms/Hr.js b/frontend/js/components/atoms/Hr.js
new file mode 100644
index 0000000..ae0af2e
--- /dev/null
+++ b/frontend/js/components/atoms/Hr.js
@@ -0,0 +1,25 @@
+'use strict';
+
+import React, { Component } from 'react';
+import PropTypes from 'prop-types';
+
+class Hr extends Component {
+ render() {
+ return (
+
+
+ {
+ this.props.label &&
+
+ }
+
+ );
+ }
+}
+
+Hr.propTypes = {
+ label: PropTypes.string,
+ color: PropTypes.string
+};
+
+export default Hr;
diff --git a/frontend/js/components/ecosystems/LocationForm.js b/frontend/js/components/ecosystems/LocationForm.js
new file mode 100644
index 0000000..62437c8
--- /dev/null
+++ b/frontend/js/components/ecosystems/LocationForm.js
@@ -0,0 +1,84 @@
+'use strict';
+
+import React, { Component } from 'react';
+import PropTypes from 'prop-types';
+
+import Hr from './../atoms/hr';
+import Alert from './../organisms/Alert';
+import TextField from './../organisms/TextField';
+
+import {
+ getLocationByGPS,
+ getLocationByAddress
+} from './../../redux/actions/pick-survey-actions';
+
+class LocationForm extends Component {
+ constructor(props) {
+ super(props);
+ this.state = {address: ''};
+ }
+
+ updateAddress(event) {
+ const address = event.target.value;
+ this.setState({
+ address: address
+ });
+ }
+
+ search(event) {
+ event && event.preventDefault();
+ this.props.dispatch(getLocationByAddress(this.state.address), () => {
+ this.setState({address: ''});
+ });
+ }
+
+ geolocate() {
+ this.props.dispatch(getLocationByGPS());
+ }
+
+ render() {
+ return (
+
+ );
+ }
+}
+
+LocationForm.propTypes = {
+ dispatch: PropTypes.func,
+ addressError: PropTypes.string,
+ status: PropTypes.object
+};
+
+export default LocationForm;
diff --git a/frontend/js/components/environments/Home.js b/frontend/js/components/environments/Home.js
index b528f9b..053faf0 100644
--- a/frontend/js/components/environments/Home.js
+++ b/frontend/js/components/environments/Home.js
@@ -1,7 +1,10 @@
-import React, { PropTypes, Component } from 'react';
+import React, { Component } from 'react';
+import PropTypes from 'prop-types';
import { connect } from 'react-redux';
+
import Card from './../atoms/Card';
+import LocationForm from './../ecosystems/LocationForm';
class Home extends Component {
@@ -15,6 +18,10 @@ class Home extends Component {
OKCandidate Home Screen
+
);
@@ -24,12 +31,14 @@ class Home extends Component {
}
Home.propTypes = {
- user: PropTypes.object
+ user: PropTypes.object,
+ pickSurvey: PropTypes.object,
+ dispatch: PropTypes.func
};
export default connect(
state => ({
- survey: state.survey,
+ pickSurvey: state.pickSurvey,
ui: state.ui
})
)(Home);
diff --git a/frontend/js/components/environments/SurveySelector.js b/frontend/js/components/environments/SurveySelector.js
new file mode 100644
index 0000000..7731baa
--- /dev/null
+++ b/frontend/js/components/environments/SurveySelector.js
@@ -0,0 +1,35 @@
+'use strict';
+
+import React, { Component } from 'react';
+import PropTypes from 'prop-types';
+
+import { connect } from 'react-redux';
+
+import Card from './../atoms/Card';
+
+class SurveySelector extends Component {
+ constructor(props) {
+ super(props);
+ }
+
+ render() {
+ return (
+
+ );
+ }
+}
+
+SurveySelector.propTypes = {
+ surveys: PropTypes.array
+};
+
+export default connect(
+ state => ({
+ pickSurvey: state.pickSurvey,
+ ui: state.ui
+ })
+)(SurveySelector);
diff --git a/frontend/js/components/organisms/TextField.js b/frontend/js/components/organisms/TextField.js
new file mode 100644
index 0000000..1d327fe
--- /dev/null
+++ b/frontend/js/components/organisms/TextField.js
@@ -0,0 +1,45 @@
+'use strict';
+
+import React, { Component } from 'react';
+import PropTypes from 'prop-types';
+
+class TextField extends Component {
+ render() {
+ return (
+
+ {
+ this.props.label &&
+
+ }
+
+
+ { this.props.button }
+
+ {
+ this.props.error &&
+
+ {this.props.error}
+
+ }
+
+ );
+ }
+}
+
+TextField.propTypes = {
+ name: PropTypes.string.isRequired,
+ value: PropTypes.string,
+ label: PropTypes.string,
+ error: PropTypes.string,
+ onChange: PropTypes.func,
+ type: PropTypes.string,
+ button: PropTypes.element
+};
+
+export default TextField;
diff --git a/frontend/js/redux/actions/pick-survey-actions.js b/frontend/js/redux/actions/pick-survey-actions.js
index 088a47e..4509866 100644
--- a/frontend/js/redux/actions/pick-survey-actions.js
+++ b/frontend/js/redux/actions/pick-survey-actions.js
@@ -28,7 +28,7 @@ export function fetchSurveysByLocationFailure(error) {
export function fetchSurveysByLocation(coordinates) {
return function(dispatch) {
dispatch(fetchSurveysByLocationRequest());
- return fetch('/api/v1/survey/location', {coordinates: coordinates})
+ return fetch(`/api/v1/survey/location?coordinates=${JSON.stringify(coordinates)}`)
.then(checkStatus)
.then(response => response.json())
.then(response => {
@@ -37,3 +37,114 @@ export function fetchSurveysByLocation(coordinates) {
.catch(error => dispatch(fetchSurveysByLocationFailure(error)));
};
}
+
+export const GET_LOCATION_BY_ADDRESS_REQUEST = 'GET_LOCATION_BY_ADDRESS_REQUEST';
+export const GET_LOCATION_BY_ADDRESS_SUCCESS = 'GET_LOCATION_BY_ADDRESS_SUCCESS';
+export const GET_LOCATION_BY_ADDRESS_FAILURE = 'GET_LOCATION_BY_ADDRESS_FAILURE';
+
+export function getLocationByAddress(address) {
+ return function(dispatch) {
+ dispatch(getLocationByAddressRequest());
+ fetch(`/api/v1/geolocation?address=${address}`)
+ .then(checkStatus)
+ .then((response) => response.json())
+ .then((response) => {
+ // If there are no results
+ if (!response.results.length) {
+ return dispatch(getLocationByAddressFailure(
+ new Error('No results found')
+ ));
+ }
+ // If there are multiple results
+ else if (response.results.length > 1) {
+ // TODO
+ // Address disambiguation page
+ }
+ // If there is one result
+ const coords = response.results[0].geometry.location;
+ dispatch(getLocationByAddressSuccess(coords));
+ return dispatch(fetchSurveysByLocation({
+ latitude: coords.lat,
+ longitude: coords.lng
+ }));
+ })
+ .catch((error) => {
+ return fetchSurveysByLocationFailure(error);
+ });
+ };
+}
+
+export function getLocationByAddressRequest() {
+ return {
+ type: GET_LOCATION_BY_ADDRESS_REQUEST
+ };
+}
+
+export function getLocationByAddressSuccess(response) {
+ return {
+ type: GET_LOCATION_BY_ADDRESS_SUCCESS,
+ response
+ };
+}
+
+export function getLocationByAddressFailure(error) {
+ return {
+ type: GET_LOCATION_BY_ADDRESS_FAILURE,
+ error
+ };
+}
+
+export const GET_LOCATION_BY_GPS_REQUEST = 'GET_LOCATION_BY_GPS_REQUEST';
+export const GET_LOCATION_BY_GPS_SUCCESS = 'GET_LOCATION_BY_GPS_SUCCESS';
+export const GET_LOCATION_BY_GPS_FAILURE = 'GET_LOCATION_BY_GPS_FAILURE';
+
+function onGeolocationSuccess(dispatch, timer, position) {
+ clearTimeout(timer);
+ dispatch(getLocationByGPSSuccess(position));
+ dispatch(fetchSurveysByLocation({
+ latitude: position.coords.latitude,
+ longitude: position.coords.longitude
+ }));
+}
+
+function onGeolocationFailure(dispatch, timer, positionError) {
+ clearTimeout(timer);
+ dispatch(getLocationByGPSFailure(positionError));
+}
+
+export function getLocationByGPS() {
+ return function(dispatch) {
+ dispatch(getLocationByGPSRequest());
+ if (!navigator.geolocation) {
+ dispatch(getLocationByGPSFailure(new Error('No support for geolocation')));
+ }
+
+ const timer = setTimeout(() => {
+ dispatch(getLocationByGPSFailure(new Error('Request timed out')));
+ }, 10000);
+ navigator.geolocation.getCurrentPosition(
+ onGeolocationSuccess.bind(this, dispatch, timer),
+ onGeolocationFailure.bind(this, dispatch, timer)
+ );
+ };
+}
+
+export function getLocationByGPSRequest() {
+ return {
+ type: GET_LOCATION_BY_GPS_REQUEST
+ };
+}
+
+export function getLocationByGPSSuccess(response) {
+ return {
+ type: GET_LOCATION_BY_GPS_SUCCESS,
+ response
+ };
+}
+
+export function getLocationByGPSFailure(error) {
+ return {
+ type: GET_LOCATION_BY_GPS_FAILURE,
+ error
+ };
+}
diff --git a/frontend/js/redux/reducers/pick-survey-reducer.js b/frontend/js/redux/reducers/pick-survey-reducer.js
index c76a903..08a390e 100644
--- a/frontend/js/redux/reducers/pick-survey-reducer.js
+++ b/frontend/js/redux/reducers/pick-survey-reducer.js
@@ -1,13 +1,20 @@
import {
FETCH_SURVEYS_BY_LOCATION_REQUEST,
FETCH_SURVEYS_BY_LOCATION_SUCCESS,
- FETCH_SURVEYS_BY_LOCATION_FAILURE
+ FETCH_SURVEYS_BY_LOCATION_FAILURE,
+ GET_LOCATION_BY_ADDRESS_REQUEST,
+ GET_LOCATION_BY_ADDRESS_SUCCESS,
+ GET_LOCATION_BY_ADDRESS_FAILURE,
+ GET_LOCATION_BY_GPS_REQUEST,
+ GET_LOCATION_BY_GPS_SUCCESS,
+ GET_LOCATION_BY_GPS_FAILURE
} from './../actions/pick-survey-actions';
const initialState = {
isFetching: false,
surveys: [],
- error: ''
+ error: '',
+ status: {}
};
export default function surveyReducer(state = initialState, action) {
@@ -29,6 +36,53 @@ export default function surveyReducer(state = initialState, action) {
isFetching: false,
error: action.error
});
+ case GET_LOCATION_BY_ADDRESS_REQUEST:
+ return Object.assign({}, state, {
+ isFetching: true,
+ status: {
+ message: 'Trying to find you using an address',
+ status: 'info'
+ }
+ });
+ case GET_LOCATION_BY_ADDRESS_SUCCESS:
+ return Object.assign({}, state, {
+ isFetching: true,
+ status: {
+ message: 'Looking for surveys for that address',
+ status: 'info'
+ }
+ });
+ case GET_LOCATION_BY_ADDRESS_FAILURE:
+ return Object.assign({}, state, {
+ isFetching: true,
+ status: {
+ message: 'There was an error locating you with that address',
+ status: 'danger'
+ }
+ });
+ case GET_LOCATION_BY_GPS_REQUEST:
+ return Object.assign({}, state, {
+ isFetching: true,
+ status: {
+ message: 'Trying to find you using GPS',
+ status: 'info'
+ }
+ });
+ case GET_LOCATION_BY_GPS_SUCCESS:
+ return Object.assign({}, state, {
+ isFetching: false,
+ status: {
+ message: 'Looking for surveys in your area',
+ level: 'info'
+ }
+ });
+ case GET_LOCATION_BY_GPS_FAILURE:
+ return Object.assign({}, state, {
+ status: {
+ message: 'There was an error finding you with GPS.\nTry searching with an address?',
+ level: 'danger'
+ }
+ });
default:
return state;
}
diff --git a/frontend/js/routes.js b/frontend/js/routes.js
index 23c9f52..1561b13 100644
--- a/frontend/js/routes.js
+++ b/frontend/js/routes.js
@@ -4,6 +4,7 @@ import { Route, IndexRoute } from 'react-router';
import Frame from './components/Frame';
import Home from './components/environments/Home';
import Admin from './components/environments/Admin';
+import SurveySelector from './components/environments/SurveySelector';
import Category from './components/environments/Category';
import Survey from './components/environments/Survey';
import SurveyCreator from './components/environments/SurveyCreator';
@@ -18,8 +19,9 @@ import Results from './components/environments/Results';
module.exports = (
-
-
+
+
+
diff --git a/frontend/styles/alert.scss b/frontend/styles/alert.scss
index 3feef04..0f4f5e7 100644
--- a/frontend/styles/alert.scss
+++ b/frontend/styles/alert.scss
@@ -6,6 +6,7 @@
align-items: center;
padding: .5em 1em;
border-radius: 4px;
+ margin-bottom: 1em;
&.info {
background: $blue;
diff --git a/frontend/styles/hr.scss b/frontend/styles/hr.scss
new file mode 100644
index 0000000..3b1c6ea
--- /dev/null
+++ b/frontend/styles/hr.scss
@@ -0,0 +1,24 @@
+@import 'colors';
+
+.hr {
+ text-align: center;
+ position: relative;
+ z-index: 0;
+
+ .hr-line {
+ width: 100%;
+ height: 1px;
+ position: absolute;
+ top: 50%;
+ background: $black;
+ z-index: -1;
+ }
+
+ .hr-label {
+ text-transform: uppercase;
+ color: $black;
+ display: inline;
+ padding: 0 1em;
+ background: $white;
+ }
+}
\ No newline at end of file
diff --git a/frontend/styles/location-form.scss b/frontend/styles/location-form.scss
new file mode 100644
index 0000000..471f890
--- /dev/null
+++ b/frontend/styles/location-form.scss
@@ -0,0 +1,13 @@
+.location-form {
+ text-align: center;
+
+ .by-address {
+ #address {
+
+ }
+ }
+
+ .by-gps {
+
+ }
+}
\ No newline at end of file
diff --git a/frontend/styles/style.scss b/frontend/styles/style.scss
index 6f431bb..2eff3a1 100644
--- a/frontend/styles/style.scss
+++ b/frontend/styles/style.scss
@@ -18,4 +18,7 @@ This file exists only to import other stylesheets.
@import 'survey-card';
@import 'results';
@import 'agreement-selector';
-@import 'alert';
\ No newline at end of file
+@import 'alert';
+@import 'hr';
+@import 'location-form';
+@import 'text-field';
\ No newline at end of file
diff --git a/frontend/styles/text-field.scss b/frontend/styles/text-field.scss
new file mode 100644
index 0000000..3edad45
--- /dev/null
+++ b/frontend/styles/text-field.scss
@@ -0,0 +1,33 @@
+@import 'colors';
+
+.text-field {
+ text-align: left;
+ input {
+ margin-bottom: 16px;
+ }
+
+ .text-field-input {
+ display: flex;
+
+ input {
+ flex: 1;
+ }
+
+ &.has-button {
+ input {
+ border-top-right-radius: 0;
+ border-bottom-right-radius: 0;
+ }
+ button {
+ border-top-left-radius: 0;
+ border-bottom-left-radius: 0;
+ }
+ }
+ }
+
+ .text-field-error {
+ color: $red;
+ position: relative;
+ bottom: 12px;
+ }
+}
\ No newline at end of file
diff --git a/package.json b/package.json
index 779a2b5..91c05d4 100644
--- a/package.json
+++ b/package.json
@@ -35,6 +35,7 @@
"inert": "^4.2.0",
"isomorphic-fetch": "^2.2.1",
"pg": "^6.1.0",
+ "prop-types": "^15.5.10",
"react": "^15.3.2",
"react-burger-menu": "^1.10.9",
"react-dnd": "^2.4.0",
diff --git a/test/integration/controllers/GeolocationController.test.js b/test/integration/controllers/GeolocationController.test.js
new file mode 100644
index 0000000..75a73fb
--- /dev/null
+++ b/test/integration/controllers/GeolocationController.test.js
@@ -0,0 +1,9 @@
+'use strict'
+
+const assert = require('assert')
+
+describe('GeolocationController', () => {
+ it('should exist', () => {
+ assert(global.app.controllers.GeolocationController)
+ })
+})
From f9e6de18eef4c7d208e61f71af6c2b0d3d7eabf4 Mon Sep 17 00:00:00 2001
From: Blaine Price <1wbprice@gmail.com>
Date: Wed, 5 Jul 2017 19:23:18 -0400
Subject: [PATCH 2/5] Fix style violations and failing geolocation test.
---
api/controllers/index.js | 2 +-
.../controllers/GeolocationController.test.js | 13 +++++++------
2 files changed, 8 insertions(+), 7 deletions(-)
diff --git a/api/controllers/index.js b/api/controllers/index.js
index 30419e1..ab14092 100644
--- a/api/controllers/index.js
+++ b/api/controllers/index.js
@@ -8,4 +8,4 @@ exports.CategoryController = require('./CategoryController');
exports.QuestionController = require('./QuestionController');
exports.SurveyResultController = require('./SurveyResultController');
exports.SurveyController = require('./SurveyController');
-exports.GeolocationController = require('./GeolocationController')
+exports.GeolocationController = require('./GeolocationController');
diff --git a/test/integration/controllers/GeolocationController.test.js b/test/integration/controllers/GeolocationController.test.js
index 75a73fb..0f6b3b8 100644
--- a/test/integration/controllers/GeolocationController.test.js
+++ b/test/integration/controllers/GeolocationController.test.js
@@ -1,9 +1,10 @@
-'use strict'
+'use strict';
-const assert = require('assert')
+const assert = require('assert');
+const app = require('../../../index');
describe('GeolocationController', () => {
- it('should exist', () => {
- assert(global.app.controllers.GeolocationController)
- })
-})
+ it('should exist', () => {
+ assert(app.api.controllers.GeolocationController);
+ });
+});
From f8a167ce5dafb941157062f952b18142153ff84d Mon Sep 17 00:00:00 2001
From: Blaine Price <1wbprice@gmail.com>
Date: Wed, 5 Jul 2017 19:25:33 -0400
Subject: [PATCH 3/5] add example google api key to env example.
---
.env-example | 1 +
1 file changed, 1 insertion(+)
diff --git a/.env-example b/.env-example
index 993be9e..dda4e45 100644
--- a/.env-example
+++ b/.env-example
@@ -10,3 +10,4 @@ OKC_DB_USER=blaine
OKC_DB_PASS=complicatedPassword
OKC_SESSION_SECRET_KEY=someGobbledygookThatIsAtLeast32CharactersLong
+GOOGLE_API_KEY=google_api_key
\ No newline at end of file
From 5c3f5854f8cde573e582f371bf48a497269dfccb Mon Sep 17 00:00:00 2001
From: Blaine Price <1wbprice@gmail.com>
Date: Fri, 7 Jul 2017 10:49:07 -0400
Subject: [PATCH 4/5] Wire up background prop for Hr component.
---
frontend/js/components/atoms/Hr.js | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/frontend/js/components/atoms/Hr.js b/frontend/js/components/atoms/Hr.js
index ae0af2e..a2016dc 100644
--- a/frontend/js/components/atoms/Hr.js
+++ b/frontend/js/components/atoms/Hr.js
@@ -5,9 +5,13 @@ import PropTypes from 'prop-types';
class Hr extends Component {
render() {
+ const hrLineStyle = {
+ background: this.props.background
+ };
+
return (
-
+
{
this.props.label &&
@@ -19,7 +23,7 @@ class Hr extends Component {
Hr.propTypes = {
label: PropTypes.string,
- color: PropTypes.string
+ background: PropTypes.string
};
export default Hr;
From 0b164cb6f7bfae2f4f6132b21d3b038d59693aff Mon Sep 17 00:00:00 2001
From: Blaine Price <1wbprice@gmail.com>
Date: Fri, 7 Jul 2017 11:08:41 -0400
Subject: [PATCH 5/5] Address review comments.
---
frontend/js/components/ecosystems/LocationForm.js | 2 +-
frontend/js/components/environments/Home.js | 1 -
frontend/js/redux/reducers/pick-survey-reducer.js | 1 +
3 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/frontend/js/components/ecosystems/LocationForm.js b/frontend/js/components/ecosystems/LocationForm.js
index 62437c8..38122c6 100644
--- a/frontend/js/components/ecosystems/LocationForm.js
+++ b/frontend/js/components/ecosystems/LocationForm.js
@@ -50,7 +50,7 @@ class LocationForm extends Component {