1
0
mirror of https://github.com/ascribe/onion.git synced 2024-06-28 16:48:04 +02:00

Merge pull request #53 from ascribe/AD-1362-implement-portfolioreview-judging-flow

Implement first cut of judging flow for portfolio review
This commit is contained in:
Dimitri De Jonghe 2015-12-10 16:58:42 +01:00
commit b467a840a4
17 changed files with 334 additions and 216 deletions

View File

@ -0,0 +1,132 @@
'use strict';
import React from 'react';
import { RouteContext } from 'react-router';
import history from '../../history';
import UserStore from '../../stores/user_store';
import UserActions from '../../actions/user_actions';
import AppConstants from '../../constants/application_constants';
const { object } = React.PropTypes;
const WHEN_ENUM = ['loggedIn', 'loggedOut'];
/**
* Redirects the user conditionally according to his authentication
*
* @param {enum/string} options.when ('loggedIn' || 'loggedOut')
*/
export function AuthRedirect({to, when}) {
// validate `when`, must be contained in `WHEN_ENUM`.
// Throw an error otherwise.
if(WHEN_ENUM.indexOf(when) === -1) {
let whenValues = WHEN_ENUM.join(', ');
throw new Error(`"when" must be one of: [${whenValues}] got "${when}" instead`);
}
return function(currentUser, query) {
const { redirectAuthenticated, redirect } = query;
// The user of this handler specifies with `when`, what kind of status
// needs to be checked to conditionally do - if that state is `true` -
// a redirect.
//
// So if when === 'loggedIn', we're checking if the user is logged in (and
// vice versa)
let exprToValidate = when === 'loggedIn' ? currentUser && currentUser.email
: currentUser && !currentUser.email;
// and redirect if `true`.
if(exprToValidate) {
window.setTimeout(() => history.replaceState(null, to, query));
return true;
// Otherwise there can also be the case that the backend
// wants to redirect the user to a specific route when the user is logged out already
} else if(!exprToValidate && when === 'loggedIn' && redirect) {
delete query.redirect;
window.setTimeout(() => history.replaceState(null, '/' + redirect, query));
return true;
} else if(!exprToValidate && when === 'loggedOut' && redirectAuthenticated) {
/*
* redirectAuthenticated contains an arbitrary path
* eg pieces/<id>, editions/<bitcoin_id>, collection, settings, ...
* hence transitionTo cannot be used directly.
*
* While we're getting rid of `query.redirect` explicitly in the
* above `else if` statement, here it's sufficient to just call
* `baseUrl` + `redirectAuthenticated`, as it gets rid of queries as well.
*/
window.location = AppConstants.baseUrl + redirectAuthenticated;
return true;
}
return false;
};
}
/**
* Can be used in combination with `Route` as an intermediate Handler
* between the actual component we want to display dependent on a certain state
* that is required to display that component.
*
* @param {[function]} redirectFn A function that conditionally redirects
*/
export function ProxyHandler(...redirectFunctions) {
return (Component) => {
return React.createClass({
displayName: 'ProxyHandler',
propTypes: {
location: object
},
// We need insert `RouteContext` here in order to be able
// to use the `Lifecycle` widget in further down nested components
mixins: [RouteContext],
getInitialState() {
return UserStore.getState();
},
componentDidMount() {
UserStore.listen(this.onChange);
UserActions.fetchCurrentUser();
},
componentDidUpdate() {
if(!UserStore.isLoading()) {
const { currentUser } = this.state;
const { query } = this.props.location;
for(let i = 0; i < redirectFunctions.length; i++) {
// if a redirectFunction redirects the user,
// it should return `true` and therefore
// stop/avoid the execution of all functions
// that follow
if(redirectFunctions[i](currentUser, query)) {
break;
}
}
}
},
componentWillUnmount() {
UserStore.unlisten(this.onChange);
},
onChange(state) {
this.setState(state);
},
render() {
return (
<Component {...this.props}/>
);
}
});
};
}

View File

