diff --git a/js-frontend/src/App.js b/js-frontend/src/App.js index 31dcd63..33bf6fa 100644 --- a/js-frontend/src/App.js +++ b/js-frontend/src/App.js @@ -87,7 +87,7 @@ export function initialize({cookies, isServer, currentLocation, userAgent} = {}) default: { //apiUrl: '/', emailSignInPath: '/login', - emailRegistrationPath: '/customers', + customersPath: '/customers', currentUserPath: '/user', accountsPath: '/accounts' } diff --git a/js-frontend/src/actions/entities.js b/js-frontend/src/actions/entities.js index 2ec3499..e379a8f 100644 --- a/js-frontend/src/actions/entities.js +++ b/js-frontend/src/actions/entities.js @@ -119,4 +119,44 @@ export function errorMessageTimedOut(error, timeout) { dispatch(errorMessageStop()); }, timeout || 5000); }; -} \ No newline at end of file +} + +export const createRefOwnerLookupStart = makeActionCreator(T.ACCOUNTS.CREATE_REF_OWNER_LOOKUP_START, 'payload'); +export const createRefOwnerLookupComplete = makeActionCreator(T.ACCOUNTS.CREATE_REF_OWNER_LOOKUP_COMPLETE, 'payload'); + +export const createRefAccountLookupStart = makeActionCreator(T.ACCOUNTS.CREATE_REF_ACCOUNT_LOOKUP_START, 'payload'); +export const createRefAccountLookupComplete = makeActionCreator(T.ACCOUNTS.CREATE_REF_ACCOUNT_LOOKUP_COMPLETE, 'payload'); + +export const createRefOwnerLookup = lookup => { + return dispatch => { + dispatch(createRefOwnerLookupStart(lookup)); + return api.apiRetrieveUsers(lookup) + .then(data => { + + const { customers = [] } = data || {}; + + const arr = customers.map(c => { + const { id, name, email } = c; + const fullName = ([name.firstName, name.lastName]).filter(i => i).join(' '); + const label = email ? `${ fullName } (${ email })` : fullName; + return { + value: id, + label + }; + }); + dispatch(createRefOwnerLookupComplete(arr)); + return { options: arr }; + }) + .catch(err => { + dispatch(createRefOwnerLookupComplete(null)); + return { options: [] }; + }); + }; +}; + +export const createRefAccountLookup = lookup => { + return dispatch => { + dispatch(createRefAccountLookupStart()); + dispatch(createRefAccountLookupComplete([])); + }; +}; \ No newline at end of file diff --git a/js-frontend/src/constants/ACTION_TYPES.js b/js-frontend/src/constants/ACTION_TYPES.js index d77fbda..5dfda40 100644 --- a/js-frontend/src/constants/ACTION_TYPES.js +++ b/js-frontend/src/constants/ACTION_TYPES.js @@ -44,6 +44,10 @@ export default defineActionTypes({ CREATE_REF_COMPLETE CREATE_REF_ERROR CREATE_REF_FORM_UPDATE + CREATE_REF_OWNER_LOOKUP_START + CREATE_REF_OWNER_LOOKUP_COMPLETE + CREATE_REF_ACCOUNT_LOOKUP_START + CREATE_REF_ACCOUNT_LOOKUP_COMPLETE `, ACCOUNT: ` diff --git a/js-frontend/src/reducers/data/bookmarkAccount.js b/js-frontend/src/reducers/data/bookmarkAccount.js new file mode 100644 index 0000000..9e4b145 --- /dev/null +++ b/js-frontend/src/reducers/data/bookmarkAccount.js @@ -0,0 +1,113 @@ +/** + * Created by andrew on 18/03/16. + */ +import T from '../../constants/ACTION_TYPES'; + +const optionsLoaderInitialState = { + loading: false, + options: [], + value: '' +}; + +const initialState = { + loading: false, + form: {}, + errors: {}, + accountsDisabled: true, + + ownersLookup: { + ...optionsLoaderInitialState + }, + accountsLookup: { + ...optionsLoaderInitialState + } +}; + +const optionsLoaderReducer = (state = {...optionsLoaderInitialState}, action) => { + switch (action.type) { + case T.ACCOUNTS.CREATE_REF_OWNER_LOOKUP_START: + case T.ACCOUNTS.CREATE_REF_ACCOUNT_LOOKUP_START: { + const value = action.payload; + return { + ...state, + loading: true, + value + }; + } + + case T.ACCOUNTS.CREATE_REF_OWNER_LOOKUP_COMPLETE: + case T.ACCOUNTS.CREATE_REF_ACCOUNT_LOOKUP_COMPLETE: { + const { payload } = action; + return { + ...state, + loading: false, + options: payload === null ? state.options : payload + }; + } + + default: + return state; + } +}; + +export const bookmarkAccount = (state = {...initialState}, action) => { + switch (action.type) { + case T.ACCOUNTS.CREATE_REF_START: { + return { + ...state, + loading: true + }; + } + case T.ACCOUNTS.CREATE_REF_COMPLETE:{ + return { + ...initialState + }; + } + case T.ACCOUNTS.CREATE_REF_ERROR: { + const { error } = action; + return { + ...state, + loading: false, + errors: error + }; + } + case T.ACCOUNTS.CREATE_REF_FORM_UPDATE:{ + const { key, value } = action; + const isOwnerSetBlank = ((key == 'owner') && !value); + const isOwnerSelected = ((key == 'owner') && value); + const nextAccountsDisabled = isOwnerSelected ? false : state.accountsDisabled; + + const nextForm = isOwnerSetBlank ? { + ...state.form, + account: null, + [key]: value + } : { + ...state.form, + [key]: value + }; + return { + ...state, + accountsDisabled: nextAccountsDisabled, + form: nextForm + }; + } + case T.ACCOUNTS.CREATE_REF_OWNER_LOOKUP_START: + case T.ACCOUNTS.CREATE_REF_OWNER_LOOKUP_COMPLETE: { + return { + ...state, + ownersLookup: + optionsLoaderReducer(state.ownersLookup, action) + }; + } + case T.ACCOUNTS.CREATE_REF_ACCOUNT_LOOKUP_START: + case T.ACCOUNTS.CREATE_REF_ACCOUNT_LOOKUP_COMPLETE: { + return { + ...state, + accountsLookup: + optionsLoaderReducer(state.accountsLookup, action) + }; + } + default: + return state; + } +}; \ No newline at end of file diff --git a/js-frontend/src/reducers/data/index.js b/js-frontend/src/reducers/data/index.js index d43d9cc..c91c952 100644 --- a/js-frontend/src/reducers/data/index.js +++ b/js-frontend/src/reducers/data/index.js @@ -9,11 +9,13 @@ import { combineReducers } from 'redux'; import { accounts } from './accounts'; import { transfers } from './transfers'; import { entities } from './entities'; +import { bookmarkAccount } from './bookmarkAccount'; const dataReducer = combineReducers({ transfers, entities, - accounts + accounts, + bookmarkAccount }); export default dataReducer; \ No newline at end of file diff --git a/js-frontend/src/utils/api.js b/js-frontend/src/utils/api.js index cebca74..80c74df 100644 --- a/js-frontend/src/utils/api.js +++ b/js-frontend/src/utils/api.js @@ -6,13 +6,18 @@ import { getEmailSignInUrl, getEmailSignUpUrl, getCurrentUserUrl, - getAccountsUrl + getAccountsUrl, + getCustomersUrl } from "./sessionStorage"; import root from './root'; import { parseResponse } from "./handleFetchResponse"; +function makeQuery(params) { + return Object.keys(params).map(key => [encodeURIComponent(key), encodeURIComponent(params[key])].join('=')).join('&'); +} + export function apiSignIn(body) { return fetch(getEmailSignInUrl(), { headers: { @@ -67,19 +72,12 @@ export function apiCreateAccount(customerId, { export function apiRetrieveAccounts(customerId) { - const params = {customerId }; - const query = Object.keys(params).map(key => [encodeURIComponent(key), encodeURIComponent(params[key])].join('=')).join('&'); - - - return fetch(`${getAccountsUrl()}?${query}`, { + return fetch(`${getAccountsUrl()}?${makeQuery({ customerId })}`, { headers: { "Accept": "application/json", "Content-Type": "application/json" }, - method: "get", - body: { - customerId - } + method: "get" }).then(parseResponse); } @@ -107,16 +105,12 @@ export function apiDeleteAccount(accountId) { }).then(parseResponse); } -export function apiRetrieveUsers(search) { - return fetch(getCurrentUserUrl(), { +export function apiRetrieveUsers(email) { + return fetch(`${getCustomersUrl()}?${makeQuery({ email })}`, { headers: { "Accept": "application/json", "Content-Type": "application/json" }, - method: "get", - body: { - email: search - } + method: "get" }).then(parseResponse); } - diff --git a/js-frontend/src/utils/sessionStorage.js b/js-frontend/src/utils/sessionStorage.js index ffb2f3c..da18eb3 100644 --- a/js-frontend/src/utils/sessionStorage.js +++ b/js-frontend/src/utils/sessionStorage.js @@ -120,7 +120,7 @@ export function getEmailSignInUrl () { } export function getEmailSignUpUrl () { - return `${getSessionEndpoint().emailRegistrationPath}` + return getCustomersUrl(); } export function getCurrentUserUrl () { @@ -131,6 +131,10 @@ export function getAccountsUrl () { return `${getSessionEndpoint().accountsPath}` } +export function getCustomersUrl () { + return `${getSessionEndpoint().customersPath}` +} + /** * @deprecated * @param key diff --git a/js-frontend/src/views/modals/Add3rdPartyAccountModal.js b/js-frontend/src/views/modals/Add3rdPartyAccountModal.js index 890259e..98c21f0 100644 --- a/js-frontend/src/views/modals/Add3rdPartyAccountModal.js +++ b/js-frontend/src/views/modals/Add3rdPartyAccountModal.js @@ -11,11 +11,13 @@ import { Link, IndexLink} from "react-router"; import { connect } from "react-redux"; import Select from "react-select"; +import * as A from '../../actions/entities'; + export class Add3rdPartyAccountModal extends React.Component { - ownerTypeIn(argq, arg2, arg3) { - debugger; + ownerTypeIn(val) { + this.props.dispatch(A.createRefOwnerLookup(val)); } ownerChanged(argq, arg2, arg3) { @@ -26,12 +28,31 @@ export class Add3rdPartyAccountModal extends React.Component { debugger; } - handleInput() {} + handleInput(key, value) { + //this.props.dispatch(A.createRefOwnerLookup(val)); +debugger; + } + getOwnersOptions(input) { + if (!input) { + return Promise.resolve({ options: [] }); + } + return this.props.dispatch(A.createRefOwnerLookup(input)); + } render() { const disabled = false; + const ownersLookup = this.props.data.ownersLookup; + const ownersOptions = ownersLookup.options; + const ownersValue = ownersLookup.value; + const ownersLoading = ownersLookup.loading; + + + // onInputChange={this.ownerTypeIn.bind(this)} + // value={ownersValue} + + return ( @@ -41,18 +62,17 @@ export class Add3rdPartyAccountModal extends React.Component {
({ - ui: app.ui.bookmarkAccount + ui: app.ui.bookmarkAccount, + data: app.data.bookmarkAccount }); export default connect(mapStateToProps)(Add3rdPartyAccountModal); \ No newline at end of file