feat: add dynamic position to editable cards, reject/authorize buttons

This commit is contained in:
José Oliveira 2021-10-18 13:42:55 +01:00
parent 5cc63d05a6
commit 550bc2b7a4
9 changed files with 403 additions and 319 deletions

View file

@ -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 ? (
<ImagePopper
src={src}
width={imageWidth}
height={imageHeight}
popupWidth={popupImageWidth}
popupHeight={popupImageHeight}
/>
) : (
<div className={classes.photoWrapper}>
<CrossedCameraIcon />
</div>
)}
</>
)
}
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: <PhoneIcon className={classes.cardIcon} />,
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: <CardIcon className={classes.cardIcon} />,
authorize: () => {},
reject: () => {},
save: () => {}
},
{
title: 'Name',
titleIcon: <EditIcon className={classes.editIcon} />,
authorize: () => {},
reject: () => {},
save: () => {}
},
{
title: 'Sanctions check',
titleIcon: <EditIcon className={classes.editIcon} />,
state: R.path(['sanctionsOverride'])(customer),
authorize: () =>
updateCustomer({ sanctionsOverride: OVERRIDE_AUTHORIZED }),
reject: () => updateCustomer({ sanctionsOverride: OVERRIDE_REJECTED }),
save: () => {},
children: <Info3>{sanctionsDisplay}</Info3>
},
{
title: 'Front facing camera',
titleIcon: <EditIcon className={classes.editIcon} />,
state: R.path(['frontCameraOverride'])(customer),
authorize: () =>
updateCustomer({ frontCameraOverride: OVERRIDE_AUTHORIZED }),
reject: () => updateCustomer({ frontCameraOverride: OVERRIDE_REJECTED }),
save: () => {},
children: customer.frontCameraPath ? (
<Photo
show={customer.frontCameraPath}
src={`${URI}/front-camera-photo/${R.path(['frontCameraPath'])(
customer
)}`}
/>
) : null
},
{
title: 'ID card image',
titleIcon: <EditIcon className={classes.editIcon} />,
state: R.path(['idCardPhotoOverride'])(customer),
authorize: () =>
updateCustomer({ idCardPhotoOverride: OVERRIDE_AUTHORIZED }),
reject: () => updateCustomer({ idCardPhotoOverride: OVERRIDE_REJECTED }),
save: () => {},
children: customer.idCardPhotoPath ? (
<Photo
show={customer.idCardPhotoPath}
src={`${URI}/id-card-photo/${R.path(['idCardPhotoPath'])(customer)}`}
/>
) : null
},
{
data: getAvailableFields(usSsnElements),
title: 'US SSN',
titleIcon: <CardIcon className={classes.cardIcon} />,
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 (
<EditableCard
title={title}
authorize={authorize}
reject={reject}
state={state}
titleIcon={titleIcon}
data={data}
children={children}
validationSchema={validationSchema}
initialValues={initialValues}
save={save}></EditableCard>
)
}
const visibleCards = getVisibleCards(cards)
return (
<div>
@ -105,7 +295,6 @@ const CustomerData = ({ customer, updateCustomer }) => {
Icon={OverviewIcon}
InverseIcon={OverviewReversedIcon}
onClick={() => setListView(false)}
variant="contained"
/>
<FeatureButton
active={listView}
@ -115,45 +304,17 @@ const CustomerData = ({ customer, updateCustomer }) => {
onClick={() => setListView(true)}></FeatureButton>
</div>
<div>
{listView && <H3>{''}</H3>}
{!listView && (
<Grid container>
<Grid container direction="column" item xs={6}>
<Card className={classes.leftSideCard}>
<CardContent>
<div className={classes.cardHeader}>
<EditIcon className={classes.editIcon} />
<H3 className={classes.cardTitle}>{'Name'}</H3>
<Tooltip width={304}></Tooltip>
</div>
<EditableCard
data={nameElements}
save={() => {}}></EditableCard>
</CardContent>
</Card>
<Card className={classes.leftSideCard}>
<CardContent>
<div className={classes.cardHeader}>
<PhoneIcon className={classes.cardIcon} />
<H3 className={classes.cardTitle}>{'ID Scan'}</H3>
<Tooltip width={304}></Tooltip>
</div>
<EditableCard
data={idScanElements}
save={() => {}}></EditableCard>
</CardContent>
</Card>
{visibleCards.map((elem, idx) => {
return isEven(idx) ? editableCard(elem) : null
})}
</Grid>
<Grid container direction="column" item xs={6}>
<Card className={classes.rightSideCard}>
<CardContent>
<div className={classes.cardHeader}>
<CardIcon className={classes.cardIcon} />
<H3 className={classes.cardTitle}>{'SMS Confirmation'}</H3>
<Tooltip width={304}></Tooltip>
</div>
</CardContent>
</Card>
{visibleCards.map((elem, idx) => {
return !isEven(idx) ? editableCard(elem) : null
})}
</Grid>
</Grid>
)}

View file

@ -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
}

View file

@ -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)}
/>
</Box>
{!showCompliance && (
<div>
<TransactionsList
customer={customerData}
data={sortedTransactions}
locale={locale}
loading={loading}
/>
</div>
)}
{showCompliance && (
<ComplianceDetails
<div>
<TransactionsList
customer={customerData}
updateCustomer={updateCustomer}
data={sortedTransactions}
locale={locale}
loading={loading}
/>
)}
</div>
</div>
)}
{isCustomerData && (

View file

@ -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 ? (
<ImagePopper
src={src}
width={imageWidth}
height={imageHeight}
popupWidth={popupImageWidth}
popupHeight={popupImageHeight}
/>
) : (
<div className={classes.photoWrapper}>
<CrossedCameraIcon />
</div>
)}
</>
)
}
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 (
<div>
<H3>Compliance details</H3>
<div>
<IdDataCard customerData={customer} updateCustomer={updateCustomer} />
<Box className={classes.complianceDetailsGrid}>
<Box className={classes.firstColumn}>
<PropertyCard
title={'ID card image'}
state={R.path(['idCardPhotoOverride'])(customer)}
authorize={() =>
updateCustomer({ idCardPhotoOverride: OVERRIDE_AUTHORIZED })
}
reject={() =>
updateCustomer({ idCardPhotoOverride: OVERRIDE_REJECTED })
}>
<Photo
show={customer.idCardPhotoPath}
src={`${URI}/id-card-photo/${R.path(['idCardPhotoPath'])(
customer
)}`}
/>
</PropertyCard>
<PropertyCard
title={'Front facing camera'}
state={R.path(['frontCameraOverride'])(customer)}
authorize={() =>
updateCustomer({ frontCameraOverride: OVERRIDE_AUTHORIZED })
}
reject={() =>
updateCustomer({ frontCameraOverride: OVERRIDE_REJECTED })
}>
<Photo
show={customer.frontCameraPath}
src={`${URI}/front-camera-photo/${R.path(['frontCameraPath'])(
customer
)}`}
/>
</PropertyCard>
</Box>
<Box className={classes.lastColumn}>
<PropertyCard
title={'US SSN'}
state={R.path(['usSsnOverride'])(customer)}
authorize={() =>
updateCustomer({ usSsnOverride: OVERRIDE_AUTHORIZED })
}
reject={() =>
updateCustomer({ usSsnOverride: OVERRIDE_REJECTED })
}>
<Field label={'US SSN'} display={customer.usSsn} />
</PropertyCard>
<PropertyCard
title={'Sanctions check'}
state={R.path(['sanctionsOverride'])(customer)}
authorize={() =>
updateCustomer({ sanctionsOverride: OVERRIDE_AUTHORIZED })
}
reject={() =>
updateCustomer({ sanctionsOverride: OVERRIDE_REJECTED })
}>
<Info3>{sanctionsDisplay}</Info3>
</PropertyCard>
</Box>
</Box>
</div>
</div>
)
}
export default ComplianceDetails

