import Grid from '@material-ui/core/Grid' import { makeStyles } from '@material-ui/core/styles' 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 { onlyFirstToUpper } from 'src/utils/string' import styles from './CustomerData.styles.js' import { EditableCard } from './components' import { customerDataElements, customerDataSchemas, formatDates, tryFormatDate, getFormattedPhone } from './helper.js' const useStyles = makeStyles(styles) const IMAGE_WIDTH = 165 const IMAGE_HEIGHT = 32 const POPUP_IMAGE_WIDTH = 360 const POPUP_IMAGE_HEIGHT = 240 const Photo = ({ show, src }) => { const classes = useStyles({ width: IMAGE_WIDTH }) return ( <> {show ? ( ) : (
)} ) } const CustomerData = ({ locale, customer = {}, updateCustomer, replacePhoto, editCustomer, deleteEditedData, updateCustomRequest, authorizeCustomRequest, updateCustomEntry, retrieveAdditionalDataDialog, setRetrieve }) => { const classes = useStyles() const [listView, setListView] = useState(false) const idData = R.path(['idCardData'])(customer) const rawExpirationDate = R.path(['expirationDate'])(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 sortByName = R.sortBy( R.compose(R.toLower, R.path(['customInfoRequest', 'customRequest', 'name'])) ) const customFields = [] const customRequirements = [] const customInfoRequests = sortByName( R.path(['customInfoRequests'])(customer) ?? [] ) const phone = R.path(['phone'])(customer) const email = R.path(['email'])(customer) const smsData = R.path(['subscriberInfo'])(customer) const isEven = elem => elem % 2 === 0 const getVisibleCards = R.filter(elem => elem.isAvailable) const initialValues = { idCardData: { firstName: R.path(['firstName'])(idData) ?? '', lastName: R.path(['lastName'])(idData) ?? '', documentNumber: R.path(['documentNumber'])(idData) ?? '', dateOfBirth: tryFormatDate(rawDob), gender: R.path(['gender'])(idData) ?? '', country: R.path(['country'])(idData) ?? '', expirationDate: tryFormatDate(rawExpirationDate) }, usSsn: { usSsn: customer.usSsn ?? '' }, frontCamera: { frontCamera: null }, idCardPhoto: { idCardPhoto: null }, email: { email }, smsData: { phoneNumber: getFormattedPhone(phone, locale.country) } } const smsDataElements = [ { name: 'phoneNumber', label: 'Phone number', component: TextInput, editable: false } ] const smsDataSchema = { smsData: Yup.lazy(values => { const additionalData = R.omit(['phoneNumber'])(values) const fields = R.keys(additionalData) if (R.length(fields) === 2) { return Yup.object().shape({ [R.head(fields)]: Yup.string().required(), [R.last(fields)]: Yup.string().required() }) } }) } const cards = [ { fields: customerDataElements.idCardData, title: 'ID Scan', titleIcon: , state: R.path(['idCardDataOverride'])(customer), authorize: () => updateCustomer({ idCardDataOverride: OVERRIDE_AUTHORIZED }), reject: () => updateCustomer({ idCardDataOverride: OVERRIDE_REJECTED }), deleteEditedData: () => deleteEditedData({ idCardData: null }), save: values => editCustomer({ idCardData: R.merge(idData, formatDates(values)) }), validationSchema: customerDataSchemas.idCardData, initialValues: initialValues.idCardData, isAvailable: !R.isNil(idData), editable: true }, { fields: smsDataElements, title: 'SMS data', titleIcon: , state: R.path(['phoneOverride'])(customer), authorize: () => updateCustomer({ phoneOverride: OVERRIDE_AUTHORIZED }), reject: () => updateCustomer({ phoneOverride: OVERRIDE_REJECTED }), save: values => { editCustomer({ subscriberInfo: { result: R.merge(smsData, R.omit(['phoneNumber'])(values)) } }) }, validationSchema: smsDataSchema.smsData, retrieveAdditionalData: () => setRetrieve(true), initialValues: initialValues.smsData, isAvailable: !R.isNil(phone), hasAdditionalData: !R.isNil(smsData) && !R.isEmpty(smsData), editable: false }, { title: 'Email', fields: customerDataElements.email, titleIcon: , // state: R.path(['emailOverride'])(customer), // authorize: () => updateCustomer({ emailOverride: OVERRIDE_AUTHORIZED }), // reject: () => updateCustomer({ emailOverride: OVERRIDE_REJECTED }), save: values => editCustomer(values), deleteEditedData: () => deleteEditedData({ email: null }), initialValues: initialValues.email, isAvailable: !R.isNil(customer.email), editable: false }, { title: 'Name', titleIcon: , authorize: () => {}, reject: () => {}, save: () => {}, isAvailable: false, editable: true }, { title: 'Sanctions check', titleIcon: , state: R.path(['sanctionsOverride'])(customer), authorize: () => updateCustomer({ sanctionsOverride: OVERRIDE_AUTHORIZED }), reject: () => updateCustomer({ sanctionsOverride: OVERRIDE_REJECTED }), children: {sanctionsDisplay}, isAvailable: !R.isNil(sanctions), editable: true }, { fields: customerDataElements.frontCamera, title: 'Front facing camera', titleIcon: , state: R.path(['frontCameraOverride'])(customer), authorize: () => updateCustomer({ frontCameraOverride: OVERRIDE_AUTHORIZED }), reject: () => updateCustomer({ frontCameraOverride: OVERRIDE_REJECTED }), save: values => replacePhoto({ newPhoto: values.frontCamera, photoType: 'frontCamera' }), deleteEditedData: () => deleteEditedData({ frontCamera: null }), children: customer.frontCameraPath ? ( ) : null, hasImage: true, validationSchema: customerDataSchemas.frontCamera, initialValues: initialValues.frontCamera, isAvailable: !R.isNil(customer.frontCameraPath), editable: true }, { fields: customerDataElements.idCardPhoto, title: 'ID card image', titleIcon: , state: R.path(['idCardPhotoOverride'])(customer), authorize: () => updateCustomer({ idCardPhotoOverride: OVERRIDE_AUTHORIZED }), reject: () => updateCustomer({ idCardPhotoOverride: OVERRIDE_REJECTED }), save: values => replacePhoto({ newPhoto: values.idCardPhoto, photoType: 'idCardPhoto' }), deleteEditedData: () => deleteEditedData({ idCardPhoto: null }), children: customer.idCardPhotoPath ? ( ) : null, hasImage: true, validationSchema: customerDataSchemas.idCardPhoto, initialValues: initialValues.idCardPhoto, isAvailable: !R.isNil(customer.idCardPhotoPath), editable: true }, { fields: customerDataElements.usSsn, title: 'US SSN', titleIcon: , state: R.path(['usSsnOverride'])(customer), authorize: () => updateCustomer({ usSsnOverride: OVERRIDE_AUTHORIZED }), reject: () => updateCustomer({ usSsnOverride: OVERRIDE_REJECTED }), save: values => editCustomer(values), deleteEditedData: () => deleteEditedData({ usSsn: null }), validationSchema: customerDataSchemas.usSsn, initialValues: initialValues.usSsn, isAvailable: !R.isNil(customer.usSsn), editable: true } ] R.forEach(it => { customRequirements.push({ fields: [ { name: it.customInfoRequest.id, label: it.customInfoRequest.customRequest.name, value: it.customerData.data ?? '', component: TextInput, editable: true } ], title: it.customInfoRequest.customRequest.name, titleIcon: , state: R.path(['override'])(it), authorize: () => authorizeCustomRequest({ variables: { customerId: it.customerId, infoRequestId: it.customInfoRequest.id, override: OVERRIDE_AUTHORIZED } }), reject: () => authorizeCustomRequest({ variables: { customerId: it.customerId, infoRequestId: it.customInfoRequest.id, override: OVERRIDE_REJECTED } }), save: values => { updateCustomRequest({ variables: { customerId: it.customerId, infoRequestId: it.customInfoRequest.id, data: { info_request_id: it.customInfoRequest.id, data: values[it.customInfoRequest.id] } } }) }, deleteEditedData: () => {}, validationSchema: Yup.object().shape({ [it.customInfoRequest.id]: Yup.string() }), initialValues: { [it.customInfoRequest.id]: it.customerData.data ?? '' } }) }, customInfoRequests) R.forEach(it => { customFields.push({ fields: [ { name: it.label, label: it.label, value: it.value ?? '', component: TextInput, editable: true } ], title: it.label, titleIcon: , save: values => { updateCustomEntry({ fieldId: it.id, value: values[it.label] }) }, deleteEditedData: () => {}, validationSchema: Yup.object().shape({ [it.label]: Yup.string() }), initialValues: { [it.label]: it.value ?? '' } }) }, R.path(['customFields'])(customer) ?? []) R.forEach(it => { initialValues.smsData[it] = smsData[it] smsDataElements.push({ name: it, label: onlyFirstToUpper(it), component: TextInput, editable: false }) }, R.keys(smsData) ?? []) const externalCompliance = R.map(it => ({ fields: [ { name: 'externalId', label: 'Third Party ID', editable: false }, { name: 'lastKnownStatus', label: 'Last Known Status', editable: false }, { name: 'lastUpdated', label: 'Last Updated', editable: false } ], titleIcon: , title: `External Info [${it.service}]`, initialValues: it ?? { externalId: '', lastKnownStatus: '', lastUpdated: '' } }))(customer.externalCompliance ?? []) const editableCard = ( { title, authorize, reject, state, titleIcon, fields, save, deleteEditedData, retrieveAdditionalData, children, validationSchema, initialValues, hasImage, hasAdditionalData, editable }, idx ) => { return ( ) } const nonEditableCard = ( { title, state, titleIcon, fields, hasImage, initialValues, children }, idx ) => { return ( ) } const visibleCards = getVisibleCards(cards) return (

{'Customer data'}

{// TODO: Remove false condition for next release false && ( <> setListView(false)} /> setListView(true)}> )}
{!listView && customer && ( {visibleCards.map((elem, idx) => { return isEven(idx) ? editableCard(elem, idx) : null })} {visibleCards.map((elem, idx) => { return !isEven(idx) ? editableCard(elem, idx) : null })} )} {!R.isEmpty(customFields) && (
Custom data entry {customFields.map((elem, idx) => { return isEven(idx) ? editableCard(elem, idx) : null })} {customFields.map((elem, idx) => { return !isEven(idx) ? editableCard(elem, idx) : null })}
)} {!R.isEmpty(customRequirements) && (
Custom requirements {customRequirements.map((elem, idx) => { return isEven(idx) ? editableCard(elem, idx) : null })} {customRequirements.map((elem, idx) => { return !isEven(idx) ? editableCard(elem, idx) : null })}
)} {!R.isEmpty(externalCompliance) && (
External compliance information {externalCompliance.map((elem, idx) => { return isEven(idx) ? nonEditableCard(elem, idx) : null })} {externalCompliance.map((elem, idx) => { return !isEven(idx) ? nonEditableCard(elem, idx) : null })}
)}
{retrieveAdditionalDataDialog}
) } export default CustomerData