import React from 'react' import PropTypes from 'prop-types' import { Box, Flex } from 'rebass' import { FormattedMessage, injectIntl } from 'react-intl' import { convert } from 'lib/utils/btc' import { Bar, Button, CryptoAmountInput, Dropdown, FiatAmountInput, Form, Header, Label, Panel, Text, TextArea } from 'components/UI' import Lightning from 'components/Icon/Lightning' import { RequestSummary } from '.' import messages from './messages' /** * Request form. */ class Request extends React.Component { state = { currentStep: 'form' } static propTypes = { /** Human readable chain name */ cryptoName: PropTypes.string.isRequired, /** Current ticker data as provided by blockchain.info */ currentTicker: PropTypes.object.isRequired, /** Currently selected cryptocurrency (key). */ cryptoCurrency: PropTypes.string.isRequired, /** Ticker symbol of the currently selected cryptocurrency. */ cryptoCurrencyTicker: PropTypes.string.isRequired, /** List of supported cryptocurrencies. */ cryptoCurrencies: PropTypes.arrayOf( PropTypes.shape({ key: PropTypes.string.isRequired, name: PropTypes.string.isRequired }) ).isRequired, /** List of supported fiat currencies. */ fiatCurrencies: PropTypes.array.isRequired, /** Currently selected fiat currency (key). */ fiatCurrency: PropTypes.string.isRequired, /** Boolean indicating wether the form is being processed. If true, form buttons are disabled. */ isProcessing: PropTypes.bool, /** Boolean indicating wether the invoice has already been paid. */ isPaid: PropTypes.bool, /** Lightning Payment request. */ payReq: PropTypes.string, /** Set the current cryptocurrency. */ setCryptoCurrency: PropTypes.func.isRequired, /** Set the current fiat currency */ setFiatCurrency: PropTypes.func.isRequired, /** Create an invoice using the supplied details */ createInvoice: PropTypes.func.isRequired } static defaultProps = { isProcessing: false, isPaid: false, payReq: null } amountInput = React.createRef() componentDidMount() { this.focusAmountInput() } componentDidUpdate(prevProps) { const { payReq } = this.props const { currentStep } = this.state if (payReq !== prevProps.payReq && currentStep === 'form') { this.nextStep() } } /** * Liost of enabled form steps. */ steps = () => { return ['form', 'summary'] } /** * Go back to previous form step. */ previousStep = () => { const { currentStep } = this.state const nextStep = Math.max(this.steps().indexOf(currentStep) - 1, 0) if (currentStep !== nextStep) { this.setState({ currentStep: this.steps()[nextStep] }) } } /** * Progress to next form step. */ nextStep = () => { const { currentStep } = this.state const nextStep = Math.min(this.steps().indexOf(currentStep) + 1, this.steps().length - 1) if (currentStep !== nextStep) { this.setState({ currentStep: this.steps()[nextStep] }) } } /** * Form submit handler. * @param {Object} values submitted form values. */ onSubmit = values => { const { cryptoCurrency, createInvoice } = this.props createInvoice(values.amountCrypto, cryptoCurrency, values.memo) } /** * Store the formApi on the component context to make it available at this.formApi. */ setFormApi = formApi => { this.formApi = formApi } /** * Focus the amount input. */ focusAmountInput = () => { if (this.amountInput.current) { this.amountInput.current.focus() } } /** * set the amountFiat field whenever the crypto amount changes. */ handleAmountCryptoChange = e => { const { cryptoCurrency, currentTicker, fiatCurrency } = this.props const lastPrice = currentTicker[fiatCurrency].last const value = convert(cryptoCurrency, 'fiat', e.target.value, lastPrice) this.formApi.setValue('amountFiat', value) } /** * set the amountCrypto field whenever the fiat amount changes. */ handleAmountFiatChange = e => { const { cryptoCurrency, currentTicker, fiatCurrency } = this.props const lastPrice = currentTicker[fiatCurrency].last const value = convert('fiat', cryptoCurrency, e.target.value, lastPrice) this.formApi.setValue('amountCrypto', value) } /** * Handle changes from the crypto currency dropdown. */ handleCryptoCurrencyChange = value => { const { setCryptoCurrency } = this.props setCryptoCurrency(value) } /** * Handle changes from the fiat currency dropdown. */ handleFiatCurrencyChange = value => { const { setFiatCurrency } = this.props setFiatCurrency(value) } renderHelpText = () => { return ( ) } renderAmountFields = () => { const { cryptoCurrency, cryptoCurrencies, currentTicker, fiatCurrency, fiatCurrencies } = this.props return ( = ) } renderMemoField = () => { const { intl } = this.props return (