This repository has been archived by the owner on Nov 17, 2023. It is now read-only.
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add components for updated Pay form and build out reference use case in the storybook environment.
- Loading branch information
Showing
22 changed files
with
2,138 additions
and
6 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
import React from 'react' | ||
import PropTypes from 'prop-types' | ||
import { FormattedMessage } from 'react-intl' | ||
import { Box, Flex, Text } from 'rebass' | ||
import BigArrowLeft from 'components/Icon/BigArrowLeft' | ||
import { Button } from 'components/UI' | ||
import messages from './messages' | ||
|
||
/** | ||
* Buttons for Pay. | ||
*/ | ||
class PayButtons extends React.PureComponent { | ||
static propTypes = { | ||
disabled: PropTypes.bool, | ||
nextButtonText: PropTypes.node, | ||
previousStep: PropTypes.func, | ||
processing: PropTypes.bool, | ||
showBack: PropTypes.bool, | ||
showSubmit: PropTypes.bool | ||
} | ||
|
||
static defaultProps = { | ||
disabled: false, | ||
nextButtonText: <FormattedMessage {...messages.next} />, | ||
previousStep: () => ({}), | ||
processing: false, | ||
showBack: true, | ||
showSubmit: true | ||
} | ||
|
||
render() { | ||
const { | ||
disabled, | ||
nextButtonText, | ||
previousStep, | ||
processing, | ||
showBack, | ||
showSubmit, | ||
...rest | ||
} = this.props | ||
return ( | ||
<Flex {...rest} justifyContent="space-between" alignItems="center"> | ||
<Box width={1 / 5}> | ||
{showBack && ( | ||
<Button | ||
type="button" | ||
variant="secondary" | ||
onClick={previousStep} | ||
px={0} | ||
disabled={processing} | ||
> | ||
<Flex> | ||
<Text> | ||
<BigArrowLeft /> | ||
</Text> | ||
<Text ml={1}> | ||
<FormattedMessage {...messages.back} /> | ||
</Text> | ||
</Flex> | ||
</Button> | ||
)} | ||
</Box> | ||
{showSubmit && ( | ||
<Button type="submit" mx="auto" disabled={disabled || processing} processing={processing}> | ||
{nextButtonText} | ||
</Button> | ||
)} | ||
<Box width={1 / 5} /> | ||
</Flex> | ||
) | ||
} | ||
} | ||
|
||
export default PayButtons |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
import React from 'react' | ||
import PropTypes from 'prop-types' | ||
import { Box } from 'rebass' | ||
import { Heading, Text } from 'components/UI' | ||
import Lightning from 'components/Icon/Lightning' | ||
import Onchain from 'components/Icon/Onchain' | ||
import PaperPlane from 'components/Icon/PaperPlane' | ||
|
||
/** | ||
* Header for opayment form. | ||
*/ | ||
class PayHeader extends React.PureComponent { | ||
static propTypes = { | ||
title: PropTypes.string.isRequired, | ||
type: PropTypes.oneOf(['onchain', 'offchain']) | ||
} | ||
|
||
render() { | ||
const { title, type } = this.props | ||
return ( | ||
<Text textAlign="center"> | ||
<Box mx="auto" css={{ height: '55px' }}> | ||
{type === 'offchain' && <Lightning height="45px" width="45px" />} | ||
{type === 'onchain' && <Onchain height="45px" width="45px" />} | ||
{!type && <PaperPlane height="35px" width="35px" />} | ||
</Box> | ||
<Heading.h1 mx="auto">{title}</Heading.h1> | ||
<Heading.h4 mx="auto"> | ||
| ||
{type === 'onchain' && 'On-Chain Payment'} {type === 'offchain' && 'Lightning Payment'} | ||
</Heading.h4> | ||
</Text> | ||
) | ||
} | ||
} | ||
|
||
export default PayHeader |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,163 @@ | ||
import React from 'react' | ||
import PropTypes from 'prop-types' | ||
import { Box, Flex } from 'rebass' | ||
import { FormattedNumber, FormattedMessage } from 'react-intl' | ||
import lightningPayReq from 'bolt11' | ||
import { satoshisToFiat } from 'lib/utils/btc' | ||
import { getNodeAlias } from 'lib/utils/crypto' | ||
import BigArrowRight from 'components/Icon/BigArrowRight' | ||
import { Bar, Dropdown, Spinner, Text, Truncate } from 'components/UI' | ||
import Value from 'components/Value' | ||
import { PaySummaryRow } from '.' | ||
import messages from './messages' | ||
|
||
class PaySummaryLightning extends React.PureComponent { | ||
static propTypes = { | ||
/** 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, | ||
/** Currently selected fiat currency (key). */ | ||
fiatCurrency: PropTypes.string.isRequired, | ||
/** Boolean indicating wether routing information is currently being fetched. */ | ||
isQueryingRoutes: PropTypes.bool, | ||
/** Maximum fee for the payment */ | ||
maxFee: PropTypes.number, | ||
/** Minimumfee for the payment */ | ||
minFee: PropTypes.number, | ||
/** List of nodes as returned by lnd */ | ||
nodes: PropTypes.array, | ||
/** Lightning Payment request */ | ||
payReq: PropTypes.string.isRequired, | ||
|
||
/** Set the current cryptocurrency. */ | ||
setCryptoCurrency: PropTypes.func.isRequired | ||
} | ||
|
||
static defaultProps = { | ||
isQueryingRoutes: false, | ||
minFee: null, | ||
maxFee: null, | ||
nodes: [] | ||
} | ||
|
||
render() { | ||
const { | ||
cryptoCurrency, | ||
cryptoCurrencyTicker, | ||
cryptoCurrencies, | ||
currentTicker, | ||
fiatCurrency, | ||
isQueryingRoutes, | ||
maxFee, | ||
minFee, | ||
nodes, | ||
payReq, | ||
setCryptoCurrency | ||
} = this.props | ||
|
||
let invoice | ||
try { | ||
invoice = lightningPayReq.decode(payReq) | ||
} catch (e) { | ||
return null | ||
} | ||
|
||
const { satoshis, payeeNodeKey } = invoice | ||
const descriptionTag = invoice.tags.find(tag => tag.tagName === 'description') || {} | ||
const memo = descriptionTag.data | ||
const fiatAmount = satoshisToFiat(satoshis, currentTicker[fiatCurrency].last) | ||
const nodeAlias = getNodeAlias(payeeNodeKey, nodes) | ||
|
||
return ( | ||
<React.Fragment> | ||
<Box pb={2}> | ||
<Flex alignItems="center"> | ||
<Box width={5 / 11}> | ||
<Flex flexWrap="wrap" alignItems="baseline"> | ||
<Box> | ||
<Text textAlign="left" fontSize={6}> | ||
<Value value={satoshis} currency={cryptoCurrency} /> | ||
</Text> | ||
</Box> | ||
<Dropdown | ||
activeKey={cryptoCurrency} | ||
items={cryptoCurrencies} | ||
onChange={setCryptoCurrency} | ||
ml={2} | ||
/> | ||
</Flex> | ||
<Text color="gray"> | ||
{'≈ '} | ||
<FormattedNumber currency={fiatCurrency} style="currency" value={fiatAmount} /> | ||
</Text> | ||
</Box> | ||
<Box width={1 / 11}> | ||
<Text textAlign="center" color="lightningOrange"> | ||
<BigArrowRight width="40px" height="28px" /> | ||
</Text> | ||
</Box> | ||
<Box width={5 / 11}> | ||
<Text textAlign="right" className="hint--bottom-left" data-hint={payeeNodeKey}> | ||
{<Truncate text={nodeAlias || payeeNodeKey} />} | ||
</Text> | ||
</Box> | ||
</Flex> | ||
</Box> | ||
|
||
<Bar /> | ||
|
||
<PaySummaryRow | ||
left={<FormattedMessage {...messages.fee} />} | ||
right={ | ||
isQueryingRoutes ? ( | ||
<Flex ml="auto" alignItems="center" justifyContent="flex-end"> | ||
<Text mr={2}> | ||
<FormattedMessage {...messages.searching_routes} /> | ||
… | ||
</Text> | ||
<Spinner color="lightningOrange" /> | ||
</Flex> | ||
) : minFee === null || maxFee === null ? ( | ||
<FormattedMessage {...messages.unknown} /> | ||
) : ( | ||
<FormattedMessage {...messages.fee_range} values={{ minFee, maxFee }} /> | ||
) | ||
} | ||
/> | ||
|
||
<Bar /> | ||
|
||
<PaySummaryRow | ||
left={<FormattedMessage {...messages.total} />} | ||
right={ | ||
<React.Fragment> | ||
<Value value={satoshis} currency={cryptoCurrency} /> {cryptoCurrencyTicker} | ||
{!isQueryingRoutes && | ||
maxFee && ( | ||
<Text fontSize="s"> | ||
(+ <FormattedMessage {...messages.upto} /> {maxFee} msats) | ||
</Text> | ||
)} | ||
</React.Fragment> | ||
} | ||
/> | ||
|
||
<Bar /> | ||
|
||
{memo && <PaySummaryRow left={<FormattedMessage {...messages.memo} />} right={memo} />} | ||
</React.Fragment> | ||
) | ||
} | ||
} | ||
|
||
export default PaySummaryLightning |
Oops, something went wrong.