Add 3rd Party modal & Account page

This commit is contained in:
Andrew Revinsky (DART)
2016-03-18 21:03:32 +03:00
parent 710487ebf9
commit febef227fd
14 changed files with 225 additions and 83 deletions

View File

@@ -56,7 +56,7 @@ export function accountCreate(customerId, payload) {
...payload
}));
dispatch(entityReceived(accountId, payload));
return authenticate(true);
return dispatch(authenticate(true));
})
.catch(err => {
dispatch(accountCreateError(err));
@@ -87,4 +87,36 @@ export function fetchAccount(accountId) {
dispatch(accountError(err));
});
};
}
export const deleteAccountRequested = makeActionCreator(T.ACCOUNT.DELETE_START);
export const deleteAccountComplete = makeActionCreator(T.ACCOUNT.DELETE_COMPLETE);
export const deleteAccountError = makeActionCreator(T.ACCOUNT.DELETE_ERROR);
export function deleteAccount(customerId, accountId) {
return dispatch => {
dispatch(deleteAccountRequested());
return api.apiDeleteAccount(accountId)
.then(data => {
//debugger;
dispatch(deleteAccountComplete());
return Promise.resolve('ok');
})
.catch(err => {
dispatch(deleteAccountError());
return Promise.reject(err);
})
};
}
export const errorMessageStart = makeActionCreator(T.ERROR.START, 'payload');
export const errorMessageStop = makeActionCreator(T.ERROR.STOP);
export function errorMessageTimedOut(error, timeout) {
return dispatch => {
dispatch(errorMessageStart(error));
setTimeout(() => {
dispatch(errorMessageStop());
}, timeout || 5000);
};
}

View File

