mirror of
https://github.com/ascribe/onion.git
synced 2025-02-14 21:10:27 +01:00
coa renders per page
verify
This commit is contained in:
parent
1c116bc7be
commit
fba30a565b
36
js/actions/coa_actions.js
Normal file
36
js/actions/coa_actions.js
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
import alt from '../alt';
|
||||||
|
import CoaFetcher from '../fetchers/coa_fetcher';
|
||||||
|
|
||||||
|
|
||||||
|
class CoaActions {
|
||||||
|
constructor() {
|
||||||
|
this.generateActions(
|
||||||
|
'updateCoa'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
fetchOne(id) {
|
||||||
|
CoaFetcher.fetchOne(id)
|
||||||
|
.then((res) => {
|
||||||
|
this.actions.updateCoa(res.coa);
|
||||||
|
console.log(res.coa);
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
console.log(err);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
create(edition) {
|
||||||
|
CoaFetcher.create(edition.bitcoin_id)
|
||||||
|
.then((res) => {
|
||||||
|
this.actions.updateCoa(res.coa);
|
||||||
|
console.log(res.coa);
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
console.log(err);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default alt.createActions(CoaActions);
|
101
js/components/coa_verify_container.js
Normal file
101
js/components/coa_verify_container.js
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
import Router from 'react-router';
|
||||||
|
|
||||||
|
import GlobalNotificationModel from '../models/global_notification_model';
|
||||||
|
import GlobalNotificationActions from '../actions/global_notification_actions';
|
||||||
|
|
||||||
|
import Form from './ascribe_forms/form';
|
||||||
|
import Property from './ascribe_forms/property';
|
||||||
|
import InputTextAreaToggable from './ascribe_forms/input_textarea_toggable';
|
||||||
|
|
||||||
|
import apiUrls from '../constants/api_urls';
|
||||||
|
|
||||||
|
|
||||||
|
let CoaVerifyContainer = React.createClass({
|
||||||
|
mixins: [Router.Navigation],
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<div className="ascribe-login-wrapper">
|
||||||
|
<br/>
|
||||||
|
<div className="ascribe-login-text ascribe-login-header">
|
||||||
|
Verify your Certificate of Authenticity
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<CoaVerifyForm />
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
ascribe is using the following public key for verification:
|
||||||
|
<br />
|
||||||
|
<pre>
|
||||||
|
-----BEGIN PUBLIC KEY-----
|
||||||
|
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDddadqY31kKPFYk8PQA8BWSTbm
|
||||||
|
gaGf9KEYBALp2nWAJcwq80qBzGF+gfi0Z+yb4ooeKHl27GnuxZYValE1Z5ZujfeJ
|
||||||
|
TgO4li59ZMYiah8oXZp/OysrBwCvWw0PtWd8/D9Nc4PqyOz5gzEh6kFah5VsuAke
|
||||||
|
Znu2w7KmeLZ85SmwEQIDAQAB
|
||||||
|
-----END PUBLIC KEY-----
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
let CoaVerifyForm = React.createClass({
|
||||||
|
mixins: [Router.Navigation],
|
||||||
|
|
||||||
|
handleSuccess(response){
|
||||||
|
let notification = null;
|
||||||
|
if (response.verdict){
|
||||||
|
notification = new GlobalNotificationModel('Certificate of Authenticity successfully verified', 'success');
|
||||||
|
GlobalNotificationActions.appendGlobalNotification(notification);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<Form
|
||||||
|
url={apiUrls.coa_verify}
|
||||||
|
handleSuccess={this.handleSuccess}
|
||||||
|
buttons={
|
||||||
|
<button
|
||||||
|
type="submit"
|
||||||
|
className="btn ascribe-btn ascribe-btn-login">
|
||||||
|
Verify your Certificate of Authenticity
|
||||||
|
</button>}
|
||||||
|
spinner={
|
||||||
|
<button className="btn ascribe-btn ascribe-btn-login ascribe-btn-login-spinner">
|
||||||
|
<img src="https://s3-us-west-2.amazonaws.com/ascribe0/media/thumbnails/ascribe_animated_medium.gif" />
|
||||||
|
</button>
|
||||||
|
}>
|
||||||
|
<Property
|
||||||
|
name='message'
|
||||||
|
label="Message">
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
placeholder="Copy paste the message on the bottom of your Certificate of Authenticity"
|
||||||
|
autoComplete="on"
|
||||||
|
name="username"
|
||||||
|
required/>
|
||||||
|
</Property>
|
||||||
|
<Property
|
||||||
|
name='signature'
|
||||||
|
label="Signature">
|
||||||
|
<InputTextAreaToggable
|
||||||
|
rows={3}
|
||||||
|
editable={true}
|
||||||
|
placeholder="Copy paste the signature on the bottom of your Certificate of Authenticity"
|
||||||
|
required/>
|
||||||
|
</Property>
|
||||||
|
<hr />
|
||||||
|
</Form>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
export default CoaVerifyContainer;
|
@ -6,9 +6,12 @@ import Row from 'react-bootstrap/lib/Row';
|
|||||||
import Col from 'react-bootstrap/lib/Col';
|
import Col from 'react-bootstrap/lib/Col';
|
||||||
import Button from 'react-bootstrap/lib/Button';
|
import Button from 'react-bootstrap/lib/Button';
|
||||||
import Glyphicon from 'react-bootstrap/lib/Glyphicon';
|
import Glyphicon from 'react-bootstrap/lib/Glyphicon';
|
||||||
|
import Panel from 'react-bootstrap/lib/Panel';
|
||||||
|
|
||||||
import UserActions from '../actions/user_actions';
|
import UserActions from '../actions/user_actions';
|
||||||
import UserStore from '../stores/user_store';
|
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 MediaPlayer from './ascribe_media/media_player';
|
||||||
|
|
||||||
@ -29,6 +32,7 @@ import GlobalNotificationActions from '../actions/global_notification_actions';
|
|||||||
|
|
||||||
import requests from '../utils/requests';
|
import requests from '../utils/requests';
|
||||||
import apiUrls from '../constants/api_urls';
|
import apiUrls from '../constants/api_urls';
|
||||||
|
import AppConstants from '../constants/application_constants';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is the component that implements display-specific functionality
|
* This is the component that implements display-specific functionality
|
||||||
@ -109,13 +113,20 @@ let Edition = React.createClass({
|
|||||||
</CollapsibleParagraph>
|
</CollapsibleParagraph>
|
||||||
|
|
||||||
<CollapsibleParagraph
|
<CollapsibleParagraph
|
||||||
title="Further Details (all editions)"
|
title="Further Details"
|
||||||
show={this.props.edition.acl.indexOf('edit') > -1 || Object.keys(this.props.edition.extra_data).length > 0}>
|
show={this.props.edition.acl.indexOf('edit') > -1 || Object.keys(this.props.edition.extra_data).length > 0}>
|
||||||
<EditionFurtherDetails
|
<EditionFurtherDetails
|
||||||
handleSuccess={this.props.loadEdition}
|
handleSuccess={this.props.loadEdition}
|
||||||
edition={this.props.edition}/>
|
edition={this.props.edition}/>
|
||||||
</CollapsibleParagraph>
|
</CollapsibleParagraph>
|
||||||
|
|
||||||
|
<CollapsibleParagraph
|
||||||
|
title="Certificate of Authenticity"
|
||||||
|
show={this.props.edition.acl.indexOf('coa') > -1}>
|
||||||
|
<CoaDetails
|
||||||
|
edition={this.props.edition}/>
|
||||||
|
</CollapsibleParagraph>
|
||||||
|
|
||||||
<CollapsibleParagraph
|
<CollapsibleParagraph
|
||||||
title="Provenance/Ownership History"
|
title="Provenance/Ownership History"
|
||||||
show={this.props.edition.ownership_history && this.props.edition.ownership_history.length > 0}>
|
show={this.props.edition.ownership_history && this.props.edition.ownership_history.length > 0}>
|
||||||
@ -421,4 +432,55 @@ let EditionFurtherDetails = React.createClass({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
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 (
|
||||||
|
<div>
|
||||||
|
<p className="text-center">
|
||||||
|
<Button bsSize="xsmall" href={this.state.coa.url_safe} target="_blank">
|
||||||
|
Download <Glyphicon glyph="cloud-download"/>
|
||||||
|
</Button>
|
||||||
|
<Button bsSize="xsmall" href={AppConstants.serverUrl + 'verify/'} target="_blank">
|
||||||
|
Verify <Glyphicon glyph="check"/>
|
||||||
|
</Button>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<div className="text-center">
|
||||||
|
<img src={AppConstants.baseUrl + 'static/img/ascribe_animated_medium.gif'} />
|
||||||
|
</div>);
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
export default Edition;
|
export default Edition;
|
||||||
|
@ -115,7 +115,7 @@ let SignupForm = React.createClass({
|
|||||||
name='promo_code'
|
name='promo_code'
|
||||||
label="Promocode">
|
label="Promocode">
|
||||||
<input
|
<input
|
||||||
type="password"
|
type="text"
|
||||||
placeholder="Enter a promocode here (Optional)"/>
|
placeholder="Enter a promocode here (Optional)"/>
|
||||||
</Property>
|
</Property>
|
||||||
<hr />
|
<hr />
|
||||||
|
@ -6,6 +6,9 @@ let apiUrls = {
|
|||||||
'applications': AppConstants.apiEndpoint + 'applications/',
|
'applications': AppConstants.apiEndpoint + 'applications/',
|
||||||
'application_token_refresh': AppConstants.apiEndpoint + 'applications/refresh_token/',
|
'application_token_refresh': AppConstants.apiEndpoint + 'applications/refresh_token/',
|
||||||
'blob_digitalworks': AppConstants.apiEndpoint + 'blob/digitalworks/',
|
'blob_digitalworks': AppConstants.apiEndpoint + 'blob/digitalworks/',
|
||||||
|
'coa': AppConstants.apiEndpoint + 'coa/${id}/',
|
||||||
|
'coa_create': AppConstants.apiEndpoint + 'coa/',
|
||||||
|
'coa_verify': AppConstants.apiEndpoint + 'coa/verify_coa/',
|
||||||
'edition': AppConstants.apiEndpoint + 'editions/${bitcoin_id}/',
|
'edition': AppConstants.apiEndpoint + 'editions/${bitcoin_id}/',
|
||||||
'edition_delete': AppConstants.apiEndpoint + 'editions/${edition_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/${edition_id}/',
|
||||||
|
19
js/fetchers/coa_fetcher.js
Normal file
19
js/fetchers/coa_fetcher.js
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
import requests from '../utils/requests';
|
||||||
|
|
||||||
|
let CoaFetcher = {
|
||||||
|
/**
|
||||||
|
* Fetch one user from the API.
|
||||||
|
* If no arg is supplied, load the current user
|
||||||
|
*/
|
||||||
|
fetchOne(id) {
|
||||||
|
return requests.get('coa', {'id': id});
|
||||||
|
},
|
||||||
|
create(bitcoinId) {
|
||||||
|
console.log(bitcoinId);
|
||||||
|
return requests.post('coa_create', {body: {'bitcoin_id': bitcoinId}});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export default CoaFetcher;
|
@ -12,6 +12,8 @@ import SignupContainer from './components/signup_container';
|
|||||||
import PasswordResetContainer from './components/password_reset_container';
|
import PasswordResetContainer from './components/password_reset_container';
|
||||||
|
|
||||||
import SettingsContainer from './components/settings_container';
|
import SettingsContainer from './components/settings_container';
|
||||||
|
import CoaVerifyContainer from './components/coa_verify_container';
|
||||||
|
|
||||||
import AppConstants from './constants/application_constants';
|
import AppConstants from './constants/application_constants';
|
||||||
import RegisterPiece from './components/register_piece';
|
import RegisterPiece from './components/register_piece';
|
||||||
|
|
||||||
@ -28,6 +30,7 @@ let routes = (
|
|||||||
<Route name="password_reset" path="password_reset" handler={PasswordResetContainer} />
|
<Route name="password_reset" path="password_reset" handler={PasswordResetContainer} />
|
||||||
<Route name="register_piece" path="register_piece" handler={RegisterPiece} />
|
<Route name="register_piece" path="register_piece" handler={RegisterPiece} />
|
||||||
<Route name="settings" path="settings" handler={SettingsContainer} />
|
<Route name="settings" path="settings" handler={SettingsContainer} />
|
||||||
|
<Route name="coa_verify" path="verify" handler={CoaVerifyContainer} />
|
||||||
|
|
||||||
<Redirect from={baseUrl} to="login" />
|
<Redirect from={baseUrl} to="login" />
|
||||||
<Redirect from={baseUrl + '/'} to="login" />
|
<Redirect from={baseUrl + '/'} to="login" />
|
||||||
|
18
js/stores/coa_store.js
Normal file
18
js/stores/coa_store.js
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
import alt from '../alt';
|
||||||
|
import CoaActions from '../actions/coa_actions';
|
||||||
|
|
||||||
|
|
||||||
|
class CoaStore {
|
||||||
|
constructor() {
|
||||||
|
this.coa = {};
|
||||||
|
this.bindActions(CoaActions);
|
||||||
|
}
|
||||||
|
|
||||||
|
onUpdateCoa(coa) {
|
||||||
|
this.coa = coa;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default alt.createStore(CoaStore, 'CoaStore');
|
@ -29,3 +29,19 @@
|
|||||||
margin-top: 1em;
|
margin-top: 1em;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.coa-file-wrapper{
|
||||||
|
display: table;
|
||||||
|
height: 200px;
|
||||||
|
overflow: hidden;
|
||||||
|
margin: 0 auto;
|
||||||
|
width: 100%;
|
||||||
|
padding: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.coa-file {
|
||||||
|
display: table-cell;
|
||||||
|
vertical-align: middle;
|
||||||
|
border: 1px solid #CCC;
|
||||||
|
background-color: #F8F8F8;
|
||||||
|
}
|
@ -5,7 +5,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.ascribe-textarea-editable:hover {
|
.ascribe-textarea-editable:hover {
|
||||||
border: 1px solid #AAA;
|
//border: 1px solid #AAA;;
|
||||||
|
border: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ascribe-pre{
|
.ascribe-pre{
|
||||||
|
Loading…
Reference in New Issue
Block a user