View file

@ -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 }

View file

@ -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
)}
</H2>
<SubpageButton
className={classes.subpageButton}
Icon={LawIcon}
InverseIcon={LawIconInverse}
toggle={setShowCompliance}>
Compliance details
</SubpageButton>
</div>
<Box display="flex" mt="auto">
{elements.map(({ size, header }, idx) => (

View file

@ -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 <EditableField field={field} editing={editing} size={180} />
}
return (
<div>
<Formik
validateOnBlur={false}
validateOnChange={false}
enableReinitialize
onSubmit={values => save(values)}
onReset={() => {
setEditing(false)
setError(false)
}}>
<Form>
<PromptWhenDirty />
<div className={classes.row}>
{data.map((field, idx) => (
<EditableField key={idx} field={field} editing={editing} />
))}
<Card className={classes.card}>
<CardContent>
<div className={classes.cardHeader}>
{titleIcon}
<H3 className={classes.cardTitle}>{title}</H3>
<Tooltip width={304}></Tooltip>
<div className={classnames(label1ClassNames)}>
<MainStatus statuses={[authorized]} />
</div>
</div>
<div className={classes.edit}>
{!editing && (
<div className={classes.editButton}>
<ActionButton
color="primary"
Icon={EditIcon}
InverseIcon={EditReversedIcon}
onClick={() => setEditing(true)}>
{`Edit`}
</ActionButton>
<Formik
validateOnBlur={false}
validateOnChange={false}
enableReinitialize
onSubmit={values => save(values)}
onReset={() => {
setEditing(false)
setError(false)
}}>
<Form>
<PromptWhenDirty />
<div className={classes.row}>
<Grid container>
<Grid container direction="column" item xs={6}>
{data?.map((field, idx) => {
return idx >= 0 && idx < 4 ? editableField(field) : null
})}
</Grid>
<Grid container direction="column" item xs={6}>
{data?.map((field, idx) => {
return idx >= 4 ? editableField(field) : null
})}
</Grid>
</Grid>
</div>
)}
{editing && (
<div className={classes.editingButtons}>
<div className={classes.saveButton}>
<ActionButton
color="secondary"
Icon={AuthorizeIcon}
InverseIcon={AuthorizeReversedIcon}
type="submit">
Save
</ActionButton>
</div>
<ActionButton
color="secondary"
Icon={CancelIcon}
InverseIcon={CancelReversedIcon}
type="reset">
Cancel
</ActionButton>
{error && <ErrorMessage>Failed to save changes</ErrorMessage>}
{children}
<div className={classes.edit}>
{!editing && (
<div className={classes.editButton}>
<ActionButton
color="primary"
Icon={EditIcon}
InverseIcon={EditReversedIcon}
onClick={() => setEditing(true)}>
{`Edit`}
</ActionButton>
</div>
)}
{editing && (
<div className={classes.editingButtons}>
{data && (
<div className={classes.button}>
<ActionButton
color="secondary"
Icon={SaveIcon}
InverseIcon={SaveReversedIcon}
type="submit">
Save
</ActionButton>
</div>
)}
<div className={classes.button}>
<ActionButton
color="secondary"
Icon={CancelIcon}
InverseIcon={CancelReversedIcon}
type="reset">
Cancel
</ActionButton>
</div>
<ActionButton
color="secondary"
Icon={isNotAuthorized ? AuthorizeIcon : CancelIcon}
InverseIcon={
isNotAuthorized
? AuthorizeReversedIcon
: CancelReversedIcon
}
type="submit"
onClick={
isNotAuthorized ? () => authorize() : () => reject()
}>
{isNotAuthorized ? 'Authorize' : 'Reject'}
</ActionButton>
{error && (
<ErrorMessage>Failed to save changes</ErrorMessage>
)}
</div>
)}
</div>
)}
</div>
</Form>
</Formik>
</Form>
</Formik>
</CardContent>
</Card>
</div>
)
}

View file

@ -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]]
}
}

View file

@ -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