1
0
mirror of https://github.com/ascribe/onion.git synced 2024-12-22 17:33:14 +01:00

Merged in AD-545-add-rating-support-for-the-pieces (pull request #36)

Ad 545 add rating support for the pieces
This commit is contained in:
diminator 2015-08-10 17:08:11 +02:00
commit a6e257bd27
7 changed files with 161 additions and 2 deletions

View File

@ -0,0 +1,66 @@
'use strict';
import alt from '../../../../alt';
import Q from 'q';
import PrizeRatingFetcher from '../fetchers/prize_rating_fetcher';
class PrizeRatingActions {
constructor() {
this.generateActions(
'updatePrizeRatings',
'updatePrizeRating'
);
}
fetch() {
return Q.Promise((resolve, reject) => {
PrizeRatingFetcher
.fetch()
.then((res) => {
this.actions.updatePrizeRatings(res.ratings);
resolve(res);
})
.catch((err) => {
console.logGlobal(err);
reject(err);
});
});
}
fetchOne(pieceId) {
return Q.Promise((resolve, reject) => {
PrizeRatingFetcher
.fetchOne(pieceId)
.then((res) => {
this.actions.updatePrizeRating(res.rating.rating);
resolve(res);
})
.catch((err) => {
console.logGlobal(err);
reject(err);
});
});
}
createRating(pieceId, rating) {
return Q.Promise((resolve, reject) => {
PrizeRatingFetcher
.rate(pieceId, rating)
.then((res) => {
this.actions.updatePrizeRating(res.rating.rating);
resolve(res);
})
.catch((err) => {
console.logGlobal(err);
reject(err);
});
});
}
updateRating(rating) {
this.actions.updatePrizeRating(rating);
}
}
export default alt.createActions(PrizeRatingActions);

View File

@ -2,9 +2,14 @@
import React from 'react';
import StarRating from 'react-star-rating';
import PieceActions from '../../../../../actions/piece_actions';
import PieceStore from '../../../../../stores/piece_store';
import PrizeRatingActions from '../../actions/prize_rating_actions';
import PrizeRatingStore from '../../stores/prize_rating_store';
import Piece from '../../../../../components/ascribe_detail/piece';
import AppConstants from '../../../../../constants/application_constants';
@ -70,6 +75,34 @@ let PrizePieceDetails = React.createClass({
propTypes: {
piece: React.PropTypes.object
},
getInitialState() {
return PrizeRatingStore.getState();
},
onChange(state) {
this.setState(state);
},
componentDidMount() {
PrizeRatingStore.listen(this.onChange);
PrizeRatingActions.fetchOne(this.props.piece.id);
},
componentWillUnmount() {
// Every time we're leaving the piece detail page,
// just reset the piece that is saved in the piece store
// as it will otherwise display wrong/old data once the user loads
// the piece detail a second time
PrizeRatingActions.updateRating({});
PrizeRatingStore.unlisten(this.onChange);
},
onRatingClick(event, args) {
event.preventDefault();
PrizeRatingActions.createRating(this.props.piece.id, args.rating);
},
render() {
if (this.props.piece.prize
&& this.props.piece.prize.name
@ -79,6 +112,14 @@ let PrizePieceDetails = React.createClass({
title="Prize Details"
show={true}
defaultExpanded={true}>
<StarRating
name="airbnb-rating"
caption=""
step={1}
size='lg'
rating={this.state.currentRating}
onRatingClick={this.onRatingClick}
ratingAmount={5} />
<Form ref='form'>
{Object.keys(this.props.piece.extra_data).map((data) => {
let label = data.replace('_', ' ');

View File

@ -14,7 +14,9 @@ function getApiUrls(subdomain) {
'jurys': AppPrizeConstants.prizeApiEndpoint + subdomain + '/jury/',
'jury': AppPrizeConstants.prizeApiEndpoint + subdomain + '/jury/${email}/',
'jury_activate': AppPrizeConstants.prizeApiEndpoint + subdomain + '/jury/${email}/activate/',
'jury_resend': AppPrizeConstants.prizeApiEndpoint + subdomain + '/jury/${email}/resend/'
'jury_resend': AppPrizeConstants.prizeApiEndpoint + subdomain + '/jury/${email}/resend/',
'ratings': AppPrizeConstants.prizeApiEndpoint + subdomain + '/ratings/',
'rating': AppPrizeConstants.prizeApiEndpoint + subdomain + '/ratings/${piece_id}/'
};
}

View File

@ -0,0 +1,20 @@
'use strict';
import requests from '../../../../utils/requests';
let PrizeRatingFetcher = {
fetch() {
return requests.get('rating');
},
fetchOne(pieceId) {
return requests.get('rating', {'piece_id': pieceId});
},
rate(pieceId, rating) {
return requests.post('ratings', {body: {'piece_id': pieceId, 'rating': rating}});
}
};
export default PrizeRatingFetcher;

View File

@ -0,0 +1,23 @@
'use strict';
import alt from '../../../../alt';
import PrizeRatingActions from '../actions/prize_rating_actions';
class PrizeRatingStore {
constructor() {
this.ratings = [];
this.currentRating = null;
this.bindActions(PrizeRatingActions);
}
onUpdatePrizeRatings( ratings ) {
this.ratings = ratings;
}
onUpdatePrizeRating( rating ) {
this.currentRating = parseInt(rating, 10);
}
}
export default alt.createStore(PrizeRatingStore, 'PrizeRatingStore');

View File

@ -84,7 +84,8 @@
"vinyl-buffer": "^1.0.0",
"vinyl-source-stream": "^1.1.0",
"watchify": "^3.1.2",
"yargs": "^3.10.0"
"yargs": "^3.10.0",
"react-star-rating": "~1.3.2"
},
"jest": {
"scriptPreprocessor": "node_modules/babel-jest",

View File

@ -6,6 +6,7 @@ $BASE_URL: '<%= BASE_URL %>';
@import 'ascribe_variables';
@import 'variables';
@import '../node_modules/bootstrap-sass/assets/stylesheets/bootstrap';
@import '../node_modules/react-star-rating/dist/css/react-star-rating.min';
@import '../node_modules/react-datepicker/dist/react-datepicker';
@import 'glyphicons-social';
@import 'ascribe_theme';
@ -382,3 +383,8 @@ hr {
font-size: 2em;
}
}
.rating-container .rating-stars {
width: 25px;
color: #000;
}