parent
4b16b69e8e
commit
6cc6630196
@ -166,7 +166,7 @@ function likeBuilding(building_id, user_id) {
|
||||
`INSERT INTO logs (
|
||||
forward_patch, building_id, user_id
|
||||
) VALUES (
|
||||
$1:jsonb, $2, $3
|
||||
$1:json, $2, $3
|
||||
) RETURNING log_id
|
||||
`,
|
||||
[{likes_total: building.likes}, building_id, user_id]
|
||||
|
@ -74,10 +74,28 @@ class EditForm extends Component {
|
||||
}
|
||||
|
||||
handleLike(event) {
|
||||
const liked = event.target.checked;
|
||||
this.setState({
|
||||
like: liked
|
||||
});
|
||||
event.preventDefault();
|
||||
|
||||
fetch(`/building/like/${this.props.building_id}`, {
|
||||
method: 'POST',
|
||||
headers:{
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
credentials: 'same-origin'
|
||||
}).then(
|
||||
res => res.json()
|
||||
).then(function(res){
|
||||
if (res.error) {
|
||||
this.setState({error: res.error})
|
||||
} else {
|
||||
this.props.selectBuilding(res);
|
||||
this.setState({
|
||||
likes_total: res.likes_total
|
||||
})
|
||||
}
|
||||
}.bind(this)).catch(
|
||||
(err) => this.setState({error: err})
|
||||
);
|
||||
}
|
||||
|
||||
handleSubmit(event) {
|
||||
@ -124,17 +142,28 @@ class EditForm extends Component {
|
||||
</a>
|
||||
: null
|
||||
}
|
||||
{
|
||||
(this.props.slug === 'like')? // special-case for likes
|
||||
<NavLink className="icon-button save" title="Done"
|
||||
to={`/building/${this.props.building_id}.html?cat=${this.props.slug}`}>
|
||||
Done
|
||||
<SaveIcon />
|
||||
</NavLink>
|
||||
:
|
||||
<Fragment>
|
||||
<NavLink className="icon-button save" title="Save Changes"
|
||||
onClick={this.handleSubmit}
|
||||
onClick={this.handleSubmit}
|
||||
to={`/building/${this.props.building_id}.html?cat=${this.props.slug}`}>
|
||||
Save
|
||||
<SaveIcon />
|
||||
</NavLink>
|
||||
<NavLink className="icon-button close-edit" title="Cancel"
|
||||
to={`/building/${this.props.building_id}.html?cat=${this.props.slug}`}>
|
||||
to={`/building/${this.props.building_id}.html?cat=${this.props.slug}`}>
|
||||
Cancel
|
||||
<CloseIcon />
|
||||
</NavLink>
|
||||
</Fragment>
|
||||
}
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
@ -174,11 +203,19 @@ class EditForm extends Component {
|
||||
hitting refresh after saving (we're working on making this
|
||||
smoother).</p>
|
||||
|
||||
<div className="buttons-container">
|
||||
<Link to={`/building/${this.props.building_id}.html?cat=${this.props.slug}`}
|
||||
className="btn btn-secondary">Cancel</Link>
|
||||
<button type="submit" className="btn btn-primary">Save</button>
|
||||
</div>
|
||||
{
|
||||
(this.props.slug === 'like')? // special-case for likes
|
||||
<div className="buttons-container">
|
||||
<Link to={`/building/${this.props.building_id}.html?cat=${this.props.slug}`}
|
||||
className="btn btn-secondary">Done</Link>
|
||||
</div>
|
||||
:
|
||||
<div className="buttons-container">
|
||||
<Link to={`/building/${this.props.building_id}.html?cat=${this.props.slug}`}
|
||||
className="btn btn-secondary">Cancel</Link>
|
||||
<button type="submit" className="btn btn-primary">Save</button>
|
||||
</div>
|
||||
}
|
||||
</form>
|
||||
</section>
|
||||
)
|
||||
@ -231,14 +268,8 @@ const NumberInput = (props) => (
|
||||
|
||||
const LikeButton = (props) => (
|
||||
<Fragment>
|
||||
<label htmlFor="likes">Like this building?</label>
|
||||
<div className="form-check">
|
||||
<input className="form-check-input position-static"
|
||||
type="checkbox"
|
||||
checked={props.value}
|
||||
onChange={props.handleLike}
|
||||
/>
|
||||
</div>
|
||||
<p class="likes">{(props.value)? props.value : 0} likes</p>
|
||||
<button class="btn btn-success btn-like" onClick={props.handleLike}>Like this building!</button>
|
||||
</Fragment>
|
||||
);
|
||||
|
||||
|
@ -155,7 +155,7 @@
|
||||
"title": "Like Me!", "slug": "like",
|
||||
"help": "https://pages.colouring.london/likeme",
|
||||
"fields": [
|
||||
{ "title": "Like", "slug": "like", "type": "like", "tooltip": "Do you like the building?" }
|
||||
{ "title": "Like", "slug": "likes_total", "type": "like", "tooltip": "Do you like the building?" }
|
||||
]
|
||||
}
|
||||
]
|
||||
|
@ -53,3 +53,11 @@ form .btn {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Like button */
|
||||
.likes {
|
||||
margin: 0.5rem 0;
|
||||
}
|
||||
form .btn-like {
|
||||
margin: 0;
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ import App from './frontend/app';
|
||||
import db from './db';
|
||||
import { authUser, createUser, getUserById, authAPIUser, getNewUserAPIKey } from './user';
|
||||
import { queryBuildingsAtPoint, queryBuildingsByReference, getBuildingById,
|
||||
saveBuilding } from './building';
|
||||
saveBuilding, likeBuilding } from './building';
|
||||
import tileserver from './tileserver';
|
||||
import { parseBuildingURL } from './parse';
|
||||
|
||||
@ -218,6 +218,28 @@ function updateBuilding(req, res, user_id){
|
||||
)
|
||||
}
|
||||
|
||||
// POST like building
|
||||
server.post('/building/like/:building_id', function(req, res){
|
||||
if (!req.session.user_id) {
|
||||
res.send({error: 'Must be logged in'});
|
||||
return
|
||||
}
|
||||
const { building_id } = req.params;
|
||||
likeBuilding(building_id, req.session.user_id).then(building => {
|
||||
if (building.error) {
|
||||
res.send(building)
|
||||
return
|
||||
}
|
||||
if (typeof(building) === "undefined") {
|
||||
res.send({error:'Database error'})
|
||||
return
|
||||
}
|
||||
res.send(building)
|
||||
}).catch(
|
||||
() => res.send({error:'Database error'})
|
||||
)
|
||||
});
|
||||
|
||||
// POST new user
|
||||
server.post('/users', function(req, res){
|
||||
const user = req.body;
|
||||
|
@ -86,4 +86,4 @@ CREATE INDEX building_likes_idx ON building_user_likes ( building_id );
|
||||
CREATE INDEX user_likes_idx ON building_user_likes ( user_id );
|
||||
|
||||
-- One like per-building, per-user
|
||||
ALTER TABLE building_user_likes ADD CONSTRAINT building_like_once UNIQUE (building_id, user_id);
|
||||
-- ALTER TABLE building_user_likes ADD CONSTRAINT building_like_once UNIQUE (building_id, user_id);
|
||||
|
Loading…
Reference in New Issue
Block a user