Handle POST/GET building

This commit is contained in:
Tom Russell 2018-09-11 23:30:17 +01:00
parent 0ec0b52f90
commit a2e995839e
6 changed files with 119 additions and 44 deletions

View File

@ -38,4 +38,54 @@ function queryBuildingAtPoint(lng, lat) {
});
}
export { queryBuildingAtPoint };
function getBuildingById(id) {
return query(
`SELECT
building_id as id,
geometry_id,
building_doc as doc
FROM
buildings
WHERE
building_id = $1
`,
[ id ]
).then(function(data){
const rows = data.rows
if (rows.length){
const id = rows[0].id
const doc = rows[0].doc
const geometry_id = rows[0].geometry_id
doc.id = id
doc.geometry_id = geometry_id
return doc
}
return null;
}).catch(function(error){
console.error(error);
return null;
});
}
function saveBuilding(id, building_doc) {
// don't save id or geometry_id into doc
delete building_doc.id;
delete building_doc.geometry_id;
return query(
`UPDATE
buildings
SET
building_doc = $2::jsonb
WHERE
building_id = $1
`,
[ id, building_doc ]
).catch(function(error){
console.error(error);
return null;
});
}
export { queryBuildingAtPoint, getBuildingById, saveBuilding };

View File

@ -38,7 +38,6 @@ class App extends React.Component {
}
selectBuilding(building) {
console.log(building)
this.setState({building: building})
}
@ -57,15 +56,22 @@ class App extends React.Component {
</Route>
<Route exact path="/map/:map.html" component={Legend} />
<Route exact path="/building/:building.html">
<BuildingView {...this.state.building} />
<BuildingView {...this.state.building}
user={this.state.user}
selectBuilding={this.selectBuilding}
/>
</Route>
<Route exact path="/building/:building/edit.html">
<BuildingEdit {...this.state.building} />
<BuildingEdit {...this.state.building}
user={this.state.user}
selectBuilding={this.selectBuilding}
/>
</Route>
</Switch>
<ColouringMap {...props}
building={this.state.building}
selectBuilding={this.selectBuilding} />
selectBuilding={this.selectBuilding}
/>
</Fragment>
) } />
<Route exact path="/about.html" component={AboutPage} />

View File

@ -5,6 +5,7 @@ import Sidebar from './sidebar';
class BuildingEdit extends Component {
constructor(props) {
super(props);
const user = props.user || {};
this.state = {
location_name: props.location_name,
location_number: props.location_number,
@ -20,7 +21,7 @@ class BuildingEdit extends Component {
size_core: props.size_core,
size_basement: props.size_basement,
likes: props.likes || [],
liked: this.user_likes(props.user_id, props.likes)
liked: this.user_likes(user.id, props.likes)
};
this.handleChange = this.handleChange.bind(this);
@ -47,12 +48,12 @@ class BuildingEdit extends Component {
const likes = this.state.likes || [];
if (liked) {
this.setState({
likes: likes.concat([this.props.user_id]),
likes: likes.concat([this.props.user.id]),
liked: true
});
} else {
this.setState({
likes: likes.filter(id => id !== this.props.user_id),
likes: likes.filter(id => id !== this.props.user.id),
liked: false
});
}
@ -60,7 +61,7 @@ class BuildingEdit extends Component {
handleSubmit(event) {
event.preventDefault();
fetch(`/building/${this.props.id}`, {
fetch(`/building/${this.props.id}.json`, {
method: 'POST',
body: JSON.stringify(this.state),
headers:{
@ -72,7 +73,7 @@ class BuildingEdit extends Component {
if (res.error) {
console.error(res.error); // tell user
} else {
console.log(res); // redirect back
this.props.selectBuilding(this.state);
}
}).catch(
err => console.error(err)
@ -81,7 +82,7 @@ class BuildingEdit extends Component {
render() {
return (
<Sidebar title="Edit building data">
<Sidebar title={`Building ${this.props.id}`}>
<form action="building-view.html" method="GET" onSubmit={this.handleSubmit}>
<fieldset className="data-section">
<legend className="h3 bullet-prefix location toggled-on">Location</legend>

View File

@ -5,7 +5,7 @@ import Sidebar from './sidebar';
import Tooltip from './tooltip';
const BuildingView = (props) => (
<Sidebar title="Building data">
<Sidebar title={`Building ${props.id}`}>
<section className="data-section">
<h3 className="h3 bullet-prefix location">Location</h3>
<p className="data-intro">

View File

@ -33,7 +33,7 @@ class ColouringMap extends Component {
this.props.history.push(`/building/${data.id}.html`);
this.props.selectBuilding(data);
} else {
// this.props.selectBuilding(undefined);
// this.props.selectBuilding(undefined); // TODO follow through back to maps
}
}.bind(this)).catch(
(err) => console.error(err)
@ -41,19 +41,10 @@ class ColouringMap extends Component {
}
render() {
var map_type = undefined;
if (this.props.match && this.props.match.params && this.props.match.params[0]) {
map_type = this.props.match.params[0].replace("/", "");
} else {
map_type = 'maps';
}
var data_layer = undefined;
if (this.props.match && this.props.match.params && this.props.match.params[1]) {
data_layer = this.props.match.params[1].replace("/", "");
} else {
data_layer = 'date_year';
}
const data_layer = (
this.props.match && this.props.match.params && this.props.match.params[1]
)? this.props.match.params[1].replace("/", "")
: 'date_year';
const position = [this.state.lat, this.state.lng];
const key = OS_API_KEY

View File

@ -12,7 +12,7 @@ const pgSession = require('connect-pg-simple')(session);
import App from './frontend/app';
import { pool } from './db';
import { authUser, createUser, getUserById } from './user';
import { queryBuildingAtPoint } from './building';
import { queryBuildingAtPoint, getBuildingById, saveBuilding } from './building';
import tileserver from './tileserver';
// create server
@ -56,26 +56,28 @@ server.get('/', frontendRoute);
function frontendRoute(req, res) {
const data = {};
var re = pathToRegexp('/buildings/:building.html')
var matches = re.exec(req.url)
var building_id = undefined;
if (matches && matches.length === 2) {
building_id = matches[1]
}
console.log(`Building: ${building_id}`)
const building_id = parseBuildingURL(req.url);
if (req.session.user_id) {
getUserById(req.session.user_id).then(function(user){
Promise.all([
req.session.user_id? getUserById(req.session.user_id) : undefined,
building_id? getBuildingById(building_id) : undefined
]).then(function(values){
const user = values[0];
const building = values[1];
data.user = user;
data.building = building;
renderHTML(data, req, res)
}).catch(function(){
renderHTML(data, req, res);
});
} else {
// getBuildingById() TODO load data server-side
renderHTML(data, req, res);
})
}
function parseBuildingURL(url){
const re = pathToRegexp('/building/:building.html')
const matches = re.exec(url)
if (matches && matches.length === 2) {
return matches[1]
}
return undefined;
}
function renderHTML(data, req, res){
@ -146,6 +148,31 @@ server.get('/buildings.json', function(req, res){
})
})
// Building routes
server.route('/building/:building_id.json')
.get(function (req, res) {
const { building_id } = req.params;
getBuildingById(building_id).then(function(result){
if (result) {
res.send(result)
} else {
res.status(404).send({error:'Not Found'})
}
}).catch(function(error){
res.send({error:'Database error'})
})
})
.post(function (req, res) {
const { building_id } = req.params;
const building = req.body;
saveBuilding(building_id, building).then(
() => res.send({success: true})
).catch(
() => res.send({error:'Database error'})
)
})
// POST new user
server.post('/users', function(req, res){
const user = req.body;