Browse Source

feature(successmodal): successmodal + fix linting errors

renovate/lint-staged-8.x
Jack Mallers 8 years ago
parent
commit
48bab0561c
  1. 11
      app/animated_checkmark.scss
  2. 3
      app/components/AnimatedCheckmark/AnimatedCheckmark.js
  3. 3
      app/components/AnimatedCheckmark/checkmark.svg
  4. 2
      app/lnd/config/index.js
  5. 1
      app/lnd/methods/index.js
  6. 10
      app/reducers/form.js
  7. 2
      app/reducers/index.js
  8. 47
      app/reducers/modal.js
  9. 9
      app/reducers/payment.js
  10. 1
      app/routes/activity/components/components/Payments.js
  11. 15
      app/routes/app/components/App.js
  12. 16
      app/routes/app/components/components/Form/Form.js
  13. 28
      app/routes/app/components/components/Form/components/Pay/Pay.js
  14. 13
      app/routes/app/components/components/Form/components/Request/Request.js
  15. 42
      app/routes/app/components/components/ModalRoot/ModalRoot.js
  16. 42
      app/routes/app/components/components/ModalRoot/ModalRoot.scss
  17. 40
      app/routes/app/components/components/ModalRoot/SuccessfulSendCoins/SuccessfulSendCoins.js
  18. 37
      app/routes/app/components/components/ModalRoot/SuccessfulSendCoins/SuccessfulSendCoins.scss
  19. 3
      app/routes/app/components/components/ModalRoot/SuccessfulSendCoins/index.js
  20. 3
      app/routes/app/components/components/ModalRoot/index.js
  21. 3
      app/routes/app/containers/AppContainer.js
  22. 7
      test/reducers/__snapshots__/form.spec.js.snap
  23. 5
      test/reducers/__snapshots__/payment.spec.js.snap

11
app/animated_checkmark.scss

@ -1,6 +1,3 @@
// @import "bourbon";
$color--green: #7ac142;
$curve: cubic-bezier(0.650, 0.000, 0.450, 1.000); $curve: cubic-bezier(0.650, 0.000, 0.450, 1.000);
.checkmark__circle { .checkmark__circle {
@ -8,7 +5,7 @@ $curve: cubic-bezier(0.650, 0.000, 0.450, 1.000);
stroke-dashoffset: 166; stroke-dashoffset: 166;
stroke-width: 2; stroke-width: 2;
stroke-miterlimit: 10; stroke-miterlimit: 10;
stroke: $color--green; stroke: $main;
fill: none; fill: none;
animation: stroke .6s $curve forwards; animation: stroke .6s $curve forwards;
} }
@ -17,12 +14,10 @@ $curve: cubic-bezier(0.650, 0.000, 0.450, 1.000);
width: 56px; width: 56px;
height: 56px; height: 56px;
border-radius: 50%; border-radius: 50%;
display: block;
stroke-width: 2; stroke-width: 2;
stroke: #fff; stroke: #fff;
stroke-miterlimit: 10; stroke-miterlimit: 10;
margin: 10% auto; box-shadow: inset 0px 0px 0px $main;
box-shadow: inset 0px 0px 0px $color--green;
animation: fill .4s ease-in-out .4s forwards, scale .3s ease-in-out .9s both; animation: fill .4s ease-in-out .4s forwards, scale .3s ease-in-out .9s both;
} }
@ -50,6 +45,6 @@ $curve: cubic-bezier(0.650, 0.000, 0.450, 1.000);
@keyframes fill { @keyframes fill {
100% { 100% {
box-shadow: inset 0px 0px 0px 30px $color--green; box-shadow: inset 0px 0px 0px 30px $main;
} }
} }

3
app/components/AnimatedCheckmark/AnimatedCheckmark.js

@ -1,7 +1,6 @@
import React from 'react' import React from 'react'
import path from 'path'
import Isvg from 'react-inlinesvg' import Isvg from 'react-inlinesvg'
const AnimatedCheckmark = () => (<Isvg src={'./components/AnimatedCheckmark/checkmark.svg'} />) const AnimatedCheckmark = () => <Isvg src={'./components/AnimatedCheckmark/checkmark.svg'} />
export default AnimatedCheckmark export default AnimatedCheckmark

