1
0
mirror of https://github.com/ascribe/onion.git synced 2025-01-03 10:25:08 +01:00

shortlisting enabled up till loan request

This commit is contained in:
diminator 2015-08-25 15:19:10 +02:00
parent a07b4cc35c
commit 5fcee39ed3
8 changed files with 147 additions and 65 deletions

View File

@ -101,10 +101,6 @@ let Edition = React.createClass({
this.transitionTo('pieces'); this.transitionTo('pieces');
}, },
getId() {
return {'bitcoin_id': this.props.edition.bitcoin_id};
},
render() { render() {
return ( return (
<Row> <Row>
@ -159,7 +155,7 @@ let Edition = React.createClass({
show={(this.state.currentUser.username && true || false) || show={(this.state.currentUser.username && true || false) ||
(this.props.edition.acl.acl_edit || this.props.edition.public_note)}> (this.props.edition.acl.acl_edit || this.props.edition.public_note)}>
<Note <Note
id={this.getId} id={() => {return {'bitcoin_id': this.props.edition.bitcoin_id}; }}
label={getLangText('Personal note (private)')} label={getLangText('Personal note (private)')}
defaultValue={this.props.edition.private_note ? this.props.edition.private_note : null} defaultValue={this.props.edition.private_note ? this.props.edition.private_note : null}
placeholder={getLangText('Enter your comments ...')} placeholder={getLangText('Enter your comments ...')}
@ -168,7 +164,7 @@ let Edition = React.createClass({
url={ApiUrls.note_private_edition} url={ApiUrls.note_private_edition}
currentUser={this.state.currentUser}/> currentUser={this.state.currentUser}/>
<Note <Note
id={this.getId} id={() => {return {'bitcoin_id': this.props.edition.bitcoin_id}; }}
label={getLangText('Edition note (public)')} label={getLangText('Edition note (public)')}
defaultValue={this.props.edition.public_note ? this.props.edition.public_note : null} defaultValue={this.props.edition.public_note ? this.props.edition.public_note : null}
placeholder={getLangText('Enter your comments ...')} placeholder={getLangText('Enter your comments ...')}

View File

@ -57,6 +57,20 @@ class PrizeRatingActions {
}); });
} }
toggleShortlist(pieceId) {
return Q.Promise((resolve, reject) => {
PrizeRatingFetcher
.select(pieceId)
.then((res) => {
this.actions.updatePrizeRating(res.rating.rating);
resolve(res);
})
.catch((err) => {
reject(err);
});
});
}
updateRating(rating) { updateRating(rating) {
this.actions.updatePrizeRating(rating); this.actions.updatePrizeRating(rating);
} }

View File

@ -4,13 +4,17 @@ import React from 'react';
import Router from 'react-router'; import Router from 'react-router';
import StarRating from 'react-star-rating'; import StarRating from 'react-star-rating';
import AccordionListItemPiece from '../../../../ascribe_accordion_list/accordion_list_item_piece';
import PieceListActions from '../../../../../actions/piece_list_actions'; import PieceListActions from '../../../../../actions/piece_list_actions';
import PieceListStore from '../../../../../stores/piece_list_store'; import PieceListStore from '../../../../../stores/piece_list_store';
import PrizeRatingActions from '../../actions/prize_rating_actions';
import UserStore from '../../../../../stores/user_store'; import UserStore from '../../../../../stores/user_store';
import InputCheckbox from '../../../../ascribe_forms/input_checkbox';
import AccordionListItemPiece from '../../../../ascribe_accordion_list/accordion_list_item_piece';
import GlobalNotificationModel from '../../../../../models/global_notification_model'; import GlobalNotificationModel from '../../../../../models/global_notification_model';
import GlobalNotificationActions from '../../../../../actions/global_notification_actions'; import GlobalNotificationActions from '../../../../../actions/global_notification_actions';
@ -76,7 +80,7 @@ let AccordionListItemPrize = React.createClass({
} }
else if (this.props.content.ratings.average){ else if (this.props.content.ratings.average){
rating = this.props.content.ratings.average; rating = this.props.content.ratings.average;
caption = 'Average (' + this.props.content.ratings.ratings.length + ' ratings)'; caption = 'Average of ' + this.props.content.ratings.ratings.length + ' rating(s)';
} }
return ( return (
@ -97,7 +101,7 @@ let AccordionListItemPrize = React.createClass({
if (this.state.currentUser.is_judge){ if (this.state.currentUser.is_judge){
return ( return (
<div className="react-rating-caption pull-right"> <div className="react-rating-caption pull-right">
No votes yet Not rated
</div> </div>
); );
} }
@ -126,22 +130,42 @@ let AccordionListItemPrize = React.createClass({
); );
}, },
getPrizeBadge(){
if (this.state.currentUser && this.state.currentUser.is_judge) {
return (
<span className="pull-right ascribe-checkbox-wrapper ascribe-checkbox-badge">
<InputCheckbox
defaultChecked={this.props.content.selected}
onChange={() => {
PrizeRatingActions.toggleShortlist(this.props.content.id).then(
PieceListActions.fetchPieceList(this.state.page, this.state.pageSize, this.state.search,
this.state.orderBy, this.state.orderAsc, this.state.filterBy)
); }}/>
</span>
);
}
return null;
},
render() { render() {
let artistName = this.state.currentUser.is_jury ? let artistName = this.state.currentUser.is_jury ?
<span className="glyphicon glyphicon-eye-close" style={{fontSize: '0.75em'}} aria-hidden="true"/> : <span className="glyphicon glyphicon-eye-close" style={{fontSize: '0.75em'}} aria-hidden="true"/> :
this.props.content.artist_name; this.props.content.artist_name;
return ( return (
<AccordionListItemPiece <div>
className={this.props.className} <AccordionListItemPiece
piece={this.props.content} className={this.props.className}
artistName={artistName} piece={this.props.content}
subsubheading={ artistName={artistName}
<div className="pull-left"> subsubheading={
<span>{this.props.content.date_created.split('-')[0]}</span> <div className="pull-left">
</div>} <span>{this.props.content.date_created.split('-')[0]}</span>
buttons={this.getPrizeButtons()}> </div>}
{this.props.children} buttons={this.getPrizeButtons()}
</AccordionListItemPiece> badge={this.getPrizeBadge()}>
{this.props.children}
</AccordionListItemPiece>
</div>
); );
} }
}); });

View File

@ -26,6 +26,8 @@ import Property from '../../../../../components/ascribe_forms/property';
import InputTextAreaToggable from '../../../../../components/ascribe_forms/input_textarea_toggable'; import InputTextAreaToggable from '../../../../../components/ascribe_forms/input_textarea_toggable';
import CollapsibleParagraph from '../../../../../components/ascribe_collapsible/collapsible_paragraph'; import CollapsibleParagraph from '../../../../../components/ascribe_collapsible/collapsible_paragraph';
import InputCheckbox from '../../../../ascribe_forms/input_checkbox';
import GlobalNotificationModel from '../../../../../models/global_notification_model'; import GlobalNotificationModel from '../../../../../models/global_notification_model';
import GlobalNotificationActions from '../../../../../actions/global_notification_actions'; import GlobalNotificationActions from '../../../../../actions/global_notification_actions';
@ -81,11 +83,13 @@ let PieceContainer = React.createClass({
loadPiece() { loadPiece() {
PieceActions.fetchOne(this.props.params.pieceId); PieceActions.fetchOne(this.props.params.pieceId);
this.setState(this.state);
}, },
render() { render() {
if('title' in this.state.piece) { if('title' in this.state.piece) {
let artistName = this.state.currentUser.is_jury ? let artistName = ((this.state.currentUser.is_jury && !this.state.currentUser.is_judge) ||
(this.state.currentUser.is_judge && !this.state.piece.selected )) ?
<span className="glyphicon glyphicon-eye-close" aria-hidden="true"/> : this.state.piece.artist_name; <span className="glyphicon glyphicon-eye-close" aria-hidden="true"/> : this.state.piece.artist_name;
return ( return (
<Piece <Piece
@ -105,6 +109,7 @@ let PieceContainer = React.createClass({
} }
subheader={ subheader={
<PrizePieceRatings <PrizePieceRatings
loadPiece={this.loadPiece}
piece={this.state.piece} piece={this.state.piece}
currentUser={this.state.currentUser}/> currentUser={this.state.currentUser}/>
}> }>
@ -156,6 +161,7 @@ let NavigationHeader = React.createClass({
let PrizePieceRatings = React.createClass({ let PrizePieceRatings = React.createClass({
propTypes: { propTypes: {
loadPiece: React.PropTypes.func,
piece: React.PropTypes.object, piece: React.PropTypes.object,
currentUser: React.PropTypes.object currentUser: React.PropTypes.object
}, },
@ -203,22 +209,50 @@ let PrizePieceRatings = React.createClass({
onRatingClick(event, args) { onRatingClick(event, args) {
event.preventDefault(); event.preventDefault();
PrizeRatingActions.createRating(this.props.piece.id, args.rating).then( PrizeRatingActions.createRating(this.props.piece.id, args.rating).then(
PieceListActions.fetchPieceList(this.state.page, this.state.pageSize, this.state.search, this.refreshPieceData()
this.state.orderBy, this.state.orderAsc, this.state.filterBy)
); );
}, },
getId() { refreshPieceData() {
return {'piece_id': this.props.piece.id}; PieceListActions.fetchPieceList(this.state.page, this.state.pageSize, this.state.search,
this.state.orderBy, this.state.orderAsc, this.state.filterBy);
this.props.loadPiece();
}, },
render(){ render(){
if (this.props.currentUser && this.props.currentUser.is_judge && this.state.average) { if (this.props.piece && this.props.currentUser && this.props.currentUser.is_judge && this.state.average) {
return ( return (
<CollapsibleParagraph <div>
title="Average Rating" <CollapsibleParagraph
show={true} title="Shortlisting"
defaultExpanded={true}> show={true}
defaultExpanded={true}>
<div className="row no-margin">
<span className="ascribe-checkbox-wrapper" style={{marginLeft: '1.5em'}}>
<InputCheckbox
defaultChecked={this.props.piece.selected}
onChange={() => {
PrizeRatingActions.toggleShortlist(this.props.piece.id).then(
this.refreshPieceData()
); }}>
<span>
Select for the prize
</span>
</InputCheckbox>
</span>
<span className="pull-right">
{this.props.piece.selected ?
<button className={'btn btn-default btn-sm '}>
SEND LOAN REQUEST
</button> : null}
</span>
</div>
<hr />
</CollapsibleParagraph>
<CollapsibleParagraph
title="Average Rating"
show={true}
defaultExpanded={true}>
<div id="list-rating" style={{marginLeft: '1.5em', marginBottom: '1em'}}> <div id="list-rating" style={{marginLeft: '1.5em', marginBottom: '1em'}}>
<StarRating <StarRating
ref='average-rating' ref='average-rating'
@ -229,33 +263,34 @@ let PrizePieceRatings = React.createClass({
rating={this.state.average} rating={this.state.average}
ratingAmount={5}/> ratingAmount={5}/>
</div> </div>
<hr /> <hr />
{this.state.ratings.map((item, i) => { {this.state.ratings.map((item, i) => {
let note = item.note ? let note = item.note ?
<div className="rating-note"> <div className="rating-note">
note: {item.note} note: {item.note}
</div> : null; </div> : null;
return ( return (
<div className="rating-list"> <div className="rating-list">
<div id="list-rating" className="row no-margin"> <div id="list-rating" className="row no-margin">
<span className="pull-right"> <span className="pull-right">
<StarRating <StarRating
ref={'rating' + i} ref={'rating' + i}
name={'rating' + i} name={'rating' + i}
caption="" caption=""
size='sm' size='sm'
step={0.5} step={0.5}
rating={item.rating} rating={item.rating}
ratingAmount={5}/> ratingAmount={5}/>
</span> </span>
<span> {item.user}</span> <span> {item.user}</span>
{note} {note}
</div>
</div> </div>
</div> );
); })}
})} <hr />
<hr /> </CollapsibleParagraph>
</CollapsibleParagraph>); </div>);
} }
else if (this.props.currentUser && this.props.currentUser.is_jury) { else if (this.props.currentUser && this.props.currentUser.is_jury) {
return ( return (
@ -275,7 +310,7 @@ let PrizePieceRatings = React.createClass({
ratingAmount={5} /> ratingAmount={5} />
</div> </div>
<Note <Note
id={this.getId} id={() => {return {'piece_id': this.props.piece.id}; }}
label={getLangText('Jury note')} label={getLangText('Jury note')}
defaultValue={this.props.piece && this.props.piece.note_from_user ? this.props.piece.note_from_user.note : null} defaultValue={this.props.piece && this.props.piece.note_from_user ? this.props.piece.note_from_user.note : null}
placeholder={getLangText('Enter your comments ...')} placeholder={getLangText('Enter your comments ...')}

View File

@ -18,6 +18,7 @@ function getPrizeApiUrls(subdomain) {
'ratings': AppPrizeConstants.prizeApiEndpoint + subdomain + '/ratings/', 'ratings': AppPrizeConstants.prizeApiEndpoint + subdomain + '/ratings/',
'rating': AppPrizeConstants.prizeApiEndpoint + subdomain + '/ratings/${piece_id}/', 'rating': AppPrizeConstants.prizeApiEndpoint + subdomain + '/ratings/${piece_id}/',
'rating_average': AppPrizeConstants.prizeApiEndpoint + subdomain + '/ratings/${piece_id}/average/', 'rating_average': AppPrizeConstants.prizeApiEndpoint + subdomain + '/ratings/${piece_id}/average/',
'select_piece' : AppPrizeConstants.prizeApiEndpoint + subdomain + '/ratings/${piece_id}/select/',
'notes': AppPrizeConstants.prizeApiEndpoint + subdomain + '/notes/', 'notes': AppPrizeConstants.prizeApiEndpoint + subdomain + '/notes/',
'note': AppPrizeConstants.prizeApiEndpoint + subdomain + '/notes/${piece_id}/' 'note': AppPrizeConstants.prizeApiEndpoint + subdomain + '/notes/${piece_id}/'

View File

@ -14,6 +14,10 @@ let PrizeRatingFetcher = {
rate(pieceId, rating) { rate(pieceId, rating) {
return requests.post('ratings', {body: {'piece_id': pieceId, 'note': rating}}); return requests.post('ratings', {body: {'piece_id': pieceId, 'note': rating}});
},
select(pieceId) {
return requests.post('select_piece', {'piece_id': pieceId});
} }
}; };

View File

@ -67,11 +67,6 @@ let CylandPieceContainer = React.createClass({
PieceActions.fetchOne(this.props.params.pieceId); PieceActions.fetchOne(this.props.params.pieceId);
}, },
getId() {
return {'id': this.state.piece.id};
},
render() { render() {
if('title' in this.state.piece) { if('title' in this.state.piece) {
return ( return (
@ -106,7 +101,7 @@ let CylandPieceContainer = React.createClass({
show={(this.state.currentUser.username && true || false) || show={(this.state.currentUser.username && true || false) ||
(this.state.piece.public_note)}> (this.state.piece.public_note)}>
<Note <Note
id={this.getId} id={() => {return {'id': this.state.piece.id}; }}
label={getLangText('Personal note (private)')} label={getLangText('Personal note (private)')}
defaultValue={this.state.piece.private_note ? this.state.piece.private_note : null} defaultValue={this.state.piece.private_note ? this.state.piece.private_note : null}
placeholder={getLangText('Enter your comments ...')} placeholder={getLangText('Enter your comments ...')}

View File

@ -145,8 +145,15 @@
display: inline-block; display: inline-block;
width: 100%; width: 100%;
border-top: 1px solid rgba(0,0,0,.05); border-top: 1px solid rgba(0,0,0,.05);
padding: .5em 1.5em .5em 1.5em; padding: .5em 1.5em .5em 1.5em;
}
.ascribe-checkbox-wrapper{
.checkbox > span {color: black;}
}
.ascribe-settings-property-collapsible-toggle, .ascribe-checkbox-wrapper {
cursor:pointer; cursor:pointer;
@ -196,4 +203,10 @@
font-size: 20px; font-size: 20px;
color: rgba(2, 182, 163, 1); color: rgba(2, 182, 163, 1);
} }
}
.ascribe-checkbox-badge{
> span > span {
margin-top: 0;
}
} }