diff --git a/js/components/whitelabel/prize/actions/prize_rating_actions.js b/js/components/whitelabel/prize/actions/prize_rating_actions.js new file mode 100644 index 00000000..536445f8 --- /dev/null +++ b/js/components/whitelabel/prize/actions/prize_rating_actions.js @@ -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); \ No newline at end of file diff --git a/js/components/whitelabel/prize/components/ascribe_detail/piece_container.js b/js/components/whitelabel/prize/components/ascribe_detail/piece_container.js index 8782f6f0..3a7c3144 100644 --- a/js/components/whitelabel/prize/components/ascribe_detail/piece_container.js +++ b/js/components/whitelabel/prize/components/ascribe_detail/piece_container.js @@ -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'; @@ -14,8 +19,6 @@ import Property from '../../../../../components/ascribe_forms/property'; import InputTextAreaToggable from '../../../../../components/ascribe_forms/input_textarea_toggable'; import CollapsibleParagraph from '../../../../../components/ascribe_collapsible/collapsible_paragraph'; -import StarRating from 'react-star-rating'; - /** * This is the component that implements resource/data specific functionality */ @@ -73,9 +76,33 @@ let PrizePieceDetails = React.createClass({ piece: React.PropTypes.object }, - onRatingClick(event, position, rating, caption, name) { - console.log(rating); + 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 @@ -90,6 +117,7 @@ let PrizePieceDetails = React.createClass({ caption="" step={1} size='lg' + rating={this.state.currentRating} onRatingClick={this.onRatingClick} ratingAmount={5} />
diff --git a/js/components/whitelabel/prize/constants/api_urls.js b/js/components/whitelabel/prize/constants/api_urls.js index 3e7260bb..480e8d4f 100644 --- a/js/components/whitelabel/prize/constants/api_urls.js +++ b/js/components/whitelabel/prize/constants/api_urls.js @@ -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}/' }; } diff --git a/js/components/whitelabel/prize/fetchers/prize_rating_fetcher.js b/js/components/whitelabel/prize/fetchers/prize_rating_fetcher.js new file mode 100644 index 00000000..91da0051 --- /dev/null +++ b/js/components/whitelabel/prize/fetchers/prize_rating_fetcher.js @@ -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; diff --git a/js/components/whitelabel/prize/stores/prize_rating_store.js b/js/components/whitelabel/prize/stores/prize_rating_store.js new file mode 100644 index 00000000..4a31501c --- /dev/null +++ b/js/components/whitelabel/prize/stores/prize_rating_store.js @@ -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'); \ No newline at end of file