Skip to content
This repository has been archived by the owner on Jul 11, 2023. It is now read-only.

Get location #148

Merged
merged 6 commits into from
Jul 16, 2017
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .env-example
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ OKC_DB_USER=blaine
OKC_DB_PASS=complicatedPassword

OKC_SESSION_SECRET_KEY=someGobbledygookThatIsAtLeast32CharactersLong
GOOGLE_API_KEY=google_api_key
28 changes: 28 additions & 0 deletions api/controllers/GeolocationController.js
Original file line number Diff line number Diff line change
@@ -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())
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

parens superfluous on single param arrow functions

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The style guide doesn't have an opinion on this.

.then((response) => {
reply(response);
})
.catch((error) => {
reply(error);
});
}

};

2 changes: 1 addition & 1 deletion api/controllers/SurveyController.js
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
1 change: 1 addition & 0 deletions api/controllers/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ exports.CategoryController = require('./CategoryController');
exports.QuestionController = require('./QuestionController');
exports.SurveyResultController = require('./SurveyResultController');
exports.SurveyController = require('./SurveyController');
exports.GeolocationController = require('./GeolocationController');
5 changes: 5 additions & 0 deletions config/routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -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'
}
];
25 changes: 25 additions & 0 deletions frontend/js/components/atoms/Hr.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
'use strict';

import React, { Component } from 'react';
import PropTypes from 'prop-types';

class Hr extends Component {
render() {
return (
<div className="hr">
<div className="hr-line"></div>
{
this.props.label &&
<label className="hr-label">{this.props.label}</label>
}
</div>
);
}
}

Hr.propTypes = {
label: PropTypes.string,
color: PropTypes.string
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

color is not used at all in this component

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The goal was that the developer could change the color of the HR where needed. I'll update the PR.

};

export default Hr;
84 changes: 84 additions & 0 deletions frontend/js/components/ecosystems/LocationForm.js
Original file line number Diff line number Diff line change
@@ -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 (
<form className="location-form" onSubmit={this.search.bind(this)}>
<section>
{this.props.status.message &&
<Alert
level={this.props.status.level}
message={this.props.status.message} />
}
</section>
<section className="by-address">
<TextField
label="Locate Using Address"
name="address"
value={this.state.value}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this implicitly the state or are we setting an object 'value'

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This works (because JavaScript), but it we should be setting this.state.address instead.

onChange={this.updateAddress.bind(this)}
button={
<button
type="button"
onClick={this.search.bind(this)}>
Search
</button>
}/>
</section>
<Hr label="or" />
<section className="by-gps">
<label htmlFor="gps">Or use GPS</label>
<button
type="button"
id="gps"
onClick={this.geolocate.bind(this)}>
Use GPS
</button>
</section>
</form>
);
}
}

LocationForm.propTypes = {
dispatch: PropTypes.func,
addressError: PropTypes.string,
status: PropTypes.object
};

export default LocationForm;
15 changes: 12 additions & 3 deletions frontend/js/components/environments/Home.js
Original file line number Diff line number Diff line change
@@ -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 {

Expand All @@ -15,6 +18,10 @@ class Home extends Component {
<div className="twelve columns">
<Card>
<pre>OKCandidate Home Screen</pre>
<LocationForm
addressError={this.props.pickSurvey.addressError}
status={this.props.pickSurvey.status}
dispatch={this.props.dispatch} />
</Card>
</div>
);
Expand All @@ -24,12 +31,14 @@ class Home extends Component {
}

Home.propTypes = {
user: PropTypes.object
user: PropTypes.object,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how is user passed into this component? unclear after looking at top level routes.

https://github.com/wbprice/okcandidate-platform/blob/f8a167ce5dafb941157062f952b18142153ff84d/frontend/js/routes.js

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be coming from the global store through connect at the bottom of Home.js (or any other environment). What user is doing isn't well defined yet, so I'll remove it for now.

pickSurvey: PropTypes.object,
dispatch: PropTypes.func
};

export default connect(
state => ({
survey: state.survey,
pickSurvey: state.pickSurvey,
ui: state.ui
})
)(Home);
35 changes: 35 additions & 0 deletions frontend/js/components/environments/SurveySelector.js
Original file line number Diff line number Diff line change
@@ -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 (
<section>
<Card>
<pre>Survey Selector</pre>
</Card>
</section>
);
}
}

SurveySelector.propTypes = {
surveys: PropTypes.array
};

export default connect(
state => ({
pickSurvey: state.pickSurvey,
ui: state.ui
})
)(SurveySelector);
45 changes: 45 additions & 0 deletions frontend/js/components/organisms/TextField.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
'use strict';

import React, { Component } from 'react';
import PropTypes from 'prop-types';

class TextField extends Component {
render() {
return (
<div className="text-field">
{
this.props.label &&
<label htmlFor={this.props.name}>
{this.props.label}
</label>
}
<div className={`text-field-input ${this.props.button && 'has-button'}`}>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we've declared this.props.button as an element type but using it in this context as a string, what happens? would be serializing the elm?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is checking to see if this.props.button is truthy, and if so it returns the string has-button.

<input
id={this.props.name}
type={this.props.type || 'text'}
value={this.props.value}
onChange={this.props.onChange} />
{ this.props.button }
</div>
{
this.props.error &&
<div className="text-field-error">
<span>{this.props.error}</span>
</div>
}
</div>
);
}
}

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;
Loading