Skip to content
Permalink
Browse files

feat(ui): implement active autopay list

fix #1778
  • Loading branch information...
korhaliv committed Mar 25, 2019
1 parent a94d46a commit 8c031ff3ffdbf43e8ac15cbaa4f8032385cc8ed2
@@ -1,11 +1,15 @@
import React from 'react'
import { ThemeProvider } from 'styled-components'
import { Panel } from 'components/UI'
import { Panel, Heading } from 'components/UI'
import { FormattedMessage } from 'react-intl'
import AutopayList from 'containers/Autopay/AutopayList'
import AutopayMerchantList from 'containers/Autopay/AutopayMerchantList'
import AutopayCreateModal from 'containers/Autopay/AutopayCreateModal'
import { palette } from 'themes/base'
import createThemeVariant from 'themes/util'
import AutopayHeader from './AutopayHeader'
import AutopayActions from './AutopayActions'
import messages from './messages'

const customiseTheme = theme => {
return createThemeVariant('autopilot', {
@@ -23,6 +27,11 @@ const Autopay = props => (
</Panel.Header>
<Panel.Body css={{ 'overflow-y': 'overlay', 'overflow-x': 'hidden' }}>
<AutopayList mx={4} />
<Heading.h1 mt={4} mx={4}>
<FormattedMessage {...messages.merchant_list_title} />
</Heading.h1>
<AutopayActions mx={4} my={3} />
<AutopayMerchantList mx={4} />
</Panel.Body>
</Panel>
<AutopayCreateModal />
@@ -3,7 +3,7 @@ import { Box } from 'rebass'
import AutopaySearch from 'containers/Autopay/AutopaySearch'

const AutopayActions = props => (
<Box {...props}>
<Box {...props} width={450}>
<AutopaySearch />
</Box>
)
@@ -48,7 +48,11 @@ const TextOverlay = styled(Overlay)`
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3);
`

const AutopayCardView = ({ merchant: { image, nickname, pubkey, isActive }, onClick, ...rest }) => (
const AutopayCardView = ({
merchant: { image, nickname, pubkey, isActive, limit, limitCurrency },
onClick,
...rest
}) => (
<Box {...rest} onClick={() => onClick(`${pubkey}`)}>
<CardWithBg mb="12px" src={image}>
<GradientOverlay />
@@ -57,8 +61,12 @@ const AutopayCardView = ({ merchant: { image, nickname, pubkey, isActive }, onCl
{nickname}
</Heading.h1>
</TextOverlay>
<Overlay alignItems="flex-end" justifyContent="center" mt="12px">
{isActive ? <AutopayLimitBadge /> : <AutopayAddButton />}
<Overlay alignItems="flex-end" justifyContent="center" mt={isActive ? -15 : 12}>
{isActive ? (
<AutopayLimitBadge limit={limit} limitCurrency={limitCurrency} />
) : (
<AutopayAddButton />
)}
</Overlay>
</CardWithBg>
</Box>
File renamed without changes.
@@ -1,12 +1,10 @@
import React from 'react'
import { Box } from 'rebass'
import AutopayActions from './AutopayActions'
import AutopayHeading from './AutopayHeading'

const AutopayHeader = props => (
<Box {...props}>
<AutopayHeading mb={3} />
<AutopayActions mb={3} />
</Box>
)

@@ -1,9 +1,10 @@
import React from 'react'
import PropTypes from 'prop-types'
import { Card, Flex, Box } from 'rebass'

import { themeGet } from 'styled-system'
import styled, { withTheme } from 'styled-components'
import { tint } from 'polished'
import Check from 'components/Icon/Check'

const Gradient = styled(Card)`
background: linear-gradient(
@@ -13,23 +14,28 @@ const Gradient = styled(Card)`
);
`

const AutopayLimitBadge = props => {
const AutopayLimitBadge = ({ limit, limitCurrency, ...rest }) => {
return (
<Gradient
bg="lightningOrange"
borderRadius="50%"
boxShadow={`0 0 24px 0 ${themeGet('colors.lightningOrange')(props)}`}
css={{ height: '35px' }}
width={35}
{...props}
borderRadius="14px"
boxShadow={`0 0 24px 0 ${themeGet('colors.lightningOrange')(rest)}`}
css={{ height: '27px' }}
px={2}
{...rest}
>
<Flex alignItems="center" css={{ height: '100%' }} justifyContent="center">
<Box color="white">
<Check height={20} width={20} />
{limit} {limitCurrency}
</Box>
</Flex>
</Gradient>
)
}

AutopayLimitBadge.propTypes = {
limit: PropTypes.number.isRequired,
limitCurrency: PropTypes.string.isRequired,
}

export default withTheme(AutopayLimitBadge)
@@ -1,37 +1,27 @@
import React from 'react'
import PropTypes from 'prop-types'
import { FormattedMessage } from 'react-intl'
import { Box } from 'rebass'
import styled from 'styled-components'
import AutopayCardView from './AutopayCardView'
import AutopaySearchNoResults from './AutopaySearchNoResults'

const Grid = styled(Box)`
display: grid;
grid-template-columns: repeat(auto-fit, 195px);
grid-gap: 1rem;
`
import { Heading } from 'components/UI'
import AutopayGrid from './AutopayGrid'
import messages from './messages'

const AutopayList = ({ merchants, openAutopayCreateModal, ...rest }) => {
if (merchants.length === 0) {
return <AutopaySearchNoResults {...rest} />
if (!merchants || !merchants.length) {
return null
}

return (
<Box as="article" {...rest}>
<Grid>
{merchants.map(merchant => {
return (
<Box key={merchant.pubkey} py={2}>
<AutopayCardView merchant={merchant} onClick={openAutopayCreateModal} />
</Box>
)
})}
</Grid>
<Heading.h1 mb={3} mt={4}>
<FormattedMessage {...messages.active_list_title} />
</Heading.h1>
<AutopayGrid items={merchants} onClick={openAutopayCreateModal} />
</Box>
)
}

AutopayList.propTypes = {
invoiceCurrencyName: PropTypes.string,
merchants: PropTypes.array,
openAutopayCreateModal: PropTypes.func.isRequired,
}
@@ -3,7 +3,7 @@ import AutopayList from 'components/Autopay/AutopayList'
import { openAutopayCreateModal, autopaySelectors } from 'reducers/autopay'

const mapStateToProps = state => ({
merchants: autopaySelectors.filteredMerchants(state),
merchants: autopaySelectors.autopayListAsArray(state),
})

const mapDispatchToProps = {
@@ -1,5 +1,6 @@
import { createSelector } from 'reselect'
import { contactFormSelectors } from './contactsform'
import { tickerSelectors } from './ticker'

// Initial State
const initialState = {
@@ -134,19 +135,44 @@ autopaySelectors.selectedMerchant = createSelector(
)
}
)

autopaySelectors.filteredMerchants = createSelector(
autopaySelectors.merchants,
autopaySelectors.searchQuery,
autopaySelectors.autopayList,
(merchants, searchQuery, autopayList) => {
const addIsActive = m => ({ ...m, isActive: [m.pubkey] in autopayList })
if (!searchQuery) {
return merchants.map(addIsActive)
const cleanedSearchQuery = searchQuery && searchQuery.toLowerCase()
const filterMerchants = merchant => {
const { nickname, pubkey } = merchant
return (
(!searchQuery || nickname.toLowerCase().includes(cleanedSearchQuery)) &&
!([pubkey] in autopayList)
)
}
const cleanedSearchQuery = searchQuery.toLowerCase()
return merchants
.filter(m => m.nickname.toLowerCase().includes(cleanedSearchQuery))
.map(addIsActive)

return merchants.filter(filterMerchants)
}
)

/**
* Returns array of active autopay entries combined with a corresponding merchant data
*/
autopaySelectors.autopayListAsArray = createSelector(
autopaySelectors.merchants,
autopaySelectors.autopayList,
tickerSelectors.autopayCurrencyName,
(merchants, autopayList, autopayCurrencyName) => {
return merchants.reduce((acc, next) => {
if (autopayList[next.pubkey]) {
acc.push({
...next,
isActive: true,
limit: autopayList[next.pubkey].limit,
limitCurrency: autopayCurrencyName,
})
}
return acc
}, [])
}
)

@@ -205,6 +205,14 @@ tickerSelectors.currencyName = createSelector(
}
)

/**
* Returns autopay limit currency unit name
*/
tickerSelectors.autopayCurrencyName = createSelector(
tickerSelectors.currencyFilters,
currencyFilters => currencyFilters && currencyFilters[currencyFilters.length - 1].name
)

export { tickerSelectors }

// ------------------------------------

0 comments on commit 8c031ff

Please sign in to comment.
You can’t perform that action at this time.