Browse Source

feature(requestform): setup and hooked up request form + successfully created invoice

renovate/lint-staged-8.x
Jack Mallers 7 years ago
parent
commit
cb3dfb0d38
  1. 1
      app/components/Form/PayForm.js
  2. 54
      app/components/Form/RequestForm.js
  3. 110
      app/components/Form/RequestForm.scss
  4. 2
      app/reducers/index.js
  5. 15
      app/reducers/invoice.js
  6. 3
      app/reducers/payform.js
  7. 5
      app/reducers/payment.js
  8. 58
      app/reducers/requestform.js
  9. 5
      app/reducers/transaction.js
  10. 3
      app/routes/app/components/App.js
  11. 4
      app/routes/app/components/components/Nav.js
  12. 18
      app/routes/app/containers/AppContainer.js

1
app/components/Form/PayForm.js

@ -40,6 +40,7 @@ class PayForm extends Component {
return (
<div className={styles.container}>
{showPayLoadingScreen && <LoadingBolt />}
<section className={`${styles.amountContainer} ${isLn ? styles.ln : ''}`}>
<label htmlFor='amount'>
<CurrencyIcon currency={currency} crypto={crypto} />

54
app/components/Form/RequestForm.js

@ -0,0 +1,54 @@
import React from 'react'
import PropTypes from 'prop-types'
import CurrencyIcon from 'components/CurrencyIcon'
import styles from './RequestForm.scss'
const RequestForm = ({
requestform: { amount, memo },
currency,
crypto,
setRequestAmount,
setRequestMemo,
onRequestSubmit
}) => {
return (
<div className={styles.container}>
<section className={styles.amountContainer}>
<label htmlFor='amount'>
<CurrencyIcon currency={currency} crypto={crypto} />
</label>
<input
type='text'
size=''
style={{ width: `${amount.length > 1 ? (amount.length * 15) - 5 : 25}%`, fontSize: `${190 - (amount.length ** 2)}px` }}
value={amount}
onChange={event => setRequestAmount(event.target.value)}
id='amount'
/>
</section>
<section className={styles.inputContainer}>
<label htmlFor='memo'>Request:</label>
<input
type='text'
placeholder='Dinner, Rent, etc'
value={memo}
onChange={event => setRequestMemo(event.target.value)}
id='memo'
/>
</section>
<section className={styles.buttonGroup}>
<div className={styles.button} onClick={onRequestSubmit}>
Request
</div>
</section>
</div>
)
}
RequestForm.propTypes = {
}
export default RequestForm

110
app/components/Form/RequestForm.scss

@ -0,0 +1,110 @@
@import '../../variables.scss';
.container {
margin: 0 auto;
display: flex;
flex-direction: column;
height: 75vh;
justify-content: center;
align-items: center;
}
.amountContainer {
color: $main;
display: flex;
justify-content: center;
min-height: 120px;
margin-bottom: 20px;
label, input[type=text] {
color: inherit;
display: inline-block;
vertical-align: top;
padding: 0;
}
label {
svg {
width: 85px;
height: 85px;
}
svg[data-icon='ltc'] {
margin-right: 10px;
g {
transform: scale(1.75) translate(-5px, -5px);
}
}
}
input[type=text] {
width: 100px;
font-size: 180px;
border: none;
outline: 0;
-webkit-appearance: none;
}
}
.inputContainer {
width: 100%;
display: flex;
justify-content: center;
font-size: 18px;
height: auto;
min-height: 55px;
margin-bottom: 20px;
border: 1px solid $traditionalgrey;
border-radius: 6px;
position: relative;
padding: 0 20px;
label, input[type=text] {
font-size: inherit;
}
label {
padding-top: 19px;
padding-bottom: 12px;
color: $traditionalgrey;
}
input[type=text] {
width: 100%;
border: none;
outline: 0;
-webkit-appearance: none;
height: 55px;
padding: 0 10px;
}
}
.buttonGroup {
width: 100%;
display: flex;
flex-direction: row;
border-radius: 6px;
overflow: hidden;
.button {
cursor: pointer;
height: 55px;
min-height: 55px;
text-transform: none;
font-size: 18px;
transition: opacity .2s ease-out;
background: $main;
color: $white;
border: none;
font-weight: 500;
padding: 0;
width: 100%;
text-align: center;
line-height: 55px;
&:first-child {
border-right: 1px solid lighten($main, 20%);
}
}
}

2
app/reducers/index.js

@ -10,6 +10,7 @@ import channels from './channels'
import form from './form'
import payform from './payform'
import requestform from './requestform'
import invoice from './invoice'
import modal from './modal'
@ -28,6 +29,7 @@ const rootReducer = combineReducers({
form,
payform,
requestform,
invoice,
modal,

15
app/reducers/invoice.js

@ -1,6 +1,10 @@
import { createSelector } from 'reselect'
import { ipcRenderer } from 'electron'
import { setFormType } from './form'
import { setPayInvoice } from './payform'
import { resetRequestForm } from './requestform'
import { showNotification } from '../notifications'
import { btc, usd } from '../utils'
// ------------------------------------
@ -98,7 +102,16 @@ export const createInvoice = (amount, memo, currency, rate) => (dispatch) => {
}
// Receive IPC event for newly created invoice
export const createdInvoice = (event, invoice) => dispatch => dispatch({ type: INVOICE_SUCCESSFUL, invoice })
export const createdInvoice = (event, invoice) => dispatch => {
// Close the form modal once the payment was succesful
dispatch(setFormType(null))
// Add new invoice to invoices list
dispatch({ type: INVOICE_SUCCESSFUL, invoice })
// Reset the payment form
dispatch(resetRequestForm())
}
// Listen for invoice updates pushed from backend from subscribeToInvoices
export const invoiceUpdate = (event, { invoice }) => (dispatch) => {

3
app/reducers/payform.js

@ -47,7 +47,7 @@ export function setPayInvoice(invoice) {
}
}
export function resetForm() {
export function resetPayForm() {
return {
type: RESET_FORM
}
@ -137,7 +137,6 @@ payFormSelectors.showPayLoadingScreen = createSelector(
sendingTransactionSelector,
sendingPaymentSelector,
(sendingTransaction, sendingPayment) => sendingTransaction || sendingPayment
)
export { payFormSelectors }

5
app/reducers/payment.js

@ -1,6 +1,7 @@
import { createSelector } from 'reselect'
import { ipcRenderer } from 'electron'
import { setForm, setFormType, resetForm } from './form'
import { setFormType } from './form'
import { resetPayForm } from './payform'
// ------------------------------------
// Constants
@ -74,7 +75,7 @@ export const paymentSuccessful = () => (dispatch) => {
dispatch(fetchPayments())
// Reset the payment form
dispatch(resetForm())
dispatch(resetPayForm())
}

58
app/reducers/requestform.js

@ -0,0 +1,58 @@
import { createSelector } from 'reselect'
import bitcoin from 'bitcoinjs-lib'
// Initial State
const initialState = {
amount: '0',
memo: ''
}
// Constants
// ------------------------------------
export const SET_REQUEST_AMOUNT = 'SET_REQUEST_AMOUNT'
export const SET_REQUEST_MEMO = 'SET_REQUEST_MEMO'
export const SET_PAY_INVOICE = 'SET_PAY_INVOICE'
export const RESET_FORM = 'RESET_FORM'
// ------------------------------------
// Actions
// ------------------------------------
export function setRequestAmount(amount) {
return {
type: SET_REQUEST_AMOUNT,
amount
}
}
export function setRequestMemo(memo) {
return {
type: SET_REQUEST_MEMO,
memo
}
}
export function resetRequestForm() {
return {
type: RESET_FORM
}
}
// ------------------------------------
// Action Handlers
// ------------------------------------
const ACTION_HANDLERS = {
[SET_REQUEST_AMOUNT]: (state, { amount }) => ({ ...state, amount }),
[SET_REQUEST_MEMO]: (state, { memo }) => ({ ...state, memo }),
[RESET_FORM]: () => (initialState)
}
// ------------------------------------
// Reducer
// ------------------------------------
export default function payFormReducer(state = initialState, action) {
const handler = ACTION_HANDLERS[action.type]
return handler ? handler(state, action) : state
}

5
app/reducers/transaction.js

@ -1,7 +1,8 @@
import { ipcRenderer } from 'electron'
import { showNotification } from '../notifications'
import { btc, usd } from '../utils'
import { setFormType, resetForm } from './form'
import { setFormType } from './form'
import { resetPayForm } from './payform'
import { showModal } from './modal'
// ------------------------------------
@ -60,7 +61,7 @@ export const transactionSuccessful = (event, { amount, addr, txid }) => (dispatc
// dispatch({ type: PAYMENT_SUCCESSFULL, payment: { amount, addr, txid, pending: true } })
dispatch({ type: TRANSACTION_SUCCESSFULL })
// Reset the payment form
dispatch(resetForm())
dispatch(resetPayForm())
}
export const transactionError = () => (dispatch) => {

3
app/routes/app/components/App.js

@ -41,6 +41,7 @@ class App extends Component {
isLn,
openPayForm,
openRequestForm,
formProps,
closeForm,
@ -72,7 +73,9 @@ class App extends Component {
setCurrency={setCurrency}
formClicked={formType => setForm({ modalOpen: true, formType })}
currentTicker={currentTicker}
openPayForm={openPayForm}
openRequestForm={openRequestForm}
/>
<div className={styles.content}>
{children}

4
app/routes/app/components/components/Nav.js

@ -9,7 +9,7 @@ import CurrencyIcon from 'components/CurrencyIcon'
import { btc, usd } from 'utils'
import styles from './Nav.scss'
const Nav = ({ ticker, balance, setCurrency, formClicked, currentTicker, openPayForm }) => (
const Nav = ({ ticker, balance, setCurrency, formClicked, currentTicker, openPayForm, openRequestForm }) => (
<nav className={styles.nav}>
<ul className={styles.info}>
<li className={`${styles.currencies} ${styles.link}`}>
@ -75,7 +75,7 @@ const Nav = ({ ticker, balance, setCurrency, formClicked, currentTicker, openPay
<div className={styles.button} onClick={openPayForm}>
<span>Pay</span>
</div>
<div className={styles.button} onClick={() => formClicked('request')}>
<div className={styles.button} onClick={openRequestForm}>
<span>Request</span>
</div>
</div>

18
app/routes/app/containers/AppContainer.js

@ -21,6 +21,7 @@ import {
} from 'reducers/form'
import { setPayAmount, setPayInput, payFormSelectors } from 'reducers/payform'
import { setRequestAmount, setRequestMemo } from 'reducers/requestform'
import App from '../components/App'
@ -48,6 +49,8 @@ const mapDispatchToProps = {
setPayAmount,
setPayInput,
setRequestAmount,setRequestMemo,
setFormType
}
@ -59,6 +62,7 @@ const mapStateToProps = state => ({
form: state.form,
payform: state.payform,
requestform: state.requestform,
invoice: state.invoice,
modal: state.modal,
@ -107,7 +111,21 @@ const mergeProps = (stateProps, dispatchProps, ownProps) => {
}
const requestFormProps = {
requestform: stateProps.requestform,
currency: stateProps.ticker.currency,
crypto: stateProps.ticker.crypto,
setRequestAmount: dispatchProps.setRequestAmount,
setRequestMemo: dispatchProps.setRequestMemo,
onRequestSubmit: () => {
dispatchProps.createInvoice(
stateProps.requestform.amount,
stateProps.requestform.memo,
stateProps.ticker.currency,
stateProps.currentTicker.price_usd
)
}
}
const formProps = (formType) => {

Loading…
Cancel
Save