Skip to content

Commit

Permalink
plaid iframe; fetching and rendering bank accounts
Browse files Browse the repository at this point in the history
  • Loading branch information
Philip Welber committed Feb 28, 2018
1 parent 6bc19b4 commit f1fe703
Show file tree
Hide file tree
Showing 16 changed files with 396 additions and 54 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import React from 'react'
import styled from 'styled-components'
import { Text } from 'blockchain-info-components'

const BankInfo = styled.div`
display: flex;
flex-direction: row;
padding: 25px 30px;
border: 1px solid #DDD;
input[type="radio"] {
display: none;
}
input[type="radio"]:checked + label:before {
content: '';
width: 16px;
height: 16px;
background-color: #004a7c;
}
`
const BankName = styled(Text)`
text-transform: capitalize;
`
const BankLabel = styled.label`
display: flex;
flex-direction: row;
::before {
content: '';
width: 16px;
height: 16px;
min-width: 16px;
border-radius: 8px;
background-color: white;
border: 1px solid #004a7c;
-webkit-transition: background-color 0.2s;
-o-transition: background-color 0.2s;
transition: background-color 0.2s;
}
`
const BankMeta = styled.div`
margin-left: 15px;
display: flex;
flex-direction: column;
`

const Bank = ({bank}) => (
<BankInfo key={bank._id}>
<input type='radio' name='bank' value={bank} id={bank._id} />

This comment has been minimized.

Copy link
@prwelber

prwelber Feb 28, 2018

Contributor

Tough time wiring up radio inputs and redux form, maybe related to the below issue. I decided to skip redux-form for this part. redux-form/redux-form#3087

<BankLabel htmlFor={bank._id}>
<BankMeta>
<Text size='16px'>
{bank.meta.name} ending in {bank.meta.number}
</Text>
<BankName size='14px'>
{bank.institution_type} Bank
</BankName>
</BankMeta>
</BankLabel>
</BankInfo>
)

export default Bank
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import React, { Component } from 'react'
import styled from 'styled-components'
import { connect } from 'react-redux'
import { bindActionCreators, compose } from 'redux'
// import { formValueSelector } from 'redux-form'
import ui from 'redux-ui'
import { actions } from 'data'

import { Field, reduxForm } from 'redux-form'
import { TextBox, SelectBoxUSState, Form } from 'components/Form'
import { Text } from 'blockchain-info-components'

import Bank from './bank'

const Container = styled.div`
display: flex;
flex-direction: column;
height: 100%;
`

class BankAccounts extends Component {
constructor (props) {
super(props)
this.state = {}
}
render () {
return (
<Container>
<Form>
{
this.props.data.map(bank => {
return (
// <Field name='bank' type='radio' component={Bank} bank={bank} value={bank} />
<Bank bank={bank} />
)
})
}
</Form>
</Container>
)
}
}

const mapStateToProps = (state) => ({
bank: 'bank selection'
})

const mapDispatchToProps = (dispatch) => ({
formActions: bindActionCreators(actions.form, dispatch),
sfoxDataActions: bindActionCreators(actions.core.data.sfox, dispatch)
})

const enhance = compose(
connect(mapStateToProps, mapDispatchToProps),
ui({ state: {} })
)

// export default enhance(BankAccounts)
export default reduxForm({ form: 'sfoxLink' })(enhance(BankAccounts))
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import React from 'react'
import styled from 'styled-components'

const ButtonContainer = styled.div`
border: 1px solid #DDD;
padding: 35px;
margin-top: 15px;
`

const plaidStyled = {
position: 'fixed',
top: '0px',
left: '0px',
right: '0px',
bottom: '0px',
display: 'block',
zIndex: 99999999,
overflowX: 'hidden',
overflowY: 'auto',
height: '100%',
width: '100%'
}

const iframe = (props) => (
<ButtonContainer>
<iframe style={props.enablePlaid ? plaidStyled : { border: 'none', width: '100%', height: '40px' }}
src={props.plaidUrl}
sandbox='allow-same-origin allow-scripts allow-forms allow-popups'
scrolling='no'
id='plaid'
/>
</ButtonContainer>
)

export default iframe
Original file line number Diff line number Diff line change
@@ -1,17 +1,72 @@
import React, { Component } from 'react'
// import { connect } from 'react-redux'
// import { bindActionCreators, compose } from 'redux'
// import ui from 'redux-ui'
// import Upload from './template'
// import { actions } from 'data'
// import { getData } from './selectors'
import { connect } from 'react-redux'
import { bindActionCreators, compose } from 'redux'
import { formValueSelector } from 'redux-form'
import ui from 'redux-ui'
import Link from './template'
import { actions, selectors } from 'data'

class LinkContainer extends Component {
constructor (props) {
super(props)
this.handleSubmit = this.handleSubmit.bind(this)
this.state = { enablePlaid: false }
}

componentWillReceiveProps (nextProps) {
console.log('nextProps', nextProps)
}

componentDidMount () {
let receiveMessage = (e) => {
const plaidWhitelist = ['enablePlaid', 'disablePlaid', 'getBankAccounts']
if (!e.data.command) return
if (e.data.from !== 'plaid') return
if (e.data.to !== 'exchange') return
if (e.origin !== `http://localhost:8081`) return
if (plaidWhitelist.indexOf(e.data.command) < 0) return

if (e.data.command === 'enablePlaid') this.setState({ enablePlaid: true })
if (e.data.command === 'disablePlaid') this.setState({ enablePlaid: false })
if (e.data.command === 'getBankAccounts' && e.data.msg) {
console.log('frontend calls core getBankAccounts', e.data.msg)
this.props.sfoxDataActions.getBankAccounts(e.data.msg)
this.setState({ enablePlaid: false })
}
console.log('listening to message', e)
}
window.addEventListener('message', receiveMessage, false)
}

handleSubmit (e) {
e.preventDefault()
this.props.sfoxDataActions.setProfile(this.props.user)
}

render () {
return (
<div>Link Step</div>
)
const { plaidUrl, bankAccounts } = this.props
return <Link
handleSubmit={this.handleSubmit}
plaidUrl={plaidUrl}
enablePlaid={this.state.enablePlaid}
bankAccounts={bankAccounts}
/>
}
}