@ -1,115 +0,0 @@
'use strict';
import React from 'react';
import { History, RouteContext } from 'react-router';
import UserStore from '../../../stores/user_store';
import UserActions from '../../../actions/user_actions';
import AppConstants from '../../../constants/application_constants';
const { object } = React.PropTypes;
const WHEN_ENUM = ['loggedIn', 'loggedOut'];
/**
* Can be used in combination with `Route` as an intermediate Handler
* between the actual component we want to display dependent on a certain state
* that is required to display that component.
*
* @param {string} options.to Any type of route path that is defined in routes.js
* @param {enum/string} options.when ('loggedIn' || 'loggedOut')
*/
export default function AuthProxyHandler({to, when}) {
// validate `when`, must be contained in `WHEN_ENUM`.
// Throw an error otherwise.
if(WHEN_ENUM.indexOf(when) === -1) {
let whenValues = WHEN_ENUM.join(', ');
throw new Error(`"when" must be one of: [${whenValues}] got "${when}" instead`);
}
return (Component) => {
return React.createClass({
displayName: 'AuthProxyHandler',
propTypes: {
location: object
},
// We need insert `RouteContext` here in order to be able
// to use the `Lifecycle` widget in further down nested components
mixins: [History, RouteContext],
getInitialState() {
return UserStore.getState();
},
componentDidMount() {
UserStore.listen(this.onChange);
UserActions.fetchCurrentUser();
},
componentDidUpdate() {
// Only refresh this component, when UserSources are not loading
// data from the server
if(!UserStore.isLoading()) {
this.redirectConditionally();
}
},
componentWillUnmount() {
UserStore.unlisten(this.onChange);
},
redirectConditionally() {
const { query } = this.props.location;
const { redirectAuthenticated, redirect } = query;
// The user of this handler specifies with `when`, what kind of status
// needs to be checked to conditionally do - if that state is `true` -
// a redirect.
//
// So if when === 'loggedIn', we're checking if the user is logged in (and
// vice versa)
let exprToValidate = when === 'loggedIn' ?
this.state.currentUser && this.state.currentUser.email :
this.state.currentUser && !this.state.currentUser.email;
// and redirect if `true`.
if(exprToValidate) {
window.setTimeout(() => this.history.replaceState(null, to, query));
// Otherwise there can also be the case that the backend
// wants to redirect the user to a specific route when the user is logged out already
} else if(!exprToValidate && when === 'loggedIn' && redirect) {
delete query.redirect;
window.setTimeout(() => this.history.replaceState(null, '/' + redirect, query));
} else if(!exprToValidate && when === 'loggedOut' && redirectAuthenticated) {
/*
* redirectAuthenticated contains an arbirary path
* eg pieces/<id>, editions/<bitcoin_id>, collection, settings, ...
* hence transitionTo cannot be used directly.
*
* While we're getting rid of `query.redirect` explicitly in the
* above `else if` statement, here it's sufficient to just call
* `baseUrl` + `redirectAuthenticated`, as it gets rid of queries as well.
*/
window.location = AppConstants.baseUrl + redirectAuthenticated;
}
},
onChange(state) {
this.setState(state);
},
render() {
return (
<Component {...this.props}/>
);
}
});
};
}

View File

