Transfers (entire patch: list & make transfer) + Specific controls
This commit is contained in:
@@ -89,7 +89,8 @@ export function initialize({cookies, isServer, currentLocation, userAgent} = {})
|
|||||||
emailSignInPath: '/login',
|
emailSignInPath: '/login',
|
||||||
customersPath: '/customers',
|
customersPath: '/customers',
|
||||||
currentUserPath: '/user',
|
currentUserPath: '/user',
|
||||||
accountsPath: '/accounts'
|
accountsPath: '/accounts',
|
||||||
|
transfersPath: '/transfers'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
], {
|
], {
|
||||||
|
|||||||
@@ -59,13 +59,16 @@ export function accountCreate(customerId, payload) {
|
|||||||
return dispatch(authenticate(true));
|
return dispatch(authenticate(true));
|
||||||
})
|
})
|
||||||
.catch(err => {
|
.catch(err => {
|
||||||
|
debugger;
|
||||||
dispatch(accountCreateError(err));
|
dispatch(accountCreateError(err));
|
||||||
return Promise.resolve({ error: err });
|
return Promise.resolve({ error: err });
|
||||||
|
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export function fetchOwnAccounts(customerId) {
|
export function fetchOwnAccounts(customerId) {
|
||||||
return dispatch => {
|
return dispatch => {
|
||||||
//dispatch(accountsListRequested());
|
//dispatch(accountsListRequested());
|
||||||
@@ -154,9 +157,54 @@ export const createRefOwnerLookup = lookup => {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export const createRefAccountLookup = lookup => {
|
export const createRefAccountLookup = customerId => {
|
||||||
return dispatch => {
|
return dispatch => {
|
||||||
dispatch(createRefAccountLookupStart());
|
dispatch(createRefAccountLookupStart());
|
||||||
dispatch(createRefAccountLookupComplete([]));
|
return api.apiRetrieveUser(customerId)
|
||||||
|
.then(data => {
|
||||||
|
debugger;
|
||||||
|
dispatch(createRefAccountLookupComplete([]));
|
||||||
|
});
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
export const makeTransferRequested = makeActionCreator(T.TRANSFERS.MAKE_START, 'payload');
|
||||||
|
export const makeTransferComplete = makeActionCreator(T.TRANSFERS.MAKE_COMPLETE, 'payload');
|
||||||
|
export const makeTransferError = makeActionCreator(T.TRANSFERS.MAKE_ERROR, 'error');
|
||||||
|
export const makeTransferFormUpdate = makeActionCreator(T.TRANSFERS.MAKE_FORM_UPDATE, 'key', 'value');
|
||||||
|
|
||||||
|
export const makeTransfer = (accountId, payload) => {
|
||||||
|
return dispatch => {
|
||||||
|
dispatch(makeTransferRequested());
|
||||||
|
return api.apiMakeTransfer(accountId, payload)
|
||||||
|
.then(data => {
|
||||||
|
const { moneyTransferId } = data;
|
||||||
|
dispatch(makeTransferComplete(data));
|
||||||
|
return moneyTransferId;
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
dispatch(makeTransferError(err));
|
||||||
|
return err;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getTransfersRequested = makeActionCreator(T.TRANSFERS.LIST_START);
|
||||||
|
export const getTransfersComplete = makeActionCreator(T.TRANSFERS.LIST_COMPLETE, 'payload');
|
||||||
|
export const getTransfersError = makeActionCreator(T.TRANSFERS.LIST_ERROR, 'error');
|
||||||
|
|
||||||
|
export const getTransfers = (accountId) => {
|
||||||
|
return dispatch => {
|
||||||
|
dispatch(getTransfersRequested());
|
||||||
|
return api.apiRetrieveTransfers(accountId)
|
||||||
|
.then(data => {
|
||||||
|
dispatch(getTransfersComplete(data));
|
||||||
|
return data;
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
dispatch(getTransfersError(err));
|
||||||
|
return err;
|
||||||
|
});
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
46
js-frontend/src/components/AccountInfo.js
Normal file
46
js-frontend/src/components/AccountInfo.js
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
/**
|
||||||
|
* Created by andrew on 3/22/16.
|
||||||
|
*/
|
||||||
|
import React from "react";
|
||||||
|
import { connect } from 'react-redux';
|
||||||
|
import Spinner from "react-loader";
|
||||||
|
import * as BS from "react-bootstrap";
|
||||||
|
import * as A from '../actions/entities';
|
||||||
|
|
||||||
|
|
||||||
|
// import { Money } from '../components/Money';
|
||||||
|
|
||||||
|
export class AccountInfo extends React.Component {
|
||||||
|
componentWillMount() {
|
||||||
|
this.ensureData(this.props);
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillReceiveProps(nextProps) {
|
||||||
|
this.ensureData(nextProps);
|
||||||
|
}
|
||||||
|
|
||||||
|
ensureData({ dispatch, entities, accountId }) {
|
||||||
|
if (entities[accountId]) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
dispatch(A.fetchAccount(accountId));
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { entities, accountId } = this.props;
|
||||||
|
|
||||||
|
const account = entities[accountId];
|
||||||
|
|
||||||
|
if (!account) {
|
||||||
|
return (<div>{ accountId } <Spinner ref="spinner" loaded={false} /></div>)
|
||||||
|
}
|
||||||
|
|
||||||
|
const { title } = account;
|
||||||
|
|
||||||
|
return (<div>{ title } </div>);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default connect(({ app }) => ({
|
||||||
|
entities: app.data.entities
|
||||||
|
}))(AccountInfo);
|
||||||
28
js-frontend/src/components/Money.js
Normal file
28
js-frontend/src/components/Money.js
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
/**
|
||||||
|
* Created by andrew on 3/22/16.
|
||||||
|
*/
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
export const moneyText = (amount) => {
|
||||||
|
|
||||||
|
if (Number.isNaN(Number(amount))) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
const absNum = Math.abs(Number(amount) / 100);
|
||||||
|
if (absNum < 0) {
|
||||||
|
return `$(${absNum.toFixed(2)})`;
|
||||||
|
}
|
||||||
|
return `$${absNum.toFixed(2)}`;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const Money = ({ amount }) => {
|
||||||
|
|
||||||
|
if (Number.isNaN(Number(amount))) {
|
||||||
|
return (<span />);
|
||||||
|
}
|
||||||
|
const absNum = Math.abs(Number(amount) / 100);
|
||||||
|
if (absNum < 0) {
|
||||||
|
return (<span className="text-danger">($${ absNum.toFixed(2) })</span>)
|
||||||
|
}
|
||||||
|
return (<span>${ absNum.toFixed(2) }</span>);
|
||||||
|
};
|
||||||
58
js-frontend/src/components/TransfersTable.js
Normal file
58
js-frontend/src/components/TransfersTable.js
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
/**
|
||||||
|
* Created by andrew on 3/22/16.
|
||||||
|
*/
|
||||||
|
import React from "react";
|
||||||
|
import Spinner from "react-loader";
|
||||||
|
import * as BS from "react-bootstrap";
|
||||||
|
|
||||||
|
|
||||||
|
import { Money } from './Money';
|
||||||
|
import AccountInfo from './AccountInfo';
|
||||||
|
|
||||||
|
export class TransfersTable extends React.Component {
|
||||||
|
render() {
|
||||||
|
const { loading, data, errors } = this.props;
|
||||||
|
|
||||||
|
if (loading) {
|
||||||
|
return (<h2><Spinner ref="spinner" loaded={false} /> Loading..</h2>);
|
||||||
|
}
|
||||||
|
if (Object.keys(errors).length) {
|
||||||
|
return (<div className="text-danger">Errors..</div>);
|
||||||
|
}
|
||||||
|
|
||||||
|
const transfers = data.map(({
|
||||||
|
amount,
|
||||||
|
fromAccountId,
|
||||||
|
toAccountId,
|
||||||
|
transactionId,
|
||||||
|
description = '',
|
||||||
|
date = null,
|
||||||
|
status = ''
|
||||||
|
}, idx) => (<tr key={idx}>
|
||||||
|
<td>{ date || 'N/a'}</td>
|
||||||
|
<td><AccountInfo accountId={ fromAccountId } /></td>
|
||||||
|
<td><AccountInfo accountId={ toAccountId } /></td>
|
||||||
|
<td><Money amount={ amount } /></td>
|
||||||
|
<td>{ description || 'N/a'}</td>
|
||||||
|
<td>{ status || 'N/a' }</td>
|
||||||
|
</tr>));
|
||||||
|
|
||||||
|
return (
|
||||||
|
<BS.Table striped bordered condensed hover>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Date</th>
|
||||||
|
<th>What</th>
|
||||||
|
<th>Counter Account</th>
|
||||||
|
<th>Amount</th>
|
||||||
|
<th>Description</th>
|
||||||
|
<th>Status</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{ transfers }
|
||||||
|
</tbody>
|
||||||
|
</BS.Table>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -32,9 +32,6 @@ class Container extends React.Component {
|
|||||||
<LinkContainer to="/" onlyActiveOnIndex={true}>
|
<LinkContainer to="/" onlyActiveOnIndex={true}>
|
||||||
<NavItem eventKey={1}>Home</NavItem>
|
<NavItem eventKey={1}>Home</NavItem>
|
||||||
</LinkContainer>
|
</LinkContainer>
|
||||||
<LinkContainer to="/account">
|
|
||||||
<NavItem eventKey={2}>Account</NavItem>
|
|
||||||
</LinkContainer>
|
|
||||||
</Nav>
|
</Nav>
|
||||||
<div>
|
<div>
|
||||||
<HeaderLinks />
|
<HeaderLinks />
|
||||||
|
|||||||
@@ -58,6 +58,16 @@ export default defineActionTypes({
|
|||||||
DELETE_COMPLETE
|
DELETE_COMPLETE
|
||||||
DELETE_ERROR
|
DELETE_ERROR
|
||||||
`,
|
`,
|
||||||
|
|
||||||
|
TRANSFERS: `
|
||||||
|
MAKE_START
|
||||||
|
MAKE_COMPLETE
|
||||||
|
MAKE_ERROR
|
||||||
|
MAKE_FORM_UPDATE
|
||||||
|
LIST_START
|
||||||
|
LIST_COMPLETE
|
||||||
|
LIST_ERROR
|
||||||
|
`,
|
||||||
|
|
||||||
ERROR: `
|
ERROR: `
|
||||||
START
|
START
|
||||||
|
|||||||
@@ -1,9 +1,6 @@
|
|||||||
/**
|
/**
|
||||||
* Created by andrew on 15/03/16.
|
* Created by andrew on 15/03/16.
|
||||||
*/
|
*/
|
||||||
/**
|
|
||||||
* Created by andrew on 25/02/16.
|
|
||||||
*/
|
|
||||||
import { combineReducers } from 'redux';
|
import { combineReducers } from 'redux';
|
||||||
|
|
||||||
import { accounts } from './accounts';
|
import { accounts } from './accounts';
|
||||||
|
|||||||
@@ -7,39 +7,36 @@
|
|||||||
import T from '../../constants/ACTION_TYPES';
|
import T from '../../constants/ACTION_TYPES';
|
||||||
|
|
||||||
const initialState = {
|
const initialState = {
|
||||||
};
|
|
||||||
|
|
||||||
const nodeInitialState = {
|
|
||||||
loading: false,
|
loading: false,
|
||||||
data: {}
|
errors: {},
|
||||||
|
data: []
|
||||||
};
|
};
|
||||||
|
|
||||||
export const transfers = (state = {...initialState}, action) => {
|
export const transfers = (state = {...initialState}, action) => {
|
||||||
switch(action.type) {
|
switch(action.type) {
|
||||||
case T.ENTITIES.REQUESTED: {
|
|
||||||
const { id } = action;
|
case T.TRANSFERS.LIST_START: {
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
[id]: {
|
loading: true
|
||||||
...nodeInitialState,
|
};
|
||||||
loading: true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
case T.ENTITIES.RECEIVED: {
|
case T.TRANSFERS.LIST_COMPLETE: {
|
||||||
const { id, entity = {} } = action;
|
const { payload } = action;
|
||||||
|
return {
|
||||||
|
...initialState,
|
||||||
|
data: [...payload]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
case T.TRANSFERS.LIST_ERROR: {
|
||||||
|
const { error } = action;
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
[id]: {
|
loading: false,
|
||||||
...(state[id] || nodeInitialState),
|
errors: Object.isSealed(error) ? { message: error } : { ...error }
|
||||||
loading: false,
|
};
|
||||||
data: {
|
|
||||||
...entity
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
case T.ENTITIES.RECEIVED_LIST:
|
|
||||||
default:
|
default:
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,11 +9,14 @@ import { combineReducers } from 'redux';
|
|||||||
import { account } from './account';
|
import { account } from './account';
|
||||||
import { error } from './errors';
|
import { error } from './errors';
|
||||||
import { bookmarkAccount } from './bookmarkAccount';
|
import { bookmarkAccount } from './bookmarkAccount';
|
||||||
|
import { transfersMake } from './transfersMake';
|
||||||
|
|
||||||
|
|
||||||
const uiReducer = combineReducers({
|
const uiReducer = combineReducers({
|
||||||
account,
|
account,
|
||||||
error,
|
error,
|
||||||
bookmarkAccount
|
bookmarkAccount,
|
||||||
|
transfersMake
|
||||||
});
|
});
|
||||||
|
|
||||||
export default uiReducer;
|
export default uiReducer;
|
||||||
54
js-frontend/src/reducers/ui/transfersMake.js
Normal file
54
js-frontend/src/reducers/ui/transfersMake.js
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
/**
|
||||||
|
* Created by andrew on 15/03/16.
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* Created by andrew on 15/03/16.
|
||||||
|
*/
|
||||||
|
import T from '../../constants/ACTION_TYPES';
|
||||||
|
|
||||||
|
const initialState = {
|
||||||
|
loading: false,
|
||||||
|
form: {},
|
||||||
|
errors: {}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const transfersMake = (state = {...initialState}, action) => {
|
||||||
|
switch(action.type) {
|
||||||
|
case T.TRANSFERS.MAKE_START: {
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
loading: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case T.TRANSFERS.MAKE_ERROR: {
|
||||||
|
const { error } = action;
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
loading: false,
|
||||||
|
errors: Object.isSealed(error) ? { message: error } : { ...error }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
case T.TRANSFERS.MAKE_COMPLETE: {
|
||||||
|
return {
|
||||||
|
...initialState
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case T.TRANSFERS.MAKE_FORM_UPDATE: {
|
||||||
|
const { key, value } = action;
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
form: {
|
||||||
|
...state.form,
|
||||||
|
[key]: value
|
||||||
|
},
|
||||||
|
errors: {
|
||||||
|
...state.errors,
|
||||||
|
[key]: null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -7,7 +7,8 @@ import {
|
|||||||
getEmailSignUpUrl,
|
getEmailSignUpUrl,
|
||||||
getCurrentUserUrl,
|
getCurrentUserUrl,
|
||||||
getAccountsUrl,
|
getAccountsUrl,
|
||||||
getCustomersUrl
|
getCustomersUrl,
|
||||||
|
getTransfersUrl
|
||||||
} from "./sessionStorage";
|
} from "./sessionStorage";
|
||||||
import root from './root';
|
import root from './root';
|
||||||
|
|
||||||
@@ -70,6 +71,24 @@ export function apiCreateAccount(customerId, {
|
|||||||
}).then(parseResponse);
|
}).then(parseResponse);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function apiMakeTransfer(fromAccountId, {
|
||||||
|
account, amount, description }) {
|
||||||
|
|
||||||
|
return fetch(getTransfersUrl(), {
|
||||||
|
headers: {
|
||||||
|
"Accept": "application/json",
|
||||||
|
"Content-Type": "application/json"
|
||||||
|
},
|
||||||
|
method: "post",
|
||||||
|
body: root.JSON.stringify({
|
||||||
|
"amount": amount,
|
||||||
|
"fromAccountId": fromAccountId,
|
||||||
|
"toAccountId": account,
|
||||||
|
description
|
||||||
|
})
|
||||||
|
}).then(parseResponse);
|
||||||
|
}
|
||||||
|
|
||||||
export function apiRetrieveAccounts(customerId) {
|
export function apiRetrieveAccounts(customerId) {
|
||||||
|
|
||||||
return fetch(`${getAccountsUrl()}?${makeQuery({ customerId })}`, {
|
return fetch(`${getAccountsUrl()}?${makeQuery({ customerId })}`, {
|
||||||
@@ -81,6 +100,17 @@ export function apiRetrieveAccounts(customerId) {
|
|||||||
}).then(parseResponse);
|
}).then(parseResponse);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function apiRetrieveTransfers(accountId) {
|
||||||
|
|
||||||
|
return fetch(`${getAccountsUrl()}/${accountId}/history`, {
|
||||||
|
headers: {
|
||||||
|
"Accept": "application/json",
|
||||||
|
"Content-Type": "application/json"
|
||||||
|
},
|
||||||
|
method: "get"
|
||||||
|
}).then(parseResponse);
|
||||||
|
}
|
||||||
|
|
||||||
export function apiRetrieveAccount(accountId) {
|
export function apiRetrieveAccount(accountId) {
|
||||||
return fetch(`${getAccountsUrl()}/${accountId}`, {
|
return fetch(`${getAccountsUrl()}/${accountId}`, {
|
||||||
headers: {
|
headers: {
|
||||||
@@ -114,3 +144,13 @@ export function apiRetrieveUsers(email) {
|
|||||||
method: "get"
|
method: "get"
|
||||||
}).then(parseResponse);
|
}).then(parseResponse);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function apiRetrieveUser(customerId) {
|
||||||
|
return fetch(`${getCustomersUrl()}?${makeQuery({ customerId })}`, {
|
||||||
|
headers: {
|
||||||
|
"Accept": "application/json",
|
||||||
|
"Content-Type": "application/json"
|
||||||
|
},
|
||||||
|
method: "get"
|
||||||
|
}).then(parseResponse);
|
||||||
|
}
|
||||||
|
|||||||
@@ -23,7 +23,11 @@ export function parseResponse (response) {
|
|||||||
message.replace(jvmPattern, (m, name) => {
|
message.replace(jvmPattern, (m, name) => {
|
||||||
errors[name] = ['Required'];
|
errors[name] = ['Required'];
|
||||||
});
|
});
|
||||||
return { errors };
|
|
||||||
|
if (Object.keys(errors).length) {
|
||||||
|
return { errors };
|
||||||
|
}
|
||||||
|
return { errors: message };
|
||||||
}).then(err => Promise.reject(err));
|
}).then(err => Promise.reject(err));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -135,6 +135,10 @@ export function getCustomersUrl () {
|
|||||||
return `${getSessionEndpoint().customersPath}`
|
return `${getSessionEndpoint().customersPath}`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getTransfersUrl () {
|
||||||
|
return `${getSessionEndpoint().transfersPath}`
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated
|
* @deprecated
|
||||||
* @param key
|
* @param key
|
||||||
|
|||||||
@@ -9,12 +9,19 @@ import { PageHeader, OverlayTrigger, Tooltip, Grid, Col, Row, Nav, NavItem, Butt
|
|||||||
import * as BS from "react-bootstrap";
|
import * as BS from "react-bootstrap";
|
||||||
import Select from "react-select";
|
import Select from "react-select";
|
||||||
import Spinner from "react-loader";
|
import Spinner from "react-loader";
|
||||||
|
import Input from "../controls/bootstrap/Input";
|
||||||
|
import { Money, moneyText } from '../components/Money';
|
||||||
|
import { TransfersTable } from '../components/TransfersTable';
|
||||||
|
|
||||||
import { Link, IndexLink} from "react-router";
|
import { Link, IndexLink} from "react-router";
|
||||||
|
|
||||||
|
|
||||||
import IndexPanel from "./../components/partials/IndexPanel";
|
import IndexPanel from "./../components/partials/IndexPanel";
|
||||||
import * as Modals from './modals';
|
import * as Modals from './modals';
|
||||||
import * as A from '../actions/entities';
|
import * as A from '../actions/entities';
|
||||||
|
import read from '../utils/readProp';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const resetModals = {
|
const resetModals = {
|
||||||
showAccountModal: false
|
showAccountModal: false
|
||||||
@@ -26,15 +33,20 @@ export class Account extends React.Component {
|
|||||||
this.state = { ...resetModals };
|
this.state = { ...resetModals };
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillMount() {
|
loadAccountInfo() {
|
||||||
const {
|
const {
|
||||||
id: customerId
|
id: customerId
|
||||||
} = this.props.auth.user.attributes;
|
} = this.props.auth.user.attributes;
|
||||||
this.props.dispatch(A.fetchOwnAccounts(customerId));
|
this.props.dispatch(A.fetchOwnAccounts(customerId));
|
||||||
|
|
||||||
const { dispatch, params } = this.props;
|
const { dispatch, params } = this.props;
|
||||||
const { accountId } = params;
|
const { accountId } = params;
|
||||||
dispatch(A.fetchAccount(accountId));
|
dispatch(A.fetchAccount(accountId));
|
||||||
|
dispatch(A.getTransfers(accountId));
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillMount() {
|
||||||
|
this.loadAccountInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
createAccountModal() {
|
createAccountModal() {
|
||||||
@@ -47,9 +59,6 @@ export class Account extends React.Component {
|
|||||||
debugger;
|
debugger;
|
||||||
}
|
}
|
||||||
|
|
||||||
accountChanged(){
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
close() {
|
close() {
|
||||||
this.setState({
|
this.setState({
|
||||||
@@ -57,6 +66,19 @@ export class Account extends React.Component {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
handleInput(key, value) {
|
||||||
|
this.props.dispatch(A.makeTransferFormUpdate(key, value));
|
||||||
|
}
|
||||||
|
initiateTransfer(){
|
||||||
|
const { dispatch, params, transfer } = this.props;
|
||||||
|
const { accountId } = params;
|
||||||
|
dispatch(A.makeTransfer(accountId, transfer.form ))
|
||||||
|
.then(() => {
|
||||||
|
this.loadAccountInfo();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
|
|
||||||
const { showAccountModal } = this.state;
|
const { showAccountModal } = this.state;
|
||||||
@@ -86,7 +108,7 @@ export class Account extends React.Component {
|
|||||||
if (itemAccountId != accountId) {
|
if (itemAccountId != accountId) {
|
||||||
memo.push({
|
memo.push({
|
||||||
value: itemAccountId ,
|
value: itemAccountId ,
|
||||||
label: `${title}: $${ Number(balance).toFixed(2) }`
|
label: `${title}: ${ moneyText(balance) }`
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return memo;
|
return memo;
|
||||||
@@ -101,12 +123,13 @@ export class Account extends React.Component {
|
|||||||
return memo;
|
return memo;
|
||||||
}, []));
|
}, []));
|
||||||
|
|
||||||
const { title: titleRaw, description: descriptionRaw, balance: balanceRaw } = account;
|
const { title: titleRaw, description: descriptionRaw, balance } = account;
|
||||||
|
|
||||||
const title = titleRaw || '[No title]';
|
const title = titleRaw || '[No title]';
|
||||||
const balance = ((balanceRaw > 0 && balanceRaw < 1) ? '$0' : '$') + Number(balanceRaw).toFixed(2);
|
|
||||||
const description = descriptionRaw || '[No description]';
|
const description = descriptionRaw || '[No description]';
|
||||||
|
|
||||||
|
const transferDisabled = this.props.transfer.loading;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<PageHeader>
|
<PageHeader>
|
||||||
@@ -128,7 +151,7 @@ export class Account extends React.Component {
|
|||||||
|
|
||||||
<Row>
|
<Row>
|
||||||
<Col xs={4}>Balance:</Col>
|
<Col xs={4}>Balance:</Col>
|
||||||
<Col xs={8}><strong>{ balance }</strong></Col>
|
<Col xs={8}><strong><Money amount={balance} /></strong></Col>
|
||||||
</Row>
|
</Row>
|
||||||
|
|
||||||
<Row>
|
<Row>
|
||||||
@@ -148,22 +171,45 @@ export class Account extends React.Component {
|
|||||||
<Col xs={4}>
|
<Col xs={4}>
|
||||||
<label>Transfer To:</label>
|
<label>Transfer To:</label>
|
||||||
<Select
|
<Select
|
||||||
value={''}
|
value={read(this.props.transfer, 'form.account', '')}
|
||||||
clearable={false}
|
clearable={true}
|
||||||
options={transferTo}
|
options={transferTo}
|
||||||
onChange={this.accountChanged.bind(this)} />
|
disabled={transferDisabled}
|
||||||
|
onChange={this.handleInput.bind(this, 'account')}
|
||||||
|
/>
|
||||||
</Col>
|
</Col>
|
||||||
<Col xs={3}>
|
<Col xs={3}>
|
||||||
<label>Amount:</label>
|
<Input type="text"
|
||||||
<BS.Input type="text" />
|
className=""
|
||||||
|
label="Amount:"
|
||||||
|
placeholder="Amount"
|
||||||
|
name="amount"
|
||||||
|
addonBefore={
|
||||||
|
(<BS.Glyphicon glyph="usd" />)
|
||||||
|
}
|
||||||
|
addonAfter=".00"
|
||||||
|
disabled={transferDisabled}
|
||||||
|
value={read(this.props.transfer, 'form.amount', '')}
|
||||||
|
errors={read(this.props.transfer, 'errors.amount', []) || []}
|
||||||
|
onChange={this.handleInput.bind(this, 'amount')}
|
||||||
|
/>
|
||||||
</Col>
|
</Col>
|
||||||
<Col xs={3}>
|
<Col xs={3}>
|
||||||
<label>Description:</label>
|
<Input type="textarea"
|
||||||
<BS.Input type="textarea" />
|
className=""
|
||||||
|
label="Description:"
|
||||||
|
placeholder="Description"
|
||||||
|
name="description"
|
||||||
|
disabled={transferDisabled}
|
||||||
|
value={read(this.props.transfer, 'form.description', '') || ''}
|
||||||
|
errors={read(this.props.transfer, 'errors.description', []) || []}
|
||||||
|
onChange={this.handleInput.bind(this, 'description')}
|
||||||
|
/>
|
||||||
</Col>
|
</Col>
|
||||||
<Col xs={2}>
|
<Col xs={2}>
|
||||||
<br/>
|
<br/>
|
||||||
<Button bsStyle="primary">Transfer</Button>
|
<Button bsStyle="primary"
|
||||||
|
onClick={this.initiateTransfer.bind(this)}>Transfer</Button>
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
|
|
||||||
@@ -172,28 +218,7 @@ export class Account extends React.Component {
|
|||||||
<h3>Account History:</h3>
|
<h3>Account History:</h3>
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
<Table>
|
<TransfersTable { ...this.props.transfers } />
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>Date</th>
|
|
||||||
<th>What</th>
|
|
||||||
<th>Counter Account</th>
|
|
||||||
<th>Amount</th>
|
|
||||||
<th>Description</th>
|
|
||||||
<th>Status</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<tr>
|
|
||||||
<td><a href="#">Account Title #1</a></td>
|
|
||||||
<td>$100.00</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><a href="#">Account Title #2</a></td>
|
|
||||||
<td>$100.00</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</Table>
|
|
||||||
|
|
||||||
<Modals.NewAccountModal show={showAccountModal}
|
<Modals.NewAccountModal show={showAccountModal}
|
||||||
action={this.createAccountModalConfirmed.bind(this)}
|
action={this.createAccountModalConfirmed.bind(this)}
|
||||||
@@ -213,5 +238,7 @@ export default connect(({
|
|||||||
}) => ({
|
}) => ({
|
||||||
auth: app.auth,
|
auth: app.auth,
|
||||||
data: app.data,
|
data: app.data,
|
||||||
ui: app.ui.account
|
transfers: app.data.transfers,
|
||||||
|
ui: app.ui.account,
|
||||||
|
transfer: app.ui.transfersMake
|
||||||
}))(Account);
|
}))(Account);
|
||||||
@@ -13,6 +13,8 @@ import IndexPanel from "./../components/partials/IndexPanel";
|
|||||||
|
|
||||||
import * as A from '../actions/entities';
|
import * as A from '../actions/entities';
|
||||||
import read from '../utils/readProp';
|
import read from '../utils/readProp';
|
||||||
|
import { Money } from '../components/Money';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const resetModals = {
|
const resetModals = {
|
||||||
@@ -50,7 +52,11 @@ class MyAccounts extends React.Component {
|
|||||||
this.props.dispatch(A.accountCreate(customerId, payload))
|
this.props.dispatch(A.accountCreate(customerId, payload))
|
||||||
.then(() => {
|
.then(() => {
|
||||||
this.close.bind(this);
|
this.close.bind(this);
|
||||||
this.props.dispatch(A.fetchOwnAccounts(customerId));
|
return this.props.dispatch(A.fetchOwnAccounts(customerId));
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
debugger;
|
||||||
|
this.props.dispatch(A.accountCreateError(err));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -139,7 +145,7 @@ class MyAccounts extends React.Component {
|
|||||||
<span>{ description }</span>
|
<span>{ description }</span>
|
||||||
]: null
|
]: null
|
||||||
}</td>
|
}</td>
|
||||||
<td key={1}>${ balance } </td>
|
<td key={1}><Money amount={balance} /></td>
|
||||||
<td key={2}><BS.Button bsStyle={"link"} onClick={this.remove3rdPartyAccountModal.bind(this, accountId)}><BS.Glyphicon glyph="remove" /></BS.Button></td>
|
<td key={2}><BS.Button bsStyle={"link"} onClick={this.remove3rdPartyAccountModal.bind(this, accountId)}><BS.Glyphicon glyph="remove" /></BS.Button></td>
|
||||||
</tr>
|
</tr>
|
||||||
));
|
));
|
||||||
|
|||||||
@@ -15,22 +15,17 @@ import * as A from '../../actions/entities';
|
|||||||
|
|
||||||
export class Add3rdPartyAccountModal extends React.Component {
|
export class Add3rdPartyAccountModal extends React.Component {
|
||||||
|
|
||||||
|
|
||||||
ownerTypeIn(val) {
|
|
||||||
this.props.dispatch(A.createRefOwnerLookup(val));
|
|
||||||
}
|
|
||||||
|
|
||||||
ownerChanged(argq, arg2, arg3) {
|
|
||||||
debugger;
|
|
||||||
}
|
|
||||||
|
|
||||||
accountChanged(argq, arg2, arg3) {
|
|
||||||
debugger;
|
|
||||||
}
|
|
||||||
|
|
||||||
handleInput(key, value) {
|
handleInput(key, value) {
|
||||||
//this.props.dispatch(A.createRefOwnerLookup(val));
|
this.props.dispatch(A.accountRefCreateFormUpdate(key, value));
|
||||||
debugger;
|
switch(key) {
|
||||||
|
case 'owner':
|
||||||
|
debugger;
|
||||||
|
if (value) {
|
||||||
|
this.props.dispatch(A.createRefAccountLookup(value));
|
||||||
|
} else {
|
||||||
|
this.props.dispatch(A.createRefAccountLookupComplete({}));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getOwnersOptions(input) {
|
getOwnersOptions(input) {
|
||||||
@@ -39,6 +34,7 @@ debugger;
|
|||||||
}
|
}
|
||||||
return this.props.dispatch(A.createRefOwnerLookup(input));
|
return this.props.dispatch(A.createRefOwnerLookup(input));
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
|
||||||
const disabled = false;
|
const disabled = false;
|
||||||
@@ -80,7 +76,7 @@ debugger;
|
|||||||
{value: "bootstrap", label: "Bootstrap"},
|
{value: "bootstrap", label: "Bootstrap"},
|
||||||
{value: "materialUi", label: "Material UI"}
|
{value: "materialUi", label: "Material UI"}
|
||||||
]}
|
]}
|
||||||
onChange={this.accountChanged.bind(this)} />
|
onChange={this.handleInput.bind(this, 'account')} />
|
||||||
|
|
||||||
<Input type="textarea"
|
<Input type="textarea"
|
||||||
className="account-create-description"
|
className="account-create-description"
|
||||||
|
|||||||
@@ -116,7 +116,7 @@ export class NewAccountModal extends React.Component {
|
|||||||
value={read(this.props.account, 'form.title', '')}
|
value={read(this.props.account, 'form.title', '')}
|
||||||
errors={read(this.props.account, 'errors.title', [])}
|
errors={read(this.props.account, 'errors.title', [])}
|
||||||
onChange={this.handleInput.bind(this, "title")}
|
onChange={this.handleInput.bind(this, "title")}
|
||||||
{...this.props.inputProps.title} />
|
/>
|
||||||
|
|
||||||
<Input type="text"
|
<Input type="text"
|
||||||
className="account-create-balance"
|
className="account-create-balance"
|
||||||
@@ -131,7 +131,7 @@ export class NewAccountModal extends React.Component {
|
|||||||
value={read(this.props.account, 'form.balance', '')}
|
value={read(this.props.account, 'form.balance', '')}
|
||||||
errors={read(this.props.account, 'errors.balance', [])}
|
errors={read(this.props.account, 'errors.balance', [])}
|
||||||
onChange={this.handleInput.bind(this, 'balance')}
|
onChange={this.handleInput.bind(this, 'balance')}
|
||||||
{...this.props.inputProps.balance} />
|
/>
|
||||||
|
|
||||||
<Input type="textarea"
|
<Input type="textarea"
|
||||||
className="account-create-description"
|
className="account-create-description"
|
||||||
@@ -139,10 +139,10 @@ export class NewAccountModal extends React.Component {
|
|||||||
placeholder="Description"
|
placeholder="Description"
|
||||||
name="description"
|
name="description"
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
value={read(this.props.account, 'form.description', '')}
|
value={read(this.props.account, 'form.description', '') || ''}
|
||||||
errors={read(this.props.account, 'errors.description', [])}
|
errors={read(this.props.account, 'errors.description', [])}
|
||||||
onChange={this.handleInput.bind(this, 'description')}
|
onChange={this.handleInput.bind(this, 'description')}
|
||||||
{...this.props.inputProps.description} />
|
/>
|
||||||
|
|
||||||
|
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
Reference in New Issue
Block a user