From 4b461c0a577322e069317835305974df0f671ac4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Oliveira?= Date: Fri, 17 Sep 2021 11:32:43 +0100 Subject: [PATCH 1/4] feat: overview rework and customer data mosaic view --- .../src/pages/Customers/CustomerData.js | 168 ++++++++++++++++++ .../pages/Customers/CustomerData.styles.js | 34 ++++ .../src/pages/Customers/CustomerProfile.js | 95 +++++++--- .../pages/Customers/CustomerProfile.styles.js | 26 ++- .../Customers/components/CustomerSidebar.js | 38 ++++ .../components/CustomerSidebar.styles.js | 35 ++++ .../Customers/components/TransactionsList.js | 12 +- .../src/pages/Customers/components/index.js | 11 +- 8 files changed, 376 insertions(+), 43 deletions(-) create mode 100644 new-lamassu-admin/src/pages/Customers/CustomerData.js create mode 100644 new-lamassu-admin/src/pages/Customers/CustomerData.styles.js create mode 100644 new-lamassu-admin/src/pages/Customers/components/CustomerSidebar.js create mode 100644 new-lamassu-admin/src/pages/Customers/components/CustomerSidebar.styles.js diff --git a/new-lamassu-admin/src/pages/Customers/CustomerData.js b/new-lamassu-admin/src/pages/Customers/CustomerData.js new file mode 100644 index 00000000..931bbb31 --- /dev/null +++ b/new-lamassu-admin/src/pages/Customers/CustomerData.js @@ -0,0 +1,168 @@ +import { Box, CardContent, Card } from '@material-ui/core' +import Grid from '@material-ui/core/Grid' +import { makeStyles } from '@material-ui/core/styles' +import moment from 'moment' +import * as R from 'ramda' +import { useState, React } from 'react' + +import { Tooltip } from 'src/components/Tooltip' +import { SubpageButton } from 'src/components/buttons' +import { H3 } from 'src/components/typography' +import { ReactComponent as CardIcon } from 'src/styling/icons/ID/card/comet.svg' +import { ReactComponent as PhoneIcon } from 'src/styling/icons/ID/phone/comet.svg' +import { ReactComponent as EditIcon } from 'src/styling/icons/action/edit/disabled.svg' +import { ReactComponent as ReverseListingViewIcon } from 'src/styling/icons/circle buttons/listing-view/white.svg' +import { ReactComponent as ListingViewIcon } from 'src/styling/icons/circle buttons/listing-view/zodiac.svg' +import { ifNotNull } from 'src/utils/nullCheck' + +import styles from './CustomerData.styles.js' +import { Field } from './components' +import { getName } from './helper.js' + +const useStyles = makeStyles(styles) + +const CustomerData = ({ customer, updateCustomer }) => { + const classes = useStyles() + + const idData = R.path(['idCardData'])(customer) + const rawExpirationDate = R.path(['expirationDate'])(idData) + const country = R.path(['country'])(idData) + const rawDob = R.path(['dateOfBirth'])(idData) + + const nameElements = [ + { + header: 'Name', + display: `${getName(customer)}`, + size: 190 + } + ] + + const idScanElementsFirstRow = [ + { + header: 'Name', + display: `${getName(customer)}`, + size: 190 + }, + { + header: 'ID number', + display: R.path(['documentNumber'])(idData), + size: 160 + }, + { + header: 'Age', + display: ifNotNull( + rawDob, + moment.utc().diff(moment.utc(rawDob).format('YYYY-MM-DD'), 'years') + ), + size: 50 + } + ] + const idScanElementsSecondRow = [ + { + header: 'Gender', + display: R.path(['gender'])(idData), + size: 80 + }, + { + header: country === 'Canada' ? 'Province' : 'State', + display: R.path(['state'])(idData), + size: 120 + }, + { + header: 'Expiration Date', + display: ifNotNull( + rawExpirationDate, + moment.utc(rawExpirationDate).format('YYYY-MM-DD') + ) + } + ] + + const [listView, setListView] = useState(false) + + return ( +
+
+

{'Customer data'}

+ +
+
+ {listView &&

{''}

} + {!listView && ( + + + + +
+ +

{'Name'}

+ +
+ + {nameElements.map(({ header, display, size }, idx) => ( + + ))} + +
+
+ + +
+ +

{'ID Scan'}

+ +
+ + {idScanElementsFirstRow.map( + ({ header, display, size }, idx) => ( + + ) + )} + + + {idScanElementsSecondRow.map( + ({ header, display, size }, idx) => ( + + ) + )} + +
+
+
+ + + +
+ +

{'SMS Confirmation'}

+ +
+
+
+
+
+ )} +
+
+ ) +} + +export default CustomerData diff --git a/new-lamassu-admin/src/pages/Customers/CustomerData.styles.js b/new-lamassu-admin/src/pages/Customers/CustomerData.styles.js new file mode 100644 index 00000000..dfc21176 --- /dev/null +++ b/new-lamassu-admin/src/pages/Customers/CustomerData.styles.js @@ -0,0 +1,34 @@ +export default { + header: { + display: 'flex', + flexDirection: 'row', + marginBottom: 15 + }, + title: { + marginTop: 7, + marginRight: 20 + }, + leftSideCard: { + borderRadius: 10, + marginRight: 10, + marginBottom: 15 + }, + rightSideCard: { + borderRadius: 10, + marginLeft: 10 + }, + cardHeader: { + display: 'flex', + flexDirection: 'row', + marginBottom: 15 + }, + editIcon: { + marginTop: 5 + }, + cardIcon: { + marginTop: 7 + }, + cardTitle: { + margin: [[8, 15, 15, 15]] + } +} diff --git a/new-lamassu-admin/src/pages/Customers/CustomerProfile.js b/new-lamassu-admin/src/pages/Customers/CustomerProfile.js index 361ae26e..dba6f870 100644 --- a/new-lamassu-admin/src/pages/Customers/CustomerProfile.js +++ b/new-lamassu-admin/src/pages/Customers/CustomerProfile.js @@ -1,6 +1,7 @@ import { useQuery, useMutation } from '@apollo/react-hooks' import { makeStyles, Breadcrumbs, Box } from '@material-ui/core' import NavigateNextIcon from '@material-ui/icons/NavigateNext' +// import classnames from 'classnames' import gql from 'graphql-tag' import * as R from 'ramda' import React, { memo, useState } from 'react' @@ -18,11 +19,13 @@ import { ReactComponent as BlockReversedIcon } from 'src/styling/icons/button/bl import { ReactComponent as BlockIcon } from 'src/styling/icons/button/block/zodiac.svg' import { fromNamespace, namespaces } from 'src/utils/config' +import CustomerData from './CustomerData' import styles from './CustomerProfile.styles' import { CustomerDetails, TransactionsList, - ComplianceDetails + ComplianceDetails, + CustomerSidebar } from './components' import { getFormattedPhone, getName } from './helper' @@ -109,6 +112,7 @@ const CustomerProfile = memo(() => { const classes = useStyles() const history = useHistory() const [showCompliance, setShowCompliance] = useState(false) + const [clickedItem, setClickedItem] = useState('overview') const { id: customerId } = useParams() const { data: customerResponse, refetch: getCustomer, loading } = useQuery( @@ -130,6 +134,8 @@ const CustomerProfile = memo(() => { } }) + const onClickSidebarItem = e => setClickedItem(e.code) + const configData = R.path(['config'])(customerResponse) ?? [] const locale = configData && fromNamespace(namespaces.LOCALE, configData) const customerData = R.path(['customer'])(customerResponse) ?? [] @@ -142,6 +148,8 @@ const CustomerProfile = memo(() => { R.path(['authorizedOverride'])(customerData) === OVERRIDE_REJECTED const isSuspended = customerData.isSuspended + const isCustomerData = clickedItem === 'customerData' + const isOverview = clickedItem === 'overview' return ( <> @@ -164,21 +172,18 @@ const CustomerProfile = memo(() => { )} -
- - setShowCompliance(!showCompliance)} - /> +
+
{!loading && !customerData.isAnonymous && (
+
+ it.code === clickedItem} + onClick={onClickSidebarItem} + /> +
Actions -
+
{isSuspended && ( { )} { {`Retrieve information`}
+
+ {}}> + {`Add individual discount`} + +
)} - +
+
+ {isOverview && ( +
+ + setShowCompliance(!showCompliance)} + /> + + {!showCompliance && ( +
+ +
+ )} + {showCompliance && ( + + )} +
+ )} + {isCustomerData && ( +
+ +
+ )} +
- {!showCompliance && ( - - )} - {showCompliance && ( - - )} ) }) diff --git a/new-lamassu-admin/src/pages/Customers/CustomerProfile.styles.js b/new-lamassu-admin/src/pages/Customers/CustomerProfile.styles.js index 82346d46..0bce506c 100644 --- a/new-lamassu-admin/src/pages/Customers/CustomerProfile.styles.js +++ b/new-lamassu-admin/src/pages/Customers/CustomerProfile.styles.js @@ -15,14 +15,26 @@ export default { customerDetails: { marginBottom: 18 }, - customerActions: { + customerBlock: { display: 'flex', flexDirection: 'row', - '& button': { - marginRight: 15 - }, - '& > :last-child': { - marginRight: 0 - } + margin: [[8, 0, 4, 0]], + padding: [[0, 35, 0]] + }, + customerDiscount: { + display: 'flex', + flexDirection: 'row', + margin: [[0, 0, 4, 0]], + padding: [[0, 34, 0]] + }, + panels: { + display: 'flex' + }, + rightSidePanel: { + display: 'block', + width: 1100 + }, + leftSidePanel: { + width: 300 } } diff --git a/new-lamassu-admin/src/pages/Customers/components/CustomerSidebar.js b/new-lamassu-admin/src/pages/Customers/components/CustomerSidebar.js new file mode 100644 index 00000000..87403d16 --- /dev/null +++ b/new-lamassu-admin/src/pages/Customers/components/CustomerSidebar.js @@ -0,0 +1,38 @@ +import { makeStyles } from '@material-ui/core/styles' +import classnames from 'classnames' +import React from 'react' + +import styles from './CustomerSidebar.styles.js' + +const useStyles = makeStyles(styles) + +const CustomerSidebar = ({ isSelected, onClick }) => { + const classes = useStyles() + const sideBarOptions = [ + { + code: 'overview', + display: 'Overview' + }, + { + code: 'customerData', + display: 'Customer Data' + } + ] + + return ( +
+ {sideBarOptions?.map(it => ( +
onClick(it)}> + {it.display} +
+ ))} +
+ ) +} + +export default CustomerSidebar diff --git a/new-lamassu-admin/src/pages/Customers/components/CustomerSidebar.styles.js b/new-lamassu-admin/src/pages/Customers/components/CustomerSidebar.styles.js new file mode 100644 index 00000000..aa16e91a --- /dev/null +++ b/new-lamassu-admin/src/pages/Customers/components/CustomerSidebar.styles.js @@ -0,0 +1,35 @@ +import typographyStyles from 'src/components/typography/styles' +import { zircon, offDarkColor, white } from 'src/styling/variables' + +const { tl2, p } = typographyStyles + +const sidebarColor = zircon + +export default { + sidebar: { + display: 'flex', + backgroundColor: sidebarColor, + width: 219, + flexDirection: 'column', + borderRadius: 5, + marginBottom: 50 + }, + link: { + extend: p, + position: 'relative', + color: offDarkColor, + padding: 15, + cursor: 'pointer' + }, + activeLink: { + extend: tl2, + color: white, + backgroundColor: offDarkColor, + '&:first-child': { + borderRadius: '5px 5px 0px 0px' + }, + '&:last-child': { + borderRadius: '0px 0px 5px 5px' + } + } +} diff --git a/new-lamassu-admin/src/pages/Customers/components/TransactionsList.js b/new-lamassu-admin/src/pages/Customers/components/TransactionsList.js index 57d9bacf..af5eb959 100644 --- a/new-lamassu-admin/src/pages/Customers/components/TransactionsList.js +++ b/new-lamassu-admin/src/pages/Customers/components/TransactionsList.js @@ -71,8 +71,7 @@ const TransactionsList = ({ customer, data, loading, locale }) => { const tableElements = [ { - header: 'Direction', - width: 207, + width: 75, view: it => ( <> {it.txClass === 'cashOut' ? ( @@ -80,20 +79,19 @@ const TransactionsList = ({ customer, data, loading, locale }) => { ) : ( )} - {it.txClass === 'cashOut' ? 'Cash-out' : 'Cash-in'} ) }, { header: 'Transaction ID', - width: 414, + width: 175, view: it => ( {it.id} ) }, { header: 'Cash', - width: 146, + width: 175, textAlign: 'right', view: it => ( <> @@ -104,7 +102,7 @@ const TransactionsList = ({ customer, data, loading, locale }) => { }, { header: 'Crypto', - width: 142, + width: 175, textAlign: 'right', view: it => ( <> @@ -117,7 +115,7 @@ const TransactionsList = ({ customer, data, loading, locale }) => { }, { header: 'Date', - width: 157, + width: 160, view: it => formatDate(it.created, timezone, 'YYYY-MM-D') }, { diff --git a/new-lamassu-admin/src/pages/Customers/components/index.js b/new-lamassu-admin/src/pages/Customers/components/index.js index 9b0c8945..82827400 100644 --- a/new-lamassu-admin/src/pages/Customers/components/index.js +++ b/new-lamassu-admin/src/pages/Customers/components/index.js @@ -1,6 +1,15 @@ import ComplianceDetails from './ComplianceDetails' import CustomerDetails from './CustomerDetails' +import CustomerSidebar from './CustomerSidebar' +import Field from './Field' import IdDataCard from './IdDataCard' import TransactionsList from './TransactionsList' -export { CustomerDetails, IdDataCard, TransactionsList, ComplianceDetails } +export { + CustomerDetails, + IdDataCard, + TransactionsList, + ComplianceDetails, + CustomerSidebar, + Field +} From 5cc63d05a65e09b0e84a79c0c25d952793a34beb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Oliveira?= Date: Tue, 12 Oct 2021 13:54:36 +0100 Subject: [PATCH 2/4] feat: add icons and make customer data cards editable --- .../src/components/buttons/FeatureButton.js | 4 +- .../src/pages/Customers/CustomerData.js | 125 +++++++------- .../pages/Customers/CustomerData.styles.js | 5 +- .../src/pages/Customers/CustomerProfile.js | 28 +-- .../pages/Customers/CustomerProfile.styles.js | 16 +- .../Customers/components/CustomerSidebar.js | 24 ++- .../components/CustomerSidebar.styles.js | 7 + .../Customers/components/EditableCard.js | 159 ++++++++++++++++++ .../components/EditableCard.styles.js | 13 ++ .../src/pages/Customers/components/index.js | 4 +- .../src/styling/icons/action/edit/comet.svg | 9 + .../styling/icons/button/discount/comet.svg | 8 + .../styling/icons/button/discount/white.svg | 8 + .../styling/icons/button/discount/zodiac.svg | 8 + .../customer-list-view/white.svg | 10 ++ .../customer-list-view/zodiac.svg | 10 ++ .../icons/circle buttons/overview/comet.svg | 10 ++ .../icons/circle buttons/overview/white.svg | 10 ++ .../icons/circle buttons/overview/zodiac.svg | 10 ++ .../styling/icons/customer-nav/data/comet.svg | 9 + .../styling/icons/customer-nav/data/white.svg | 9 + .../icons/customer-nav/data/zodiac.svg | 9 + .../icons/customer-nav/overview/comet.svg | 10 ++ .../icons/customer-nav/overview/white.svg | 10 ++ .../icons/customer-nav/overview/zodiac.svg | 10 ++ 25 files changed, 431 insertions(+), 94 deletions(-) create mode 100644 new-lamassu-admin/src/pages/Customers/components/EditableCard.js create mode 100644 new-lamassu-admin/src/pages/Customers/components/EditableCard.styles.js create mode 100644 new-lamassu-admin/src/styling/icons/action/edit/comet.svg create mode 100644 new-lamassu-admin/src/styling/icons/button/discount/comet.svg create mode 100644 new-lamassu-admin/src/styling/icons/button/discount/white.svg create mode 100644 new-lamassu-admin/src/styling/icons/button/discount/zodiac.svg create mode 100644 new-lamassu-admin/src/styling/icons/circle buttons/customer-list-view/white.svg create mode 100644 new-lamassu-admin/src/styling/icons/circle buttons/customer-list-view/zodiac.svg create mode 100644 new-lamassu-admin/src/styling/icons/circle buttons/overview/comet.svg create mode 100644 new-lamassu-admin/src/styling/icons/circle buttons/overview/white.svg create mode 100644 new-lamassu-admin/src/styling/icons/circle buttons/overview/zodiac.svg create mode 100644 new-lamassu-admin/src/styling/icons/customer-nav/data/comet.svg create mode 100644 new-lamassu-admin/src/styling/icons/customer-nav/data/white.svg create mode 100644 new-lamassu-admin/src/styling/icons/customer-nav/data/zodiac.svg create mode 100644 new-lamassu-admin/src/styling/icons/customer-nav/overview/comet.svg create mode 100644 new-lamassu-admin/src/styling/icons/customer-nav/overview/white.svg create mode 100644 new-lamassu-admin/src/styling/icons/customer-nav/overview/zodiac.svg diff --git a/new-lamassu-admin/src/components/buttons/FeatureButton.js b/new-lamassu-admin/src/components/buttons/FeatureButton.js index 3fe97cd7..86a06c5e 100644 --- a/new-lamassu-admin/src/components/buttons/FeatureButton.js +++ b/new-lamassu-admin/src/components/buttons/FeatureButton.js @@ -32,8 +32,8 @@ const styles = { const useStyles = makeStyles(styles) const FeatureButton = memo( - ({ className, Icon, InverseIcon, children, ...props }) => { - const classes = useStyles() + ({ className, Icon, InverseIcon, children, active, ...props }) => { + const classes = useStyles({ active }) const classNames = { [classes.featureButton]: true, diff --git a/new-lamassu-admin/src/pages/Customers/CustomerData.js b/new-lamassu-admin/src/pages/Customers/CustomerData.js index 931bbb31..efc19626 100644 --- a/new-lamassu-admin/src/pages/Customers/CustomerData.js +++ b/new-lamassu-admin/src/pages/Customers/CustomerData.js @@ -1,4 +1,4 @@ -import { Box, CardContent, Card } from '@material-ui/core' +import { CardContent, Card } from '@material-ui/core' import Grid from '@material-ui/core/Grid' import { makeStyles } from '@material-ui/core/styles' import moment from 'moment' @@ -6,17 +6,20 @@ import * as R from 'ramda' import { useState, React } from 'react' import { Tooltip } from 'src/components/Tooltip' -import { SubpageButton } from 'src/components/buttons' +import { FeatureButton } from 'src/components/buttons' +import { TextInput } from 'src/components/inputs/formik' import { H3 } from 'src/components/typography' import { ReactComponent as CardIcon } from 'src/styling/icons/ID/card/comet.svg' import { ReactComponent as PhoneIcon } from 'src/styling/icons/ID/phone/comet.svg' -import { ReactComponent as EditIcon } from 'src/styling/icons/action/edit/disabled.svg' -import { ReactComponent as ReverseListingViewIcon } from 'src/styling/icons/circle buttons/listing-view/white.svg' -import { ReactComponent as ListingViewIcon } from 'src/styling/icons/circle buttons/listing-view/zodiac.svg' +import { ReactComponent as EditIcon } from 'src/styling/icons/action/edit/comet.svg' +import { ReactComponent as CustomerListViewReversedIcon } from 'src/styling/icons/circle buttons/customer-list-view/white.svg' +import { ReactComponent as CustomerListViewIcon } from 'src/styling/icons/circle buttons/customer-list-view/zodiac.svg' +import { ReactComponent as OverviewReversedIcon } from 'src/styling/icons/circle buttons/overview/white.svg' +import { ReactComponent as OverviewIcon } from 'src/styling/icons/circle buttons/overview/zodiac.svg' import { ifNotNull } from 'src/utils/nullCheck' import styles from './CustomerData.styles.js' -import { Field } from './components' +import { EditableCard } from './components' import { getName } from './helper.js' const useStyles = makeStyles(styles) @@ -31,49 +34,62 @@ const CustomerData = ({ customer, updateCustomer }) => { const nameElements = [ { - header: 'Name', - display: `${getName(customer)}`, + name: 'name', + label: 'Name', + value: `${getName(customer)}` ?? '', + component: TextInput, size: 190 } ] - const idScanElementsFirstRow = [ + const idScanElements = [ { - header: 'Name', - display: `${getName(customer)}`, + name: 'name', + label: 'Name', + value: `${getName(customer)}`, + component: TextInput, size: 190 }, { - header: 'ID number', - display: R.path(['documentNumber'])(idData), + name: 'ID number', + label: 'ID number', + value: R.path(['documentNumber'])(idData), + component: TextInput, size: 160 }, { - header: 'Age', - display: ifNotNull( + name: 'age', + label: 'Age', + value: ifNotNull( rawDob, moment.utc().diff(moment.utc(rawDob).format('YYYY-MM-DD'), 'years') ), + component: TextInput, size: 50 - } - ] - const idScanElementsSecondRow = [ + }, { - header: 'Gender', - display: R.path(['gender'])(idData), + name: 'gender', + label: 'Gender', + value: R.path(['gender'])(idData), + component: TextInput, size: 80 }, { - header: country === 'Canada' ? 'Province' : 'State', - display: R.path(['state'])(idData), + name: country === 'Canada' ? 'province' : 'state', + label: country === 'Canada' ? 'Province' : 'State', + value: R.path(['state'])(idData), + component: TextInput, size: 120 }, { - header: 'Expiration Date', - display: ifNotNull( + name: 'expiration date', + label: 'Expiration Date', + value: ifNotNull( rawExpirationDate, moment.utc(rawExpirationDate).format('YYYY-MM-DD') - ) + ), + component: TextInput, + size: 120 } ] @@ -83,11 +99,20 @@ const CustomerData = ({ customer, updateCustomer }) => {

{'Customer data'}

- + setListView(false)} + variant="contained" + /> + setListView(true)}>
{listView &&

{''}

} @@ -101,16 +126,9 @@ const CustomerData = ({ customer, updateCustomer }) => {

{'Name'}

- - {nameElements.map(({ header, display, size }, idx) => ( - - ))} - + {}}> @@ -120,30 +138,9 @@ const CustomerData = ({ customer, updateCustomer }) => {

{'ID Scan'}

- - {idScanElementsFirstRow.map( - ({ header, display, size }, idx) => ( - - ) - )} - - - {idScanElementsSecondRow.map( - ({ header, display, size }, idx) => ( - - ) - )} - + {}}> diff --git a/new-lamassu-admin/src/pages/Customers/CustomerData.styles.js b/new-lamassu-admin/src/pages/Customers/CustomerData.styles.js index dfc21176..47793122 100644 --- a/new-lamassu-admin/src/pages/Customers/CustomerData.styles.js +++ b/new-lamassu-admin/src/pages/Customers/CustomerData.styles.js @@ -6,7 +6,7 @@ export default { }, title: { marginTop: 7, - marginRight: 20 + marginRight: 24 }, leftSideCard: { borderRadius: 10, @@ -30,5 +30,8 @@ export default { }, cardTitle: { margin: [[8, 15, 15, 15]] + }, + viewIcons: { + marginRight: 12 } } diff --git a/new-lamassu-admin/src/pages/Customers/CustomerProfile.js b/new-lamassu-admin/src/pages/Customers/CustomerProfile.js index dba6f870..1c2d6fe3 100644 --- a/new-lamassu-admin/src/pages/Customers/CustomerProfile.js +++ b/new-lamassu-admin/src/pages/Customers/CustomerProfile.js @@ -1,7 +1,6 @@ import { useQuery, useMutation } from '@apollo/react-hooks' import { makeStyles, Breadcrumbs, Box } from '@material-ui/core' import NavigateNextIcon from '@material-ui/icons/NavigateNext' -// import classnames from 'classnames' import gql from 'graphql-tag' import * as R from 'ramda' import React, { memo, useState } from 'react' @@ -17,6 +16,8 @@ import { ReactComponent as AuthorizeReversedIcon } from 'src/styling/icons/butto import { ReactComponent as AuthorizeIcon } from 'src/styling/icons/button/authorize/zodiac.svg' import { ReactComponent as BlockReversedIcon } from 'src/styling/icons/button/block/white.svg' import { ReactComponent as BlockIcon } from 'src/styling/icons/button/block/zodiac.svg' +import { ReactComponent as DiscountReversedIcon } from 'src/styling/icons/button/discount/white.svg' +import { ReactComponent as Discount } from 'src/styling/icons/button/discount/zodiac.svg' import { fromNamespace, namespaces } from 'src/utils/config' import CustomerData from './CustomerData' @@ -109,7 +110,6 @@ const SET_CUSTOMER = gql` ` const CustomerProfile = memo(() => { - const classes = useStyles() const history = useHistory() const [showCompliance, setShowCompliance] = useState(false) const [clickedItem, setClickedItem] = useState('overview') @@ -134,7 +134,7 @@ const CustomerProfile = memo(() => { } }) - const onClickSidebarItem = e => setClickedItem(e.code) + const onClickSidebarItem = code => setClickedItem(code) const configData = R.path(['config'])(customerResponse) ?? [] const locale = configData && fromNamespace(namespaces.LOCALE, configData) @@ -151,6 +151,8 @@ const CustomerProfile = memo(() => { const isCustomerData = clickedItem === 'customerData' const isOverview = clickedItem === 'overview' + const classes = useStyles({ blocked }) + return ( <> {
it.code === clickedItem} + isSelected={code => code === clickedItem} onClick={onClickSidebarItem} />
Actions +
+ {}}> + {`Add individual discount`} + +
{isSuspended && ( { {`Retrieve information`}
-
- {}}> - {`Add individual discount`} - -
)}
diff --git a/new-lamassu-admin/src/pages/Customers/CustomerProfile.styles.js b/new-lamassu-admin/src/pages/Customers/CustomerProfile.styles.js index 0bce506c..69094460 100644 --- a/new-lamassu-admin/src/pages/Customers/CustomerProfile.styles.js +++ b/new-lamassu-admin/src/pages/Customers/CustomerProfile.styles.js @@ -15,17 +15,17 @@ export default { customerDetails: { marginBottom: 18 }, - customerBlock: { - display: 'flex', - flexDirection: 'row', - margin: [[8, 0, 4, 0]], - padding: [[0, 35, 0]] - }, - customerDiscount: { + customerBlock: props => ({ display: 'flex', flexDirection: 'row', margin: [[0, 0, 4, 0]], - padding: [[0, 34, 0]] + padding: [[0, props.blocked ? 35 : 48, 0]] + }), + customerDiscount: { + display: 'flex', + flexDirection: 'row', + margin: [[8, 0, 4, 0]], + padding: [[0, 24, 0]] }, panels: { display: 'flex' diff --git a/new-lamassu-admin/src/pages/Customers/components/CustomerSidebar.js b/new-lamassu-admin/src/pages/Customers/components/CustomerSidebar.js index 87403d16..57c430ff 100644 --- a/new-lamassu-admin/src/pages/Customers/components/CustomerSidebar.js +++ b/new-lamassu-admin/src/pages/Customers/components/CustomerSidebar.js @@ -2,6 +2,11 @@ import { makeStyles } from '@material-ui/core/styles' import classnames from 'classnames' import React from 'react' +import { ReactComponent as CustomerDataReversedIcon } from 'src/styling/icons/customer-nav/data/comet.svg' +import { ReactComponent as CustomerDataIcon } from 'src/styling/icons/customer-nav/data/white.svg' +import { ReactComponent as OverviewReversedIcon } from 'src/styling/icons/customer-nav/overview/comet.svg' +import { ReactComponent as OverviewIcon } from 'src/styling/icons/customer-nav/overview/white.svg' + import styles from './CustomerSidebar.styles.js' const useStyles = makeStyles(styles) @@ -11,24 +16,31 @@ const CustomerSidebar = ({ isSelected, onClick }) => { const sideBarOptions = [ { code: 'overview', - display: 'Overview' + display: 'Overview', + Icon: OverviewIcon, + InverseIcon: OverviewReversedIcon }, { code: 'customerData', - display: 'Customer Data' + display: 'Customer Data', + Icon: CustomerDataIcon, + InverseIcon: CustomerDataReversedIcon } ] return (
- {sideBarOptions?.map(it => ( + {sideBarOptions?.map(({ Icon, InverseIcon, display, code }) => (
onClick(it)}> - {it.display} + onClick={() => onClick(code)}> +
+ {isSelected(code) ? : } +
+ {display}
))}
diff --git a/new-lamassu-admin/src/pages/Customers/components/CustomerSidebar.styles.js b/new-lamassu-admin/src/pages/Customers/components/CustomerSidebar.styles.js index aa16e91a..f40f871a 100644 --- a/new-lamassu-admin/src/pages/Customers/components/CustomerSidebar.styles.js +++ b/new-lamassu-admin/src/pages/Customers/components/CustomerSidebar.styles.js @@ -15,6 +15,8 @@ export default { marginBottom: 50 }, link: { + alignItems: 'center', + display: 'flex', extend: p, position: 'relative', color: offDarkColor, @@ -22,6 +24,8 @@ export default { cursor: 'pointer' }, activeLink: { + display: 'flex', + alignItems: 'center', extend: tl2, color: white, backgroundColor: offDarkColor, @@ -31,5 +35,8 @@ export default { '&:last-child': { borderRadius: '0px 0px 5px 5px' } + }, + icon: { + marginRight: 15 } } diff --git a/new-lamassu-admin/src/pages/Customers/components/EditableCard.js b/new-lamassu-admin/src/pages/Customers/components/EditableCard.js new file mode 100644 index 00000000..44959e17 --- /dev/null +++ b/new-lamassu-admin/src/pages/Customers/components/EditableCard.js @@ -0,0 +1,159 @@ +import { makeStyles } from '@material-ui/core/styles' +import classnames from 'classnames' +import { Form, Formik, Field as FormikField } from 'formik' +import { useState, React } from 'react' + +import ErrorMessage from 'src/components/ErrorMessage' +import PromptWhenDirty from 'src/components/PromptWhenDirty' +import { ActionButton } from 'src/components/buttons' +import { Label1, Info3 } from 'src/components/typography' +import { ReactComponent as EditIcon } from 'src/styling/icons/action/edit/enabled.svg' +import { ReactComponent as EditReversedIcon } from 'src/styling/icons/action/edit/white.svg' +import { ReactComponent as AuthorizeReversedIcon } from 'src/styling/icons/button/authorize/white.svg' +import { ReactComponent as AuthorizeIcon } from 'src/styling/icons/button/authorize/zodiac.svg' +import { ReactComponent as CancelReversedIcon } from 'src/styling/icons/button/cancel/white.svg' +import { ReactComponent as CancelIcon } from 'src/styling/icons/button/cancel/zodiac.svg' +import { comet } from 'src/styling/variables' + +import styles from './EditableCard.styles.js' + +const useStyles = makeStyles(styles) + +const fieldStyles = { + field: { + position: 'relative', + width: 280, + height: 48, + padding: [[0, 4, 4, 0]] + }, + label: { + color: comet, + margin: [[0, 3]] + }, + notEditing: { + display: 'flex', + flexDirection: 'column', + '& > p:first-child': { + height: 16, + lineHeight: '16px', + transformOrigin: 'left', + paddingLeft: 0, + margin: [[3, 0, 3, 0]] + }, + '& > p:last-child': { + overflow: 'hidden', + whiteSpace: 'nowrap', + textOverflow: 'ellipsis', + margin: 0 + } + }, + editing: { + '& > input': { + padding: 0 + } + } +} + +const fieldUseStyles = makeStyles(fieldStyles) + +const EditableField = ({ editing, field, size, ...props }) => { + const classes = fieldUseStyles() + + const classNames = { + [classes.field]: true, + [classes.notEditing]: !editing + } + + return ( +
+ {!editing && ( + <> + {field.label} + {field.value} + + )} + {editing && ( + <> + {field.label} + + + )} +
+ ) +} + +const EditableCard = ({ data, save }) => { + const classes = useStyles() + + const [editing, setEditing] = useState(false) + const [error, setError] = useState(null) + + return ( +
+ save(values)} + onReset={() => { + setEditing(false) + setError(false) + }}> +
+ +
+ {data.map((field, idx) => ( + + ))} +
+
+ {!editing && ( +
+ setEditing(true)}> + {`Edit`} + +
+ )} + {editing && ( +
+
+ + Save + +
+ + Cancel + + {error && Failed to save changes} +
+ )} +
+ +
+
+ ) +} + +export default EditableCard diff --git a/new-lamassu-admin/src/pages/Customers/components/EditableCard.styles.js b/new-lamassu-admin/src/pages/Customers/components/EditableCard.styles.js new file mode 100644 index 00000000..a59797a4 --- /dev/null +++ b/new-lamassu-admin/src/pages/Customers/components/EditableCard.styles.js @@ -0,0 +1,13 @@ +export default { + editButton: { + display: 'flex', + justifyContent: 'right' + }, + saveButton: { + marginRight: 12 + }, + editingButtons: { + display: 'flex', + justifyContent: 'right' + } +} diff --git a/new-lamassu-admin/src/pages/Customers/components/index.js b/new-lamassu-admin/src/pages/Customers/components/index.js index 82827400..65a03ca2 100644 --- a/new-lamassu-admin/src/pages/Customers/components/index.js +++ b/new-lamassu-admin/src/pages/Customers/components/index.js @@ -1,6 +1,7 @@ import ComplianceDetails from './ComplianceDetails' import CustomerDetails from './CustomerDetails' import CustomerSidebar from './CustomerSidebar' +import EditableCard from './EditableCard' import Field from './Field' import IdDataCard from './IdDataCard' import TransactionsList from './TransactionsList' @@ -11,5 +12,6 @@ export { TransactionsList, ComplianceDetails, CustomerSidebar, - Field + Field, + EditableCard } diff --git a/new-lamassu-admin/src/styling/icons/action/edit/comet.svg b/new-lamassu-admin/src/styling/icons/action/edit/comet.svg new file mode 100644 index 00000000..8b77414e --- /dev/null +++ b/new-lamassu-admin/src/styling/icons/action/edit/comet.svg @@ -0,0 +1,9 @@ + + + + Created with Sketch. + + + + + \ No newline at end of file diff --git a/new-lamassu-admin/src/styling/icons/button/discount/comet.svg b/new-lamassu-admin/src/styling/icons/button/discount/comet.svg new file mode 100644 index 00000000..ac2ab03c --- /dev/null +++ b/new-lamassu-admin/src/styling/icons/button/discount/comet.svg @@ -0,0 +1,8 @@ + + + icon/button/loyalty/comet + + + + + \ No newline at end of file diff --git a/new-lamassu-admin/src/styling/icons/button/discount/white.svg b/new-lamassu-admin/src/styling/icons/button/discount/white.svg new file mode 100644 index 00000000..538dc4f6 --- /dev/null +++ b/new-lamassu-admin/src/styling/icons/button/discount/white.svg @@ -0,0 +1,8 @@ + + + icon/button/loyalty/white + + + + + \ No newline at end of file diff --git a/new-lamassu-admin/src/styling/icons/button/discount/zodiac.svg b/new-lamassu-admin/src/styling/icons/button/discount/zodiac.svg new file mode 100644 index 00000000..e7a46dc3 --- /dev/null +++ b/new-lamassu-admin/src/styling/icons/button/discount/zodiac.svg @@ -0,0 +1,8 @@ + + + icon/button/loyalty/zodiac + + + + + \ No newline at end of file diff --git a/new-lamassu-admin/src/styling/icons/circle buttons/customer-list-view/white.svg b/new-lamassu-admin/src/styling/icons/circle buttons/customer-list-view/white.svg new file mode 100644 index 00000000..f9188caa --- /dev/null +++ b/new-lamassu-admin/src/styling/icons/circle buttons/customer-list-view/white.svg @@ -0,0 +1,10 @@ + + + icon/sf-small/listing/white + + + + + + + \ No newline at end of file diff --git a/new-lamassu-admin/src/styling/icons/circle buttons/customer-list-view/zodiac.svg b/new-lamassu-admin/src/styling/icons/circle buttons/customer-list-view/zodiac.svg new file mode 100644 index 00000000..b8aa5902 --- /dev/null +++ b/new-lamassu-admin/src/styling/icons/circle buttons/customer-list-view/zodiac.svg @@ -0,0 +1,10 @@ + + + icon/sf-small/listing/zodiac + + + + + + + \ No newline at end of file diff --git a/new-lamassu-admin/src/styling/icons/circle buttons/overview/comet.svg b/new-lamassu-admin/src/styling/icons/circle buttons/overview/comet.svg new file mode 100644 index 00000000..46a0342c --- /dev/null +++ b/new-lamassu-admin/src/styling/icons/circle buttons/overview/comet.svg @@ -0,0 +1,10 @@ + + + icon/sf-small/overview/comet + + + + + + + \ No newline at end of file diff --git a/new-lamassu-admin/src/styling/icons/circle buttons/overview/white.svg b/new-lamassu-admin/src/styling/icons/circle buttons/overview/white.svg new file mode 100644 index 00000000..3af8ca54 --- /dev/null +++ b/new-lamassu-admin/src/styling/icons/circle buttons/overview/white.svg @@ -0,0 +1,10 @@ + + + icon/sf-small/overview/white + + + + + + + \ No newline at end of file diff --git a/new-lamassu-admin/src/styling/icons/circle buttons/overview/zodiac.svg b/new-lamassu-admin/src/styling/icons/circle buttons/overview/zodiac.svg new file mode 100644 index 00000000..112c8d25 --- /dev/null +++ b/new-lamassu-admin/src/styling/icons/circle buttons/overview/zodiac.svg @@ -0,0 +1,10 @@ + + + icon/sf-small/overview/zodiac + + + + + + + \ No newline at end of file diff --git a/new-lamassu-admin/src/styling/icons/customer-nav/data/comet.svg b/new-lamassu-admin/src/styling/icons/customer-nav/data/comet.svg new file mode 100644 index 00000000..471c383b --- /dev/null +++ b/new-lamassu-admin/src/styling/icons/customer-nav/data/comet.svg @@ -0,0 +1,9 @@ + + + icon/customer-nav/data/comet + + + + + + \ No newline at end of file diff --git a/new-lamassu-admin/src/styling/icons/customer-nav/data/white.svg b/new-lamassu-admin/src/styling/icons/customer-nav/data/white.svg new file mode 100644 index 00000000..20cf2885 --- /dev/null +++ b/new-lamassu-admin/src/styling/icons/customer-nav/data/white.svg @@ -0,0 +1,9 @@ + + + icon/customer-nav/data/white + + + + + + \ No newline at end of file diff --git a/new-lamassu-admin/src/styling/icons/customer-nav/data/zodiac.svg b/new-lamassu-admin/src/styling/icons/customer-nav/data/zodiac.svg new file mode 100644 index 00000000..ffc069f2 --- /dev/null +++ b/new-lamassu-admin/src/styling/icons/customer-nav/data/zodiac.svg @@ -0,0 +1,9 @@ + + + icon/customer-nav/data/zodiac + + + + + + \ No newline at end of file diff --git a/new-lamassu-admin/src/styling/icons/customer-nav/overview/comet.svg b/new-lamassu-admin/src/styling/icons/customer-nav/overview/comet.svg new file mode 100644 index 00000000..c0ef3b45 --- /dev/null +++ b/new-lamassu-admin/src/styling/icons/customer-nav/overview/comet.svg @@ -0,0 +1,10 @@ + + + icon/customer-nav/overview/comet + + + + + + + \ No newline at end of file diff --git a/new-lamassu-admin/src/styling/icons/customer-nav/overview/white.svg b/new-lamassu-admin/src/styling/icons/customer-nav/overview/white.svg new file mode 100644 index 00000000..87c8dc82 --- /dev/null +++ b/new-lamassu-admin/src/styling/icons/customer-nav/overview/white.svg @@ -0,0 +1,10 @@ + + + icon/customer-nav/overview/white + + + + + + + \ No newline at end of file diff --git a/new-lamassu-admin/src/styling/icons/customer-nav/overview/zodiac.svg b/new-lamassu-admin/src/styling/icons/customer-nav/overview/zodiac.svg new file mode 100644 index 00000000..9e2819a5 --- /dev/null +++ b/new-lamassu-admin/src/styling/icons/customer-nav/overview/zodiac.svg @@ -0,0 +1,10 @@ + + + icon/customer-nav/overview/zodiac + + + + + + + \ No newline at end of file From 550bc2b7a46a7c0c442c5f6d6565bcb8d9b05269 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Oliveira?= Date: Mon, 18 Oct 2021 13:42:55 +0100 Subject: [PATCH 3/4] feat: add dynamic position to editable cards, reject/authorize buttons --- .../src/pages/Customers/CustomerData.js | 293 ++++++++++++++---- .../pages/Customers/CustomerData.styles.js | 17 - .../src/pages/Customers/CustomerProfile.js | 21 +- .../Customers/components/ComplianceDetails.js | 131 -------- .../components/ComplianceDetails.styles.js | 25 -- .../Customers/components/CustomerDetails.js | 10 - .../Customers/components/EditableCard.js | 182 ++++++++--- .../components/EditableCard.styles.js | 41 ++- .../src/pages/Customers/components/index.js | 2 - 9 files changed, 403 insertions(+), 319 deletions(-) delete mode 100644 new-lamassu-admin/src/pages/Customers/components/ComplianceDetails.js delete mode 100644 new-lamassu-admin/src/pages/Customers/components/ComplianceDetails.styles.js diff --git a/new-lamassu-admin/src/pages/Customers/CustomerData.js b/new-lamassu-admin/src/pages/Customers/CustomerData.js index efc19626..6293893c 100644 --- a/new-lamassu-admin/src/pages/Customers/CustomerData.js +++ b/new-lamassu-admin/src/pages/Customers/CustomerData.js @@ -1,21 +1,28 @@ -import { CardContent, Card } from '@material-ui/core' import Grid from '@material-ui/core/Grid' import { makeStyles } from '@material-ui/core/styles' +import _ from 'lodash/fp' import moment from 'moment' import * as R from 'ramda' import { useState, React } from 'react' +import * as Yup from 'yup' -import { Tooltip } from 'src/components/Tooltip' +import ImagePopper from 'src/components/ImagePopper' import { FeatureButton } from 'src/components/buttons' import { TextInput } from 'src/components/inputs/formik' -import { H3 } from 'src/components/typography' +import { H3, Info3 } from 'src/components/typography' +import { + OVERRIDE_AUTHORIZED, + OVERRIDE_REJECTED +} from 'src/pages/Customers/components/propertyCard' import { ReactComponent as CardIcon } from 'src/styling/icons/ID/card/comet.svg' import { ReactComponent as PhoneIcon } from 'src/styling/icons/ID/phone/comet.svg' +import { ReactComponent as CrossedCameraIcon } from 'src/styling/icons/ID/photo/crossed-camera.svg' import { ReactComponent as EditIcon } from 'src/styling/icons/action/edit/comet.svg' import { ReactComponent as CustomerListViewReversedIcon } from 'src/styling/icons/circle buttons/customer-list-view/white.svg' import { ReactComponent as CustomerListViewIcon } from 'src/styling/icons/circle buttons/customer-list-view/zodiac.svg' import { ReactComponent as OverviewReversedIcon } from 'src/styling/icons/circle buttons/overview/white.svg' import { ReactComponent as OverviewIcon } from 'src/styling/icons/circle buttons/overview/zodiac.svg' +import { URI } from 'src/utils/apollo' import { ifNotNull } from 'src/utils/nullCheck' import styles from './CustomerData.styles.js' @@ -24,38 +31,91 @@ import { getName } from './helper.js' const useStyles = makeStyles(styles) +const imageWidth = 165 +const imageHeight = 45 +const popupImageWidth = 360 +const popupImageHeight = 240 + +const Photo = ({ show, src }) => { + const classes = useStyles({ width: imageWidth }) + + return ( + <> + {show ? ( + + ) : ( +
+ +
+ )} + + ) +} + const CustomerData = ({ customer, updateCustomer }) => { const classes = useStyles() + const [listView, setListView] = useState(false) const idData = R.path(['idCardData'])(customer) const rawExpirationDate = R.path(['expirationDate'])(idData) const country = R.path(['country'])(idData) const rawDob = R.path(['dateOfBirth'])(idData) - const nameElements = [ - { - name: 'name', - label: 'Name', - value: `${getName(customer)}` ?? '', - component: TextInput, - size: 190 - } - ] + const sanctions = R.path(['sanctions'])(customer) + const sanctionsAt = R.path(['sanctionsAt'])(customer) + const sanctionsDisplay = !sanctionsAt + ? 'Not checked yet' + : sanctions + ? 'Passed' + : 'Failed' + + const isEven = elem => elem % 2 === 0 + + const getVisibleCards = _.filter( + elem => !_.isEmpty(elem.data) || !_.isNil(elem.children) + ) + + const getAvailableFields = _.filter(({ value }) => value !== '') + + const schemas = { + idScan: Yup.object().shape({ + name: Yup.string(), + idNumber: Yup.string(), + birthDate: Yup.string(), + age: Yup.string(), + gender: Yup.string(), + state: Yup.string(), + expirationDate: Yup.string() + }), + usSsn: Yup.object().shape({ + usSsn: Yup.string() + }) + } const idScanElements = [ { name: 'name', label: 'Name', value: `${getName(customer)}`, - component: TextInput, - size: 190 + component: TextInput }, { - name: 'ID number', + name: 'idNumber', label: 'ID number', - value: R.path(['documentNumber'])(idData), - component: TextInput, - size: 160 + value: R.path(['documentNumber'])(idData) ?? '', + component: TextInput + }, + { + name: 'birthDate', + label: 'Birth Date', + value: ifNotNull(rawDob, moment.utc(rawDob).format('YYYY-MM-DD')), + component: TextInput }, { name: 'age', @@ -64,36 +124,166 @@ const CustomerData = ({ customer, updateCustomer }) => { rawDob, moment.utc().diff(moment.utc(rawDob).format('YYYY-MM-DD'), 'years') ), - component: TextInput, - size: 50 + component: TextInput }, { name: 'gender', label: 'Gender', - value: R.path(['gender'])(idData), - component: TextInput, - size: 80 + value: R.path(['gender'])(idData) ?? '', + component: TextInput }, { - name: country === 'Canada' ? 'province' : 'state', + name: 'state', label: country === 'Canada' ? 'Province' : 'State', - value: R.path(['state'])(idData), - component: TextInput, - size: 120 + value: R.path(['state'])(idData) ?? '', + component: TextInput }, { - name: 'expiration date', + name: 'expirationDate', label: 'Expiration Date', value: ifNotNull( rawExpirationDate, moment.utc(rawExpirationDate).format('YYYY-MM-DD') ), - component: TextInput, - size: 120 + component: TextInput } ] - const [listView, setListView] = useState(false) + const usSsnElements = [ + { + name: 'us ssn', + label: 'US SSN', + value: `${customer.usSsn ?? ''}`, + component: TextInput, + size: 190 + } + ] + + const initialValues = { + idScan: { + name: '', + idNumber: '', + birthDate: '', + age: '', + gender: '', + state: '', + expirationDate: '' + }, + usSsn: { + usSsn: '' + } + } + + const cards = [ + { + data: getAvailableFields(idScanElements), + title: 'ID Scan', + titleIcon: , + state: R.path(['idCardDataOverride'])(customer), + authorize: () => + updateCustomer({ idCardDataOverride: OVERRIDE_AUTHORIZED }), + reject: () => updateCustomer({ idCardDataOverride: OVERRIDE_REJECTED }), + save: values => console.log(values), + validationSchema: schemas.idScan, + initialValues: initialValues.idScan + }, + { + title: 'SMS Confirmation', + titleIcon: , + authorize: () => {}, + reject: () => {}, + save: () => {} + }, + { + title: 'Name', + titleIcon: , + authorize: () => {}, + reject: () => {}, + save: () => {} + }, + { + title: 'Sanctions check', + titleIcon: , + state: R.path(['sanctionsOverride'])(customer), + authorize: () => + updateCustomer({ sanctionsOverride: OVERRIDE_AUTHORIZED }), + reject: () => updateCustomer({ sanctionsOverride: OVERRIDE_REJECTED }), + save: () => {}, + children: {sanctionsDisplay} + }, + { + title: 'Front facing camera', + titleIcon: , + state: R.path(['frontCameraOverride'])(customer), + authorize: () => + updateCustomer({ frontCameraOverride: OVERRIDE_AUTHORIZED }), + reject: () => updateCustomer({ frontCameraOverride: OVERRIDE_REJECTED }), + save: () => {}, + children: customer.frontCameraPath ? ( + + ) : null + }, + { + title: 'ID card image', + titleIcon: , + state: R.path(['idCardPhotoOverride'])(customer), + authorize: () => + updateCustomer({ idCardPhotoOverride: OVERRIDE_AUTHORIZED }), + reject: () => updateCustomer({ idCardPhotoOverride: OVERRIDE_REJECTED }), + save: () => {}, + children: customer.idCardPhotoPath ? ( + + ) : null + }, + { + data: getAvailableFields(usSsnElements), + title: 'US SSN', + titleIcon: , + state: R.path(['usSsnOverride'])(customer), + authorize: () => updateCustomer({ usSsnOverride: OVERRIDE_AUTHORIZED }), + reject: () => updateCustomer({ usSsnOverride: OVERRIDE_REJECTED }), + save: () => {}, + validationSchema: schemas.usSsn, + initialValues: initialValues.usSsn + } + ] + + const editableCard = ({ + title, + authorize, + reject, + state, + titleIcon, + data, + save, + children, + validationSchema, + initialValues + }) => { + return ( + + ) + } + + const visibleCards = getVisibleCards(cards) return (
@@ -105,7 +295,6 @@ const CustomerData = ({ customer, updateCustomer }) => { Icon={OverviewIcon} InverseIcon={OverviewReversedIcon} onClick={() => setListView(false)} - variant="contained" /> { onClick={() => setListView(true)}>
- {listView &&

{''}

} {!listView && ( - - -
- -

{'Name'}

- -
- {}}> -
-
- - -
- -

{'ID Scan'}

- -
- {}}> -
-
+ {visibleCards.map((elem, idx) => { + return isEven(idx) ? editableCard(elem) : null + })}
- - -
- -

{'SMS Confirmation'}

- -
-
-
+ {visibleCards.map((elem, idx) => { + return !isEven(idx) ? editableCard(elem) : null + })}
)} diff --git a/new-lamassu-admin/src/pages/Customers/CustomerData.styles.js b/new-lamassu-admin/src/pages/Customers/CustomerData.styles.js index 47793122..5dfecd1a 100644 --- a/new-lamassu-admin/src/pages/Customers/CustomerData.styles.js +++ b/new-lamassu-admin/src/pages/Customers/CustomerData.styles.js @@ -8,29 +8,12 @@ export default { marginTop: 7, marginRight: 24 }, - leftSideCard: { - borderRadius: 10, - marginRight: 10, - marginBottom: 15 - }, - rightSideCard: { - borderRadius: 10, - marginLeft: 10 - }, - cardHeader: { - display: 'flex', - flexDirection: 'row', - marginBottom: 15 - }, editIcon: { marginTop: 5 }, cardIcon: { marginTop: 7 }, - cardTitle: { - margin: [[8, 15, 15, 15]] - }, viewIcons: { marginRight: 12 } diff --git a/new-lamassu-admin/src/pages/Customers/CustomerProfile.js b/new-lamassu-admin/src/pages/Customers/CustomerProfile.js index 1c2d6fe3..657cbf47 100644 --- a/new-lamassu-admin/src/pages/Customers/CustomerProfile.js +++ b/new-lamassu-admin/src/pages/Customers/CustomerProfile.js @@ -25,7 +25,6 @@ import styles from './CustomerProfile.styles' import { CustomerDetails, TransactionsList, - ComplianceDetails, CustomerSidebar } from './components' import { getFormattedPhone, getName } from './helper' @@ -260,22 +259,14 @@ const CustomerProfile = memo(() => { setShowCompliance={() => setShowCompliance(!showCompliance)} /> - {!showCompliance && ( -
- -
- )} - {showCompliance && ( - + - )} +
)} {isCustomerData && ( diff --git a/new-lamassu-admin/src/pages/Customers/components/ComplianceDetails.js b/new-lamassu-admin/src/pages/Customers/components/ComplianceDetails.js deleted file mode 100644 index d5d66773..00000000 --- a/new-lamassu-admin/src/pages/Customers/components/ComplianceDetails.js +++ /dev/null @@ -1,131 +0,0 @@ -import { Box } from '@material-ui/core' -import { makeStyles } from '@material-ui/core/styles' -import * as R from 'ramda' -import React from 'react' - -import ImagePopper from 'src/components/ImagePopper' -import { H3, Info3 } from 'src/components/typography' -import { - PropertyCard, - OVERRIDE_AUTHORIZED, - OVERRIDE_REJECTED -} from 'src/pages/Customers/components/propertyCard' -import { ReactComponent as CrossedCameraIcon } from 'src/styling/icons/ID/photo/crossed-camera.svg' -import { URI } from 'src/utils/apollo' - -import { complianceDetailsStyles } from './ComplianceDetails.styles' -import Field from './Field' - -import { IdDataCard } from './' - -const useStyles = makeStyles(complianceDetailsStyles) - -const imageWidth = 165 -const imageHeight = 45 -const popupImageWidth = 360 -const popupImageHeight = 240 - -const Photo = ({ show, src }) => { - const classes = useStyles({ width: imageWidth }) - - return ( - <> - {show ? ( - - ) : ( -
- -
- )} - - ) -} - -const ComplianceDetails = ({ customer, updateCustomer }) => { - const classes = useStyles({ width: imageWidth }) - - const sanctions = R.path(['sanctions'])(customer) - const sanctionsAt = R.path(['sanctionsAt'])(customer) - const sanctionsDisplay = !sanctionsAt - ? 'Not checked yet' - : sanctions - ? 'Passed' - : 'Failed' - - return ( -
-

Compliance details

-
- - - - - updateCustomer({ idCardPhotoOverride: OVERRIDE_AUTHORIZED }) - } - reject={() => - updateCustomer({ idCardPhotoOverride: OVERRIDE_REJECTED }) - }> - - - - updateCustomer({ frontCameraOverride: OVERRIDE_AUTHORIZED }) - } - reject={() => - updateCustomer({ frontCameraOverride: OVERRIDE_REJECTED }) - }> - - - - - - updateCustomer({ usSsnOverride: OVERRIDE_AUTHORIZED }) - } - reject={() => - updateCustomer({ usSsnOverride: OVERRIDE_REJECTED }) - }> - - - - updateCustomer({ sanctionsOverride: OVERRIDE_AUTHORIZED }) - } - reject={() => - updateCustomer({ sanctionsOverride: OVERRIDE_REJECTED }) - }> - {sanctionsDisplay} - - - -
-
- ) -} - -export default ComplianceDetails diff --git a/new-lamassu-admin/src/pages/Customers/components/ComplianceDetails.styles.js b/new-lamassu-admin/src/pages/Customers/components/ComplianceDetails.styles.js deleted file mode 100644 index 1bb1d48f..00000000 --- a/new-lamassu-admin/src/pages/Customers/components/ComplianceDetails.styles.js +++ /dev/null @@ -1,25 +0,0 @@ -const complianceDetailsStyles = { - complianceDetailsGrid: { - display: 'flex', - flexDirection: 'row' - }, - firstColumn: { - display: 'flex', - flexDirection: 'column', - width: '100%', - marginRight: 10 - }, - lastColumn: { - display: 'flex', - flexDirection: 'column', - width: '100%', - marginLeft: 10 - }, - photoWrapper: ({ width }) => ({ - display: 'flex', - justifyContent: 'center', - width - }) -} - -export { complianceDetailsStyles } diff --git a/new-lamassu-admin/src/pages/Customers/components/CustomerDetails.js b/new-lamassu-admin/src/pages/Customers/components/CustomerDetails.js index 27714ee9..d5412738 100644 --- a/new-lamassu-admin/src/pages/Customers/components/CustomerDetails.js +++ b/new-lamassu-admin/src/pages/Customers/components/CustomerDetails.js @@ -2,11 +2,8 @@ import { makeStyles, Box } from '@material-ui/core' import * as R from 'ramda' import React, { memo } from 'react' -import { SubpageButton } from 'src/components/buttons' import { H2, Label1, P } from 'src/components/typography' import { ReactComponent as IdIcon } from 'src/styling/icons/ID/card/zodiac.svg' -import { ReactComponent as LawIconInverse } from 'src/styling/icons/circle buttons/law/white.svg' -import { ReactComponent as LawIcon } from 'src/styling/icons/circle buttons/law/zodiac.svg' import mainStyles from '../CustomersList.styles' import { getFormattedPhone, getName } from '../helper' @@ -70,13 +67,6 @@ const CustomerDetails = memo( locale.country )} - - Compliance details - {elements.map(({ size, header }, idx) => ( diff --git a/new-lamassu-admin/src/pages/Customers/components/EditableCard.js b/new-lamassu-admin/src/pages/Customers/components/EditableCard.js index 44959e17..e3a7f230 100644 --- a/new-lamassu-admin/src/pages/Customers/components/EditableCard.js +++ b/new-lamassu-admin/src/pages/Customers/components/EditableCard.js @@ -1,3 +1,4 @@ +import { CardContent, Card, Grid } from '@material-ui/core' import { makeStyles } from '@material-ui/core/styles' import classnames from 'classnames' import { Form, Formik, Field as FormikField } from 'formik' @@ -5,14 +6,23 @@ import { useState, React } from 'react' import ErrorMessage from 'src/components/ErrorMessage' import PromptWhenDirty from 'src/components/PromptWhenDirty' +import { MainStatus } from 'src/components/Status' +import { Tooltip } from 'src/components/Tooltip' import { ActionButton } from 'src/components/buttons' -import { Label1, Info3 } from 'src/components/typography' +import { Label1, Info3, H3 } from 'src/components/typography' +import { + OVERRIDE_AUTHORIZED, + OVERRIDE_REJECTED, + OVERRIDE_PENDING +} from 'src/pages/Customers/components/propertyCard' import { ReactComponent as EditIcon } from 'src/styling/icons/action/edit/enabled.svg' import { ReactComponent as EditReversedIcon } from 'src/styling/icons/action/edit/white.svg' import { ReactComponent as AuthorizeReversedIcon } from 'src/styling/icons/button/authorize/white.svg' import { ReactComponent as AuthorizeIcon } from 'src/styling/icons/button/authorize/zodiac.svg' import { ReactComponent as CancelReversedIcon } from 'src/styling/icons/button/cancel/white.svg' import { ReactComponent as CancelIcon } from 'src/styling/icons/button/cancel/zodiac.svg' +import { ReactComponent as SaveReversedIcon } from 'src/styling/icons/circle buttons/save/white.svg' +import { ReactComponent as SaveIcon } from 'src/styling/icons/circle buttons/save/zodiac.svg' import { comet } from 'src/styling/variables' import styles from './EditableCard.styles.js' @@ -92,66 +102,136 @@ const EditableField = ({ editing, field, size, ...props }) => { ) } -const EditableCard = ({ data, save }) => { +const EditableCard = ({ + data, + save, + authorize, + reject, + state, + title, + titleIcon, + children +}) => { const classes = useStyles() const [editing, setEditing] = useState(false) const [error, setError] = useState(null) + const label1ClassNames = { + [classes.label1]: true, + [classes.label1Pending]: state === OVERRIDE_PENDING, + [classes.label1Rejected]: state === OVERRIDE_REJECTED, + [classes.label1Accepted]: state === OVERRIDE_AUTHORIZED + } + const isNotAuthorized = + state === OVERRIDE_REJECTED || state === OVERRIDE_PENDING + const authorized = + state === OVERRIDE_PENDING + ? { label: 'Pending', type: 'neutral' } + : state === OVERRIDE_REJECTED + ? { label: 'Rejected', type: 'error' } + : { label: 'Accepted', type: 'success' } + + const editableField = field => { + return + } + return (
- save(values)} - onReset={() => { - setEditing(false) - setError(false) - }}> -
- -
- {data.map((field, idx) => ( - - ))} + + +
+ {titleIcon} +

{title}

+ +
+ +
-
- {!editing && ( -
- setEditing(true)}> - {`Edit`} - + save(values)} + onReset={() => { + setEditing(false) + setError(false) + }}> + + +
+ + + {data?.map((field, idx) => { + return idx >= 0 && idx < 4 ? editableField(field) : null + })} + + + {data?.map((field, idx) => { + return idx >= 4 ? editableField(field) : null + })} + +
- )} - {editing && ( -
-
- - Save - -
- - Cancel - - {error && Failed to save changes} + {children} +
+ {!editing && ( +
+ setEditing(true)}> + {`Edit`} + +
+ )} + {editing && ( +
+ {data && ( +
+ + Save + +
+ )} +
+ + Cancel + +
+ authorize() : () => reject() + }> + {isNotAuthorized ? 'Authorize' : 'Reject'} + + {error && ( + Failed to save changes + )} +
+ )}
- )} -
- -
+ + + +
) } diff --git a/new-lamassu-admin/src/pages/Customers/components/EditableCard.styles.js b/new-lamassu-admin/src/pages/Customers/components/EditableCard.styles.js index a59797a4..1c2a8603 100644 --- a/new-lamassu-admin/src/pages/Customers/components/EditableCard.styles.js +++ b/new-lamassu-admin/src/pages/Customers/components/EditableCard.styles.js @@ -1,13 +1,50 @@ +import { tomato, spring4, comet } from 'src/styling/variables' + export default { + label1: { + display: 'flex', + width: 85, + justifyContent: 'right' + }, + label1Pending: { + color: comet + }, + label1Rejected: { + color: tomato + }, + label1Accepted: { + color: spring4 + }, editButton: { + marginTop: 30, display: 'flex', justifyContent: 'right' }, - saveButton: { - marginRight: 12 + button: { + marginRight: 8 }, editingButtons: { + marginTop: 30, display: 'flex', justifyContent: 'right' + }, + card: { + borderRadius: 10, + marginRight: 15, + marginBottom: 15 + }, + cardHeader: { + display: 'flex', + flexDirection: 'row', + marginBottom: 15 + }, + editIcon: { + marginTop: 5 + }, + cardIcon: { + marginTop: 7 + }, + cardTitle: { + margin: [[8, 15, 15, 15]] } } diff --git a/new-lamassu-admin/src/pages/Customers/components/index.js b/new-lamassu-admin/src/pages/Customers/components/index.js index 65a03ca2..a8b7b184 100644 --- a/new-lamassu-admin/src/pages/Customers/components/index.js +++ b/new-lamassu-admin/src/pages/Customers/components/index.js @@ -1,4 +1,3 @@ -import ComplianceDetails from './ComplianceDetails' import CustomerDetails from './CustomerDetails' import CustomerSidebar from './CustomerSidebar' import EditableCard from './EditableCard' @@ -10,7 +9,6 @@ export { CustomerDetails, IdDataCard, TransactionsList, - ComplianceDetails, CustomerSidebar, Field, EditableCard From 8e83d184ba5b7d5731d58d72b11658816c6645a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Oliveira?= Date: Mon, 18 Oct 2021 15:48:17 +0100 Subject: [PATCH 4/4] fix: button display and revert button component changes --- .../src/components/buttons/FeatureButton.js | 4 +- .../Customers/components/EditableCard.js | 39 +++++++++++-------- 2 files changed, 25 insertions(+), 18 deletions(-) diff --git a/new-lamassu-admin/src/components/buttons/FeatureButton.js b/new-lamassu-admin/src/components/buttons/FeatureButton.js index 86a06c5e..3fe97cd7 100644 --- a/new-lamassu-admin/src/components/buttons/FeatureButton.js +++ b/new-lamassu-admin/src/components/buttons/FeatureButton.js @@ -32,8 +32,8 @@ const styles = { const useStyles = makeStyles(styles) const FeatureButton = memo( - ({ className, Icon, InverseIcon, children, active, ...props }) => { - const classes = useStyles({ active }) + ({ className, Icon, InverseIcon, children, ...props }) => { + const classes = useStyles() const classNames = { [classes.featureButton]: true, diff --git a/new-lamassu-admin/src/pages/Customers/components/EditableCard.js b/new-lamassu-admin/src/pages/Customers/components/EditableCard.js index e3a7f230..fc75f458 100644 --- a/new-lamassu-admin/src/pages/Customers/components/EditableCard.js +++ b/new-lamassu-admin/src/pages/Customers/components/EditableCard.js @@ -123,8 +123,7 @@ const EditableCard = ({ [classes.label1Rejected]: state === OVERRIDE_REJECTED, [classes.label1Accepted]: state === OVERRIDE_AUTHORIZED } - const isNotAuthorized = - state === OVERRIDE_REJECTED || state === OVERRIDE_PENDING + const authorized = state === OVERRIDE_PENDING ? { label: 'Pending', type: 'neutral' } @@ -208,20 +207,28 @@ const EditableCard = ({ Cancel
- authorize() : () => reject() - }> - {isNotAuthorized ? 'Authorize' : 'Reject'} - + {authorized.label !== 'Accepted' && ( +
+ authorize()}> + {'Authorize'} + +
+ )} + {authorized.label !== 'Rejected' && ( + reject()}> + {'Reject'} + + )} {error && ( Failed to save changes )}