Merge pull request #874 from josepfo/feat/rework-customer-profile-page
Feat: rework customer profile page
326
new-lamassu-admin/src/pages/Customers/CustomerData.js
Normal file
|
|
@ -0,0 +1,326 @@
|
||||||
|
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 ImagePopper from 'src/components/ImagePopper'
|
||||||
|
import { FeatureButton } from 'src/components/buttons'
|
||||||
|
import { TextInput } from 'src/components/inputs/formik'
|
||||||
|
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'
|
||||||
|
import { EditableCard } from './components'
|
||||||
|
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 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
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'idNumber',
|
||||||
|
label: 'ID number',
|
||||||
|
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',
|
||||||
|
label: 'Age',
|
||||||
|
value: ifNotNull(
|
||||||
|
rawDob,
|
||||||
|
moment.utc().diff(moment.utc(rawDob).format('YYYY-MM-DD'), 'years')
|
||||||
|
),
|
||||||
|
component: TextInput
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'gender',
|
||||||
|
label: 'Gender',
|
||||||
|
value: R.path(['gender'])(idData) ?? '',
|
||||||
|
component: TextInput
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'state',
|
||||||
|
label: country === 'Canada' ? 'Province' : 'State',
|
||||||
|
value: R.path(['state'])(idData) ?? '',
|
||||||
|
component: TextInput
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'expirationDate',
|
||||||
|
label: 'Expiration Date',
|
||||||
|
value: ifNotNull(
|
||||||
|
rawExpirationDate,
|
||||||
|
moment.utc(rawExpirationDate).format('YYYY-MM-DD')
|
||||||
|
),
|
||||||
|
component: TextInput
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
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>
|
||||||
|
<div className={classes.header}>
|
||||||
|
<H3 className={classes.title}>{'Customer data'}</H3>
|
||||||
|
<FeatureButton
|
||||||
|
active={!listView}
|
||||||
|
className={classes.viewIcons}
|
||||||
|
Icon={OverviewIcon}
|
||||||
|
InverseIcon={OverviewReversedIcon}
|
||||||
|
onClick={() => setListView(false)}
|
||||||
|
/>
|
||||||
|
<FeatureButton
|
||||||
|
active={listView}
|
||||||
|
className={classes.viewIcons}
|
||||||
|
Icon={CustomerListViewIcon}
|
||||||
|
InverseIcon={CustomerListViewReversedIcon}
|
||||||
|
onClick={() => setListView(true)}></FeatureButton>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
{!listView && (
|
||||||
|
<Grid container>
|
||||||
|
<Grid container direction="column" item xs={6}>
|
||||||
|
{visibleCards.map((elem, idx) => {
|
||||||
|
return isEven(idx) ? editableCard(elem) : null
|
||||||
|
})}
|
||||||
|
</Grid>
|
||||||
|
<Grid container direction="column" item xs={6}>
|
||||||
|
{visibleCards.map((elem, idx) => {
|
||||||
|
return !isEven(idx) ? editableCard(elem) : null
|
||||||
|
})}
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default CustomerData
|
||||||
20
new-lamassu-admin/src/pages/Customers/CustomerData.styles.js
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
export default {
|
||||||
|
header: {
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'row',
|
||||||
|
marginBottom: 15
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
marginTop: 7,
|
||||||
|
marginRight: 24
|
||||||
|
},
|
||||||
|
editIcon: {
|
||||||
|
marginTop: 5
|
||||||
|
},
|
||||||
|
cardIcon: {
|
||||||
|
marginTop: 7
|
||||||
|
},
|
||||||
|
viewIcons: {
|
||||||
|
marginRight: 12
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -16,13 +16,16 @@ import { ReactComponent as AuthorizeReversedIcon } from 'src/styling/icons/butto
|
||||||
import { ReactComponent as AuthorizeIcon } from 'src/styling/icons/button/authorize/zodiac.svg'
|
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 BlockReversedIcon } from 'src/styling/icons/button/block/white.svg'
|
||||||
import { ReactComponent as BlockIcon } from 'src/styling/icons/button/block/zodiac.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 { fromNamespace, namespaces } from 'src/utils/config'
|
||||||
|
|
||||||
|
import CustomerData from './CustomerData'
|
||||||
import styles from './CustomerProfile.styles'
|
import styles from './CustomerProfile.styles'
|
||||||
import {
|
import {
|
||||||
CustomerDetails,
|
CustomerDetails,
|
||||||
TransactionsList,
|
TransactionsList,
|
||||||
ComplianceDetails
|
CustomerSidebar
|
||||||
} from './components'
|
} from './components'
|
||||||
import { getFormattedPhone, getName } from './helper'
|
import { getFormattedPhone, getName } from './helper'
|
||||||
|
|
||||||
|
|
@ -106,9 +109,9 @@ const SET_CUSTOMER = gql`
|
||||||
`
|
`
|
||||||
|
|
||||||
const CustomerProfile = memo(() => {
|
const CustomerProfile = memo(() => {
|
||||||
const classes = useStyles()
|
|
||||||
const history = useHistory()
|
const history = useHistory()
|
||||||
const [showCompliance, setShowCompliance] = useState(false)
|
const [showCompliance, setShowCompliance] = useState(false)
|
||||||
|
const [clickedItem, setClickedItem] = useState('overview')
|
||||||
const { id: customerId } = useParams()
|
const { id: customerId } = useParams()
|
||||||
|
|
||||||
const { data: customerResponse, refetch: getCustomer, loading } = useQuery(
|
const { data: customerResponse, refetch: getCustomer, loading } = useQuery(
|
||||||
|
|
@ -130,6 +133,8 @@ const CustomerProfile = memo(() => {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const onClickSidebarItem = code => setClickedItem(code)
|
||||||
|
|
||||||
const configData = R.path(['config'])(customerResponse) ?? []
|
const configData = R.path(['config'])(customerResponse) ?? []
|
||||||
const locale = configData && fromNamespace(namespaces.LOCALE, configData)
|
const locale = configData && fromNamespace(namespaces.LOCALE, configData)
|
||||||
const customerData = R.path(['customer'])(customerResponse) ?? []
|
const customerData = R.path(['customer'])(customerResponse) ?? []
|
||||||
|
|
@ -142,6 +147,10 @@ const CustomerProfile = memo(() => {
|
||||||
R.path(['authorizedOverride'])(customerData) === OVERRIDE_REJECTED
|
R.path(['authorizedOverride'])(customerData) === OVERRIDE_REJECTED
|
||||||
|
|
||||||
const isSuspended = customerData.isSuspended
|
const isSuspended = customerData.isSuspended
|
||||||
|
const isCustomerData = clickedItem === 'customerData'
|
||||||
|
const isOverview = clickedItem === 'overview'
|
||||||
|
|
||||||
|
const classes = useStyles({ blocked })
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
|
@ -164,21 +173,28 @@ const CustomerProfile = memo(() => {
|
||||||
)}
|
)}
|
||||||
</Label2>
|
</Label2>
|
||||||
</Breadcrumbs>
|
</Breadcrumbs>
|
||||||
<div>
|
<div className={classes.panels}>
|
||||||
<Box
|
<div className={classes.leftSidePanel}>
|
||||||
className={classes.customerDetails}
|
|
||||||
display="flex"
|
|
||||||
justifyContent="space-between">
|
|
||||||
<CustomerDetails
|
|
||||||
customer={customerData}
|
|
||||||
txData={sortedTransactions}
|
|
||||||
locale={locale}
|
|
||||||
setShowCompliance={() => setShowCompliance(!showCompliance)}
|
|
||||||
/>
|
|
||||||
{!loading && !customerData.isAnonymous && (
|
{!loading && !customerData.isAnonymous && (
|
||||||
<div>
|
<div>
|
||||||
|
<div>
|
||||||
|
<CustomerSidebar
|
||||||
|
isSelected={code => code === clickedItem}
|
||||||
|
onClick={onClickSidebarItem}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
<Label1 className={classes.actionLabel}>Actions</Label1>
|
<Label1 className={classes.actionLabel}>Actions</Label1>
|
||||||
<div className={classes.customerActions}>
|
<div>
|
||||||
|
<ActionButton
|
||||||
|
className={classes.customerDiscount}
|
||||||
|
color="primary"
|
||||||
|
Icon={Discount}
|
||||||
|
InverseIcon={DiscountReversedIcon}
|
||||||
|
onClick={() => {}}>
|
||||||
|
{`Add individual discount`}
|
||||||
|
</ActionButton>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
{isSuspended && (
|
{isSuspended && (
|
||||||
<ActionButton
|
<ActionButton
|
||||||
color="primary"
|
color="primary"
|
||||||
|
|
@ -194,6 +210,7 @@ const CustomerProfile = memo(() => {
|
||||||
)}
|
)}
|
||||||
<ActionButton
|
<ActionButton
|
||||||
color="primary"
|
color="primary"
|
||||||
|
className={classes.customerBlock}
|
||||||
Icon={blocked ? AuthorizeIcon : BlockIcon}
|
Icon={blocked ? AuthorizeIcon : BlockIcon}
|
||||||
InverseIcon={
|
InverseIcon={
|
||||||
blocked ? AuthorizeReversedIcon : BlockReversedIcon
|
blocked ? AuthorizeReversedIcon : BlockReversedIcon
|
||||||
|
|
@ -228,22 +245,39 @@ const CustomerProfile = memo(() => {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</Box>
|
</div>
|
||||||
|
<div className={classes.rightSidePanel}>
|
||||||
|
{isOverview && (
|
||||||
|
<div>
|
||||||
|
<Box
|
||||||
|
className={classes.customerDetails}
|
||||||
|
display="flex"
|
||||||
|
justifyContent="space-between">
|
||||||
|
<CustomerDetails
|
||||||
|
customer={customerData}
|
||||||
|
locale={locale}
|
||||||
|
setShowCompliance={() => setShowCompliance(!showCompliance)}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
<div>
|
||||||
|
<TransactionsList
|
||||||
|
customer={customerData}
|
||||||
|
data={sortedTransactions}
|
||||||
|
locale={locale}
|
||||||
|
loading={loading}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{isCustomerData && (
|
||||||
|
<div>
|
||||||
|
<CustomerData
|
||||||
|
customer={customerData}
|
||||||
|
updateCustomer={updateCustomer}></CustomerData>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{!showCompliance && (
|
|
||||||
<TransactionsList
|
|
||||||
customer={customerData}
|
|
||||||
data={sortedTransactions}
|
|
||||||
locale={locale}
|
|
||||||
loading={loading}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
{showCompliance && (
|
|
||||||
<ComplianceDetails
|
|
||||||
customer={customerData}
|
|
||||||
updateCustomer={updateCustomer}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -15,14 +15,26 @@ export default {
|
||||||
customerDetails: {
|
customerDetails: {
|
||||||
marginBottom: 18
|
marginBottom: 18
|
||||||
},
|
},
|
||||||
customerActions: {
|
customerBlock: props => ({
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
flexDirection: 'row',
|
flexDirection: 'row',
|
||||||
'& button': {
|
margin: [[0, 0, 4, 0]],
|
||||||
marginRight: 15
|
padding: [[0, props.blocked ? 35 : 48, 0]]
|
||||||
},
|
}),
|
||||||
'& > :last-child': {
|
customerDiscount: {
|
||||||
marginRight: 0
|
display: 'flex',
|
||||||
}
|
flexDirection: 'row',
|
||||||
|
margin: [[8, 0, 4, 0]],
|
||||||
|
padding: [[0, 24, 0]]
|
||||||
|
},
|
||||||
|
panels: {
|
||||||
|
display: 'flex'
|
||||||
|
},
|
||||||
|
rightSidePanel: {
|
||||||
|
display: 'block',
|
||||||
|
width: 1100
|
||||||
|
},
|
||||||
|
leftSidePanel: {
|
||||||
|
width: 300
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
@ -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 }
|
|
||||||
|
|
@ -2,11 +2,8 @@ import { makeStyles, Box } from '@material-ui/core'
|
||||||
import * as R from 'ramda'
|
import * as R from 'ramda'
|
||||||
import React, { memo } from 'react'
|
import React, { memo } from 'react'
|
||||||
|
|
||||||
import { SubpageButton } from 'src/components/buttons'
|
|
||||||
import { H2, Label1, P } from 'src/components/typography'
|
import { H2, Label1, P } from 'src/components/typography'
|
||||||
import { ReactComponent as IdIcon } from 'src/styling/icons/ID/card/zodiac.svg'
|
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 mainStyles from '../CustomersList.styles'
|
||||||
import { getFormattedPhone, getName } from '../helper'
|
import { getFormattedPhone, getName } from '../helper'
|
||||||
|
|
@ -70,13 +67,6 @@ const CustomerDetails = memo(
|
||||||
locale.country
|
locale.country
|
||||||
)}
|
)}
|
||||||
</H2>
|
</H2>
|
||||||
<SubpageButton
|
|
||||||
className={classes.subpageButton}
|
|
||||||
Icon={LawIcon}
|
|
||||||
InverseIcon={LawIconInverse}
|
|
||||||
toggle={setShowCompliance}>
|
|
||||||
Compliance details
|
|
||||||
</SubpageButton>
|
|
||||||
</div>
|
</div>
|
||||||
<Box display="flex" mt="auto">
|
<Box display="flex" mt="auto">
|
||||||
{elements.map(({ size, header }, idx) => (
|
{elements.map(({ size, header }, idx) => (
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,50 @@
|
||||||
|
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)
|
||||||
|
|
||||||
|
const CustomerSidebar = ({ isSelected, onClick }) => {
|
||||||
|
const classes = useStyles()
|
||||||
|
const sideBarOptions = [
|
||||||
|
{
|
||||||
|
code: 'overview',
|
||||||
|
display: 'Overview',
|
||||||
|
Icon: OverviewIcon,
|
||||||
|
InverseIcon: OverviewReversedIcon
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 'customerData',
|
||||||
|
display: 'Customer Data',
|
||||||
|
Icon: CustomerDataIcon,
|
||||||
|
InverseIcon: CustomerDataReversedIcon
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={classes.sidebar}>
|
||||||
|
{sideBarOptions?.map(({ Icon, InverseIcon, display, code }) => (
|
||||||
|
<div
|
||||||
|
className={classnames({
|
||||||
|
[classes.activeLink]: isSelected(code),
|
||||||
|
[classes.link]: true
|
||||||
|
})}
|
||||||
|
onClick={() => onClick(code)}>
|
||||||
|
<div className={classes.icon}>
|
||||||
|
{isSelected(code) ? <Icon /> : <InverseIcon />}
|
||||||
|
</div>
|
||||||
|
{display}
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default CustomerSidebar
|
||||||
|
|
@ -0,0 +1,42 @@
|
||||||
|
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: {
|
||||||
|
alignItems: 'center',
|
||||||
|
display: 'flex',
|
||||||
|
extend: p,
|
||||||
|
position: 'relative',
|
||||||
|
color: offDarkColor,
|
||||||
|
padding: 15,
|
||||||
|
cursor: 'pointer'
|
||||||
|
},
|
||||||
|
activeLink: {
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
extend: tl2,
|
||||||
|
color: white,
|
||||||
|
backgroundColor: offDarkColor,
|
||||||
|
'&:first-child': {
|
||||||
|
borderRadius: '5px 5px 0px 0px'
|
||||||
|
},
|
||||||
|
'&:last-child': {
|
||||||
|
borderRadius: '0px 0px 5px 5px'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
icon: {
|
||||||
|
marginRight: 15
|
||||||
|
}
|
||||||
|
}
|
||||||
246
new-lamassu-admin/src/pages/Customers/components/EditableCard.js
Normal file
|
|
@ -0,0 +1,246 @@
|
||||||
|
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'
|
||||||
|
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, 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'
|
||||||
|
|
||||||
|
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 (
|
||||||
|
<div className={classnames(classNames)}>
|
||||||
|
{!editing && (
|
||||||
|
<>
|
||||||
|
<Label1 className={classes.label}>{field.label}</Label1>
|
||||||
|
<Info3>{field.value}</Info3>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
{editing && (
|
||||||
|
<>
|
||||||
|
<Label1 className={classes.label}>{field.label}</Label1>
|
||||||
|
<FormikField
|
||||||
|
className={classes.editing}
|
||||||
|
id={field.name}
|
||||||
|
name={field.name}
|
||||||
|
component={field.component}
|
||||||
|
placeholder={field.placeholder}
|
||||||
|
value={field.value}
|
||||||
|
type={field.type}
|
||||||
|
width={size}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
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 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>
|
||||||
|
<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>
|
||||||
|
<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>
|
||||||
|
{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>
|
||||||
|
{authorized.label !== 'Accepted' && (
|
||||||
|
<div className={classes.button}>
|
||||||
|
<ActionButton
|
||||||
|
color="secondary"
|
||||||
|
Icon={AuthorizeIcon}
|
||||||
|
InverseIcon={AuthorizeReversedIcon}
|
||||||
|
type="submit"
|
||||||
|
onClick={() => authorize()}>
|
||||||
|
{'Authorize'}
|
||||||
|
</ActionButton>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{authorized.label !== 'Rejected' && (
|
||||||
|
<ActionButton
|
||||||
|
color="secondary"
|
||||||
|
Icon={CancelIcon}
|
||||||
|
InverseIcon={CancelReversedIcon}
|
||||||
|
type="submit"
|
||||||
|
onClick={() => reject()}>
|
||||||
|
{'Reject'}
|
||||||
|
</ActionButton>
|
||||||
|
)}
|
||||||
|
{error && (
|
||||||
|
<ErrorMessage>Failed to save changes</ErrorMessage>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</Form>
|
||||||
|
</Formik>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default EditableCard
|
||||||
|
|
@ -0,0 +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'
|
||||||
|
},
|
||||||
|
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]]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -71,8 +71,7 @@ const TransactionsList = ({ customer, data, loading, locale }) => {
|
||||||
|
|
||||||
const tableElements = [
|
const tableElements = [
|
||||||
{
|
{
|
||||||
header: 'Direction',
|
width: 75,
|
||||||
width: 207,
|
|
||||||
view: it => (
|
view: it => (
|
||||||
<>
|
<>
|
||||||
{it.txClass === 'cashOut' ? (
|
{it.txClass === 'cashOut' ? (
|
||||||
|
|
@ -80,20 +79,19 @@ const TransactionsList = ({ customer, data, loading, locale }) => {
|
||||||
) : (
|
) : (
|
||||||
<TxInIcon className={classes.txClassIconLeft} />
|
<TxInIcon className={classes.txClassIconLeft} />
|
||||||
)}
|
)}
|
||||||
{it.txClass === 'cashOut' ? 'Cash-out' : 'Cash-in'}
|
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
header: 'Transaction ID',
|
header: 'Transaction ID',
|
||||||
width: 414,
|
width: 175,
|
||||||
view: it => (
|
view: it => (
|
||||||
<CopyToClipboard className={classes.txId}>{it.id}</CopyToClipboard>
|
<CopyToClipboard className={classes.txId}>{it.id}</CopyToClipboard>
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
header: 'Cash',
|
header: 'Cash',
|
||||||
width: 146,
|
width: 175,
|
||||||
textAlign: 'right',
|
textAlign: 'right',
|
||||||
view: it => (
|
view: it => (
|
||||||
<>
|
<>
|
||||||
|
|
@ -104,7 +102,7 @@ const TransactionsList = ({ customer, data, loading, locale }) => {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
header: 'Crypto',
|
header: 'Crypto',
|
||||||
width: 142,
|
width: 175,
|
||||||
textAlign: 'right',
|
textAlign: 'right',
|
||||||
view: it => (
|
view: it => (
|
||||||
<>
|
<>
|
||||||
|
|
@ -117,7 +115,7 @@ const TransactionsList = ({ customer, data, loading, locale }) => {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
header: 'Date',
|
header: 'Date',
|
||||||
width: 157,
|
width: 160,
|
||||||
view: it => formatDate(it.created, timezone, 'YYYY-MM-D')
|
view: it => formatDate(it.created, timezone, 'YYYY-MM-D')
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,15 @@
|
||||||
import ComplianceDetails from './ComplianceDetails'
|
|
||||||
import CustomerDetails from './CustomerDetails'
|
import CustomerDetails from './CustomerDetails'
|
||||||
|
import CustomerSidebar from './CustomerSidebar'
|
||||||
|
import EditableCard from './EditableCard'
|
||||||
|
import Field from './Field'
|
||||||
import IdDataCard from './IdDataCard'
|
import IdDataCard from './IdDataCard'
|
||||||
import TransactionsList from './TransactionsList'
|
import TransactionsList from './TransactionsList'
|
||||||
|
|
||||||
export { CustomerDetails, IdDataCard, TransactionsList, ComplianceDetails }
|
export {
|
||||||
|
CustomerDetails,
|
||||||
|
IdDataCard,
|
||||||
|
TransactionsList,
|
||||||
|
CustomerSidebar,
|
||||||
|
Field,
|
||||||
|
EditableCard
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<svg width="22px" height="22px" viewBox="0 0 22 22" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
|
<!-- Generator: Sketch 62 (91390) - https://sketch.com -->
|
||||||
|
<desc>Created with Sketch.</desc>
|
||||||
|
<g id="icon/action/edit/disabled" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round">
|
||||||
|
<path d="M1,18 L1,18 C1,19.657 2.343,21 4,21 L18,21 C19.657,21 21,19.657 21,18" id="Stroke-1" stroke="#5f668a" stroke-width="2"></path>
|
||||||
|
<polygon id="Stroke-3" stroke="#5f668a" stroke-width="2" points="6 12 17 1 21 5 10 16 6 16"></polygon>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 704 B |
|
|
@ -0,0 +1,8 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<svg width="12px" height="12px" viewBox="0 0 12 12" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
|
<title>icon/button/loyalty/comet</title>
|
||||||
|
<g id="icon/button/loyalty/comet" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||||
|
<polygon id="Stroke-2" stroke="#5f668a" stroke-linejoin="round" points="8.27822222 0.5 3.72177778 0.5 0.5 3.72177778 0.5 8.27822222 3.72177778 11.5 8.27822222 11.5 11.5 8.27822222 11.5 3.72177778"></polygon>
|
||||||
|
<path d="M7.55533889,6.66641667 C8.04667222,6.66641667 8.44450556,7.06486111 8.44450556,7.55558333 C8.44450556,8.04630556 8.04667222,8.44475 7.55533889,8.44475 C7.06461667,8.44475 6.66678333,8.04630556 6.66678333,7.55558333 C6.66678333,7.06486111 7.06461667,6.66641667 7.55533889,6.66641667 Z M8.44481111,3.55555556 L4.44447778,8.44444444 L3.55592222,8.44444444 L7.55564444,3.55555556 L8.44481111,3.55555556 Z M4.44423333,3.55525 C4.93556667,3.55525 5.3334,3.95369444 5.3334,4.44441667 C5.3334,4.93513889 4.93556667,5.33358333 4.44423333,5.33358333 C3.95351111,5.33358333 3.55567778,4.93513889 3.55567778,4.44441667 C3.55567778,3.95369444 3.95351111,3.55525 4.44423333,3.55525 Z" id="Combined-Shape" fill="#5f668a"></path>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.3 KiB |
|
|
@ -0,0 +1,8 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<svg width="12px" height="12px" viewBox="0 0 12 12" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
|
<title>icon/button/loyalty/white</title>
|
||||||
|
<g id="icon/button/loyalty/white" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||||
|
<polygon id="Stroke-2" stroke="#FFFFFF" stroke-linejoin="round" points="8.27822222 0.5 3.72177778 0.5 0.5 3.72177778 0.5 8.27822222 3.72177778 11.5 8.27822222 11.5 11.5 8.27822222 11.5 3.72177778"></polygon>
|
||||||
|
<path d="M7.55533889,6.66641667 C8.04667222,6.66641667 8.44450556,7.06486111 8.44450556,7.55558333 C8.44450556,8.04630556 8.04667222,8.44475 7.55533889,8.44475 C7.06461667,8.44475 6.66678333,8.04630556 6.66678333,7.55558333 C6.66678333,7.06486111 7.06461667,6.66641667 7.55533889,6.66641667 Z M8.44481111,3.55555556 L4.44447778,8.44444444 L3.55592222,8.44444444 L7.55564444,3.55555556 L8.44481111,3.55555556 Z M4.44423333,3.55525 C4.93556667,3.55525 5.3334,3.95369444 5.3334,4.44441667 C5.3334,4.93513889 4.93556667,5.33358333 4.44423333,5.33358333 C3.95351111,5.33358333 3.55567778,4.93513889 3.55567778,4.44441667 C3.55567778,3.95369444 3.95351111,3.55525 4.44423333,3.55525 Z" id="Combined-Shape" fill="#FFFFFF"></path>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.3 KiB |
|
|
@ -0,0 +1,8 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<svg width="12px" height="12px" viewBox="0 0 12 12" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
|
<title>icon/button/loyalty/zodiac</title>
|
||||||
|
<g id="icon/button/loyalty/zodiac" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||||
|
<polygon id="Stroke-2" stroke="#1B2559" stroke-linejoin="round" points="8.27822222 0.5 3.72177778 0.5 0.5 3.72177778 0.5 8.27822222 3.72177778 11.5 8.27822222 11.5 11.5 8.27822222 11.5 3.72177778"></polygon>
|
||||||
|
<path d="M7.55533889,6.66641667 C8.04667222,6.66641667 8.44450556,7.06486111 8.44450556,7.55558333 C8.44450556,8.04630556 8.04667222,8.44475 7.55533889,8.44475 C7.06461667,8.44475 6.66678333,8.04630556 6.66678333,7.55558333 C6.66678333,7.06486111 7.06461667,6.66641667 7.55533889,6.66641667 Z M8.44481111,3.55555556 L4.44447778,8.44444444 L3.55592222,8.44444444 L7.55564444,3.55555556 L8.44481111,3.55555556 Z M4.44423333,3.55525 C4.93556667,3.55525 5.3334,3.95369444 5.3334,4.44441667 C5.3334,4.93513889 4.93556667,5.33358333 4.44423333,5.33358333 C3.95351111,5.33358333 3.55567778,4.93513889 3.55567778,4.44441667 C3.55567778,3.95369444 3.95351111,3.55525 4.44423333,3.55525 Z" id="Combined-Shape" fill="#1B2559"></path>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.3 KiB |
|
|
@ -0,0 +1,10 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<svg width="20px" height="20px" viewBox="0 0 20 20" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
|
<title>icon/sf-small/listing/white</title>
|
||||||
|
<g id="icon/sf-small/listing/white" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round">
|
||||||
|
<line x1="1" y1="1" x2="19.0952381" y2="1" id="Path-4" stroke="#FFFFFF" stroke-width="2"></line>
|
||||||
|
<line x1="1" y1="7" x2="19.0952381" y2="7" id="Path-4-Copy" stroke="#FFFFFF" stroke-width="2"></line>
|
||||||
|
<line x1="1" y1="13" x2="19.0952381" y2="13" id="Path-4-Copy-2" stroke="#FFFFFF" stroke-width="2"></line>
|
||||||
|
<line x1="1" y1="19" x2="19.0952381" y2="19" id="Path-4-Copy-3" stroke="#FFFFFF" stroke-width="2"></line>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 840 B |
|
|
@ -0,0 +1,10 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<svg width="20px" height="20px" viewBox="0 0 20 20" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
|
<title>icon/sf-small/listing/zodiac</title>
|
||||||
|
<g id="icon/sf-small/listing/zodiac" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round">
|
||||||
|
<line x1="1" y1="1" x2="19.0952381" y2="1" id="Path-4" stroke="#1B2559" stroke-width="2"></line>
|
||||||
|
<line x1="1" y1="7" x2="19.0952381" y2="7" id="Path-4-Copy" stroke="#1B2559" stroke-width="2"></line>
|
||||||
|
<line x1="1" y1="13" x2="19.0952381" y2="13" id="Path-4-Copy-2" stroke="#1B2559" stroke-width="2"></line>
|
||||||
|
<line x1="1" y1="19" x2="19.0952381" y2="19" id="Path-4-Copy-3" stroke="#1B2559" stroke-width="2"></line>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 842 B |
|
|
@ -0,0 +1,10 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<svg width="20px" height="20px" viewBox="0 0 20 20" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
|
<title>icon/sf-small/overview/comet</title>
|
||||||
|
<g id="icon/sf-small/overview/comet" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||||
|
<rect id="Rectangle" stroke="#5F668A" stroke-width="2" x="1" y="1" width="7" height="7" rx="2"></rect>
|
||||||
|
<rect id="Rectangle-Copy-2" stroke="#5F668A" stroke-width="2" x="1" y="12" width="7" height="7" rx="2"></rect>
|
||||||
|
<rect id="Rectangle-Copy" stroke="#5F668A" stroke-width="2" x="12" y="1" width="7" height="7" rx="2"></rect>
|
||||||
|
<rect id="Rectangle-Copy-3" stroke="#5F668A" stroke-width="2" x="12" y="12" width="7" height="7" rx="2"></rect>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 819 B |
|
|
@ -0,0 +1,10 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<svg width="20px" height="20px" viewBox="0 0 20 20" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
|
<title>icon/sf-small/overview/white</title>
|
||||||
|
<g id="icon/sf-small/overview/white" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||||
|
<rect id="Rectangle" stroke="#FFFFFF" stroke-width="2" x="1" y="1" width="7" height="7" rx="2"></rect>
|
||||||
|
<rect id="Rectangle-Copy-2" stroke="#FFFFFF" stroke-width="2" x="1" y="12" width="7" height="7" rx="2"></rect>
|
||||||
|
<rect id="Rectangle-Copy" stroke="#FFFFFF" stroke-width="2" x="12" y="1" width="7" height="7" rx="2"></rect>
|
||||||
|
<rect id="Rectangle-Copy-3" stroke="#FFFFFF" stroke-width="2" x="12" y="12" width="7" height="7" rx="2"></rect>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 819 B |
|
|
@ -0,0 +1,10 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<svg width="20px" height="20px" viewBox="0 0 20 20" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
|
<title>icon/sf-small/overview/zodiac</title>
|
||||||
|
<g id="icon/sf-small/overview/zodiac" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||||
|
<rect id="Rectangle" stroke="#1B2559" stroke-width="2" x="1" y="1" width="7" height="7" rx="2"></rect>
|
||||||
|
<rect id="Rectangle-Copy-2" stroke="#1B2559" stroke-width="2" x="1" y="12" width="7" height="7" rx="2"></rect>
|
||||||
|
<rect id="Rectangle-Copy" stroke="#1B2559" stroke-width="2" x="12" y="1" width="7" height="7" rx="2"></rect>
|
||||||
|
<rect id="Rectangle-Copy-3" stroke="#1B2559" stroke-width="2" x="12" y="12" width="7" height="7" rx="2"></rect>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 821 B |
|
|
@ -0,0 +1,9 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<svg width="20px" height="20px" viewBox="0 0 20 20" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
|
<title>icon/customer-nav/data/comet</title>
|
||||||
|
<g id="icon/customer-nav/data/comet" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||||
|
<path d="M19,5 L19,10 C19,12.209139 14.9705627,14 10,14 C5.12689927,14 1.1537547,12.1492238 1,10 L1.00462428,5" id="Path-Copy-3" stroke="#5F668A" stroke-width="2"></path>
|
||||||
|
<path d="M19,10 L19,15 C19,17.209139 14.9705627,19 10,19 C5.12689927,19 1.1537547,17.1492238 1,15 L1.00462428,10" id="Path-Copy-3" stroke="#5F668A" stroke-width="2"></path>
|
||||||
|
<ellipse id="Oval-Copy-3" stroke="#5F668A" stroke-width="2" cx="10" cy="5" rx="9" ry="4"></ellipse>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 820 B |
|
|
@ -0,0 +1,9 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<svg width="20px" height="20px" viewBox="0 0 20 20" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
|
<title>icon/customer-nav/data/white</title>
|
||||||
|
<g id="icon/customer-nav/data/white" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||||
|
<path d="M19,5 L19,10 C19,12.209139 14.9705627,14 10,14 C5.12689927,14 1.1537547,12.1492238 1,10 L1.00462428,5" id="Path-Copy-3" stroke="#FFFFFF" stroke-width="2"></path>
|
||||||
|
<path d="M19,10 L19,15 C19,17.209139 14.9705627,19 10,19 C5.12689927,19 1.1537547,17.1492238 1,15 L1.00462428,10" id="Path-Copy-3" stroke="#FFFFFF" stroke-width="2"></path>
|
||||||
|
<ellipse id="Oval-Copy-3" stroke="#FFFFFF" stroke-width="2" cx="10" cy="5" rx="9" ry="4"></ellipse>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 820 B |
|
|
@ -0,0 +1,9 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<svg width="20px" height="20px" viewBox="0 0 20 20" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
|
<title>icon/customer-nav/data/zodiac</title>
|
||||||
|
<g id="icon/customer-nav/data/zodiac" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||||
|
<path d="M19,5 L19,10 C19,12.209139 14.9705627,14 10,14 C5.12689927,14 1.1537547,12.1492238 1,10 L1.00462428,5" id="Path-Copy-3" stroke="#1B2559" stroke-width="2"></path>
|
||||||
|
<path d="M19,10 L19,15 C19,17.209139 14.9705627,19 10,19 C5.12689927,19 1.1537547,17.1492238 1,15 L1.00462428,10" id="Path-Copy-3" stroke="#1B2559" stroke-width="2"></path>
|
||||||
|
<ellipse id="Oval-Copy-3" stroke="#1B2559" stroke-width="2" cx="10" cy="5" rx="9" ry="4"></ellipse>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 822 B |
|
|
@ -0,0 +1,10 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<svg width="20px" height="20px" viewBox="0 0 20 20" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
|
<title>icon/customer-nav/overview/comet</title>
|
||||||
|
<g id="icon/customer-nav/overview/comet" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||||
|
<rect id="Rectangle" stroke="#5F668A" stroke-width="2" x="1" y="1" width="7" height="7" rx="2"></rect>
|
||||||
|
<rect id="Rectangle-Copy-2" stroke="#5F668A" stroke-width="2" x="1" y="12" width="7" height="7" rx="2"></rect>
|
||||||
|
<rect id="Rectangle-Copy" stroke="#5F668A" stroke-width="2" x="12" y="1" width="7" height="7" rx="2"></rect>
|
||||||
|
<rect id="Rectangle-Copy-3" stroke="#5F668A" stroke-width="2" x="12" y="12" width="7" height="7" rx="2"></rect>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 827 B |
|
|
@ -0,0 +1,10 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<svg width="20px" height="20px" viewBox="0 0 20 20" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
|
<title>icon/customer-nav/overview/white</title>
|
||||||
|
<g id="icon/customer-nav/overview/white" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||||
|
<rect id="Rectangle" stroke="#FFFFFF" stroke-width="2" x="1" y="1" width="7" height="7" rx="2"></rect>
|
||||||
|
<rect id="Rectangle-Copy-2" stroke="#FFFFFF" stroke-width="2" x="1" y="12" width="7" height="7" rx="2"></rect>
|
||||||
|
<rect id="Rectangle-Copy" stroke="#FFFFFF" stroke-width="2" x="12" y="1" width="7" height="7" rx="2"></rect>
|
||||||
|
<rect id="Rectangle-Copy-3" stroke="#FFFFFF" stroke-width="2" x="12" y="12" width="7" height="7" rx="2"></rect>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 827 B |
|
|
@ -0,0 +1,10 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<svg width="20px" height="20px" viewBox="0 0 20 20" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
|
<title>icon/customer-nav/overview/zodiac</title>
|
||||||
|
<g id="icon/customer-nav/overview/zodiac" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||||
|
<rect id="Rectangle" stroke="#1B2559" stroke-width="2" x="1" y="1" width="7" height="7" rx="2"></rect>
|
||||||
|
<rect id="Rectangle-Copy-2" stroke="#1B2559" stroke-width="2" x="1" y="12" width="7" height="7" rx="2"></rect>
|
||||||
|
<rect id="Rectangle-Copy" stroke="#1B2559" stroke-width="2" x="12" y="1" width="7" height="7" rx="2"></rect>
|
||||||
|
<rect id="Rectangle-Copy-3" stroke="#1B2559" stroke-width="2" x="12" y="12" width="7" height="7" rx="2"></rect>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 829 B |