@ -37,16 +37,9 @@ import { constructHead } from '../utils/dom_utils';
let Header = React.createClass({
propTypes: {
showAddWork: React.PropTypes.bool,
routes: React.PropTypes.arrayOf(React.PropTypes.object)
},
getDefaultProps() {
return {
showAddWork: true
};
},
getInitialState() {
return mergeOptions(
WhitelabelStore.getState(),
@ -55,10 +48,11 @@ let Header = React.createClass({
},
componentDidMount() {
UserActions.fetchCurrentUser();
UserStore.listen(this.onChange);
WhitelabelActions.fetchWhitelabel();
UserActions.fetchCurrentUser.defer();
WhitelabelStore.listen(this.onChange);
WhitelabelActions.fetchWhitelabel.defer();
// react-bootstrap 0.25.1 has a bug in which it doesn't
// close the mobile expanded navigation after a click by itself.
@ -223,7 +217,7 @@ let Header = React.createClass({
{this.getPoweredBy()}
</Nav>
<Nav navbar right>
<HeaderNotificationDebug show = {false}/>
<HeaderNotificationDebug show={false}/>
{account}
{signup}
</Nav>

View File

@ -1,11 +1,14 @@
'use strict';
import React from 'react';
import { Link } from 'react-router';
import Glyphicon from 'react-bootstrap/lib/Glyphicon';
import UserStore from '../../../../../stores/user_store';
import UserActions from '../../../../../actions/user_actions';
import Glyphicon from 'react-bootstrap/lib/Glyphicon';
import { getLangText } from '../../../../../utils/lang_utils';
const PRHero = React.createClass({
@ -15,7 +18,7 @@ const PRHero = React.createClass({
componentDidMount() {
UserStore.listen(this.onChange);
UserActions.fetchCurrentUser();
UserActions.fetchCurrentUser.defer();
},
componentWillUnmount() {
@ -31,12 +34,14 @@ const PRHero = React.createClass({
return (
<div className="piece--hero">
<h2><Glyphicon glyph="ok" /> Congratulations {currentUser.email}!</h2>
<h1>You have successfully submitted to Portfolio Review 2016</h1>
<p>See below, your uploaded portfolio:</p>
<h2><Glyphicon glyph="ok" />
&nbsp;{getLangText('Congratulations') + (currentUser.email ? ` ${currentUser.email}!` : '!')}
</h2>
<h1>{getLangText('You have successfully submitted to Portfolio Review 2016.')}</h1>
<p>Not you? <Link to="/logout">{getLangText('Change account.')}</Link></p>
</div>
);
}
});
export default PRHero;
export default PRHero;

View File

@ -0,0 +1,26 @@
'use strict';
import history from '../../../../../../history';
export function AuthPrizeRoleRedirect({ to, when }) {
if (when.constructor !== Array || !when.length) {
throw new Error('`when` of AuthPrizeRoleRedirect must be an array containing values');
}
if (!to || to.indexOf('/') === -1) {
throw new Error('`to` of AuthPrizeRoleRedirect must be defined and contain a valid route');
}
return function(currentUser, query) {
const exprToValidate = when
.map(role => currentUser[role])
.reduce((a, b) => a || b);
if (exprToValidate) {
window.setTimeout(() => history.replaceState(null, to, query));
return true;
} else {
return false;
}
};
}

View File

@ -4,6 +4,7 @@ import React from 'react';
import GlobalNotification from '../../../global_notification';
import Hero from './components/pr_hero';
import Header from '../../../header';
import UserStore from '../../../../stores/user_store';
import UserActions from '../../../../actions/user_actions';
@ -40,19 +41,28 @@ let PRApp = React.createClass({
},
render() {
const { history, children } = this.props;
const { history, children, routes } = this.props;
const { currentUser } = this.state;
let style = {};
let subdomain = getSubdomain();
let header;
if (currentUser && currentUser.email && history.isActive(`/pieces/${getCookie(currentUser.email)}`)) {
header = <Hero />;
style = { paddingTop: '0 !important' };
} else if(currentUser && (currentUser.is_admin || currentUser.is_jury || currentUser.is_judge)) {
header = <Header routes={routes} />;
} else {
style = { paddingTop: '0 !important' };
}
return (
<div>
{header}
<div className={'container ascribe-prize-app client--' + subdomain}>
<div
style={style}
className={'container ascribe-prize-app client--' + subdomain}>
{children}
<GlobalNotification />
<div id="modal" className="container"></div>

View File

@ -22,7 +22,8 @@ import PasswordResetContainer from '../../password_reset_container';
import CoaVerifyContainer from '../../coa_verify_container';
import ErrorNotFoundPage from '../../error_not_found_page';
import AuthProxyHandler from '../../../components/ascribe_routes/proxy_routes/auth_proxy_handler';
import { ProxyHandler, AuthRedirect } from '../../../components/ascribe_routes/proxy_handler';
import { AuthPrizeRoleRedirect } from './portfolioreview/components/pr_routes/pr_proxy_handler';
const ROUTES = {
@ -31,28 +32,27 @@ const ROUTES = {
<IndexRoute component={SPLanding} />
<Route
path='login'
component={AuthProxyHandler({to: '/collection', when: 'loggedIn'})(SPLoginContainer)} />
component={ProxyHandler(AuthRedirect({to: '/collection', when: 'loggedIn'}))(SPLoginContainer)} />
<Route
path='logout'
component={AuthProxyHandler({to: '/', when: 'loggedOut'})(LogoutContainer)}/>
component={ProxyHandler(AuthRedirect({to: '/', when: 'loggedOut'}))(LogoutContainer)}/>
<Route
path='signup'
component={AuthProxyHandler({to: '/collection', when: 'loggedIn'})(SPSignupContainer)} />
component={ProxyHandler(AuthRedirect({to: '/collection', when: 'loggedIn'}))(SPSignupContainer)} />
<Route
path='password_reset'
component={AuthProxyHandler({to: '/collection', when: 'loggedIn'})(PasswordResetContainer)} />
component={ProxyHandler(AuthRedirect({to: '/collection', when: 'loggedIn'}))(PasswordResetContainer)} />
<Route
path='settings'
component={AuthProxyHandler({to: '/login', when: 'loggedOut'})(SPSettingsContainer)}/>
component={ProxyHandler(AuthRedirect({to: '/login', when: 'loggedOut'}))(SPSettingsContainer)}/>
<Route
path='register_piece'
component={AuthProxyHandler({to: '/login', when: 'loggedOut'})(SPRegisterPiece)}
component={ProxyHandler(AuthRedirect({to: '/login', when: 'loggedOut'}))(SPRegisterPiece)}
headerTitle='+ NEW WORK'/>
<Route
path='collection'
component={AuthProxyHandler({to: '/login', when: 'loggedOut'})(SPPieceList)}
component={ProxyHandler(AuthRedirect({to: '/login', when: 'loggedOut'}))(SPPieceList)}
headerTitle='COLLECTION'/>
<Route path='pieces/:pieceId' component={SPPieceContainer} />
<Route path='editions/:editionId' component={EditionContainer} />
<Route path='verify' component={CoaVerifyContainer} />
@ -61,24 +61,41 @@ const ROUTES = {
),
portfolioreview: (
<Route path='/' component={PRApp}>
<IndexRoute component={PRLanding} />
<IndexRoute component={ProxyHandler(AuthPrizeRoleRedirect({ to: '/collection', when: ['is_admin', 'is_judge', 'is_jury'] }))(PRLanding)} />
<Route
path='register_piece'
component={AuthProxyHandler({to: '/login', when: 'loggedOut'})(PRRegisterPiece)}
headerTitle='+ NEW WORK'/>
component={ProxyHandler(AuthRedirect({to: '/login', when: 'loggedOut'}))(PRRegisterPiece)}/>
<Route
path='collection'
component={ProxyHandler(AuthRedirect({to: '/login', when: 'loggedOut'}))(SPPieceList)}
headerTitle='SUBMISSIONS'/>
<Route
path='login'
component={AuthProxyHandler({to: '/register_piece', when: 'loggedIn'})(SPLoginContainer)} />
component={ProxyHandler(
AuthPrizeRoleRedirect({ to: '/collection', when: ['is_admin', 'is_judge', 'is_jury'] }),
AuthRedirect({to: '/register_piece', when: 'loggedIn'})
)(SPLoginContainer)} />
<Route
path='logout'
component={AuthProxyHandler({to: '/', when: 'loggedOut'})(LogoutContainer)} />
component={ProxyHandler(AuthRedirect({to: '/', when: 'loggedOut'}))(LogoutContainer)} />
<Route
path='signup'
component={AuthProxyHandler({to: '/register_piece', when: 'loggedIn'})(SPSignupContainer)} />
component={ProxyHandler(
AuthPrizeRoleRedirect({ to: '/collection', when: ['is_admin', 'is_judge', 'is_jury'] }),
AuthRedirect({to: '/register_piece', when: 'loggedIn'})
)(SPSignupContainer)} />
<Route
path='password_reset'
component={AuthProxyHandler({to: '/register_piece', when: 'loggedIn'})(PasswordResetContainer)} />
component={ProxyHandler(
AuthPrizeRoleRedirect({ to: '/collection', when: ['is_admin', 'is_judge', 'is_jury'] }),
AuthRedirect({to: '/register_piece', when: 'loggedIn'})
)(PasswordResetContainer)} />
<Route
path='settings'
component={ProxyHandler(AuthRedirect({to: '/login', when: 'loggedOut'}))(SPSettingsContainer)}/>
<Route path='pieces/:pieceId' component={SPPieceContainer} />
<Route path='editions/:editionId' component={EditionContainer} />
<Route path='verify' component={CoaVerifyContainer} />
<Route path='*' component={ErrorNotFoundPage} />
</Route>
)

View File

@ -16,7 +16,7 @@ class PrizeActions {
.fetch()
.then((res) => {
this.actions.updatePrize({
prize: res.prize
prize: res
});
})
.catch((err) => {

View File

@ -48,7 +48,9 @@ let PrizePieceList = React.createClass({
},
getButtonSubmit() {
if (this.state.prize && this.state.prize.active && !this.state.currentUser.is_jury){
const { currentUser } = this.state;
if (this.state.prize && this.state.prize.active &&
!currentUser.is_jury && !currentUser.is_admin && !currentUser.is_judge){
return (
<LinkContainer to="/register_piece">
<Button>
@ -57,9 +59,6 @@ let PrizePieceList = React.createClass({
</LinkContainer>
);
}
else if (this.state.prize && this.state.currentUser.is_judge){
return null;
}
return null;
},

View File

@ -40,7 +40,7 @@ import LumenusLanding from './components/lumenus/lumenus_landing';
import Vivi23Landing from './components/23vivi/23vivi_landing';
import Vivi23PieceList from './components/23vivi/23vivi_piece_list';
import AuthProxyHandler from '../../../components/ascribe_routes/proxy_routes/auth_proxy_handler';
import { ProxyHandler, AuthRedirect } from '../../../components/ascribe_routes/proxy_handler';
import WalletApp from './wallet_app';
@ -51,29 +51,29 @@ let ROUTES = {
<IndexRoute component={CylandLanding} />
<Route
path='login'
component={AuthProxyHandler({to: '/collection', when: 'loggedIn'})(LoginContainer)} />
component={ProxyHandler(AuthRedirect({to: '/collection', when: 'loggedIn'}))(LoginContainer)} />
<Route
path='logout'
component={AuthProxyHandler({to: '/', when: 'loggedOut'})(LogoutContainer)}/>
component={ProxyHandler(AuthRedirect({to: '/', when: 'loggedOut'}))(LogoutContainer)}/>
<Route
path='signup'
component={AuthProxyHandler({to: '/collection', when: 'loggedIn'})(SignupContainer)} />
component={ProxyHandler(AuthRedirect({to: '/collection', when: 'loggedIn'}))(SignupContainer)} />
<Route
path='password_reset'
component={AuthProxyHandler({to: '/collection', when: 'loggedIn'})(PasswordResetContainer)} />
component={ProxyHandler(AuthRedirect({to: '/collection', when: 'loggedIn'}))(PasswordResetContainer)} />
<Route
path='settings'
component={AuthProxyHandler({to: '/login', when: 'loggedOut'})(SettingsContainer)}/>
component={ProxyHandler(AuthRedirect({to: '/login', when: 'loggedOut'}))(SettingsContainer)}/>
<Route
path='contract_settings'
component={AuthProxyHandler({to: '/login', when: 'loggedOut'})(ContractSettings)}/>
component={ProxyHandler(AuthRedirect({to: '/login', when: 'loggedOut'}))(ContractSettings)}/>
<Route
path='register_piece'
component={AuthProxyHandler({to: '/login', when: 'loggedOut'})(CylandRegisterPiece)}
component={ProxyHandler(AuthRedirect({to: '/login', when: 'loggedOut'}))(CylandRegisterPiece)}
headerTitle='+ NEW WORK'/>
<Route
path='collection'
component={AuthProxyHandler({to: '/login', when: 'loggedOut'})(CylandPieceList)}
component={ProxyHandler(AuthRedirect({to: '/login', when: 'loggedOut'}))(CylandPieceList)}
headerTitle='COLLECTION'/>
<Route path='editions/:editionId' component={EditionContainer} />
<Route path='verify' component={CoaVerifyContainer} />
@ -85,29 +85,29 @@ let ROUTES = {
<Route path='/' component={WalletApp}>
<Route
path='login'
component={AuthProxyHandler({to: '/collection', when: 'loggedIn'})(LoginContainer)} />
component={ProxyHandler(AuthRedirect({to: '/collection', when: 'loggedIn'}))(LoginContainer)} />
<Route
path='logout'
component={AuthProxyHandler({to: '/', when: 'loggedOut'})(LogoutContainer)}/>
component={ProxyHandler(AuthRedirect({to: '/', when: 'loggedOut'}))(LogoutContainer)}/>
<Route
path='signup'
component={AuthProxyHandler({to: '/collection', when: 'loggedIn'})(SignupContainer)} />
component={ProxyHandler(AuthRedirect({to: '/collection', when: 'loggedIn'}))(SignupContainer)} />
<Route
path='password_reset'
component={AuthProxyHandler({to: '/collection', when: 'loggedIn'})(PasswordResetContainer)} />
component={ProxyHandler(AuthRedirect({to: '/collection', when: 'loggedIn'}))(PasswordResetContainer)} />
<Route
path='settings'
component={AuthProxyHandler({to: '/login', when: 'loggedOut'})(SettingsContainer)}/>
component={ProxyHandler(AuthRedirect({to: '/login', when: 'loggedOut'}))(SettingsContainer)}/>
<Route
path='contract_settings'
component={AuthProxyHandler({to: '/login', when: 'loggedOut'})(ContractSettings)}/>
component={ProxyHandler(AuthRedirect({to: '/login', when: 'loggedOut'}))(ContractSettings)}/>
<Route
path='register_piece'
component={AuthProxyHandler({to: '/login', when: 'loggedOut'})(CCRegisterPiece)}
component={ProxyHandler(AuthRedirect({to: '/login', when: 'loggedOut'}))(CCRegisterPiece)}
headerTitle='+ NEW WORK'/>
<Route
path='collection'
component={AuthProxyHandler({to: '/login', when: 'loggedOut'})(PieceList)}
component={ProxyHandler(AuthRedirect({to: '/login', when: 'loggedOut'}))(PieceList)}
headerTitle='COLLECTION'/>
<Route path='pieces/:pieceId' component={PieceContainer} />
<Route path='editions/:editionId' component={EditionContainer} />
@ -120,39 +120,39 @@ let ROUTES = {
<IndexRoute component={IkonotvLanding} />
<Route
path='login'
component={AuthProxyHandler({to: '/collection', when: 'loggedIn'})(LoginContainer)} />
component={ProxyHandler(AuthRedirect({to: '/collection', when: 'loggedIn'}))(LoginContainer)} />
<Route
path='logout'
component={AuthProxyHandler({to: '/', when: 'loggedOut'})(LogoutContainer)}/>
component={ProxyHandler(AuthRedirect({to: '/', when: 'loggedOut'}))(LogoutContainer)}/>
<Route
path='signup'
component={AuthProxyHandler({to: '/collection', when: 'loggedIn'})(SignupContainer)} />
component={ProxyHandler(AuthRedirect({to: '/collection', when: 'loggedIn'}))(SignupContainer)} />
<Route
path='password_reset'
component={AuthProxyHandler({to: '/collection', when: 'loggedIn'})(PasswordResetContainer)} />
component={ProxyHandler(AuthRedirect({to: '/collection', when: 'loggedIn'}))(PasswordResetContainer)} />
<Route
path='settings'
component={AuthProxyHandler({to: '/login', when: 'loggedOut'})(SettingsContainer)}/>
component={ProxyHandler(AuthRedirect({to: '/login', when: 'loggedOut'}))(SettingsContainer)}/>
<Route
path='contract_settings'
component={AuthProxyHandler({to: '/login', when: 'loggedOut'})(ContractSettings)}/>
component={ProxyHandler(AuthRedirect({to: '/login', when: 'loggedOut'}))(ContractSettings)}/>
<Route
path='request_loan'
component={AuthProxyHandler({to: '/login', when: 'loggedOut'})(SendContractAgreementForm)}
component={ProxyHandler(AuthRedirect({to: '/login', when: 'loggedOut'}))(SendContractAgreementForm)}
headerTitle='SEND NEW CONTRACT'
aclName='acl_create_contractagreement'/>
<Route
path='register_piece'
component={AuthProxyHandler({to: '/login', when: 'loggedOut'})(IkonotvRegisterPiece)}
component={ProxyHandler(AuthRedirect({to: '/login', when: 'loggedOut'}))(IkonotvRegisterPiece)}
headerTitle='+ NEW WORK'
aclName='acl_create_piece'/>
<Route
path='collection'
component={AuthProxyHandler({to: '/login', when: 'loggedOut'})(IkonotvPieceList)}
component={ProxyHandler(AuthRedirect({to: '/login', when: 'loggedOut'}))(IkonotvPieceList)}
headerTitle='COLLECTION'/>
<Route
path='contract_notifications'
component={AuthProxyHandler({to: '/login', when: 'loggedOut'})(IkonotvContractNotifications)}/>
component={ProxyHandler(AuthRedirect({to: '/login', when: 'loggedOut'}))(IkonotvContractNotifications)}/>
<Route path='pieces/:pieceId' component={IkonotvPieceContainer} />
<Route path='editions/:editionId' component={EditionContainer} />
<Route path='verify' component={CoaVerifyContainer} />
@ -161,32 +161,32 @@ let ROUTES = {
),
'lumenus': (
<Route path='/' component={WalletApp}>
<IndexRoute component={AuthProxyHandler({to: '/collection', when: 'loggedIn'})(LumenusLanding)} />
<IndexRoute component={ProxyHandler(AuthRedirect({to: '/collection', when: 'loggedIn'}))(LumenusLanding)} />
<Route
path='login'
component={AuthProxyHandler({to: '/collection', when: 'loggedIn'})(LoginContainer)} />
component={ProxyHandler(AuthRedirect({to: '/collection', when: 'loggedIn'}))(LoginContainer)} />
<Route
path='logout'
component={AuthProxyHandler({to: '/', when: 'loggedOut'})(LogoutContainer)}/>
component={ProxyHandler(AuthRedirect({to: '/', when: 'loggedOut'}))(LogoutContainer)}/>
<Route
path='signup'
component={AuthProxyHandler({to: '/collection', when: 'loggedIn'})(SignupContainer)} />
component={ProxyHandler(AuthRedirect({to: '/collection', when: 'loggedIn'}))(SignupContainer)} />
<Route
path='password_reset'
component={AuthProxyHandler({to: '/collection', when: 'loggedIn'})(PasswordResetContainer)} />
component={ProxyHandler(AuthRedirect({to: '/collection', when: 'loggedIn'}))(PasswordResetContainer)} />
<Route
path='settings'
component={AuthProxyHandler({to: '/login', when: 'loggedOut'})(SettingsContainer)}/>
component={ProxyHandler(AuthRedirect({to: '/login', when: 'loggedOut'}))(SettingsContainer)}/>
<Route
path='contract_settings'
component={AuthProxyHandler({to: '/login', when: 'loggedOut'})(ContractSettings)}/>
component={ProxyHandler(AuthRedirect({to: '/login', when: 'loggedOut'}))(ContractSettings)}/>
<Route
path='register_piece'
component={AuthProxyHandler({to: '/login', when: 'loggedOut'})(MarketRegisterPiece)}
component={ProxyHandler(AuthRedirect({to: '/login', when: 'loggedOut'}))(MarketRegisterPiece)}
headerTitle='+ NEW WORK'/>
<Route
path='collection'
component={AuthProxyHandler({to: '/login', when: 'loggedOut'})(MarketPieceList)}
component={ProxyHandler(AuthRedirect({to: '/login', when: 'loggedOut'}))(MarketPieceList)}
headerTitle='COLLECTION'/>
<Route path='pieces/:pieceId' component={MarketPieceContainer} />
<Route path='editions/:editionId' component={MarketEditionContainer} />
@ -196,33 +196,33 @@ let ROUTES = {
),
'23vivi': (
<Route path='/' component={WalletApp}>
<IndexRoute component={AuthProxyHandler({to: '/collection', when: 'loggedIn'})(Vivi23Landing)} />
<IndexRoute component={ProxyHandler(AuthRedirect({to: '/collection', when: 'loggedIn'}))(Vivi23Landing)} />
<Route
path='login'
component={AuthProxyHandler({to: '/collection', when: 'loggedIn'})(LoginContainer)} />
component={ProxyHandler(AuthRedirect({to: '/collection', when: 'loggedIn'}))(LoginContainer)} />
<Route
path='logout'
component={AuthProxyHandler({to: '/', when: 'loggedOut'})(LogoutContainer)}/>
component={ProxyHandler(AuthRedirect({to: '/', when: 'loggedOut'}))(LogoutContainer)}/>
<Route
path='signup'
component={AuthProxyHandler({to: '/collection', when: 'loggedIn'})(SignupContainer)} />
component={ProxyHandler(AuthRedirect({to: '/collection', when: 'loggedIn'}))(SignupContainer)} />
<Route
path='password_reset'
component={AuthProxyHandler({to: '/collection', when: 'loggedIn'})(PasswordResetContainer)} />
component={ProxyHandler(AuthRedirect({to: '/collection', when: 'loggedIn'}))(PasswordResetContainer)} />
<Route
path='settings'
component={AuthProxyHandler({to: '/login', when: 'loggedOut'})(SettingsContainer)}/>
component={ProxyHandler(AuthRedirect({to: '/login', when: 'loggedOut'}))(SettingsContainer)}/>
<Route
path='contract_settings'
component={AuthProxyHandler({to: '/login', when: 'loggedOut'})(ContractSettings)}/>
component={ProxyHandler(AuthRedirect({to: '/login', when: 'loggedOut'}))(ContractSettings)}/>
<Route
path='register_piece'
component={AuthProxyHandler({to: '/login', when: 'loggedOut'})(MarketRegisterPiece)}
component={ProxyHandler(AuthRedirect({to: '/login', when: 'loggedOut'}))(MarketRegisterPiece)}
headerTitle='+ NEW WORK'
aclName='acl_wallet_submit'/>
<Route
path='collection'
component={AuthProxyHandler({to: '/login', when: 'loggedOut'})(Vivi23PieceList)}
component={ProxyHandler(AuthRedirect({to: '/login', when: 'loggedOut'}))(Vivi23PieceList)}
headerTitle='COLLECTION'/>
<Route path='pieces/:pieceId' component={MarketPieceContainer} />
<Route path='editions/:editionId' component={MarketEditionContainer} />

View File

@ -25,39 +25,39 @@ import ErrorNotFoundPage from './components/error_not_found_page';
import RegisterPiece from './components/register_piece';
import AuthProxyHandler from './components/ascribe_routes/proxy_routes/auth_proxy_handler';
import { ProxyHandler, AuthRedirect } from './components/ascribe_routes/proxy_handler';
let COMMON_ROUTES = (
<Route path='/' component={App}>
<Route
path='login'
component={AuthProxyHandler({to: '/collection', when: 'loggedIn'})(LoginContainer)} />
component={ProxyHandler(AuthRedirect({to: '/collection', when: 'loggedIn'}))(LoginContainer)} />
<Route
path='register_piece'
component={AuthProxyHandler({to: '/login', when: 'loggedOut'})(RegisterPiece)}
component={ProxyHandler(AuthRedirect({to: '/login', when: 'loggedOut'}))(RegisterPiece)}
headerTitle='+ NEW WORK'/>
<Route
path='collection'
component={AuthProxyHandler({to: '/login', when: 'loggedOut'})(PieceList)}
component={ProxyHandler(AuthRedirect({to: '/login', when: 'loggedOut'}))(PieceList)}
headerTitle='COLLECTION'/>
<Route
path='signup'
component={AuthProxyHandler({to: '/collection', when: 'loggedIn'})(SignupContainer)} />
component={ProxyHandler(AuthRedirect({to: '/collection', when: 'loggedIn'}))(SignupContainer)} />
<Route
path='logout'
component={AuthProxyHandler({to: '/login', when: 'loggedOut'})(LogoutContainer)}/>
component={ProxyHandler(AuthRedirect({to: '/login', when: 'loggedOut'}))(LogoutContainer)}/>
<Route path='pieces/:pieceId' component={PieceContainer} />
<Route path='editions/:editionId' component={EditionContainer} />
<Route
path='password_reset'
component={AuthProxyHandler({to: '/collection', when: 'loggedIn'})(PasswordResetContainer)} />
component={ProxyHandler(AuthRedirect({to: '/collection', when: 'loggedIn'}))(PasswordResetContainer)} />
<Route
path='settings'
component={AuthProxyHandler({to: '/login', when: 'loggedOut'})(SettingsContainer)}/>
component={ProxyHandler(AuthRedirect({to: '/login', when: 'loggedOut'}))(SettingsContainer)}/>
<Route
path='contract_settings'
component={AuthProxyHandler({to: '/login', when: 'loggedOut'})(ContractSettings)}/>
component={ProxyHandler(AuthRedirect({to: '/login', when: 'loggedOut'}))(ContractSettings)}/>
<Route path='coa_verify' component={CoaVerifyContainer} />
<Route path='*' component={ErrorNotFoundPage} />
</Route>

View File

@ -7,6 +7,8 @@ import EditionActions from '../actions/edition_actions';
import EditionSource from '../sources/edition_source';
import CoaSource from '../sources/coa_source';
import { mergeOptions } from '../utils/general_utils';
class EditionStore {
constructor() {
@ -20,7 +22,7 @@ class EditionStore {
};
this.bindActions(EditionActions);
this.registerAsync(Object.assign(EditionSource, CoaSource));
this.registerAsync(mergeOptions(EditionSource, CoaSource));
}
onFetchEdition(idToFetch) {

View File

@ -26,7 +26,7 @@ class UserStore {
}
}
onSuccessFetchCurrentUser({users: [user]}) {
onSuccessFetchCurrentUser({users: [user = {}]}) {
this.userMeta.invalidateCache = false;
this.userMeta.err = null;
this.currentUser = user;

View File

@ -28,7 +28,7 @@ class WebhookStore {
this.getInstance().lookupWebhooks();
}
onSuccessFetchWebhooks({ webhooks }) {
onSuccessFetchWebhooks({ webhooks = [] }) {
this.webhookMeta.invalidateCache = false;
this.webhookMeta.err = null;
this.webhooks = webhooks;

View File

@ -25,7 +25,7 @@ class WhitelabelStore {
}
}
onSuccessFetchWhitelabel({ whitelabel }) {
onSuccessFetchWhitelabel({ whitelabel = {} }) {
this.whitelabelMeta.invalidateCache = false;
this.whitelabelMeta.err = null;
this.whitelabel = whitelabel;

View File

@ -2,7 +2,6 @@ $pr--nav-fg-prim-color: black;
$pr--button-color: $pr--nav-fg-prim-color;
.client--portfolioreview {
padding-top: 0 !important;
.btn-wide,
.btn-default {
@ -23,10 +22,59 @@ $pr--button-color: $pr--nav-fg-prim-color;
}
}
.navbar-default {
.navbar-nav > .ascribe-powered-by, li > a {
color: $pr--button-color !important;
}
.active a {
border-bottom-color: $pr--button-color !important;
color: $pr--button-color !important;
}
}
.search-bar > .form-group > .input-group input {
&::-webkit-input-placeholder {
color: rgba($pr--button-color, 0.5);
}
&::-moz-placeholder {
color: rgba($pr--button-color, 0.5);
}
&:-ms-input-placeholder {
color: rgba($pr--button-color, 0.5);
}
&:-moz-placeholder {
color: rgba($pr--button-color, 0.5);
}
}
.icon-ascribe-search {
color: $pr--button-color;
}
// filter widget
.ascribe-piece-list-toolbar-filter-widget button {
background-color: transparent !important;
border-color: transparent !important;
color: $pr--button-color !important;
&:hover,
&:active {
background-color: $pr--button-color !important;
border-color: $pr--button-color !important;
color: white !important;
}
}
.ascribe-property {
> p > span:not(> .span),
> textarea,
> input {
> div,
> input,
> pre,
> select,
> span:not(.glyphicon),
> p,
> p > span,
> textarea {
color: $pr--nav-fg-prim-color;
}
}