diff --git a/js/components/edition.js b/js/components/edition.js
index e69de29b..682e0c9b 100644
--- a/js/components/edition.js
+++ b/js/components/edition.js
@@ -0,0 +1,525 @@
+'use strict';
+
+import React from 'react';
+import Router from 'react-router';
+
+import Row from 'react-bootstrap/lib/Row';
+import Col from 'react-bootstrap/lib/Col';
+import Button from 'react-bootstrap/lib/Button';
+import Glyphicon from 'react-bootstrap/lib/Glyphicon';
+
+import UserActions from '../actions/user_actions';
+import UserStore from '../stores/user_store';
+import CoaActions from '../actions/coa_actions';
+import CoaStore from '../stores/coa_store';
+
+import MediaPlayer from './ascribe_media/media_player';
+
+import CollapsibleParagraph from './ascribe_collapsible/collapsible_paragraph';
+
+import Form from './ascribe_forms/form';
+import Property from './ascribe_forms/property';
+import InputTextAreaToggable from './ascribe_forms/input_textarea_toggable';
+
+import PieceExtraDataForm from './ascribe_forms/form_piece_extradata';
+import RequestActionForm from './ascribe_forms/form_request_action';
+
+import EditionActions from '../actions/edition_actions';
+import AclButtonList from './ascribe_buttons/acl_button_list';
+
+import GlobalNotificationModel from '../models/global_notification_model';
+import GlobalNotificationActions from '../actions/global_notification_actions';
+
+import apiUrls from '../constants/api_urls';
+import AppConstants from '../constants/application_constants';
+
+let Link = Router.Link;
+/**
+ * This is the component that implements display-specific functionality
+ */
+let Edition = React.createClass({
+ propTypes: {
+ edition: React.PropTypes.object,
+ loadEdition: React.PropTypes.func
+ },
+
+ getInitialState() {
+ return UserStore.getState();
+ },
+
+ componentDidMount() {
+ UserStore.listen(this.onChange);
+ UserActions.fetchCurrentUser();
+ },
+
+ componentWillUnmount() {
+ UserStore.unlisten(this.onChange);
+ },
+
+ onChange(state) {
+ this.setState(state);
+ },
+
+ render() {
+ let thumbnail = this.props.edition.thumbnail;
+ let mimetype = this.props.edition.digital_work.mime;
+ let extraData = null;
+
+ if (this.props.edition.digital_work.encoding_urls) {
+ extraData = this.props.edition.digital_work.encoding_urls.map(e => { return { url: e.url, type: e.label }; });
+ }
+
+ let bitcoinIdValue = (
+ {this.props.edition.bitcoin_id}
+ );
+
+ let hashOfArtwork = (
+ {this.props.edition.hash_as_address}
+ );
+
+ let ownerAddress = (
+ {this.props.edition.btc_owner_address_noprefix}
+ );
+
+ return (
+
+
+
+
+
+
+
+
+
+
+
+ -1 || this.props.edition.public_note)}>
+
+
+
+
+ -1 || Object.keys(this.props.edition.extra_data).length > 0}>
+
+
+
+ -1}>
+
+
+
+ 0}>
+
+
+
+ 0}>
+
+
+
+ 0}>
+
+
+
+
+
+
+
+
+ );
+ }
+});
+
+let EditionHeader = React.createClass({
+ propTypes: {
+ edition: React.PropTypes.object
+ },
+
+ render() {
+ var titleHtml =
{this.props.edition.title}
;
+ return (
+
+
+
+
+
+
+ );
+ }
+});
+
+
+let EditionSummary = React.createClass({
+ propTypes: {
+ edition: React.PropTypes.object
+ },
+
+ handleSuccess(){
+ EditionActions.fetchOne(this.props.edition.id);
+ },
+ showNotification(response){
+ this.handleSuccess();
+ let notification = new GlobalNotificationModel(response.notification, 'success');
+ GlobalNotificationActions.appendGlobalNotification(notification);
+ },
+ render() {
+ let status = null;
+ if (this.props.edition.status.length > 0){
+ let statusStr = this.props.edition.status.join().replace(/_/, ' ');
+ let statusAction = null;
+ if (this.props.edition.pending_new_owner && this.props.edition.acl.indexOf('withdraw_transfer') > -1){
+ statusAction = (
+
+ );
+ }
+ status =(
+
+ {statusAction}
+ );
+ }
+ let actions = null;
+ if (this.props.edition.request_action && this.props.edition.request_action.length > 0){
+ actions = (
+ );
+ }
+ else {
+ actions = (
+
+
+
+
+
);
+ }
+
+ return (
+
+
+
+
+ {status}
+
+ {actions}
+
+
+ );
+
+ }
+});
+
+
+let EditionDetailProperty = React.createClass({
+ propTypes: {
+ label: React.PropTypes.string,
+ value: React.PropTypes.oneOfType([
+ React.PropTypes.string,
+ React.PropTypes.element
+ ]),
+ separator: React.PropTypes.string,
+ labelClassName: React.PropTypes.string,
+ valueClassName: React.PropTypes.string
+ },
+
+ getDefaultProps() {
+ return {
+ separator: ':',
+ labelClassName: 'col-xs-5 col-sm-4 col-md-3 col-lg-3',
+ valueClassName: 'col-xs-7 col-sm-8 col-md-9 col-lg-9'
+ };
+ },
+
+ render() {
+ let value = this.props.value;
+ if (this.props.children){
+ value = (
+
+
+ { this.props.value }
+
+
+ { this.props.children }
+
+
);
+ }
+ return (
+
+
+
+
{ this.props.label + this.props.separator}
+
+
+ {value}
+
+
+
+ );
+ }
+});
+
+let EditionDetailHistoryIterator = React.createClass({
+ propTypes: {
+ history: React.PropTypes.array
+ },
+
+ render() {
+ return (
+
+ );
+ }
+});
+
+let EditionPersonalNote = React.createClass({
+ propTypes: {
+ edition: React.PropTypes.object,
+ currentUser: React.PropTypes.object,
+ handleSuccess: React.PropTypes.func
+ },
+ showNotification(){
+ this.props.handleSuccess();
+ let notification = new GlobalNotificationModel('Private note saved', 'success');
+ GlobalNotificationActions.appendGlobalNotification(notification);
+ },
+
+ render() {
+ if (this.props.currentUser.username && true || false) {
+ return (
+
+ );
+ }
+ return null;
+ }
+});
+
+let EditionPublicEditionNote = React.createClass({
+ propTypes: {
+ edition: React.PropTypes.object,
+ handleSuccess: React.PropTypes.func
+ },
+ showNotification(){
+ this.props.handleSuccess();
+ let notification = new GlobalNotificationModel('Public note saved', 'success');
+ GlobalNotificationActions.appendGlobalNotification(notification);
+ },
+ render() {
+ let isEditable = this.props.edition.acl.indexOf('edit') > -1;
+ if (this.props.edition.acl.indexOf('edit') > -1 || this.props.edition.public_note){
+ return (
+
+ );
+ }
+ return null;
+ }
+});
+
+
+let EditionFurtherDetails = React.createClass({
+ propTypes: {
+ edition: React.PropTypes.object,
+ handleSuccess: React.PropTypes.func
+ },
+ showNotification(){
+ this.props.handleSuccess();
+ let notification = new GlobalNotificationModel('Details updated', 'success');
+ GlobalNotificationActions.appendGlobalNotification(notification);
+ },
+
+ render() {
+ let editable = this.props.edition.acl.indexOf('edit') > -1;
+ return (
+
+
+
+
+
+
+
+ );
+ }
+});
+
+let CoaDetails = React.createClass({
+ propTypes: {
+ edition: React.PropTypes.object
+ },
+
+ getInitialState() {
+ return CoaStore.getState();
+ },
+
+ componentDidMount() {
+ CoaStore.listen(this.onChange);
+ if (this.props.edition.coa) {
+ CoaActions.fetchOne(this.props.edition.coa);
+ }
+ else{
+ console.log('create coa');
+ CoaActions.create(this.props.edition);
+ }
+ },
+
+ componentWillUnmount() {
+ CoaStore.unlisten(this.onChange);
+ },
+
+ onChange(state) {
+ this.setState(state);
+ },
+
+ render() {
+ if (this.state.coa.url_safe) {
+ return (
+
+
+
+
+
+
+
+
+
+ );
+ }
+ return (
+
+

+
);
+
+ }
+});
+
+export default Edition;