From 4d7a2527104a904f48a8c00c1d3348a496c66b50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Oliveira?= Date: Tue, 3 Aug 2021 14:27:40 +0100 Subject: [PATCH] feat: compliance and t&c photos displayed on carousel --- lib/customers.js | 2 +- new-lamassu-admin/package-lock.json | 44 +++++++ new-lamassu-admin/package.json | 1 + .../src/components/InformativeDialog.js | 2 +- .../Customers/components/CustomerDetails.js | 11 +- .../pages/Customers/components/PhotosCard.js | 112 +++++++++++++----- .../Customers/components/PhotosCard.styles.js | 8 +- 7 files changed, 143 insertions(+), 37 deletions(-) diff --git a/lib/customers.js b/lib/customers.js index f46a1438..2a1a6302 100644 --- a/lib/customers.js +++ b/lib/customers.js @@ -519,7 +519,7 @@ function getCustomersList (phone = null, name = null, address = null, id = null) */ function getCustomerById (id) { const passableErrorCodes = _.map(Pgp.as.text, TX_PASSTHROUGH_ERROR_CODES).join(',') - const sql = `select id, authorized_override, days_suspended, is_suspended, front_camera_path, front_camera_override, + const sql = `select id, authorized_override, days_suspended, is_suspended, front_camera_path, front_camera_at, front_camera_override, phone, sms_override, id_card_data, id_card_data_override, id_card_data_expiration, id_card_photo_path, id_card_photo_override, us_ssn, us_ssn_override, sanctions, sanctions_at, sanctions_override, total_txs, total_spent, created as last_active, fiat as last_tx_fiat, diff --git a/new-lamassu-admin/package-lock.json b/new-lamassu-admin/package-lock.json index 92ddcad7..5dac80f0 100644 --- a/new-lamassu-admin/package-lock.json +++ b/new-lamassu-admin/package-lock.json @@ -6057,6 +6057,11 @@ "@types/node": "*" } }, + "@types/scheduler": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz", + "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==" + }, "@types/source-list-map": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/@types/source-list-map/-/source-list-map-0.1.2.tgz", @@ -7192,6 +7197,31 @@ "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", "dev": true }, + "auto-bind": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/auto-bind/-/auto-bind-2.1.1.tgz", + "integrity": "sha512-NUwV1i9D3vxxY1KnfZgSZ716d6ovY7o8LfOwLhGIPFBowIb6Ln6DBW64+jCqPzUznel2hRSkQnYQqvh7/ldw8A==", + "requires": { + "@types/react": "^16.8.12" + }, + "dependencies": { + "@types/react": { + "version": "16.14.11", + "resolved": "https://registry.npmjs.org/@types/react/-/react-16.14.11.tgz", + "integrity": "sha512-Don0MtsZZ3fjwTJ2BsoqkyOy7e176KplEAKOpr/4XDdzinlyJBn9yfsKn5mcSgn4kh1B22+3tBnzBC1z63ybtQ==", + "requires": { + "@types/prop-types": "*", + "@types/scheduler": "*", + "csstype": "^3.0.2" + } + }, + "csstype": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.8.tgz", + "integrity": "sha512-jXKhWqXPmlUeoQnF/EhTtTl4C9SnrxSH/jZUih3jmO6lBKr99rP3/+FmrMj4EFpOXzMtXHAZkd3x0E6h6Fgflw==" + } + } + }, "autoprefixer": { "version": "9.8.6", "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.8.6.tgz", @@ -21860,6 +21890,15 @@ "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz", "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==" }, + "react-material-ui-carousel": { + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/react-material-ui-carousel/-/react-material-ui-carousel-2.2.7.tgz", + "integrity": "sha512-aO42C4oupmIxmJwYaTWrlWaXvVVspKcpEu/5efZ9slteATEsqqPtNAeVaE40Vimw2hZeIh2e8vpRwjq7fSsLxw==", + "requires": { + "auto-bind": "^2.1.1", + "react-swipeable": "^6.1.0" + } + }, "react-number-format": { "version": "4.4.4", "resolved": "https://registry.npmjs.org/react-number-format/-/react-number-format-4.4.4.tgz", @@ -23328,6 +23367,11 @@ "throttle-debounce": "^2.1.0" } }, + "react-swipeable": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/react-swipeable/-/react-swipeable-6.1.2.tgz", + "integrity": "sha512-vfZtOZNivwd/aI+ZZH1Grx0eQBdbV1UI3pB9p65jbW5guHHdSIPpKsND6XmaiZXP5REOOc9Ckfr36ChswPqwsA==" + }, "react-syntax-highlighter": { "version": "12.2.1", "resolved": "https://registry.npmjs.org/react-syntax-highlighter/-/react-syntax-highlighter-12.2.1.tgz", diff --git a/new-lamassu-admin/package.json b/new-lamassu-admin/package.json index c3910b71..041b402c 100644 --- a/new-lamassu-admin/package.json +++ b/new-lamassu-admin/package.json @@ -35,6 +35,7 @@ "react": "^16.12.0", "react-copy-to-clipboard": "^5.0.2", "react-dom": "^16.10.2", + "react-material-ui-carousel": "^2.2.7", "react-number-format": "^4.4.1", "react-otp-input": "^2.3.0", "react-router-dom": "5.1.2", diff --git a/new-lamassu-admin/src/components/InformativeDialog.js b/new-lamassu-admin/src/components/InformativeDialog.js index a416cb19..25b78c38 100644 --- a/new-lamassu-admin/src/components/InformativeDialog.js +++ b/new-lamassu-admin/src/components/InformativeDialog.js @@ -14,7 +14,7 @@ const useStyles = makeStyles({ justifyContent: 'end' }, title: { - margin: [[0, spacer * 2, spacer * 2, spacer * 2]] + margin: [[0, spacer * 2, spacer * 2, spacer * 2 + 4]] } }) diff --git a/new-lamassu-admin/src/pages/Customers/components/CustomerDetails.js b/new-lamassu-admin/src/pages/Customers/components/CustomerDetails.js index e0939993..27714ee9 100644 --- a/new-lamassu-admin/src/pages/Customers/components/CustomerDetails.js +++ b/new-lamassu-admin/src/pages/Customers/components/CustomerDetails.js @@ -49,8 +49,15 @@ const CustomerDetails = memo( return (
diff --git a/new-lamassu-admin/src/pages/Customers/components/PhotosCard.js b/new-lamassu-admin/src/pages/Customers/components/PhotosCard.js index fd321bd7..c76fd0d5 100644 --- a/new-lamassu-admin/src/pages/Customers/components/PhotosCard.js +++ b/new-lamassu-admin/src/pages/Customers/components/PhotosCard.js @@ -3,6 +3,7 @@ import Paper from '@material-ui/core/Card' import { makeStyles } from '@material-ui/core/styles' import * as R from 'ramda' import React, { memo, useState } from 'react' +import Carousel from 'react-material-ui-carousel' import { InformativeDialog } from 'src/components/InformativeDialog' import { Info2, Label1 } from 'src/components/typography' @@ -20,40 +21,67 @@ const Label = ({ children }) => { return {children} } -const PhotosCard = memo(({ frontCameraPath, txData }) => { +const PhotosCard = memo(({ frontCameraData, txPhotosData }) => { const classes = useStyles() const [photosDialog, setPhotosDialog] = useState(false) - const txsWithCustomerPhoto = R.filter( - tx => !R.isNil(tx.txCustomerPhotoAt) && !R.isNil(tx.txCustomerPhotoPath) - )(txData) + const mapKeys = pair => { + const key = R.head(pair) + const value = R.last(pair) + if (key === 'txCustomerPhotoPath' || key === 'frontCameraPath') { + return ['path', value] + } + if (key === 'txCustomerPhotoAt' || key === 'frontCameraAt') { + return ['date', value] + } + return pair + } - const photoDir = frontCameraPath - ? 'front-camera-photo' - : 'operator-data/customersphotos' + const addPhotoDir = R.map(it => { + const hasFrontCameraData = R.has('id')(it) + return hasFrontCameraData + ? { ...it, photoDir: 'operator-data/customersphotos' } + : { ...it, photoDir: 'front-camera-photo' } + }) - const photo = - frontCameraPath ?? R.head(txsWithCustomerPhoto)?.txCustomerPhotoPath + const standardizeKeys = R.map( + R.compose(R.fromPairs, R.map(mapKeys), R.toPairs) + ) + + const filterByPhotoAvaiable = R.filter( + tx => !R.isNil(tx.date) && !R.isNil(tx.path) + ) + + const photosData = filterByPhotoAvaiable( + addPhotoDir(standardizeKeys(R.append(frontCameraData, txPhotosData))) + ) + + const singlePhoto = R.head(photosData) + + const isPhotoRollAvailable = () => { + return !singlePhoto + } return ( <> { setPhotosDialog(true) }}> - {photo ? ( + {singlePhoto ? (
- {txsWithCustomerPhoto.length} + {photosData.length}
@@ -65,7 +93,7 @@ const PhotosCard = memo(({ frontCameraPath, txData }) => { } + data={} onDissmised={() => { setPhotosDialog(false) }} @@ -74,38 +102,62 @@ const PhotosCard = memo(({ frontCameraPath, txData }) => { ) }) -export const PhotosCarousel = memo(({ txData }) => { +export const PhotosCarousel = memo(({ photosData }) => { const classes = useStyles() + const [currentIndex, setCurrentIndex] = useState(0) + + const isFaceCustomerPhoto = !R.has('id')(photosData[currentIndex]) + + const slidePhoto = index => setCurrentIndex(index) return ( <> -
- -
-
-
+ slidePhoto(activeIndex)} + prev={activeIndex => slidePhoto(activeIndex)}> + {photosData.map((item, i) => (
- - {txData && R.head(txData)?.id} +
+ +
+ ))} +
+ {!isFaceCustomerPhoto && ( +
+ + + {photosData && photosData[currentIndex]?.id} +
-
+ )}
-
{txData && R.head(txData)?.txCustomerPhotoAt}
+
{photosData && photosData[currentIndex]?.date}
-
{'Acceptance of T&C'}
+
+ {!isFaceCustomerPhoto ? 'Acceptance of T&C' : 'Compliance scan'} +
diff --git a/new-lamassu-admin/src/pages/Customers/components/PhotosCard.styles.js b/new-lamassu-admin/src/pages/Customers/components/PhotosCard.styles.js index ba424540..002c5bfb 100644 --- a/new-lamassu-admin/src/pages/Customers/components/PhotosCard.styles.js +++ b/new-lamassu-admin/src/pages/Customers/components/PhotosCard.styles.js @@ -47,7 +47,9 @@ export default { margin: [[0, 0, 6, 0]] }, firstRow: { - padding: [[8]] + padding: [[8]], + display: 'flex', + flexDirection: 'column' }, secondRow: { extend: p, @@ -64,14 +66,14 @@ export default { } } }, - carousel: { + imgWrapper: { alignItems: 'center', justifyContent: 'center', display: 'flex', width: 550, height: 550 }, - carouselImg: { + imgInner: { objectFit: 'cover', objectPosition: 'center', width: 550,