mirror of
https://github.com/ascribe/onion.git
synced 2024-11-15 01:25:17 +01:00
Merge branch 'tmp2' into AD-456-ikonotv-branded-page-for-registra
This commit is contained in:
commit
6d8d318e8d
@ -15,6 +15,8 @@ import GlobalNotificationActions from '../../actions/global_notification_actions
|
||||
|
||||
import FurtherDetailsFileuploader from './further_details_fileuploader';
|
||||
|
||||
import { isReadyForFormSubmission } from '../ascribe_uploader/react_s3_fine_uploader_utils';
|
||||
|
||||
let FurtherDetails = React.createClass({
|
||||
propTypes: {
|
||||
editable: React.PropTypes.bool,
|
||||
@ -48,15 +50,6 @@ let FurtherDetails = React.createClass({
|
||||
});
|
||||
},
|
||||
|
||||
isReadyForFormSubmission(files) {
|
||||
files = files.filter((file) => file.status !== 'deleted' && file.status !== 'canceled');
|
||||
if(files.length > 0 && files[0].status === 'upload successful') {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
||||
render() {
|
||||
//return (<span />);
|
||||
return (
|
||||
@ -88,7 +81,7 @@ let FurtherDetails = React.createClass({
|
||||
<FurtherDetailsFileuploader
|
||||
submitKey={this.submitKey}
|
||||
setIsUploadReady={this.setIsUploadReady}
|
||||
isReadyForFormSubmission={this.isReadyForFormSubmission}
|
||||
isReadyForFormSubmission={isReadyForFormSubmission}
|
||||
editable={this.props.editable}
|
||||
pieceId={this.props.pieceId}
|
||||
otherData={this.props.otherData}
|
||||
|
@ -16,6 +16,7 @@ import ApiUrls from '../../constants/api_urls';
|
||||
import { getCookie } from '../../utils/fetch_api_utils';
|
||||
import { getLangText } from '../../utils/lang_utils';
|
||||
import { mergeOptions } from '../../utils/general_utils';
|
||||
import { isReadyForFormSubmission } from '../ascribe_uploader/react_s3_fine_uploader_utils';
|
||||
|
||||
|
||||
let RegisterPieceForm = React.createClass({
|
||||
@ -24,6 +25,7 @@ let RegisterPieceForm = React.createClass({
|
||||
submitMessage: React.PropTypes.string,
|
||||
handleSuccess: React.PropTypes.func,
|
||||
isFineUploaderActive: React.PropTypes.bool,
|
||||
isFineUploaderEditable: React.PropTypes.bool,
|
||||
enableLocalHashing: React.PropTypes.bool,
|
||||
children: React.PropTypes.element,
|
||||
onLoggedOut: React.PropTypes.func
|
||||
@ -78,15 +80,6 @@ let RegisterPieceForm = React.createClass({
|
||||
});
|
||||
},
|
||||
|
||||
isReadyForFormSubmission(files) {
|
||||
files = files.filter((file) => file.status !== 'deleted' && file.status !== 'canceled');
|
||||
if (files.length > 0 && files[0].status === 'upload successful') {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
||||
render() {
|
||||
let currentUser = this.state.currentUser;
|
||||
let enableLocalHashing = currentUser && currentUser.profile ? currentUser.profile.hash_locally : false;
|
||||
@ -117,7 +110,7 @@ let RegisterPieceForm = React.createClass({
|
||||
<FileUploader
|
||||
submitKey={this.submitKey}
|
||||
setIsUploadReady={this.setIsUploadReady}
|
||||
isReadyForFormSubmission={this.isReadyForFormSubmission}
|
||||
isReadyForFormSubmission={isReadyForFormSubmission}
|
||||
isFineUploaderActive={this.props.isFineUploaderActive}
|
||||
onLoggedOut={this.props.onLoggedOut}
|
||||
editable={this.props.isFineUploaderEditable}
|
||||
|
@ -145,7 +145,10 @@ let SlidesContainer = React.createClass({
|
||||
<div className="no-margin row ascribe-breadcrumb-container">
|
||||
{this.props.breadcrumbs.map((breadcrumb, i) => {
|
||||
return (
|
||||
<Col className="no-padding" sm={columnWidth}>
|
||||
<Col
|
||||
className="no-padding"
|
||||
sm={columnWidth}
|
||||
key={i}>
|
||||
<div className="ascribe-breadcrumb">
|
||||
<a className={this.state.slideNum === i ? 'active' : ''}>
|
||||
{this.props.breadcrumbs[i]}
|
||||
|
@ -57,7 +57,13 @@ let FileDragAndDropDialog = React.createClass({
|
||||
if(this.props.multipleFiles) {
|
||||
return (
|
||||
<span className="file-drag-and-drop-dialog">
|
||||
{getLangText('Click or drag to add files')}
|
||||
<p>{getLangText('Drag files here')}</p>
|
||||
<p>{getLangText('or')}</p>
|
||||
<span
|
||||
className="btn btn-default"
|
||||
onClick={this.props.onClick}>
|
||||
{getLangText('choose files to upload')}
|
||||
</span>
|
||||
</span>
|
||||
);
|
||||
} else {
|
||||
|
@ -435,7 +435,9 @@ var ReactS3FineUploader = React.createClass({
|
||||
},
|
||||
|
||||
onCancel(id) {
|
||||
this.removeFileWithIdFromFilesToUpload(id);
|
||||
|
||||
// when a upload is canceled, we need to update this components file array
|
||||
this.setStatusOfFile(id, 'canceled');
|
||||
|
||||
let notification = new GlobalNotificationModel(getLangText('File upload canceled'), 'success', 5000);
|
||||
GlobalNotificationActions.appendGlobalNotification(notification);
|
||||
@ -455,6 +457,7 @@ var ReactS3FineUploader = React.createClass({
|
||||
},
|
||||
|
||||
onProgress(id, name, uploadedBytes, totalBytes) {
|
||||
|
||||
let newState = React.addons.update(this.state, {
|
||||
filesToUpload: { [id]: {
|
||||
progress: { $set: (uploadedBytes / totalBytes) * 100} }
|
||||
@ -498,7 +501,9 @@ var ReactS3FineUploader = React.createClass({
|
||||
let notification = new GlobalNotificationModel(getLangText('Couldn\'t delete file'), 'danger', 10000);
|
||||
GlobalNotificationActions.appendGlobalNotification(notification);
|
||||
} else {
|
||||
this.removeFileWithIdFromFilesToUpload(id);
|
||||
|
||||
// To hide the file in this component, we need to set it's status to "deleted"
|
||||
this.setStatusOfFile(id, 'deleted');
|
||||
|
||||
let notification = new GlobalNotificationModel(getLangText('File deleted'), 'success', 5000);
|
||||
GlobalNotificationActions.appendGlobalNotification(notification);
|
||||
@ -521,7 +526,8 @@ var ReactS3FineUploader = React.createClass({
|
||||
},
|
||||
|
||||
handleDeleteFile(fileId) {
|
||||
// In some instances (when the file was already uploaded and is just displayed to the user)
|
||||
// In some instances (when the file was already uploaded and is just displayed to the user
|
||||
// - for example in the loan contract or additional files dialog)
|
||||
// fineuploader does not register an id on the file (we do, don't be confused by this!).
|
||||
// Since you can only delete a file by its id, we have to implement this method ourselves
|
||||
//
|
||||
@ -532,7 +538,7 @@ var ReactS3FineUploader = React.createClass({
|
||||
if(this.state.filesToUpload[fileId].status !== 'online') {
|
||||
// delete file from server
|
||||
this.state.uploader.deleteFile(fileId);
|
||||
// this is being continues in onDeleteFile, as
|
||||
// this is being continued in onDeleteFile, as
|
||||
// fineuploaders deleteFile does not return a correct callback or
|
||||
// promise
|
||||
} else {
|
||||
@ -739,31 +745,23 @@ var ReactS3FineUploader = React.createClass({
|
||||
this.setState(newState);
|
||||
},
|
||||
|
||||
removeFileWithIdFromFilesToUpload(fileId) {
|
||||
// also, sync files from state with the ones from fineuploader
|
||||
let filesToUpload = JSON.parse(JSON.stringify(this.state.filesToUpload));
|
||||
|
||||
// splice because I can
|
||||
filesToUpload.splice(fileId, 1);
|
||||
|
||||
// set state
|
||||
let newState = React.addons.update(this.state, {
|
||||
filesToUpload: { $set: filesToUpload }
|
||||
});
|
||||
this.setState(newState);
|
||||
},
|
||||
|
||||
setStatusOfFile(fileId, status) {
|
||||
// also, sync files from state with the ones from fineuploader
|
||||
let filesToUpload = JSON.parse(JSON.stringify(this.state.filesToUpload));
|
||||
|
||||
// splice because I can
|
||||
filesToUpload[fileId].status = status;
|
||||
|
||||
// is status is set to deleted or canceled, we also need to reset the progress
|
||||
// back to zero
|
||||
if(status === 'deleted' || status === 'canceled') {
|
||||
filesToUpload[fileId].progress = 0;
|
||||
}
|
||||
|
||||
// set state
|
||||
let newState = React.addons.update(this.state, {
|
||||
filesToUpload: { $set: filesToUpload }
|
||||
});
|
||||
|
||||
this.setState(newState);
|
||||
},
|
||||
|
||||
|
@ -0,0 +1,16 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Returns a boolean if there has been at least one file uploaded
|
||||
* successfully without it being deleted or canceled.
|
||||
* @param {array of files} files provided by react fine uploader
|
||||
* @return {Boolean}
|
||||
*/
|
||||
export function isReadyForFormSubmission(files) {
|
||||
files = files.filter((file) => file.status !== 'deleted' && file.status !== 'canceled');
|
||||
if (files.length > 0 && files[0].status === 'upload successful') {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
@ -3,16 +3,42 @@
|
||||
import React from 'react';
|
||||
import classNames from 'classnames';
|
||||
|
||||
import Moment from 'moment';
|
||||
|
||||
import WhitelabelActions from '../../../../../../actions/whitelabel_actions';
|
||||
import WhitelabelStore from '../../../../../../stores/whitelabel_store';
|
||||
|
||||
import ModalWrapper from '../../../../../ascribe_modal/modal_wrapper';
|
||||
import CylandPieceSubmitForm from '../ascribe_forms/cyland_form_submit';
|
||||
import LoanForm from '../../../../../ascribe_forms/form_loan';
|
||||
|
||||
import ApiUrls from '../../../../../../constants/api_urls';
|
||||
|
||||
import { getLangText } from '../../../../../../utils/lang_utils';
|
||||
import { getAclFormMessage } from '../../../../../../utils/form_utils';
|
||||
|
||||
let CylandSubmitButton = React.createClass({
|
||||
propTypes: {
|
||||
className: React.PropTypes.string,
|
||||
handleSuccess: React.PropTypes.func,
|
||||
piece: React.PropTypes.object.isRequired
|
||||
piece: React.PropTypes.object.isRequired,
|
||||
username: React.PropTypes.string
|
||||
},
|
||||
|
||||
getInitialState() {
|
||||
return WhitelabelStore.getState();
|
||||
},
|
||||
|
||||
componentDidMount() {
|
||||
WhitelabelStore.listen(this.onChange);
|
||||
WhitelabelActions.fetchWhitelabel();
|
||||
},
|
||||
|
||||
componentWillUnmount() {
|
||||
WhitelabelStore.unlisten(this.onChange);
|
||||
},
|
||||
|
||||
onChange(state) {
|
||||
this.setState(state);
|
||||
},
|
||||
|
||||
getSubmitButton() {
|
||||
@ -25,16 +51,26 @@ let CylandSubmitButton = React.createClass({
|
||||
},
|
||||
|
||||
render() {
|
||||
let today = new Moment();
|
||||
let loanEndDate = new Moment();
|
||||
loanEndDate.add(1000, 'years');
|
||||
|
||||
return (
|
||||
<ModalWrapper
|
||||
trigger={this.getSubmitButton()}
|
||||
handleSuccess={this.props.handleSuccess}
|
||||
title={getLangText('Submit to Cyland')}>
|
||||
<CylandPieceSubmitForm
|
||||
piece={this.props.piece}
|
||||
<LoanForm
|
||||
message={getAclFormMessage('acl_loan', '\"' + this.props.piece.title + '\"', this.props.username)}
|
||||
id={{piece_id: this.props.piece.id}}
|
||||
url={ApiUrls.ownership_loans_pieces}
|
||||
email={this.state.whitelabel.user}
|
||||
gallery="Cyland Archive"
|
||||
startdate={today}
|
||||
enddate={loanEndDate}
|
||||
showPersonalMessage={false}
|
||||
handleSuccess={this.props.handleSuccess}/>
|
||||
</ModalWrapper>
|
||||
|
||||
);
|
||||
}
|
||||
});
|
||||
|
@ -43,6 +43,7 @@ let CylandAdditionalDataForm = React.createClass({
|
||||
extradata: extradata,
|
||||
piece_id: this.props.piece.id
|
||||
};
|
||||
|
||||
},
|
||||
|
||||
setIsUploadReady(isReady) {
|
||||
@ -51,8 +52,15 @@ let CylandAdditionalDataForm = React.createClass({
|
||||
});
|
||||
},
|
||||
|
||||
isReadyForFormSubmission() {
|
||||
return true;
|
||||
isReadyForFormSubmission(files) {
|
||||
let uploadedFiles = files.filter((file) => file.status === 'upload successful');
|
||||
let uploadingFiles = files.filter((file) => file.status === 'submitting');
|
||||
|
||||
if (uploadedFiles.length > 0 && uploadingFiles.length === 0) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
||||
render() {
|
||||
|
@ -1,89 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import Form from '../../../../../ascribe_forms/form';
|
||||
import Property from '../../../../../ascribe_forms/property';
|
||||
import InputTextAreaToggable from '../../../../../ascribe_forms/input_textarea_toggable';
|
||||
import InputCheckbox from '../../../../../ascribe_forms/input_checkbox';
|
||||
|
||||
import Alert from 'react-bootstrap/lib/Alert';
|
||||
|
||||
import AppConstants from '../../../../../../constants/application_constants';
|
||||
import ApiUrls from '../../../../../../constants/api_urls';
|
||||
|
||||
import { getLangText } from '../../../../../../utils/lang_utils.js';
|
||||
|
||||
import requests from '../../../../../../utils/requests';
|
||||
|
||||
let CylandPieceSubmitForm = React.createClass({
|
||||
propTypes: {
|
||||
piece: React.PropTypes.object,
|
||||
handleSuccess: React.PropTypes.func
|
||||
},
|
||||
|
||||
render() {
|
||||
//return (
|
||||
// <Form
|
||||
// ref='form'
|
||||
// url={requests.prepareUrl(ApiUrls.piece_submit_to_prize, {piece_id: this.props.piece.id})}
|
||||
// handleSuccess={this.props.handleSuccess}
|
||||
// buttons={
|
||||
// <div className="modal-footer">
|
||||
// <p className="pull-right">
|
||||
// <button
|
||||
// className="btn btn-default btn-sm ascribe-margin-1px"
|
||||
// type="submit">
|
||||
// {getLangText('SUBMIT TO PRIZE')}
|
||||
// </button>
|
||||
// </p>
|
||||
// </div>}
|
||||
// spinner={
|
||||
// <div className="modal-footer">
|
||||
// <img src={AppConstants.baseUrl + 'static/img/ascribe_animated_small.gif'} />
|
||||
// </div>}>
|
||||
// <Property
|
||||
// name='artist_statement'
|
||||
// label={getLangText('Artist statement')}
|
||||
// editable={true}>
|
||||
// <InputTextAreaToggable
|
||||
// rows={1}
|
||||
// editable={true}
|
||||
// placeholder={getLangText('Enter your statement')}
|
||||
// required="required"/>
|
||||
// </Property>
|
||||
// <Property
|
||||
// name='work_description'
|
||||
// label={getLangText('Work description')}
|
||||
// editable={true}>
|
||||
// <InputTextAreaToggable
|
||||
// rows={1}
|
||||
// editable={true}
|
||||
// placeholder={getLangText('Enter the description for your work')}
|
||||
// required="required"/>
|
||||
// </Property>
|
||||
// <Property
|
||||
// name="terms"
|
||||
// className="ascribe-settings-property-collapsible-toggle"
|
||||
// style={{paddingBottom: 0}}>
|
||||
// <InputCheckbox>
|
||||
// <span>
|
||||
// {' ' + getLangText('I agree to the Terms of Service the art price') + ' '}
|
||||
// (<a href="https://s3-us-west-2.amazonaws.com/ascribe0/whitelabel/sluice/terms.pdf" target="_blank" style={{fontSize: '0.9em', color: 'rgba(0,0,0,0.7)'}}>
|
||||
// {getLangText('read')}
|
||||
// </a>)
|
||||
// </span>
|
||||
// </InputCheckbox>
|
||||
// </Property>
|
||||
// <Alert bsStyle='warning'>
|
||||
// <p>{getLangText('Are you sure you want to submit to the prize?')}</p>
|
||||
// <p>{getLangText('This is an irrevocable action%s', '.')}</p>
|
||||
// </Alert>
|
||||
// </Form>
|
||||
//);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
export default CylandPieceSubmitForm;
|
@ -0,0 +1,20 @@
|
||||
'use strict';
|
||||
|
||||
import React from 'react';
|
||||
import constants from '../../../../constants/application_constants';
|
||||
|
||||
|
||||
let Hero = React.createClass({
|
||||
render() {
|
||||
return (
|
||||
<div className="hero">
|
||||
<img
|
||||
className="logo" src={constants.whitelabel.logo}
|
||||
alt="Sluice Art Prize"
|
||||
height="200px"/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
export default Hero;
|
@ -0,0 +1,77 @@
|
||||
'use strict';
|
||||
|
||||
import React from 'react';
|
||||
import Router from 'react-router';
|
||||
|
||||
import ButtonLink from 'react-router-bootstrap/lib/ButtonLink';
|
||||
import ButtonGroup from 'react-bootstrap/lib/ButtonGroup';
|
||||
|
||||
import UserStore from '../../../../../stores/user_store';
|
||||
import UserActions from '../../../../../actions/user_actions';
|
||||
|
||||
import { mergeOptions } from '../../../../../utils/general_utils';
|
||||
|
||||
|
||||
let CylandLanding = React.createClass({
|
||||
|
||||
mixins: [Router.Navigation],
|
||||
|
||||
getInitialState() {
|
||||
return mergeOptions(
|
||||
UserStore.getState()
|
||||
);
|
||||
},
|
||||
|
||||
componentDidMount() {
|
||||
UserStore.listen(this.onChange);
|
||||
UserActions.fetchCurrentUser();
|
||||
},
|
||||
|
||||
componentWillUnmount() {
|
||||
UserStore.unlisten(this.onChange);
|
||||
},
|
||||
|
||||
onChange(state) {
|
||||
this.setState(state);
|
||||
|
||||
// if user is already logged in, redirect him to piece list
|
||||
if(this.state.currentUser && this.state.currentUser.email) {
|
||||
// FIXME: hack to redirect out of the dispatch cycle
|
||||
window.setTimeout(() => this.replaceWith('pieces'), 0);
|
||||
}
|
||||
},
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className="container ascribe-form-wrapper">
|
||||
<div className="row">
|
||||
<div className="col-xs-12 wp-landing-wrapper">
|
||||
<div className="row">
|
||||
<img src="https://s3.amazonaws.com/upload.uxpin/files/308247/312701/logo.gif" />
|
||||
</div>
|
||||
<div className="row">
|
||||
<div className="col-sm-6">
|
||||
<div>
|
||||
Existing ascribe user?
|
||||
</div>
|
||||
<ButtonLink to="login">
|
||||
Log in
|
||||
</ButtonLink>
|
||||
</div>
|
||||
<div className="col-sm-6">
|
||||
<div>
|
||||
Do you need an account?
|
||||
</div>
|
||||
<ButtonLink to="signup">
|
||||
Sign up
|
||||
</ButtonLink>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
export default CylandLanding;
|
@ -85,17 +85,6 @@ let CylandRegisterPiece = React.createClass({
|
||||
|
||||
handleRegisterSuccess(response){
|
||||
|
||||
// once the user was able to register a piece successfully, we need to make sure to keep
|
||||
// the piece list up to date
|
||||
PieceListActions.fetchPieceList(
|
||||
this.state.page,
|
||||
this.state.pageSize,
|
||||
this.state.searchTerm,
|
||||
this.state.orderBy,
|
||||
this.state.orderAsc,
|
||||
this.state.filterBy
|
||||
);
|
||||
|
||||
// also start loading the piece for the next step
|
||||
if(response && response.piece) {
|
||||
PieceActions.updatePiece(response.piece);
|
||||
@ -111,6 +100,18 @@ let CylandRegisterPiece = React.createClass({
|
||||
handleLoanSuccess(response) {
|
||||
let notification = new GlobalNotificationModel(response.notification, 'success', 10000);
|
||||
GlobalNotificationActions.appendGlobalNotification(notification);
|
||||
|
||||
// once the user was able to register + loan a piece successfully, we need to make sure to keep
|
||||
// the piece list up to date
|
||||
PieceListActions.fetchPieceList(
|
||||
this.state.page,
|
||||
this.state.pageSize,
|
||||
this.state.searchTerm,
|
||||
this.state.orderBy,
|
||||
this.state.orderAsc,
|
||||
this.state.filterBy
|
||||
);
|
||||
|
||||
PieceActions.fetchOne(this.state.piece.id);
|
||||
this.transitionTo('piece', {pieceId: this.state.piece.id});
|
||||
},
|
||||
|
@ -30,6 +30,7 @@
|
||||
border: 1px solid #EEE;
|
||||
border-right: 1px solid rgba(0, 0, 0, 0);
|
||||
margin-bottom: 0.6em;
|
||||
background-color: white;
|
||||
|
||||
.active {
|
||||
color: #666;
|
||||
|
@ -41,6 +41,9 @@
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
|
||||
margin-left: .7em;
|
||||
margin-right: .7em;
|
||||
|
||||
.delete-file {
|
||||
display: block;
|
||||
background-color: black;
|
||||
|
Loading…
Reference in New Issue
Block a user