diff --git a/js/components/ascribe_buttons/acl_button.js b/js/components/ascribe_buttons/acl_button.js index e054a23c..1e20d0d8 100644 --- a/js/components/ascribe_buttons/acl_button.js +++ b/js/components/ascribe_buttons/acl_button.js @@ -14,18 +14,21 @@ import GlobalNotificationModel from '../../models/global_notification_model'; import GlobalNotificationActions from '../../actions/global_notification_actions'; import { getLangText } from '../../utils/lang_utils.js'; - +import apiUrls from '../../constants/api_urls'; let AclButton = React.createClass({ propTypes: { action: React.PropTypes.oneOf(AppConstants.aclList).isRequired, availableAcls: React.PropTypes.array.isRequired, - pieceOrEditions: React.PropTypes.array.isRequired, + pieceOrEditions: React.PropTypes.object.isRequired, currentUser: React.PropTypes.object, handleSuccess: React.PropTypes.func.isRequired, className: React.PropTypes.string }, + isPiece(){ + return !(this.props.pieceOrEditions.constructor === Array); + }, actionProperties(){ if (this.props.action === 'consign'){ return { @@ -62,16 +65,46 @@ let AclButton = React.createClass({ return { title: getLangText('Share artwork'), tooltip: getLangText('Share the artwork'), - form: , + form: ( + + ), handleSuccess: this.showNotification }; } }, + showNotification(response){ this.props.handleSuccess(); let notification = new GlobalNotificationModel(response.notification, 'success'); GlobalNotificationActions.appendGlobalNotification(notification); }, + + getTitlesString(){ + if (this.isPiece()){ + return '\"' + this.props.pieceOrEditions.title + '\"'; + } + else { + return this.props.pieceOrEditions.map(function(edition) { + return '- \"' + edition.title + ', ' + getLangText('edition') + ' ' + edition.edition_number + '\"\n'; + }).join(''); + } + + }, + + getFormDataId(){ + if (this.isPiece()) { + return {piece_id: this.props.pieceOrEditions.id}; + } + else { + return {bitcoin_id: this.props.pieceOrEditions.map(function(edition){ + return edition.bitcoin_id; + }).join()}; + } + }, + render() { let shouldDisplay = this.props.availableAcls.indexOf(this.props.action) > -1; let aclProps = this.actionProperties(); @@ -88,6 +121,18 @@ let AclButton = React.createClass({ { aclProps.form } ); + }, + + getShareMessage(){ + return ( +`${getLangText('Hi')}, + +${getLangText('I am sharing')} : +${this.getTitlesString()}${getLangText('with you')}. + +${getLangText('Truly yours')}, +${this.props.currentUser.username}` + ); } }); diff --git a/js/components/ascribe_buttons/acl_button_list.js b/js/components/ascribe_buttons/acl_button_list.js index 07003d11..eb3dc720 100644 --- a/js/components/ascribe_buttons/acl_button_list.js +++ b/js/components/ascribe_buttons/acl_button_list.js @@ -7,11 +7,12 @@ import UserStore from '../../stores/user_store'; import AclButton from '../ascribe_buttons/acl_button'; import DeleteButton from '../ascribe_buttons/delete_button'; +import CreateEditionButton from '../ascribe_buttons/create_editions_button'; let AclButtonList = React.createClass({ propTypes: { className: React.PropTypes.string, - editions: React.PropTypes.array, + editions: React.PropTypes.object, availableAcls: React.PropTypes.array, handleSuccess: React.PropTypes.func }, @@ -66,7 +67,10 @@ let AclButtonList = React.createClass({ pieceOrEditions={this.props.editions} currentUser={this.state.currentUser} handleSuccess={this.props.handleSuccess} /> - + + ); } diff --git a/js/components/ascribe_buttons/create_editions_button.js b/js/components/ascribe_buttons/create_editions_button.js new file mode 100644 index 00000000..4b189db2 --- /dev/null +++ b/js/components/ascribe_buttons/create_editions_button.js @@ -0,0 +1,44 @@ +'use strict'; + +import React from 'react'; +import Router from 'react-router'; + +import Button from 'react-bootstrap/lib/Button'; + +import EditionDeleteForm from '../ascribe_forms/form_delete_edition'; +import EditionRemoveFromCollectionForm from '../ascribe_forms/form_remove_editions_from_collection'; +import ModalWrapper from '../ascribe_modal/modal_wrapper'; +import AccordionListItemCreateEditions from './../ascribe_accordion_list/accordion_list_item_create_editions'; +import GlobalNotificationModel from '../../models/global_notification_model'; +import GlobalNotificationActions from '../../actions/global_notification_actions'; + +import { getAvailableAcls } from '../../utils/acl_utils'; +import { getLangText } from '../../utils/lang_utils.js' + +import EditionListActions from '../../actions/edition_list_actions'; + +let CreateEditionsButton = React.createClass({ + propTypes: { + piece: React.PropTypes.object.isRequired + }, + + mixins: [Router.Navigation], + + render: function () { + if (this.props.piece.constructor === Array){ + return null; + } + let availableAcls = getAvailableAcls([this.props.piece]); + if (availableAcls.indexOf('editions') === -1){ + return null; + } + return ( + + ); + } +}); + +export default CreateEditionsButton; + diff --git a/js/components/ascribe_detail/edition.js b/js/components/ascribe_detail/edition.js index df3f86b5..028cb8ae 100644 --- a/js/components/ascribe_detail/edition.js +++ b/js/components/ascribe_detail/edition.js @@ -218,7 +218,6 @@ let EditionSummary = React.createClass({ {this.getStatus()} -
{this.getActions()}
diff --git a/js/components/ascribe_detail/piece.js b/js/components/ascribe_detail/piece.js index b04b511e..d37addea 100644 --- a/js/components/ascribe_detail/piece.js +++ b/js/components/ascribe_detail/piece.js @@ -70,7 +70,8 @@ let Piece = React.createClass({ content={this.props.piece}/> + piece={this.props.piece} + handleSuccess={this.props.loadPiece}/> -1 @@ -95,26 +96,24 @@ let PieceSummary = React.createClass({ propTypes: { piece: React.PropTypes.object }, - getActions(){ - //let actions = ( - // - // - // - // - // ); - //return actions; - return null; + let actions = ( + + + + + ); + return actions; + //return null; }, render() { return (
-
{this.getActions()}
diff --git a/js/components/ascribe_forms/form_login.js b/js/components/ascribe_forms/form_login.js deleted file mode 100644 index fc44b08b..00000000 --- a/js/components/ascribe_forms/form_login.js +++ /dev/null @@ -1,64 +0,0 @@ -'use strict'; - -import React from 'react'; - -import apiUrls from '../../constants/api_urls'; -import FormMixin from '../../mixins/form_mixin'; -import InputText from './input_text'; -import ButtonSubmitOrClose from '../ascribe_buttons/button_submit_close'; - -import SignupModal from '../ascribe_modal/modal_signup'; -import PasswordResetRequestModal from '../ascribe_modal/modal_password_request_reset'; -import { getLangText } from '../../utils/lang_utils.js'; - -let LoginForm = React.createClass({ - mixins: [FormMixin], - - - url() { - return apiUrls.users_login; - }, - - getFormData() { - return { - email: this.refs.email.state.value, - password: this.refs.password.state.value - }; - }, - renderForm() { - return ( -
- - - - -
- {getLangText('Forgot your password')}? - {getLangText('Reset password')}}/> -
-
- {getLangText('Not a member yet')}? - {getLangText('Sign up')}}/> -
- - - ); - } -}); - -export default LoginForm; diff --git a/js/components/ascribe_forms/form_note_edition.js b/js/components/ascribe_forms/form_note_edition.js deleted file mode 100644 index ca1af7ed..00000000 --- a/js/components/ascribe_forms/form_note_edition.js +++ /dev/null @@ -1,43 +0,0 @@ -'use strict'; - -import React from 'react'; - -import apiUrls from '../../constants/api_urls'; -import FormMixin from '../../mixins/form_mixin'; - -import InputTextAreaToggable from './input_textarea_toggable'; - - -let EditionNoteForm = React.createClass({ - mixins: [FormMixin], - - url() { - return apiUrls.note_edition; - }, - - getFormData() { - return { - bitcoin_id: this.getBitcoinIds().join(), - note: this.refs.personalNote.state.value - }; - }, - - renderForm() { - - return ( -
- - - ); - } -}); - -export default EditionNoteForm; \ No newline at end of file diff --git a/js/components/ascribe_forms/form_note_personal.js b/js/components/ascribe_forms/form_note_personal.js deleted file mode 100644 index 7f3c4f2b..00000000 --- a/js/components/ascribe_forms/form_note_personal.js +++ /dev/null @@ -1,43 +0,0 @@ -'use strict'; - -import React from 'react'; - -import apiUrls from '../../constants/api_urls'; -import FormMixin from '../../mixins/form_mixin'; - -import InputTextAreaToggable from './input_textarea_toggable'; - - -let PersonalNoteForm = React.createClass({ - mixins: [FormMixin], - - url() { - return apiUrls.note_notes; - }, - - getFormData() { - return { - bitcoin_id: this.getBitcoinIds().join(), - note: this.refs.personalNote.state.value - }; - }, - - renderForm() { - - return ( -
- - - ); - } -}); - -export default PersonalNoteForm; \ No newline at end of file diff --git a/js/components/ascribe_forms/form_password_reset.js b/js/components/ascribe_forms/form_password_reset.js deleted file mode 100644 index e42689a4..00000000 --- a/js/components/ascribe_forms/form_password_reset.js +++ /dev/null @@ -1,51 +0,0 @@ -'use strict'; - -import React from 'react'; - -import apiUrls from '../../constants/api_urls'; -import FormMixin from '../../mixins/form_mixin'; -import InputText from './input_text'; -import ButtonSubmit from '../ascribe_buttons/button_submit'; -import { getLangText } from '../../utils/lang_utils.js' - -let PasswordResetForm = React.createClass({ - mixins: [FormMixin], - - url() { - return apiUrls.users_password_reset; - }, - - getFormData() { - return { - email: this.props.email, - token: this.props.token, - password: this.refs.password.state.value, - password_confirm: this.refs.password_confirm.state.value - }; - }, - - renderForm() { - return ( -
-
Reset the password for {this.props.email}:
- - - - - ); - } -}); - -export default PasswordResetForm; \ No newline at end of file diff --git a/js/components/ascribe_forms/form_password_reset_request.js b/js/components/ascribe_forms/form_password_reset_request.js deleted file mode 100644 index 7e5ac62b..00000000 --- a/js/components/ascribe_forms/form_password_reset_request.js +++ /dev/null @@ -1,42 +0,0 @@ -'use strict'; - -import React from 'react'; - -import apiUrls from '../../constants/api_urls'; -import FormMixin from '../../mixins/form_mixin'; -import InputText from './input_text'; -import ButtonSubmitOrClose from '../ascribe_buttons/button_submit_close'; -import { getLangText } from '../../utils/lang_utils.js' - -let PasswordResetRequestForm = React.createClass({ - mixins: [FormMixin], - - url() { - return apiUrls.users_password_reset_request; - }, - - getFormData() { - return { - email: this.refs.email.state.value - }; - }, - - renderForm() { - return ( -
- - - - ); - } -}); - -export default PasswordResetRequestForm; diff --git a/js/components/ascribe_forms/form_remove_editions_from_collection.js b/js/components/ascribe_forms/form_remove_editions_from_collection.js index 71607b3d..0ba13975 100644 --- a/js/components/ascribe_forms/form_remove_editions_from_collection.js +++ b/js/components/ascribe_forms/form_remove_editions_from_collection.js @@ -24,8 +24,9 @@ let EditionRemoveFromCollectionForm = React.createClass({

{getLangText('Are you sure you would like to remove these editions from your collection')}?

{getLangText('This is an irrevocable action%s', '.')}

- - + +
); diff --git a/js/components/ascribe_forms/form_share_email.js b/js/components/ascribe_forms/form_share_email.js index 8c01cf6a..cfdce452 100644 --- a/js/components/ascribe_forms/form_share_email.js +++ b/js/components/ascribe_forms/form_share_email.js @@ -2,7 +2,7 @@ import React from 'react'; -import ApiUrls from '../../constants/api_urls'; + import Form from './form'; import Property from './property'; @@ -15,49 +15,27 @@ import { getLangText } from '../../utils/lang_utils.js'; let ShareForm = React.createClass({ propTypes: { + url: React.PropTypes.string, + id: React.PropTypes.string, + message: React.PropTypes.string, editions: React.PropTypes.array, - currentUser: React.PropTypes.object + currentUser: React.PropTypes.object, + onRequestHide: React.PropTypes.func, + handleSuccess: React.PropTypes.func }, - getFormData() { - return { - bitcoin_id: this.getBitcoinIds().join() - }; - }, - handleSuccess(response){ - if ('handleSuccess' in this.props){ - this.props.handleSuccess(response); - } - }, - getBitcoinIds(){ - return this.props.editions.map(function(edition){ - return edition.bitcoin_id; - }); - }, - - getTitlesString(){ - return this.props.editions.map(function(edition){ - return '- \"' + edition.title + ', ' + getLangText('edition') + ' ' + edition.edition_number + '\"\n'; - }); + getFormData(){ + return this.props.id; }, render() { - let title = this.getTitlesString().join(''); - let username = this.props.currentUser.username; - let message = -`${getLangText('Hi')}, -${getLangText('I am sharing')} : -${title}${getLangText('with you')}. - -${getLangText('Truly yours')}, -${username}`; return (

@@ -73,9 +51,7 @@ ${username}`; spinner={

-
- } - > + }> @@ -91,7 +67,7 @@ ${username}`; diff --git a/js/components/ascribe_modal/modal_login.js b/js/components/ascribe_modal/modal_login.js deleted file mode 100644 index 70fe9ece..00000000 --- a/js/components/ascribe_modal/modal_login.js +++ /dev/null @@ -1,33 +0,0 @@ -'use strict'; - -import React from 'react'; - -import ModalWrapper from './modal_wrapper'; -import LoginForm from '../ascribe_forms/form_login'; - -import GlobalNotificationModel from '../../models/global_notification_model'; -import GlobalNotificationActions from '../../actions/global_notification_actions'; -import { getLangText } from '../../utils/lang_utils.js' - -let LoginModal = React.createClass({ - handleLoginSuccess(){ - this.props.handleSuccess(); - let notificationText = getLangText('Login successful'); - let notification = new GlobalNotificationModel(notificationText, 'success'); - GlobalNotificationActions.appendGlobalNotification(notification); - }, - - render() { - return ( - - - - ); - } -}); - -export default LoginModal; diff --git a/js/components/ascribe_modal/modal_signup.js b/js/components/ascribe_modal/modal_signup.js deleted file mode 100644 index 49f3cde5..00000000 --- a/js/components/ascribe_modal/modal_signup.js +++ /dev/null @@ -1,32 +0,0 @@ -'use strict'; - -import React from 'react'; - -import ModalWrapper from './modal_wrapper'; -import SignupForm from '../ascribe_forms/form_signup'; - -import GlobalNotificationModel from '../../models/global_notification_model'; -import GlobalNotificationActions from '../../actions/global_notification_actions'; -import { getLangText } from '../../utils/lang_utils.js' - -let SignupModal = React.createClass({ - handleSignupSuccess(response){ - let notificationText = getLangText('We sent an email to your address') + ' ' + response.user.email + ', ' + getLangText('please confirm') + '.'; - let notification = new GlobalNotificationModel(notificationText, 'success', 50000); - GlobalNotificationActions.appendGlobalNotification(notification); - }, - - render() { - return ( - - - - ); - } -}); - -export default SignupModal; diff --git a/js/constants/api_urls.js b/js/constants/api_urls.js index b5d9a9eb..6d3ce7c8 100644 --- a/js/constants/api_urls.js +++ b/js/constants/api_urls.js @@ -12,7 +12,7 @@ let apiUrls = { 'coa_verify': AppConstants.apiEndpoint + 'coa/verify_coa/', 'edition': AppConstants.apiEndpoint + 'editions/${bitcoin_id}/', 'edition_delete': AppConstants.apiEndpoint + 'editions/${edition_id}/', - 'edition_remove_from_collection': AppConstants.apiEndpoint + 'ownership/shares/${edition_id}/', + 'edition_remove_from_collection': AppConstants.apiEndpoint + 'ownership/shares/editions/${edition_id}/', 'editions': AppConstants.apiEndpoint + 'editions/', // this should be moved to the one below 'editions_list': AppConstants.apiEndpoint + 'pieces/${piece_id}/editions/', 'licenses': AppConstants.apiEndpoint + 'ownership/licenses/', @@ -26,6 +26,7 @@ let apiUrls = { 'ownership_loans_deny': AppConstants.apiEndpoint + 'ownership/loans/deny/', 'ownership_loans_contract': AppConstants.apiEndpoint + 'ownership/loans/contract/', 'ownership_shares_editions': AppConstants.apiEndpoint + 'ownership/shares/editions/', + 'ownership_shares_pieces': AppConstants.apiEndpoint + 'ownership/shares/pieces/', 'ownership_transfers': AppConstants.apiEndpoint + 'ownership/transfers/', 'ownership_transfers_withdraw': AppConstants.apiEndpoint + 'ownership/transfers/withdraw/', 'ownership_unconsigns': AppConstants.apiEndpoint + 'ownership/unconsigns/', diff --git a/sass/ascribe_accordion_list.scss b/sass/ascribe_accordion_list.scss index 6a8208ce..962358f2 100644 --- a/sass/ascribe_accordion_list.scss +++ b/sass/ascribe_accordion_list.scss @@ -93,7 +93,7 @@ $ascribe-accordion-list-font: 'Source Sans Pro'; } } border-left: 3px solid rgba(0,0,0,0); - border-top: 1px solid rgba(0,0,0,.1); + //border-top: 1px solid rgba(0,0,0,.1); border-bottom: 1px solid rgba(0,0,0,.05); } tbody {