@@ -5,6 +5,8 @@ import React from 'react';
import { connect } from 'react-redux';
import { pushState } from 'redux-router';
import read from '../utils/readProp';
export function requireAuthentication(Component) {
class AuthComponent extends React.Component {
@@ -45,12 +47,8 @@ export function requireAuthentication(Component) {
const mapStateToProps =
(state) => {
console.info('state', state);
return ({
//token: state.auth.token,
//userName: state.auth.userName,
//isAuthenticated: state.auth.isAuthenticated
isAuthenticated: state.app.auth.user.isSignedIn
isAuthenticated: read(state, 'app.auth.user.isSignedIn', false)
})
};

View File

@@ -50,6 +50,14 @@ export default defineActionTypes({
SINGLE_START
SINGLE_COMPLETE
SINGLE_ERROR
DELETE_START
DELETE_COMPLETE
DELETE_ERROR
`,
ERROR: `
START
STOP
`
})

View File

@@ -0,0 +1,9 @@
/**
* Created by andrew on 18/03/16.
*/
export const bookmarkAccount = (state = {}, action) => {
switch (action.type) {
default:
return state;
}
};

View File

@@ -0,0 +1,17 @@
/**
* Created by andrew on 18/03/16.
*/
import T from '../../constants/ACTION_TYPES';
export const error = (state = null, action ) => {
switch (action.type) {
case T.ERROR.STOP: {
return null;
}
case T.ERROR.START:
return action.payload;
default:
return state;
}
};

View File

@@ -7,9 +7,13 @@
import { combineReducers } from 'redux';
import { account } from './account';
import { error } from './errors';
import { bookmarkAccount } from './bookmarkAccount';
const uiReducer = combineReducers({
account
account,
error,
bookmarkAccount
});
export default uiReducer;

View File

@@ -93,6 +93,20 @@ export function apiRetrieveAccount(accountId) {
}).then(parseResponse);
}
export function apiDeleteAccount(accountId) {
return Promise.reject({
message: '\'Delete Account\' is not implemented.'
});
return fetch(`${getAccountsUrl()}/${accountId}`, {
headers: {
"Accept": "application/json",
"Content-Type": "application/json"
},
method: "delete"
}).then(parseResponse);
}
export function apiRetrieveUsers(search) {
return fetch(getCurrentUserUrl(), {
headers: {

View File

@@ -101,11 +101,11 @@ export class Account extends React.Component {
return memo;
}, []));
const { title = '[No title]', description: descriptionRaw, balance: balanceRaw } = account;
const { title: titleRaw, description: descriptionRaw, balance: balanceRaw } = account;
const title = titleRaw || '[No title]';
const balance = ((balanceRaw > 0 && balanceRaw < 1) ? '$0' : '$') + Number(balanceRaw).toFixed(2);
const description = descriptionRaw || '[No description provided]';
const description = descriptionRaw || '[No description]';
return (
<div>

View File

@@ -3,6 +3,7 @@
*/
import React from "react";
import { PageHeader, OverlayTrigger, Tooltip, Grid, Col, Row, Nav, NavItem, ButtonGroup, Button, Table } from "react-bootstrap";
import * as BS from "react-bootstrap";
import { Link, IndexLink} from "react-router";
import { connect } from "react-redux";
//import * as DefaultTheme from "redux-auth";
@@ -11,6 +12,7 @@ import * as Modals from './modals';
import IndexPanel from "./../components/partials/IndexPanel";
import * as A from '../actions/entities';
import read from '../utils/readProp';
const resetModals = {
@@ -39,15 +41,17 @@ class MyAccounts extends React.Component {
});
}
createAccountModalConfirmed(evt, payload) {
createAccountModalConfirmed(payload) {
const {
id: customerId
} = this.props.auth.user.attributes;
this.props.dispatch(A.accountCreate(customerId, payload))
.then(this.close.bind(this));
.then(() => {
this.close.bind(this);
this.props.dispatch(A.fetchOwnAccounts(customerId));
});
}
create3rdPartyAccountModal() {
@@ -61,18 +65,22 @@ class MyAccounts extends React.Component {
}
remove3rdPartyAccountModal(evt, evtKey) {
debugger;
const account = evtKey;
remove3rdPartyAccountModal(accountId, evt) {
const account = this.props.app.entities[accountId];
this.setState({
accountToRemove: account,
showDeleteAccountModal: true
});
}
remove3rdPartyAccountModalConfirmed() {
remove3rdPartyAccountModalConfirmed(accountId) {
const { customerId } = this.props;
this.props.dispatch(A.deleteAccount(customerId, accountId))
.then(this.close.bind(this),
err => {
this.props.dispatch(A.errorMessageTimedOut(err && err.message || err));
this.close();
});
}
close() {
@@ -109,7 +117,10 @@ class MyAccounts extends React.Component {
} = address;
const { showAccountModal, show3rdPartyAccountModal, showDeleteAccountModal } = this.state;
const { accountToRemove = null } = this.state;
const { accountToRemove = null} = this.state;
const { error } = this.props;
const errorLine = error ? (<BS.Panel bsStyle="danger"><strong>{ error }</strong></BS.Panel>) : [];
const ownAccountsData = this.props.app.accounts.own || [];
@@ -122,15 +133,17 @@ class MyAccounts extends React.Component {
accountId, balance, description = '', title
}, idx) => (
<tr key={`own_${idx}`}>
<td><Link to={`/account/${accountId}`}>{ title }</Link>{
<td key={0}><Link to={`/account/${accountId}`}>{ title }</Link>{
(description) ? [
(<br />),
<span>{ description }</span>
]: null
}</td>
<td>${ balance }</td>
<td key={1}>${ balance } </td>
<td key={2}><BS.Button bsStyle={"link"} onClick={this.remove3rdPartyAccountModal.bind(this, accountId)}><BS.Glyphicon glyph="remove" /></BS.Button></td>
</tr>
));
const refAccountsData = this.props.app.accounts.other || [];
const refAccounts = refAccountsData.map(({
title,
@@ -138,14 +151,15 @@ class MyAccounts extends React.Component {
id
}, idx) => (
<tr key={`ref_${idx}`}>
<td><Link to={`/account/${id}`}>{ title }</Link>{
<td key={0}><Link to={`/account/${id}`}>{ title }</Link>{
(description) ? [
(<br />),
<span>{ description }</span>
]: null
}
</td>
<td><Button eventKey={ id } bsStyle={"link"} onClick={this.remove3rdPartyAccountModal.bind(this)}>remove</Button>
<td key={1}></td>
<td key={2}><Button pullRight={true} bsStyle={"link"} onClick={this.remove3rdPartyAccountModal.bind(this, id)}><BS.Glyphicon glyph="remove" /></Button>
</td>
</tr>
));
@@ -162,6 +176,8 @@ class MyAccounts extends React.Component {
</Nav>
</PageHeader>
{ errorLine }
<Row>
<IndexPanel header="Personal Info:">
@@ -194,6 +210,7 @@ class MyAccounts extends React.Component {
<tr>
<th>Account Title</th>
<th>Balance</th>
<th></th>
</tr>
</thead>
<tbody>
@@ -286,6 +303,8 @@ class MyAccounts extends React.Component {
export default connect(({ app }) => {
return ({
auth: app.auth,
app: app.data
app: app.data,
customerId: read(app, 'auth.user.isSignedIn', false) ? read(app, 'auth.user.attributes.id', null): null,
error: app.ui.error
})
})(MyAccounts);

View File

@@ -3,12 +3,21 @@
*/
import React from "react";
import { PageHeader, OverlayTrigger, Modal, Tooltip, Grid, Col, Row, Nav, NavItem, ButtonGroup, Button, Table } from "react-bootstrap";
import * as BS from "react-bootstrap";
import Input from "../../controls/bootstrap/Input";
import read from '../../utils/readProp';
import { Link, IndexLink} from "react-router";
import { connect } from "react-redux";
import Select from "react-select";
export class Add3rdPartyAccountModal extends React.Component {
ownerTypeIn(argq, arg2, arg3) {
debugger;
}
ownerChanged(argq, arg2, arg3) {
debugger;
}
@@ -17,8 +26,12 @@ export class Add3rdPartyAccountModal extends React.Component {
debugger;
}
handleInput() {}
render() {
const disabled = false;
return (
<Modal show={this.props.show} onHide={this.props.onHide} key={1}>
<Modal.Header closeButton>
@@ -35,7 +48,9 @@ export class Add3rdPartyAccountModal extends React.Component {
{value: "bootstrap", label: "Bootstrap"},
{value: "materialUi", label: "Material UI"}
]}
onInputChange={this.ownerTypeIn.bind(this)}
onChange={this.ownerChanged.bind(this)} />
<label>Account:</label>
<Select
value={this.props.theme}
@@ -46,8 +61,16 @@ export class Add3rdPartyAccountModal extends React.Component {
{value: "materialUi", label: "Material UI"}
]}
onChange={this.accountChanged.bind(this)} />
<label>Account:</label>
<div>Description</div>
<Input type="textarea"
className="account-create-description"
label="Description:"
placeholder="Description"
name="description"
disabled={disabled}
value={read(this.props, 'account.form.description', '')}
errors={read(this.props, 'account.errors.description', [])}
onChange={this.handleInput.bind(this, 'description')} />
</form>
</Modal.Body>
<Modal.Footer>
@@ -59,10 +82,8 @@ export class Add3rdPartyAccountModal extends React.Component {
}
}
const mapStateToProps = (state) => ({
//token: state.auth.token,
//userName: state.auth.userName,
//isAuthenticated: state.auth.isAuthenticated
const mapStateToProps = ({ app }) => ({
ui: app.ui.bookmarkAccount
});
export default connect(mapStateToProps)(Add3rdPartyAccountModal);

View File

@@ -7,8 +7,8 @@ import { connect } from "react-redux";
import * as BS from "react-bootstrap";
import Input from "../../controls/bootstrap/Input";
import ButtonLoader from "../../controls/bootstrap/ButtonLoader";
//import { PageHeader, OverlayTrigger, Modal, Tooltip, Grid, Col, Row, Nav, NavItem, ButtonGroup, Button, Table } from "react-bootstrap";
import { Link, IndexLink} from "react-router";
import read from '../../utils/readProp';
@@ -83,7 +83,7 @@ export class NewAccountModal extends React.Component {
const { action } = this.props;
if (action) {
action(event, payload);
action(payload);
}
}
@@ -162,10 +162,6 @@ export class NewAccountModal extends React.Component {
</BS.Modal.Footer>
</BS.Modal>);
}
// className='account-create-submit pull-right'
}
const mapStateToProps = ({ }) => ({ });
export default connect(mapStateToProps)(NewAccountModal);
export default connect()(NewAccountModal);

View File

@@ -1,44 +0,0 @@
/**
* Created by andrew on 20/02/16.
*/
import React from "react";
import { PageHeader, OverlayTrigger, Modal, Tooltip, Grid, Col, Row, Nav, NavItem, ButtonGroup, Button, Table } from "react-bootstrap";
import { Link, IndexLink} from "react-router";
import { connect } from "react-redux";
import Select from "react-select";
export class NewAccountModal extends React.Component {
render() {
const account = this.props.account;
return (<Modal show={this.props.show} onHide={this.props.onHide} key={0}>
<Modal.Header closeButton>
<Modal.Title>Remove Account Bookmark</Modal.Title>
</Modal.Header>
<Modal.Body>
<form>
<label>Title:</label>
<div>Acct one</div>
<label>Balance:</label>
<div>$105.00</div>
<label>Description:</label>
<div>$105.00</div>
</form>
</Modal.Body>
<Modal.Footer>
<Button onClick={this.props.onHide}>Cancel</Button>
<Button bsStyle="danger" onClick={this.props.action}>Remove</Button>
</Modal.Footer>
</Modal>);
}
}
const mapStateToProps = (state) => ({
//token: state.auth.token,
//userName: state.auth.userName,
//isAuthenticated: state.auth.isAuthenticated
});
export default connect(mapStateToProps)(NewAccountModal);

View File

@@ -0,0 +1,68 @@
/**
* Created by andrew on 20/02/16.
*/
import React, { PropTypes } from "react";
import * as BS from 'react-bootstrap';
import { PageHeader, OverlayTrigger, Modal, Tooltip, Grid, Col, Row, Nav, NavItem, ButtonGroup, Button, Table } from "react-bootstrap";
import { Link, IndexLink} from "react-router";
import { connect } from "react-redux";
import Select from "react-select";
export class RemoveAccountBookmarkModal extends React.Component {
static propTypes = {
action: PropTypes.func,
account: PropTypes.object
};
handleAction(evt) {
evt.preventDefault();
const { action } = this.props;
const { account } = this.props;
const {
id,
accountId
} = account || {};
if (action) {
action(id || accountId);
}
}
render() {
const { account } = this.props;
const { title: titleRaw,
description: descriptionRaw,
balance: balanceRaw,
id,
accountId } = account || {};
const entityId = id || accountId;
const title = titleRaw || '[No title]';
const balance = ((balanceRaw > 0 && balanceRaw < 1) ? '$0' : '$') + Number(balanceRaw).toFixed(2);
const description = descriptionRaw || '[No description]';
return (<Modal show={this.props.show} onHide={this.props.onHide} key={0}>
<Modal.Header closeButton>
<Modal.Title>Remove Account Bookmark</Modal.Title>
</Modal.Header>
<Modal.Body>
<form className="form-horizontal">
<BS.FormControls.Static label="Title" labelClassName="col-xs-2" wrapperClassName="col-xs-10">{ title }</BS.FormControls.Static>
<BS.FormControls.Static label="Balance" labelClassName="col-xs-2" wrapperClassName="col-xs-10">{ balance }</BS.FormControls.Static>
<BS.FormControls.Static label="Description" labelClassName="col-xs-2" wrapperClassName="col-xs-10">{ description }</BS.FormControls.Static>
</form>
</Modal.Body>
<Modal.Footer>
<Button onClick={this.props.onHide}>Cancel</Button>
<Button bsStyle="danger" eventKey={ entityId } onClick={this.handleAction.bind(this)}>Remove</Button>
</Modal.Footer>
</Modal>);
}
}
export default RemoveAccountBookmarkModal;

View File

@@ -3,4 +3,4 @@
*/
export { default as Add3rdPartyAccountModal } from './Add3rdPartyAccountModal';
export { default as NewAccountModal } from './NewAccountModal';
export { default as RemoveAccountBookmarkModal } from './RemoveAccountBookmarkModal';
export { default as RemoveAccountBookmarkModal } from './RemoveAccountModal';