export default LinkContainer
const mapStateToProps = (state) => ({
plaidUrl: 'http://localhost:8081/wallet-helper/plaid/#/key/0b041cd9e9fbf1e7d93a0d5a39f5b9/env/production', //TODO: get from wallet options
bankAccounts: selectors.core.data.sfox.getBankAccounts(state)
})

const mapDispatchToProps = (dispatch) => ({
formActions: bindActionCreators(actions.form, dispatch),
sfoxDataActions: bindActionCreators(actions.core.data.sfox, dispatch)
})

const enhance = compose(
connect(mapStateToProps, mapDispatchToProps),
ui({ state: {} })
)

export default enhance(LinkContainer)
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import React from 'react'
import styled from 'styled-components'
import { FormattedMessage } from 'react-intl'
import { Field, reduxForm } from 'redux-form'
import { TextBox, SelectBoxUSState, Form } from 'components/Form'
import { Text, Button, Icon } from 'blockchain-info-components'
import { required, normalizeSocialSecurity, normalizeDateOfBirth, normalizeUSZipcode, ageOverEighteen } from 'services/FormHelper'

import PlaidFrame from './iframe.js'
import BankAccounts from './bankAccounts.js'

const Row = styled.div`
display: flex;
flex-direction: row;
width: 100%;
`
const ColLeft = styled.div`
width: 40%;
`
const ColRight = styled.div`
width: 60%;
`
const ColLeftInner = styled.div`
width: 80%;
`
const Title = styled.div`
font-size: 20px;
font-weight: 500;
margin-bottom: 20px;
`
const Subtitle = styled.div`
font-size: 16px;
font-weight: 400;
margin-bottom: 15px;
`
const Info = styled.div`
font-size: 14px;
margin-bottom: 10px;
`
const LinkContainer = styled.div`
display: flex;
flex-direction: column;
justify-content: center;
`

const Link = (props) => {
const { plaidUrl, enablePlaid, bankAccounts } = props

console.log('Link template', props)
return (
<Row>
<ColLeft>
<ColLeftInner>
<Title>
<FormattedMessage id='sfoxexchangedata.link.title' defaultMessage='Link Account' />
</Title>
<Subtitle>
<FormattedMessage id='sfoxexchangedata.link.subtitle' defaultMessage='Sync your bank account instantly by securely signing into your bank directly.' />
</Subtitle>
<Info>
<FormattedMessage id='sfoxexchangedata.link.info' defaultMessage='You can also manually add your account by typing your routing number and account information. Please note that manually adding your bank account could take up to 4 business days to process.' />
</Info>
<Info>
<FormattedMessage id='sfoxexchangedata.link.info2' defaultMessage='(PS: Your bank information will be sent directly to SFOX and will not be viewed by or saved to your Blockchain wallet.)' />
</Info>
</ColLeftInner>
</ColLeft>
<ColRight>
<LinkContainer>
<Text>
<FormattedMessage id='sfoxexchangedata.link.selectmethod' defaultMessage='Select Method To Link Your Bank Account' />
</Text>
{
bankAccounts
? <BankAccounts data={bankAccounts.data} />
: <PlaidFrame enablePlaid={enablePlaid} plaidUrl={plaidUrl} />
}
</LinkContainer>
</ColRight>
</Row>
)
}

export default reduxForm({ form: 'sfoxUpload' })(Link)
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,19 @@ const CamHelp = styled.span`
position: absolute;
background: rgba(0, 0, 0, 0.44);
`
const VideoContainer = styled.div`
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
`

const Camera = (props) => (
<div>
<VideoContainer>
<video id='video' />
{/* <CamHelp>Help text here!</CamHelp> */}
<a id='startButton' onClick={props.handleStartClick}>Take photo</a>
</div>
{/* <CamHelp>Help text here</CamHelp> */}
</VideoContainer>
)

class CameraContainer extends Component {
Expand All @@ -36,8 +42,8 @@ class CameraContainer extends Component {
componentDidMount () {
const constraints = this.state.constraints
const getUserMedia = (params) => (
new Promise((resolve, errorCallback) => {
navigator.webkitGetUserMedia.call(navigator, params, resolve, errorCallback)
new Promise((resolve, reject) => {
navigator.webkitGetUserMedia.call(navigator, params, resolve, reject)
})
)

Expand Down Expand Up @@ -89,18 +95,15 @@ class CameraContainer extends Component {
context.drawImage(video, 0, 0, width, height)

const data = canvas.toDataURL('image/png')
console.log('takePicture', this.props)
this.props.setPhoto(data)
}

render () {
return (
<div>
<Camera
handleStartClick={this.handleStartClick}
/>
<span>
<Camera handleStartClick={this.handleStartClick} />
<canvas id='canvas' hidden />
</div>
</span>
)
}
}
Expand Down

0 comments on commit f1fe703

Please sign in to comment.