3
app/components/AnimatedCheckmark/checkmark.svg

@ -1,3 +1,4 @@
<svg class="checkmark" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 52 52"> <svg class="checkmark" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 52 52">
<circle class="checkmark__circle" cx="26" cy="26" r="25" fill="none"/><path class="checkmark__check" fill="none" d="M14.1 27.2l7.1 7.2 16.7-16.8"/> <circle class="checkmark__circle" cx="26" cy="26" r="25" fill="none"/>
<path class="checkmark__check" fill="none" d="M14.1 27.2l7.1 7.2 16.7-16.8"/>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 235 B

After

Width:  |  Height:  |  Size: 238 B

2
app/lnd/config/index.js

@ -7,5 +7,5 @@ import { userInfo } from 'os'
export default { export default {
lightningRpc: `${__dirname}/rpc.proto`, lightningRpc: `${__dirname}/rpc.proto`,
lightningHost: 'localhost:10009', lightningHost: 'localhost:10009',
cert: `/Users/${userInfo().username}/Library/Application\ Support/Lnd/tls.cert` cert: `/Users/${userInfo().username}/Library/Application Support/Lnd/tls.cert`
} }

1
app/lnd/methods/index.js

@ -18,7 +18,6 @@ import * as networkController from './networkController'
// TODO - DeleteAllPayments // TODO - DeleteAllPayments
export default function (lnd, event, msg, data) { export default function (lnd, event, msg, data) {
switch (msg) { switch (msg) {
case 'info': case 'info':

10
app/reducers/form.js

@ -4,7 +4,6 @@ import { createSelector } from 'reselect'
const initialState = { const initialState = {
modalOpen: false, modalOpen: false,
formType: 'pay', formType: 'pay',
paymentType: '',
amount: '0', amount: '0',
onchainAmount: '0', onchainAmount: '0',
message: '', message: '',
@ -19,7 +18,6 @@ export const SET_AMOUNT = 'SET_AMOUNT'
export const SET_ONCHAIN_AMOUNT = 'SET_ONCHAIN_AMOUNT' export const SET_ONCHAIN_AMOUNT = 'SET_ONCHAIN_AMOUNT'
export const SET_MESSAGE = 'SET_MESSAGE' export const SET_MESSAGE = 'SET_MESSAGE'
export const SET_PUBKEY = 'SET_PUBKEY' export const SET_PUBKEY = 'SET_PUBKEY'
export const SET_PAYMENT_TYPE = 'SET_PAYMENT_TYPE'
export const SET_PAYMENT_REQUEST = 'SET_PAYMENT_REQUEST' export const SET_PAYMENT_REQUEST = 'SET_PAYMENT_REQUEST'
export const RESET_FORM = 'RESET_FORM' export const RESET_FORM = 'RESET_FORM'
@ -34,13 +32,6 @@ export function setForm({ modalOpen, formType }) {
} }
} }
export function setPaymentType(paymentType) {
return {
type: SET_PAYMENT_TYPE,
paymentType
}
}
export function setAmount(amount) { export function setAmount(amount) {
return { return {
type: SET_AMOUNT, type: SET_AMOUNT,
@ -91,7 +82,6 @@ const ACTION_HANDLERS = {
[SET_ONCHAIN_AMOUNT]: (state, { onchainAmount }) => ({ ...state, onchainAmount }), [SET_ONCHAIN_AMOUNT]: (state, { onchainAmount }) => ({ ...state, onchainAmount }),
[SET_MESSAGE]: (state, { message }) => ({ ...state, message }), [SET_MESSAGE]: (state, { message }) => ({ ...state, message }),
[SET_PUBKEY]: (state, { pubkey }) => ({ ...state, pubkey }), [SET_PUBKEY]: (state, { pubkey }) => ({ ...state, pubkey }),
[SET_PAYMENT_TYPE]: (state, { paymentType }) => ({ ...state, paymentType }),
[SET_PAYMENT_REQUEST]: (state, { payment_request }) => ({ ...state, payment_request }), [SET_PAYMENT_REQUEST]: (state, { payment_request }) => ({ ...state, payment_request }),
[RESET_FORM]: () => (initialState) [RESET_FORM]: () => (initialState)
} }

2
app/reducers/index.js

@ -9,6 +9,7 @@ import peers from './peers'
import channels from './channels' import channels from './channels'
import form from './form' import form from './form'
import invoice from './invoice' import invoice from './invoice'
import modal from './modal'
import address from './address' import address from './address'
const rootReducer = combineReducers({ const rootReducer = combineReducers({
@ -21,6 +22,7 @@ const rootReducer = combineReducers({
channels, channels,
form, form,
invoice, invoice,
modal,
address address
}) })

47
app/reducers/modal.js

@ -0,0 +1,47 @@
// ------------------------------------
// Initial State
// ------------------------------------
const initialState = {
modalType: null,
modalProps: {}
}
// ------------------------------------
// Constants
// ------------------------------------
export const SHOW_MODAL = 'SHOW_MODAL'
export const HIDE_MODAL = 'HIDE_MODAL'
// ------------------------------------
// Actions
// ------------------------------------
export function showModal(modalType, modalProps) {
return {
type: SHOW_MODAL,
modalType,
modalProps
}
}
export function hideModal() {
return {
type: HIDE_MODAL
}
}
// ------------------------------------
// Action Handlers
// ------------------------------------
const ACTION_HANDLERS = {
[SHOW_MODAL]: (state, { modalType, modalProps }) => ({ ...state, modalType, modalProps }),
[HIDE_MODAL]: () => initialState
}
// ------------------------------------
// Reducer
// ------------------------------------
export default function modalReducer(state = initialState, action) {
const handler = ACTION_HANDLERS[action.type]
return handler ? handler(state, action) : state
}

9
app/reducers/payment.js

@ -2,6 +2,7 @@ import { createSelector } from 'reselect'
import { ipcRenderer } from 'electron' import { ipcRenderer } from 'electron'
import { btc, usd } from '../utils' import { btc, usd } from '../utils'
import { setForm } from './form' import { setForm } from './form'
import { showModal } from './modal'
// ------------------------------------ // ------------------------------------
// Constants // Constants
@ -65,7 +66,7 @@ export const payInvoice = paymentRequest => (dispatch) => {
ipcRenderer.send('lnd', { msg: 'sendPayment', data: { paymentRequest } }) ipcRenderer.send('lnd', { msg: 'sendPayment', data: { paymentRequest } })
} }
export const sendCoins = ({ value, addr, currency, crypto, rate }) => dispatch => { export const sendCoins = ({ value, addr, currency, rate }) => (dispatch) => {
const amount = currency === 'usd' ? btc.btcToSatoshis(usd.usdToBtc(value, rate)) : btc.btcToSatoshis(value) const amount = currency === 'usd' ? btc.btcToSatoshis(usd.usdToBtc(value, rate)) : btc.btcToSatoshis(value)
dispatch(sendPayment()) dispatch(sendPayment())
ipcRenderer.send('lnd', { msg: 'sendCoins', data: { amount, addr } }) ipcRenderer.send('lnd', { msg: 'sendCoins', data: { amount, addr } })
@ -75,12 +76,10 @@ export const sendCoins = ({ value, addr, currency, crypto, rate }) => dispatch =
// TODO: Add payment to state, not a total re-fetch // TODO: Add payment to state, not a total re-fetch
export const paymentSuccessful = () => fetchPayments() export const paymentSuccessful = () => fetchPayments()
export const sendSuccessful = (event, { amount, addr, txid }) => dispatch => { export const sendSuccessful = (event, { amount, addr, txid }) => (dispatch) => {
console.log('amount: ', amount)
console.log('addr: ', addr)
console.log('txid: ', txid)
// Close the form modal once the payment was succesful // Close the form modal once the payment was succesful
dispatch(setForm({ modalOpen: false })) dispatch(setForm({ modalOpen: false }))
dispatch(showModal('SUCCESSFUL_SEND_COINS', { txid, amount, addr }))
// TODO: Add successful on-chain payment to payments list once payments list supports on-chain and LN // TODO: Add successful on-chain payment to payments list once payments list supports on-chain and LN
// dispatch({ type: PAYMENT_SUCCESSFULL, payment: { amount, addr, txid, pending: true } }) // dispatch({ type: PAYMENT_SUCCESSFULL, payment: { amount, addr, txid, pending: true } })
} }

1
app/routes/activity/components/components/Payments.js

@ -3,7 +3,6 @@ import PropTypes from 'prop-types'
import Moment from 'react-moment' import Moment from 'react-moment'
import 'moment-timezone' import 'moment-timezone'
import Modal from './Modal' import Modal from './Modal'
import { FaBolt } from 'react-icons/lib/fa'
import CurrencyIcon from '../../../../components/CurrencyIcon' import CurrencyIcon from '../../../../components/CurrencyIcon'
import { btc } from '../../../../utils' import { btc } from '../../../../utils'
import styles from './Payments.scss' import styles from './Payments.scss'

15
app/routes/app/components/App.js

@ -1,8 +1,8 @@
import React, { Component } from 'react' import React, { Component } from 'react'
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
import ModalRoot from './components/ModalRoot'
import Form from './components/Form' import Form from './components/Form'
import Nav from './components/Nav' import Nav from './components/Nav'
import AnimatedCheckmark from '../../../components/AnimatedCheckmark'
import styles from './App.scss' import styles from './App.scss'
class App extends Component { class App extends Component {
@ -16,6 +16,8 @@ class App extends Component {
render() { render() {
const { const {
modal: { modalType, modalProps },
hideModal,
ticker, ticker,
balance, balance,
invoice: { formInvoice }, invoice: { formInvoice },
@ -29,7 +31,6 @@ class App extends Component {
peers, peers,
setCurrency, setCurrency,
setForm, setForm,
setPaymentType,
createInvoice, createInvoice,
payInvoice, payInvoice,
sendCoins, sendCoins,
@ -44,10 +45,16 @@ class App extends Component {
return ( return (
<div> <div>
<ModalRoot
modalType={modalType}
modalProps={modalProps}
hideModal={hideModal}
currentTicker={currentTicker}
currency={ticker.currency}
/>
<Form <Form
isOpen={form.modalOpen} isOpen={form.modalOpen}
close={() => setForm({ modalOpen: false })} close={() => setForm({ modalOpen: false })}
setPaymentType={setPaymentType}
setAmount={setAmount} setAmount={setAmount}
setOnchainAmount={setOnchainAmount} setOnchainAmount={setOnchainAmount}
setMessage={setMessage} setMessage={setMessage}
@ -82,6 +89,8 @@ class App extends Component {
} }
App.propTypes = { App.propTypes = {
modal: PropTypes.object.isRequired,
hideModal: PropTypes.func.isRequired,
fetchTicker: PropTypes.func.isRequired, fetchTicker: PropTypes.func.isRequired,
fetchBalance: PropTypes.func.isRequired, fetchBalance: PropTypes.func.isRequired,
ticker: PropTypes.object.isRequired, ticker: PropTypes.object.isRequired,

16
app/routes/app/components/components/Form/Form.js

@ -3,14 +3,11 @@ import PropTypes from 'prop-types'
import { MdClose } from 'react-icons/lib/md' import { MdClose } from 'react-icons/lib/md'
import Pay from './components/Pay' import Pay from './components/Pay'
import Request from './components/Request' import Request from './components/Request'
import CurrencyIcon from '../../../../../components/CurrencyIcon'
import { btc } from '../../../../../utils'
import styles from './Form.scss' import styles from './Form.scss'
const Form = ({ const Form = ({
form: { formType, paymentType, amount, onchainAmount, message, payment_request }, form: { formType, amount, onchainAmount, message, payment_request },
payment: { sendingPayment }, payment: { sendingPayment },
setPaymentType,
setAmount, setAmount,
setOnchainAmount, setOnchainAmount,
setMessage, setMessage,
@ -26,9 +23,7 @@ const Form = ({
currentTicker, currentTicker,
isOnchain, isOnchain,
isLn isLn
}) => { }) => (
return (
<div className={`${styles.formContainer} ${isOpen ? styles.open : ''}`}> <div className={`${styles.formContainer} ${isOpen ? styles.open : ''}`}>
<div className={styles.container}> <div className={styles.container}>
<div className={styles.esc} onClick={close}> <div className={styles.esc} onClick={close}>
@ -39,8 +34,6 @@ const Form = ({
formType === 'pay' ? formType === 'pay' ?
<Pay <Pay
sendingPayment={sendingPayment} sendingPayment={sendingPayment}
paymentType={paymentType}
setPaymentType={setPaymentType}
invoiceAmount={formInvoice.amount} invoiceAmount={formInvoice.amount}
onchainAmount={onchainAmount} onchainAmount={onchainAmount}
setOnchainAmount={setOnchainAmount} setOnchainAmount={setOnchainAmount}
@ -56,9 +49,6 @@ const Form = ({
close={close} close={close}
isOnchain={isOnchain} isOnchain={isOnchain}
isLn={isLn} isLn={isLn}
currency={currency}
crypto={crypto}
close={close}
/> />
: :
<Request <Request
@ -79,12 +69,10 @@ const Form = ({
</div> </div>
</div> </div>
) )
}
Form.propTypes = { Form.propTypes = {
payment: PropTypes.object.isRequired, payment: PropTypes.object.isRequired,
form: PropTypes.object.isRequired, form: PropTypes.object.isRequired,
setPaymentType: PropTypes.func.isRequired,
ticker: PropTypes.object.isRequired, ticker: PropTypes.object.isRequired,
setAmount: PropTypes.func.isRequired, setAmount: PropTypes.func.isRequired,
setOnchainAmount: PropTypes.func.isRequired, setOnchainAmount: PropTypes.func.isRequired,

28
app/routes/app/components/components/Form/components/Pay/Pay.js

@ -17,20 +17,16 @@ class Pay extends Component {
render() { render() {
const { const {
sendingPayment, sendingPayment,
paymentType,
setPaymentType,
invoiceAmount, invoiceAmount,
onchainAmount, onchainAmount,
setOnchainAmount, setOnchainAmount,
payment_request, payment_request,
setPaymentRequest, setPaymentRequest,
fetchInvoice,
payInvoice, payInvoice,
sendCoins, sendCoins,
currentTicker, currentTicker,
currency, currency,
crypto, crypto,
close,
isOnchain, isOnchain,
isLn isLn
} = this.props } = this.props
@ -38,7 +34,7 @@ class Pay extends Component {
const payClicked = () => { const payClicked = () => {
if (!isOnchain && !isLn) { return } if (!isOnchain && !isLn) { return }
if (isOnchain) { sendCoins({ value: onchainAmount, addr: payment_request, currency, crypto, rate: currentTicker.price_usd }) } if (isOnchain) { sendCoins({ value: onchainAmount, addr: payment_request, currency, rate: currentTicker.price_usd }) }
if (isLn) { payInvoice(payment_request) } if (isLn) { payInvoice(payment_request) }
} }
@ -54,13 +50,13 @@ class Pay extends Component {
} }
<div className={styles.container}> <div className={styles.container}>
<section className={`${styles.amountContainer} ${paymentType === 'ln' ? styles.ln : ''}`}> <section className={`${styles.amountContainer} ${isLn ? styles.ln : ''}`}>
<label htmlFor='amount'> <label htmlFor='amount'>
<CurrencyIcon currency={currency} crypto={crypto} /> <CurrencyIcon currency={currency} crypto={crypto} />
</label> </label>
<input <input
type='text' type='text'
ref={(input) => this.amountInput = input} ref={input => this.amountInput = input} // eslint-disable-line
size='' size=''
style={ style={
isLn ? isLn ?
@ -83,11 +79,10 @@ class Pay extends Component {
) )
} else if (isLn) { } else if (isLn) {
return ( return (
<span>{`You're about to send ${calculateAmount(invoiceAmount)} ${currency.toUpperCase()} over the Lightning Network which will be instant`}</span> <span>{`You're about to send ${calculateAmount(invoiceAmount)} ${currency.toUpperCase()} over the Lightning Network which will be instant`}</span> // eslint-disable-line
) )
} else {
return null
} }
return null
})()} })()}
</div> </div>
<aside className={styles.paymentIcon}> <aside className={styles.paymentIcon}>
@ -106,9 +101,8 @@ class Pay extends Component {
<FaBolt /> <FaBolt />
</i> </i>
) )
} else {
return null
} }
return null
})()} })()}
{ {
} }
@ -136,13 +130,19 @@ class Pay extends Component {
Pay.propTypes = { Pay.propTypes = {
sendingPayment: PropTypes.bool.isRequired, sendingPayment: PropTypes.bool.isRequired,
amount: PropTypes.string.isRequired, invoiceAmount: PropTypes.string.isRequired,
onchainAmount: PropTypes.string.isRequired,
setOnchainAmount: PropTypes.func.isRequired,
payment_request: PropTypes.string.isRequired,
setPaymentRequest: PropTypes.func.isRequired, setPaymentRequest: PropTypes.func.isRequired,
fetchInvoice: PropTypes.func.isRequired, fetchInvoice: PropTypes.func.isRequired,
payInvoice: PropTypes.func.isRequired, payInvoice: PropTypes.func.isRequired,
sendCoins: PropTypes.func.isRequired,
currentTicker: PropTypes.object.isRequired,
currency: PropTypes.string.isRequired, currency: PropTypes.string.isRequired,
crypto: PropTypes.string.isRequired, crypto: PropTypes.string.isRequired,
close: PropTypes.func.isRequired isOnchain: PropTypes.bool.isRequired,
isLn: PropTypes.bool.isRequired
} }
export default Pay export default Pay

13
app/routes/app/components/components/Form/components/Request/Request.js

@ -6,7 +6,6 @@ import styles from './Request.scss'
const Request = ({ const Request = ({
amount, amount,
setAmount, setAmount,
payment_request,
setMessage, setMessage,
createInvoice, createInvoice,
message, message,
@ -54,6 +53,16 @@ const Request = ({
) )
} }
Request.propTypes = {} Request.propTypes = {
amount: PropTypes.string.isRequired,
setAmount: PropTypes.func.isRequired,
setMessage: PropTypes.func.isRequired,
createInvoice: PropTypes.func.isRequired,
message: PropTypes.string.isRequired,
currentTicker: PropTypes.object.isRequired,
currency: PropTypes.string.isRequired,
crypto: PropTypes.string.isRequired,
close: PropTypes.func.isRequired
}
export default Request export default Request

42
app/routes/app/components/components/ModalRoot/ModalRoot.js

@ -0,0 +1,42 @@
import React from 'react'
import PropTypes from 'prop-types'
import { MdClose } from 'react-icons/lib/md'
import SuccessfulSendCoins from './SuccessfulSendCoins'
import styles from './ModalRoot.scss'
const MODAL_COMPONENTS = {
SUCCESSFUL_SEND_COINS: SuccessfulSendCoins
/* other modals */
}
const ModalRoot = ({ modalType, modalProps, hideModal, currentTicker, currency }) => {
if (!modalType) { return null }
const SpecificModal = MODAL_COMPONENTS[modalType]
return (
<div className={styles.container}>
<div className={styles.content}>
<div className={styles.esc} onClick={hideModal}>
<MdClose />
</div>
<SpecificModal
{...modalProps}
hideModal={hideModal}
currentTicker={currentTicker}
currency={currency}
/>
</div>
</div>
)
}
ModalRoot.propTypes = {
modalType: PropTypes.string,
modalProps: PropTypes.object.isRequired,
hideModal: PropTypes.func.isRequired,
currentTicker: PropTypes.object.isRequired,
currency: PropTypes.string.isRequired
}
export default ModalRoot

42
app/routes/app/components/components/ModalRoot/ModalRoot.scss

@ -0,0 +1,42 @@
@import '../../../../../variables.scss';
.container {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 10;
background: #fff;
}
.content {
position: relative;
height: 100vh;
margin: 5%;
}
.esc {
position: absolute;
top: 0;
right: 0;
color: $darkestgrey;
cursor: pointer;
padding: 20px;
border-radius: 50%;
&:hover {
color: $bluegrey;
background: $darkgrey;
}
&:active {
color: $white;
background: $main;
}
svg {
width: 32px;
height: 32px;
}
}

40
app/routes/app/components/components/ModalRoot/SuccessfulSendCoins/SuccessfulSendCoins.js

@ -0,0 +1,40 @@
import { shell } from 'electron'
import React from 'react'
import PropTypes from 'prop-types'
import AnimatedCheckmark from '../../../../../../components/AnimatedCheckmark'
import { btc } from '../../../../../../utils'
import styles from './SuccessfulSendCoins.scss'
const SuccessfulSendCoins = ({ amount, addr, txid, hideModal, currentTicker, currency }) => {
const calculatedAmount = currency === 'usd' ? btc.satoshisToUsd(amount, currentTicker.price_usd) : btc.satoshisToBtc(amount)
return (
<div className={styles.container}>
<AnimatedCheckmark />
<h1>
You&nbsp;
<span className={styles.link} onClick={() => shell.openExternal(`https://testnet.smartbit.com.au/tx/${txid}`)}>sent</span>&nbsp;
<span className={styles.amount}>{calculatedAmount} {currency.toUpperCase()}</span>&nbsp;
to&nbsp;
<span className={styles.addr}>{addr}</span>
</h1>
<div className={styles.button} onClick={hideModal}>
Done
</div>
</div>
)
}
SuccessfulSendCoins.propTypes = {
amount: PropTypes.oneOf([
PropTypes.number,
PropTypes.string
]).isRequired,
addr: PropTypes.string.isRequired,
txid: PropTypes.string.isRequired,
hideModal: PropTypes.func.isRequired,
currentTicker: PropTypes.object.isRequired,
currency: PropTypes.string.isRequired
}
export default SuccessfulSendCoins

37
app/routes/app/components/components/ModalRoot/SuccessfulSendCoins/SuccessfulSendCoins.scss

@ -0,0 +1,37 @@
@import '../../../../../../variables.scss';
.container {
position: relative;
min-height: 250px;
top: calc(50% - 250px);
text-align: center;
h1 {
font-size: 20px;
margin: 50px 0;
.link {
cursor: pointer;
color: $main;
text-decoration: underline;
}
.amount, .addr {
font-weight: bold;
}
}
.button {
text-align: center;
border-radius: 8px;
background: $main;
padding: 20px 10px;
font-weight: bold;
cursor: pointer;
text-transform: uppercase;
letter-spacing: .2px;
color: $white;
width: 15%;
margin: 0 auto;
}
}

3
app/routes/app/components/components/ModalRoot/SuccessfulSendCoins/index.js

@ -0,0 +1,3 @@
import SuccessfulSendCoins from './SuccessfulSendCoins'
export default SuccessfulSendCoins

3
app/routes/app/components/components/ModalRoot/index.js

@ -0,0 +1,3 @@
import ModalRoot from './ModalRoot'
export default ModalRoot

3
app/routes/app/containers/AppContainer.js

@ -4,6 +4,7 @@ import { fetchTicker, setCurrency, tickerSelectors } from '../../../reducers/tic
import { fetchBalance } from '../../../reducers/balance' import { fetchBalance } from '../../../reducers/balance'
import { fetchInfo } from '../../../reducers/info' import { fetchInfo } from '../../../reducers/info'
import { createInvoice, fetchInvoice } from '../../../reducers/invoice' import { createInvoice, fetchInvoice } from '../../../reducers/invoice'
import { hideModal } from '../../../reducers/modal'
import { payInvoice, sendCoins } from '../../../reducers/payment' import { payInvoice, sendCoins } from '../../../reducers/payment'
import { fetchChannels } from '../../../reducers/channels' import { fetchChannels } from '../../../reducers/channels'
import { import {
@ -30,6 +31,7 @@ const mapDispatchToProps = {
setForm, setForm,
setPaymentType, setPaymentType,
createInvoice, createInvoice,
hideModal,
payInvoice, payInvoice,
sendCoins, sendCoins,
fetchChannels, fetchChannels,
@ -42,6 +44,7 @@ const mapStateToProps = state => ({
payment: state.payment, payment: state.payment,
form: state.form, form: state.form,
invoice: state.invoice, invoice: state.invoice,
modal: state.modal,
currentTicker: tickerSelectors.currentTicker(state), currentTicker: tickerSelectors.currentTicker(state),
isOnchain: formSelectors.isOnchain(state), isOnchain: formSelectors.isOnchain(state),

7
test/reducers/__snapshots__/form.spec.js.snap

@ -6,6 +6,7 @@ Object {
"formType": "pay", "formType": "pay",
"message": "", "message": "",
"modalOpen": false, "modalOpen": false,
"onchainAmount": "0",
"payment_request": "", "payment_request": "",
"pubkey": "", "pubkey": "",
} }
@ -17,6 +18,7 @@ Object {
"formType": "pay", "formType": "pay",
"message": "", "message": "",
"modalOpen": false, "modalOpen": false,
"onchainAmount": "0",
"payment_request": "", "payment_request": "",
"pubkey": "", "pubkey": "",
} }
@ -28,6 +30,7 @@ Object {
"formType": "foo", "formType": "foo",
"message": "", "message": "",
"modalOpen": true, "modalOpen": true,
"onchainAmount": "0",
"payment_request": "", "payment_request": "",
"pubkey": "", "pubkey": "",
} }
@ -39,6 +42,7 @@ Object {
"formType": "pay", "formType": "pay",
"message": "foo", "message": "foo",
"modalOpen": false, "modalOpen": false,
"onchainAmount": "0",
"payment_request": "", "payment_request": "",
"pubkey": "", "pubkey": "",
} }
@ -50,6 +54,7 @@ Object {
"formType": "pay", "formType": "pay",
"message": "", "message": "",
"modalOpen": false, "modalOpen": false,
"onchainAmount": "0",
"payment_request": "foo", "payment_request": "foo",
"pubkey": "", "pubkey": "",
} }
@ -61,6 +66,7 @@ Object {
"formType": "pay", "formType": "pay",
"message": "", "message": "",
"modalOpen": false, "modalOpen": false,
"onchainAmount": "0",
"payment_request": "", "payment_request": "",
"pubkey": "foo", "pubkey": "foo",
} }
@ -72,6 +78,7 @@ Object {
"formType": "pay", "formType": "pay",
"message": "", "message": "",
"modalOpen": false, "modalOpen": false,
"onchainAmount": "0",
"payment_request": "", "payment_request": "",
"pubkey": "", "pubkey": "",
} }

5
test/reducers/__snapshots__/payment.spec.js.snap

@ -5,6 +5,7 @@ Object {
"payment": null, "payment": null,
"paymentLoading": true, "paymentLoading": true,
"payments": Array [], "payments": Array [],
"sendingPayment": false,
} }
`; `;
@ -15,6 +16,7 @@ Object {
"payments": Array [ "payments": Array [
"foo", "foo",
], ],
"sendingPayment": false,
} }
`; `;
@ -26,6 +28,7 @@ Object {
1, 1,
2, 2,
], ],
"sendingPayment": false,
} }
`; `;
@ -34,6 +37,7 @@ Object {
"payment": "foo", "payment": "foo",
"paymentLoading": false, "paymentLoading": false,
"payments": Array [], "payments": Array [],
"sendingPayment": false,
} }
`; `;
@ -42,5 +46,6 @@ Object {
"payment": null, "payment": null,
"paymentLoading": false, "paymentLoading": false,
"payments": Array [], "payments": Array [],
"sendingPayment": false,
} }
`; `;

Loading…
Cancel
Save