diff --git a/js/actions/wallet_settings_actions.js b/js/actions/wallet_settings_actions.js new file mode 100644 index 00000000..48c8555f --- /dev/null +++ b/js/actions/wallet_settings_actions.js @@ -0,0 +1,25 @@ +'use strict'; + +import alt from '../alt'; +import WalletSettingsFetcher from '../fetchers/wallet_settings_fetcher'; + + +class WalletSettingsActions { + constructor() { + this.generateActions( + 'updateWalletSettings' + ); + } + + fetchWalletSettings() { + WalletSettingsFetcher.fetchOne() + .then((res) => { + this.actions.updateWalletSettings(res.wallet_settings); + }) + .catch((err) => { + console.log(err); + }); + } +} + +export default alt.createActions(WalletSettingsActions); diff --git a/js/components/ascribe_forms/form_piece_extradata.js b/js/components/ascribe_forms/form_piece_extradata.js index 8cb23813..045c6adb 100644 --- a/js/components/ascribe_forms/form_piece_extradata.js +++ b/js/components/ascribe_forms/form_piece_extradata.js @@ -28,7 +28,7 @@ let PieceExtraDataForm = React.createClass({ renderForm() { let defaultValue = this.props.editions[0].extra_data[this.props.name] || ''; - if (defaultValue.length === 0 && ~this.props.editable){ + if (defaultValue.length === 0 && !this.props.editable){ return null; } return ( diff --git a/js/components/edition.js b/js/components/edition.js index b09e3d95..21469f22 100644 --- a/js/components/edition.js +++ b/js/components/edition.js @@ -91,25 +91,27 @@ let Edition = React.createClass({ + + show={this.state.currentUser.username && true || false}> + -1 || this.props.edition.public_note} - iconName="pencil"> + show={this.props.edition.acl.indexOf('edit') > -1 || this.props.edition.public_note}> + + title="Further Details (all editions)" + show={this.props.edition.acl.indexOf('edit') > -1 || Object.keys(this.props.edition.extra_data).length > 0}> diff --git a/js/components/header.js b/js/components/header.js index 85d06ca5..66984c62 100644 --- a/js/components/header.js +++ b/js/components/header.js @@ -15,6 +15,7 @@ import Navbar from 'react-bootstrap/lib/Navbar'; import NavItem from 'react-bootstrap/lib/NavItem'; import DropdownButton from 'react-bootstrap/lib/DropdownButton'; import MenuItem from 'react-bootstrap/lib/MenuItem'; +import MenuItemLink from 'react-router-bootstrap/lib/MenuItemLink'; import LoginModal from '../components/ascribe_modal/modal_login'; import SignupModal from '../components/ascribe_modal/modal_signup'; @@ -57,7 +58,7 @@ let Header = React.createClass({ if (this.state.currentUser.username){ account = ( - {getLangText('Account Settings')} + {getLangText('Account Settings')}
  • {getLangText('FAQ')} {getLangText('Terms of Service')} diff --git a/js/components/settings_container.js b/js/components/settings_container.js new file mode 100644 index 00000000..6595042e --- /dev/null +++ b/js/components/settings_container.js @@ -0,0 +1,257 @@ +'use strict'; + +import React from 'react'; +import Router from 'react-router'; + +import CollapsibleMixin from 'react-bootstrap/lib/CollapsibleMixin'; + +import UserActions from '../actions/user_actions'; +import UserStore from '../stores/user_store'; + +import WalletSettingsActions from '../actions/wallet_settings_actions'; +import WalletSettingsStore from '../stores/wallet_settings_store'; + +import GlobalNotificationModel from '../models/global_notification_model'; +import GlobalNotificationActions from '../actions/global_notification_actions'; + +import classNames from 'classnames'; + +let SettingsContainer = React.createClass({ + mixins: [Router.Navigation], + + getInitialState() { + return UserStore.getState(); + }, + + componentDidMount() { + UserStore.listen(this.onChange); + UserActions.fetchCurrentUser(); + }, + + componentWillUnmount() { + UserStore.unlisten(this.onChange); + }, + + onChange(state) { + this.setState(state); + }, + + handleSuccess(){ + this.transitionTo('pieces'); + let notification = new GlobalNotificationModel('password succesfully updated', 'success', 10000); + GlobalNotificationActions.appendGlobalNotification(notification); + }, + render() { + return ( +
    + + + + + + + + + + + + + + + +
    + ); + } +}); + +const CollapsibleParagraph = React.createClass({ + + propTypes: { + title: React.PropTypes.string, + children: React.PropTypes.oneOfType([ + React.PropTypes.object, + React.PropTypes.array + ]), + iconName: React.PropTypes.string + }, + + mixins: [CollapsibleMixin], + + getCollapsibleDOMNode(){ + return React.findDOMNode(this.refs.panel); + }, + + getCollapsibleDimensionValue(){ + return React.findDOMNode(this.refs.panel).scrollHeight; + }, + + onHandleToggle(e){ + e.preventDefault(); + this.setState({expanded: !this.state.expanded}); + }, + + render() { + let styles = this.getCollapsibleClassSet(); + let text = this.isExpanded() ? '-' : '+'; + + return ( +
    +
    +
    + {text} {this.props.title} +
    +
    + {this.props.children} +
    +
    +
    + ); + } +}); + +let SettingsProperty = 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-3 col-sm-3 col-md-2 col-lg-1', + valueClassName: 'col-xs-9 col-sm-9 col-md-10 col-lg-11' + }; + }, + + //render() { + // return ( + //
    + //
    + //
    + //
    { this.props.label + this.props.separator}
    + //
    + //
    + //
    { this.props.value }
    + //
    + //
    + //
    + // ); + //} + render() { + return ( +
    +
    + +
    +
    + ); + } +}); + +let AccountSettings = React.createClass({ + + propTypes: { + currentUser: React.PropTypes.object + }, + + render() { + + return ( +
    + + +
    + ); + } +}); + +let BitcoinWalletSettings = React.createClass({ + + propTypes: { + currentUser: React.PropTypes.object + }, + + getInitialState() { + return WalletSettingsStore.getState(); + }, + + componentDidMount() { + WalletSettingsStore.listen(this.onChange); + WalletSettingsActions.fetchWalletSettings(); + }, + + componentWillUnmount() { + WalletSettingsStore.unlisten(this.onChange); + }, + + onChange(state) { + this.setState(state); + }, + render() { + + return ( +
    + + +
    + ); + } +}); + +let ContractSettings = React.createClass({ + + propTypes: { + currentUser: React.PropTypes.object + }, + + render() { + + return ( +
    +
    Username: {this.props.currentUser.username}
    +
    Email: {this.props.currentUser.email}
    +
    + ); + } +}); + +let APISettings = React.createClass({ + + propTypes: { + currentUser: React.PropTypes.object + }, + + render() { + + return ( +
    +
    Username: {this.props.currentUser.username}
    +
    Email: {this.props.currentUser.email}
    +
    + ); + } +}); + +export default SettingsContainer; \ No newline at end of file diff --git a/js/constants/api_urls.js b/js/constants/api_urls.js index 494d52d0..e7f9c174 100644 --- a/js/constants/api_urls.js +++ b/js/constants/api_urls.js @@ -28,7 +28,8 @@ let apiUrls = { 'users_logout': AppConstants.apiEndpoint + 'users/logout/', 'users_password_reset': AppConstants.apiEndpoint + 'users/reset_password/', 'users_password_reset_request': AppConstants.apiEndpoint + 'users/request_reset_password/', - 'users_signup': AppConstants.apiEndpoint + 'users/' + 'users_signup': AppConstants.apiEndpoint + 'users/', + 'wallet_settings': AppConstants.apiEndpoint + 'users/wallet_settings/' }; export default apiUrls; diff --git a/js/fetchers/wallet_settings_fetcher.js b/js/fetchers/wallet_settings_fetcher.js new file mode 100644 index 00000000..198d2834 --- /dev/null +++ b/js/fetchers/wallet_settings_fetcher.js @@ -0,0 +1,12 @@ +'use strict'; + +import requests from '../utils/requests'; + + +let WalletSettingsFetcher = { + fetchOne() { + return requests.get('wallet_settings'); + } +}; + +export default WalletSettingsFetcher; diff --git a/js/routes.js b/js/routes.js index b5196a77..ddc77385 100644 --- a/js/routes.js +++ b/js/routes.js @@ -7,6 +7,7 @@ import AscribeApp from './components/ascribe_app'; import PieceList from './components/piece_list'; import EditionContainer from './components/edition_container'; import PasswordResetContainer from './components/password_reset_container'; +import SettingsContainer from './components/settings_container'; import AppConstants from './constants/application_constants'; //import LoginModalHandler from './components/login_modal_handler'; @@ -20,6 +21,7 @@ let routes = ( + diff --git a/js/stores/wallet_settings_store.js b/js/stores/wallet_settings_store.js new file mode 100644 index 00000000..df4cce99 --- /dev/null +++ b/js/stores/wallet_settings_store.js @@ -0,0 +1,18 @@ +'use strict'; + +import alt from '../alt'; +import WalletSettingsActions from '../actions/wallet_settings_actions'; + + +class WalletSettingsStore { + constructor() { + this.walletSettings = {}; + this.bindActions(WalletSettingsActions); + } + + onUpdateWalletSettings(walletSettings) { + this.walletSettings = walletSettings; + } +} + +export default alt.createStore(WalletSettingsStore, 'WalletSettingsStore'); diff --git a/package.json b/package.json index ec3be0e4..553fa33b 100644 --- a/package.json +++ b/package.json @@ -60,7 +60,8 @@ "vinyl-buffer": "^1.0.0", "vinyl-source-stream": "^1.1.0", "watchify": "^3.1.2", - "yargs": "^3.10.0" + "yargs": "^3.10.0", + "react-router-bootstrap": "~0.16.0" }, "jest": { "scriptPreprocessor": "node_modules/babel-jest",