diff --git a/lib/blockchain/bitcoin.js b/lib/blockchain/bitcoin.js index ddee67a4..b6f9f31b 100644 --- a/lib/blockchain/bitcoin.js +++ b/lib/blockchain/bitcoin.js @@ -45,6 +45,7 @@ keypool=10000 prune=4000 daemon=0 addresstype=p2sh-segwit +changetype=bech32 walletrbf=1 bind=0.0.0.0:8332 rpcport=8333` diff --git a/lib/blockchain/litecoin.js b/lib/blockchain/litecoin.js index 1c721c6f..5290cbf1 100644 --- a/lib/blockchain/litecoin.js +++ b/lib/blockchain/litecoin.js @@ -44,5 +44,6 @@ connections=40 keypool=10000 prune=4000 daemon=0 -addresstype=p2sh-segwit` +addresstype=p2sh-segwit +changetype=bech32` } diff --git a/lib/customers.js b/lib/customers.js index 4bdcd9e4..e96155f9 100644 --- a/lib/customers.js +++ b/lib/customers.js @@ -683,18 +683,18 @@ 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, - 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, + 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_at, id_card_data, id_card_data_override, id_card_data_expiration, + id_card_photo_path, id_card_photo_at, id_card_photo_override, us_ssn_at, us_ssn, us_ssn_override, sanctions, sanctions_at, sanctions_override, total_txs, total_spent, created AS last_active, fiat AS last_tx_fiat, fiat_code AS last_tx_fiat_code, tx_class AS last_tx_class, subscriber_info, custom_fields, notes FROM ( SELECT c.id, c.authorized_override, greatest(0, date_part('day', c.suspended_until - now())) AS days_suspended, c.suspended_until > now() AS is_suspended, - c.front_camera_path, c.front_camera_override, - c.phone, c.sms_override, c.id_card_data, c.id_card_data_override, c.id_card_data_expiration, - c.id_card_photo_path, c.id_card_photo_override, c.us_ssn, c.us_ssn_override, c.sanctions, + c.front_camera_path, c.front_camera_override, c.front_camera_at, + c.phone, c.sms_override, c.id_card_data, c.id_card_data_at, c.id_card_data_override, c.id_card_data_expiration, + c.id_card_photo_path, c.id_card_photo_at, c.id_card_photo_override, c.us_ssn, c.us_ssn_at, c.us_ssn_override, c.sanctions, c.sanctions_at, c.sanctions_override, c.subscriber_info, t.tx_class, t.fiat, t.fiat_code, t.created, cn.notes, row_number() OVER (PARTITION BY c.id ORDER BY t.created DESC) AS rn, sum(CASE WHEN t.id IS NOT NULL THEN 1 ELSE 0 END) OVER (PARTITION BY c.id) AS total_txs, diff --git a/lib/new-admin/services/transactions.js b/lib/new-admin/services/transactions.js index 3c50b688..494630f9 100644 --- a/lib/new-admin/services/transactions.js +++ b/lib/new-admin/services/transactions.js @@ -56,7 +56,7 @@ function batch ( ((NOT txs.send_confirmed) AND (txs.created <= now() - interval $1)) AS expired FROM (SELECT *, ${cashInTx.TRANSACTION_STATES} AS txStatus FROM cash_in_txs) AS txs LEFT OUTER JOIN customers c ON txs.customer_id = c.id - INNER JOIN devices d ON txs.device_id = d.device_id + LEFT JOIN devices d ON txs.device_id = d.device_id WHERE txs.created >= $2 AND txs.created <= $3 ${ id !== null ? `AND txs.device_id = $6` : `` } @@ -87,7 +87,7 @@ function batch ( INNER JOIN cash_out_actions actions ON txs.id = actions.tx_id AND actions.action = 'provisionAddress' LEFT OUTER JOIN customers c ON txs.customer_id = c.id - INNER JOIN devices d ON txs.device_id = d.device_id + LEFT JOIN devices d ON txs.device_id = d.device_id WHERE txs.created >= $2 AND txs.created <= $3 ${ id !== null ? `AND txs.device_id = $6` : `` } @@ -130,7 +130,10 @@ function simplifiedBatch (data) { const getCryptoAmount = it => coinUtils.toUnit(BN(it.cryptoAtoms), it.cryptoCode).toString() const getProfit = it => { - const getCommissionFee = it => BN(it.commissionPercentage).times(BN(it.fiat)) + const discountValue = _.isNil(it.discount) ? BN(100) : BN(100).minus(it.discount) + const discountPercentage = BN(discountValue).div(100) + const commissionPercentage = BN(it.commissionPercentage).times(discountPercentage) + const getCommissionFee = it => BN(commissionPercentage).times(BN(it.fiat)) if (!it.cashInFee) return getCommissionFee(it) return getCommissionFee(it).plus(BN(it.cashInFee)) } diff --git a/new-lamassu-admin/package-lock.json b/new-lamassu-admin/package-lock.json index 3c21f1c3..e64cc12a 100644 --- a/new-lamassu-admin/package-lock.json +++ b/new-lamassu-admin/package-lock.json @@ -6889,11 +6889,14 @@ } }, "apollo-upload-client": { - "version": "16.0.0", - "resolved": "https://registry.npmjs.org/apollo-upload-client/-/apollo-upload-client-16.0.0.tgz", - "integrity": "sha512-aLhYucyA0T8aBEQ5g+p13qnR9RUyL8xqb8FSZ7e/Kw2KUOsotLUlFluLobqaE7JSUFwc6sKfXIcwB7y4yEjbZg==", + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/apollo-upload-client/-/apollo-upload-client-13.0.0.tgz", + "integrity": "sha512-lJ9/bk1BH1lD15WhWRha2J3+LrXrPIX5LP5EwiOUHv8PCORp4EUrcujrA3rI5hZeZygrTX8bshcuMdpqpSrvtA==", "requires": { - "extract-files": "^11.0.0" + "@babel/runtime": "^7.9.2", + "apollo-link": "^1.2.12", + "apollo-link-http-common": "^0.2.14", + "extract-files": "^8.0.0" } }, "apollo-utilities": { @@ -12617,9 +12620,9 @@ } }, "extract-files": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/extract-files/-/extract-files-11.0.0.tgz", - "integrity": "sha512-FuoE1qtbJ4bBVvv94CC7s0oTnKUGvQs+Rjf1L2SJFfS+HTVVjhPFtehPdQ0JiGPqVNfSSZvL5yzHHQq2Z4WNhQ==" + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/extract-files/-/extract-files-8.1.0.tgz", + "integrity": "sha512-PTGtfthZK79WUMk+avLmwx3NGdU8+iVFXC2NMGxKsn0MnihOG2lvumj+AZo8CTwTrwjXDgZ5tztbRlEdRjBonQ==" }, "extsprintf": { "version": "1.3.0", @@ -27096,6 +27099,11 @@ "resolved": "https://registry.npmjs.org/typeforce/-/typeforce-1.18.0.tgz", "integrity": "sha512-7uc1O8h1M1g0rArakJdf0uLRSSgFcYexrVoKo+bzJd32gd4gDy2L/Z+8/FjPnU9ydY3pEnVPtr9FyscYY60K1g==" }, + "ua-parser-js": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-1.0.2.tgz", + "integrity": "sha512-00y/AXhx0/SsnI51fTc0rLRmafiGOM4/O+ny10Ps7f+j/b8p/ZY11ytMgznXkOVo4GQ+KwQG5UQLkLGirsACRg==" + }, "unfetch": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/unfetch/-/unfetch-4.2.0.tgz", diff --git a/new-lamassu-admin/package.json b/new-lamassu-admin/package.json index 5c2d5569..bd97a32c 100644 --- a/new-lamassu-admin/package.json +++ b/new-lamassu-admin/package.json @@ -14,7 +14,7 @@ "apollo-link": "^1.2.14", "apollo-link-error": "^1.1.13", "apollo-link-http": "^1.5.17", - "apollo-upload-client": "^16.0.0", + "apollo-upload-client": "^13.0.0", "axios": "0.21.1", "base-64": "^1.0.0", "bignumber.js": "9.0.0", @@ -47,6 +47,7 @@ "react-use": "15.3.2", "react-virtualized": "^9.21.2", "sanctuary": "^2.0.1", + "ua-parser-js": "^1.0.2", "uuid": "^7.0.2", "yup": "0.32.9" }, diff --git a/new-lamassu-admin/src/components/fake-table/Table.js b/new-lamassu-admin/src/components/fake-table/Table.js index 35154582..b43d5bee 100644 --- a/new-lamassu-admin/src/components/fake-table/Table.js +++ b/new-lamassu-admin/src/components/fake-table/Table.js @@ -79,6 +79,7 @@ const Tr = ({ onClick, error, errorMessage, + shouldShowError, children, className, size, @@ -99,7 +100,9 @@ const Tr = ({
{children}
- {error &&
{errorMessage}
} + {error && shouldShowError && ( +
{errorMessage}
+ )}
diff --git a/new-lamassu-admin/src/components/inputs/base/CodeInput.styles.js b/new-lamassu-admin/src/components/inputs/base/CodeInput.styles.js index 189add4c..0f0bba93 100644 --- a/new-lamassu-admin/src/components/inputs/base/CodeInput.styles.js +++ b/new-lamassu-admin/src/components/inputs/base/CodeInput.styles.js @@ -9,10 +9,12 @@ const styles = { borderRadius: '4px' }, focus: { - color: primaryColor, border: '2px solid', borderColor: primaryColor, - borderRadius: '4px' + borderRadius: '4px', + '&:focus': { + outline: 'none' + } }, error: { borderColor: errorColor diff --git a/new-lamassu-admin/src/components/tables/DataTable.js b/new-lamassu-admin/src/components/tables/DataTable.js index bc5e609e..ec68f3e1 100644 --- a/new-lamassu-admin/src/components/tables/DataTable.js +++ b/new-lamassu-admin/src/components/tables/DataTable.js @@ -28,6 +28,7 @@ const useStyles = makeStyles(styles) const Row = ({ id, + index, elements, data, width, @@ -48,9 +49,11 @@ const Row = ({ [classes.row]: true, [classes.expanded]: expanded } + return (
-
+
+ error={data.error || data.hasError} + shouldShowError={false} + errorMessage={data.errorMessage || data.hasError}> {elements.map(({ view = it => it?.toString(), ...props }, idx) => ( {view(data)} @@ -142,6 +146,7 @@ const DataTable = ({ width={width} size={rowSize} id={data[index].id ? data[index].id : index} + index={index} expWidth={expWidth} elements={elements} data={data[index]} diff --git a/new-lamassu-admin/src/components/typography/styles.js b/new-lamassu-admin/src/components/typography/styles.js index 44cfac11..ac06d238 100644 --- a/new-lamassu-admin/src/components/typography/styles.js +++ b/new-lamassu-admin/src/components/typography/styles.js @@ -129,7 +129,7 @@ export default { confirmationCode: { extend: base, fontSize: codeInputFontSize, - fontFamily: fontPrimary, + fontFamily: fontSecondary, fontWeight: 900 }, inline: { diff --git a/new-lamassu-admin/src/pages/Accounting/Accounting.js b/new-lamassu-admin/src/pages/Accounting/Accounting.js index 74d65a88..fbde444d 100644 --- a/new-lamassu-admin/src/pages/Accounting/Accounting.js +++ b/new-lamassu-admin/src/pages/Accounting/Accounting.js @@ -114,7 +114,7 @@ const Accounting = () => { const { data: configResponse, loading: configLoading } = useQuery(GET_DATA) const timezone = R.path(['config', 'locale_timezone'], configResponse) - const loading = operatorLoading && configLoading + const loading = operatorLoading || configLoading const operatorData = R.path(['operatorByUsername'], opData) @@ -170,26 +170,22 @@ const Accounting = () => { ] return ( - !loading && ( - <> - - -

Fiat balance history

- - - ) + <> + + +

Fiat balance history

+ + ) } diff --git a/new-lamassu-admin/src/pages/AddMachine/AddMachine.js b/new-lamassu-admin/src/pages/AddMachine/AddMachine.js index 45d531d1..5cc36b47 100644 --- a/new-lamassu-admin/src/pages/AddMachine/AddMachine.js +++ b/new-lamassu-admin/src/pages/AddMachine/AddMachine.js @@ -14,6 +14,7 @@ import { Button } from 'src/components/buttons' import { TextInput } from 'src/components/inputs/formik' import Sidebar from 'src/components/layout/Sidebar' import { Info2, P } from 'src/components/typography' +import { ReactComponent as CameraIcon } from 'src/styling/icons/ID/photo/zodiac.svg' import { ReactComponent as CloseIcon } from 'src/styling/icons/action/close/zodiac.svg' import { ReactComponent as CompleteStageIconSpring } from 'src/styling/icons/stage/spring/complete.svg' import { ReactComponent as CompleteStageIconZodiac } from 'src/styling/icons/stage/zodiac/complete.svg' @@ -70,8 +71,18 @@ const QrCodeComponent = ({ classes, qrCode, name, count, onPaired }) => { Scan QR code with your new cryptomat
-
- +
+ +
+ +

Snap a picture and scan

+
diff --git a/new-lamassu-admin/src/pages/AddMachine/styles.js b/new-lamassu-admin/src/pages/AddMachine/styles.js index 8e11e216..75d3c608 100644 --- a/new-lamassu-admin/src/pages/AddMachine/styles.js +++ b/new-lamassu-admin/src/pages/AddMachine/styles.js @@ -126,6 +126,23 @@ const styles = { }, errorMessage: { color: errorColor + }, + qrCodeImageWrapper: { + display: 'flex', + flexDirection: 'column', + backgroundColor: 'white', + border: `5px solid ${primaryColor}`, + padding: 5, + borderRadius: 15 + }, + qrCodeScanMessage: { + display: 'flex', + flexDirection: 'row', + alignItems: 'center', + margin: [[0, 0, 20, 20]], + '& > p': { + marginLeft: 10 + } } } diff --git a/new-lamassu-admin/src/pages/Authentication/Input2FAState.js b/new-lamassu-admin/src/pages/Authentication/Input2FAState.js index 34063f3d..31deaf63 100644 --- a/new-lamassu-admin/src/pages/Authentication/Input2FAState.js +++ b/new-lamassu-admin/src/pages/Authentication/Input2FAState.js @@ -1,6 +1,7 @@ import { useMutation, useLazyQuery } from '@apollo/react-hooks' import { makeStyles } from '@material-ui/core/styles' import base64 from 'base-64' +import { Form, Formik } from 'formik' import gql from 'graphql-tag' import React, { useContext, useState } from 'react' import { useHistory } from 'react-router-dom' @@ -120,14 +121,20 @@ const Input2FAState = ({ state, dispatch }) => { Enter your two-factor authentication code - + {/* TODO: refactor the 2FA CodeInput to properly use Formik */} + {}} initialValues={{}}> +
+ +
- + {/* TODO: refactor the 2FA CodeInput to properly use Formik */} + {}} initialValues={{}}> +
+ +
{getErrorMsg() && (

{getErrorMsg()}

)} diff --git a/new-lamassu-admin/src/pages/Authentication/Setup2FAState.js b/new-lamassu-admin/src/pages/Authentication/Setup2FAState.js index 231aae48..410b49e4 100644 --- a/new-lamassu-admin/src/pages/Authentication/Setup2FAState.js +++ b/new-lamassu-admin/src/pages/Authentication/Setup2FAState.js @@ -1,6 +1,7 @@ import { useMutation, useQuery, useLazyQuery } from '@apollo/react-hooks' import { makeStyles } from '@material-ui/core/styles' import base64 from 'base-64' +import { Form, Formik } from 'formik' import gql from 'graphql-tag' import QRCode from 'qrcode.react' import React, { useContext, useState } from 'react' @@ -125,6 +126,14 @@ const Setup2FAState = ({ state, dispatch }) => { return null } + const handleSubmit = () => { + if (twoFAConfirmation.length !== 6) { + setInvalidToken(true) + return + } + setup2FA(mutationOptions) + } + return ( secret && otpauth && ( @@ -159,28 +168,26 @@ const Setup2FAState = ({ state, dispatch }) => {
- + {/* TODO: refactor the 2FA CodeInput to properly use Formik */} + {}} initialValues={{}}> +
+ +
{getErrorMsg() && (

{getErrorMsg()}

)} -
diff --git a/new-lamassu-admin/src/pages/Authentication/shared.styles.js b/new-lamassu-admin/src/pages/Authentication/shared.styles.js index c8d12568..20ed5058 100644 --- a/new-lamassu-admin/src/pages/Authentication/shared.styles.js +++ b/new-lamassu-admin/src/pages/Authentication/shared.styles.js @@ -100,6 +100,9 @@ const styles = { }, error: { color: errorColor + }, + enterButton: { + display: 'none' } } diff --git a/new-lamassu-admin/src/pages/Customers/CustomerPhotos.js b/new-lamassu-admin/src/pages/Customers/CustomerPhotos.js new file mode 100644 index 00000000..6bb8a19c --- /dev/null +++ b/new-lamassu-admin/src/pages/Customers/CustomerPhotos.js @@ -0,0 +1,81 @@ +import { makeStyles, Paper } from '@material-ui/core' +import { format } from 'date-fns/fp' +import * as R from 'ramda' +import { React, useState } from 'react' + +import { InformativeDialog } from 'src/components/InformativeDialog' +import { Label2, H3 } from 'src/components/typography' +import { ReactComponent as CameraIcon } from 'src/styling/icons/ID/photo/comet.svg' +import { URI } from 'src/utils/apollo' + +import styles from './CustomerPhotos.styles' +import PhotosCarousel from './components/PhotosCarousel' + +const useStyles = makeStyles(styles) + +const CustomerPhotos = ({ photosData }) => { + const classes = useStyles() + + const [photosDialog, setPhotosDialog] = useState(false) + const [photoClickedIndex, setPhotoClickIndex] = useState(null) + const orderedPhotosData = !R.isNil(photoClickedIndex) + ? R.compose(R.flatten, R.reverse, R.splitAt(photoClickedIndex))(photosData) + : photosData + + return ( +
+
+

{'Photos & files'}

+
+
+ {photosData.map((elem, idx) => ( + + ))} +
+ } + onDissmised={() => { + setPhotosDialog(false) + setPhotoClickIndex(null) + }} + /> +
+ ) +} + +export const PhotoCard = ({ + idx, + date, + src, + setPhotosDialog, + setPhotoClickIndex +}) => { + const classes = useStyles() + + return ( + { + setPhotoClickIndex(idx) + setPhotosDialog(true) + }}> + +
+ + + {format('yyyy-MM-dd', new Date(date))} + +
+
+ ) +} + +export default CustomerPhotos diff --git a/new-lamassu-admin/src/pages/Customers/CustomerPhotos.styles.js b/new-lamassu-admin/src/pages/Customers/CustomerPhotos.styles.js new file mode 100644 index 00000000..a7fdffe4 --- /dev/null +++ b/new-lamassu-admin/src/pages/Customers/CustomerPhotos.styles.js @@ -0,0 +1,37 @@ +const styles = { + header: { + display: 'flex', + flexDirection: 'row' + }, + title: { + marginTop: 7, + marginRight: 24, + marginBottom: 32 + }, + photosChipList: { + display: 'flex', + flexDirection: 'row', + flexWrap: 'wrap' + }, + image: { + objectFit: 'cover', + objectPosition: 'center', + width: 224, + height: 200, + borderTopLeftRadius: 4, + borderTopRightRadius: 4 + }, + photoCardChip: { + margin: [[0, 16, 0, 0]] + }, + footer: { + display: 'flex', + flexDirection: 'row', + margin: [[8, 0, 0, 8]] + }, + date: { + margin: [[0, 0, 8, 12]] + } +} + +export default styles diff --git a/new-lamassu-admin/src/pages/Customers/CustomerProfile.js b/new-lamassu-admin/src/pages/Customers/CustomerProfile.js index 626c5f38..91b076ee 100644 --- a/new-lamassu-admin/src/pages/Customers/CustomerProfile.js +++ b/new-lamassu-admin/src/pages/Customers/CustomerProfile.js @@ -24,6 +24,7 @@ import { fromNamespace, namespaces } from 'src/utils/config' import CustomerData from './CustomerData' import CustomerNotes from './CustomerNotes' +import CustomerPhotos from './CustomerPhotos' import styles from './CustomerProfile.styles' import { CustomerDetails, @@ -31,7 +32,7 @@ import { CustomerSidebar, Wizard } from './components' -import { getFormattedPhone, getName } from './helper' +import { getFormattedPhone, getName, formatPhotosData } from './helper' const useStyles = makeStyles(styles) @@ -367,12 +368,24 @@ const CustomerProfile = memo(() => { const isCustomerData = clickedItem === 'customerData' const isOverview = clickedItem === 'overview' const isNotes = clickedItem === 'notes' + const isPhotos = clickedItem === 'photos' - const loading = customerLoading && configLoading + const frontCameraData = R.pick(['frontCameraPath', 'frontCameraAt'])( + customerData + ) + const txPhotosData = + sortedTransactions && + R.map(R.pick(['id', 'txCustomerPhotoPath', 'txCustomerPhotoAt']))( + sortedTransactions + ) + + const photosData = formatPhotosData(R.append(frontCameraData, txPhotosData)) + + const loading = customerLoading || configLoading const timezone = R.path(['config', 'locale_timezone'], configResponse) - const classes = useStyles({ blocked }) + const classes = useStyles() return ( <> @@ -406,29 +419,26 @@ const CustomerProfile = memo(() => { />
Actions -
+
setWizard(true)}> {`Manual data entry`} -
-
{}}> {`Add individual discount`} -
-
{isSuspended && ( { )} { { justifyContent="space-between"> setShowCompliance(!showCompliance)} /> @@ -524,6 +535,11 @@ const CustomerProfile = memo(() => { timezone={timezone}>
)} + {isPhotos && ( +
+ +
+ )}
{wizard && ( ({ + actionButton: { + margin: [[0, 0, 4, 0]], display: 'flex', flexDirection: 'row', - margin: [[0, 0, 4, 0]], - padding: [[0, props.blocked ? 35 : 48, 0]] - }), - customerDiscount: { - display: 'flex', - flexDirection: 'row', - margin: [[0, 0, 4, 0]], - padding: [[0, 23.5, 0]] + justifyContent: 'center' }, - customerManualDataEntry: { + actionBar: { display: 'flex', - flexDirection: 'row', - margin: [[8, 0, 4, 0]], - padding: [[0, 40.5, 0]] - }, - retrieveInformation: { - display: 'flex', - flexDirection: 'row', - margin: [[0, 0, 4, 0]], - padding: [[0, 32.5, 0]] + flexDirection: 'column', + width: 219 }, panels: { display: 'flex' diff --git a/new-lamassu-admin/src/pages/Customers/components/CustomerDetails.js b/new-lamassu-admin/src/pages/Customers/components/CustomerDetails.js index d5412738..8aebf62f 100644 --- a/new-lamassu-admin/src/pages/Customers/components/CustomerDetails.js +++ b/new-lamassu-admin/src/pages/Customers/components/CustomerDetails.js @@ -12,88 +12,73 @@ import PhotosCard from './PhotosCard' const useStyles = makeStyles(mainStyles) -const CustomerDetails = memo( - ({ txData, customer, locale, setShowCompliance }) => { - const classes = useStyles() +const CustomerDetails = memo(({ customer, photosData, locale }) => { + const classes = useStyles() - const idNumber = R.path(['idCardData', 'documentNumber'])(customer) - const usSsn = R.path(['usSsn'])(customer) + const idNumber = R.path(['idCardData', 'documentNumber'])(customer) + const usSsn = R.path(['usSsn'])(customer) - const elements = [ - { - header: 'Phone number', - size: 172, - value: getFormattedPhone(customer.phone, locale.country) - } - ] + const elements = [ + { + header: 'Phone number', + size: 172, + value: getFormattedPhone(customer.phone, locale.country) + } + ] - if (idNumber) - elements.push({ - header: 'ID number', - size: 172, - value: idNumber - }) + if (idNumber) + elements.push({ + header: 'ID number', + size: 172, + value: idNumber + }) - if (usSsn) - elements.push({ - header: 'US SSN', - size: 127, - value: usSsn - }) + if (usSsn) + elements.push({ + header: 'US SSN', + size: 127, + value: usSsn + }) - const name = getName(customer) + const name = getName(customer) - return ( - - - -
- -

- {name.length - ? name - : getFormattedPhone( - R.path(['phone'])(customer), - locale.country - )} -

-
- - {elements.map(({ size, header }, idx) => ( - - {header} - - ))} - - - {elements.map(({ size, value }, idx) => ( -

- {value} -

- ))} -
+ return ( + + + +
+ +

+ {name.length + ? name + : getFormattedPhone(R.path(['phone'])(customer), locale.country)} +

+
+ + {elements.map(({ size, header }, idx) => ( + + {header} + + ))} + + + {elements.map(({ size, value }, idx) => ( +

+ {value} +

+ ))}
- ) - } -) +
+ ) +}) export default CustomerDetails diff --git a/new-lamassu-admin/src/pages/Customers/components/CustomerSidebar.js b/new-lamassu-admin/src/pages/Customers/components/CustomerSidebar.js index a6190f13..6bcf3444 100644 --- a/new-lamassu-admin/src/pages/Customers/components/CustomerSidebar.js +++ b/new-lamassu-admin/src/pages/Customers/components/CustomerSidebar.js @@ -8,6 +8,8 @@ import { ReactComponent as NoteReversedIcon } from 'src/styling/icons/customer-n import { ReactComponent as NoteIcon } from 'src/styling/icons/customer-nav/note/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 { ReactComponent as PhotosReversedIcon } from 'src/styling/icons/customer-nav/photos/comet.svg' +import { ReactComponent as Photos } from 'src/styling/icons/customer-nav/photos/white.svg' import styles from './CustomerSidebar.styles.js' @@ -33,6 +35,12 @@ const CustomerSidebar = ({ isSelected, onClick }) => { display: 'Notes', Icon: NoteIcon, InverseIcon: NoteReversedIcon + }, + { + code: 'photos', + display: 'Photos & files', + Icon: Photos, + InverseIcon: PhotosReversedIcon } ] diff --git a/new-lamassu-admin/src/pages/Customers/components/PhotosCard.js b/new-lamassu-admin/src/pages/Customers/components/PhotosCard.js index 97674ec8..0181fdca 100644 --- a/new-lamassu-admin/src/pages/Customers/components/PhotosCard.js +++ b/new-lamassu-admin/src/pages/Customers/components/PhotosCard.js @@ -4,58 +4,21 @@ import { makeStyles } from '@material-ui/core/styles' import * as R from 'ramda' import React, { memo, useState } from 'react' -import { Carousel } from 'src/components/Carousel' import { InformativeDialog } from 'src/components/InformativeDialog' -import { Info2, Label1 } from 'src/components/typography' +import { Info2 } from 'src/components/typography' import { ReactComponent as CrossedCameraIcon } from 'src/styling/icons/ID/photo/crossed-camera.svg' import { URI } from 'src/utils/apollo' -import CopyToClipboard from '../../Transactions/CopyToClipboard' - import styles from './PhotosCard.styles' +import PhotosCarousel from './PhotosCarousel' const useStyles = makeStyles(styles) -const Label = ({ children }) => { - const classes = useStyles() - return {children} -} - -const PhotosCard = memo(({ frontCameraData, txPhotosData }) => { +const PhotosCard = memo(({ photosData }) => { const classes = useStyles() const [photosDialog, setPhotosDialog] = useState(false) - const mapKeys = pair => { - const [key, value] = pair - if (key === 'txCustomerPhotoPath' || key === 'frontCameraPath') { - return ['path', value] - } - if (key === 'txCustomerPhotoAt' || key === 'frontCameraAt') { - return ['date', value] - } - return pair - } - - const addPhotoDir = R.map(it => { - const hasFrontCameraData = R.has('id')(it) - return hasFrontCameraData - ? { ...it, photoDir: 'operator-data/customersphotos' } - : { ...it, photoDir: 'front-camera-photo' } - }) - - const standardizeKeys = R.map( - R.compose(R.fromPairs, R.map(mapKeys), R.toPairs) - ) - - const filterByPhotoAvailable = R.filter( - tx => !R.isNil(tx.date) && !R.isNil(tx.path) - ) - - const photosData = filterByPhotoAvailable( - addPhotoDir(standardizeKeys(R.append(frontCameraData, txPhotosData))) - ) - const singlePhoto = R.head(photosData) return ( @@ -97,41 +60,4 @@ const PhotosCard = memo(({ frontCameraData, txPhotosData }) => { ) }) -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 ( - <> - - {!isFaceCustomerPhoto && ( -
- - - {photosData && photosData[currentIndex]?.id} - -
- )} -
-
-
- -
{photosData && photosData[currentIndex]?.date}
-
-
-
- -
- {!isFaceCustomerPhoto ? 'Acceptance of T&C' : 'Compliance scan'} -
-
-
- - ) -}) - export default PhotosCard 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 002c5bfb..5d974078 100644 --- a/new-lamassu-admin/src/pages/Customers/components/PhotosCard.styles.js +++ b/new-lamassu-admin/src/pages/Customers/components/PhotosCard.styles.js @@ -1,7 +1,4 @@ -import typographyStyles from 'src/components/typography/styles' -import { zircon, backgroundColor, offColor } from 'src/styling/variables' - -const { p } = typographyStyles +import { zircon, backgroundColor } from 'src/styling/variables' export default { photo: { @@ -41,43 +38,5 @@ export default { alignItems: 'center', justifyContent: 'center', display: 'flex' - }, - label: { - color: offColor, - margin: [[0, 0, 6, 0]] - }, - firstRow: { - padding: [[8]], - display: 'flex', - flexDirection: 'column' - }, - secondRow: { - extend: p, - display: 'flex', - padding: [[8]], - '& > div': { - display: 'flex', - flexDirection: 'column', - '& > div': { - width: 144, - height: 37, - marginBottom: 15, - marginRight: 55 - } - } - }, - imgWrapper: { - alignItems: 'center', - justifyContent: 'center', - display: 'flex', - width: 550, - height: 550 - }, - imgInner: { - objectFit: 'cover', - objectPosition: 'center', - width: 550, - height: 550, - marginBottom: 40 } } diff --git a/new-lamassu-admin/src/pages/Customers/components/PhotosCarousel.js b/new-lamassu-admin/src/pages/Customers/components/PhotosCarousel.js new file mode 100644 index 00000000..e0d6f2e0 --- /dev/null +++ b/new-lamassu-admin/src/pages/Customers/components/PhotosCarousel.js @@ -0,0 +1,56 @@ +import { makeStyles } from '@material-ui/core/styles' +import * as R from 'ramda' +import React, { memo, useState } from 'react' + +import { Carousel } from 'src/components/Carousel' +import { Label1 } from 'src/components/typography' + +import CopyToClipboard from '../../Transactions/CopyToClipboard' + +import styles from './PhotosCarousel.styles' + +const useStyles = makeStyles(styles) + +const PhotosCarousel = memo(({ photosData }) => { + const classes = useStyles() + const [currentIndex, setCurrentIndex] = useState(0) + + const Label = ({ children }) => { + const classes = useStyles() + return {children} + } + + const isFaceCustomerPhoto = !R.has('id')(photosData[currentIndex]) + + const slidePhoto = index => setCurrentIndex(index) + + return ( + <> + + {!isFaceCustomerPhoto && ( +
+ + + {photosData && photosData[currentIndex]?.id} + +
+ )} +
+
+
+ +
{photosData && photosData[currentIndex]?.date}
+
+
+
+ +
+ {!isFaceCustomerPhoto ? 'Acceptance of T&C' : 'Compliance scan'} +
+
+
+ + ) +}) + +export default PhotosCarousel diff --git a/new-lamassu-admin/src/pages/Customers/components/PhotosCarousel.styles.js b/new-lamassu-admin/src/pages/Customers/components/PhotosCarousel.styles.js new file mode 100644 index 00000000..5c568cd9 --- /dev/null +++ b/new-lamassu-admin/src/pages/Customers/components/PhotosCarousel.styles.js @@ -0,0 +1,31 @@ +import typographyStyles from 'src/components/typography/styles' +import { offColor } from 'src/styling/variables' + +const { p } = typographyStyles + +export default { + label: { + color: offColor, + margin: [[0, 0, 6, 0]] + }, + firstRow: { + padding: [[8]], + display: 'flex', + flexDirection: 'column' + }, + secondRow: { + extend: p, + display: 'flex', + padding: [[8]], + '& > div': { + display: 'flex', + flexDirection: 'column', + '& > div': { + width: 144, + height: 37, + marginBottom: 15, + marginRight: 55 + } + } + } +} diff --git a/new-lamassu-admin/src/pages/Customers/components/TransactionsList.js b/new-lamassu-admin/src/pages/Customers/components/TransactionsList.js index 8b55208c..ea8d765e 100644 --- a/new-lamassu-admin/src/pages/Customers/components/TransactionsList.js +++ b/new-lamassu-admin/src/pages/Customers/components/TransactionsList.js @@ -70,12 +70,7 @@ const TransactionsList = ({ customer, data, loading, locale }) => { const tableElements = [ { - header: 'Machine', - width: 160, - view: R.path(['machineName']) - }, - { - width: 125, + width: 40, view: it => ( <> {it.txClass === 'cashOut' ? ( @@ -86,6 +81,11 @@ const TransactionsList = ({ customer, data, loading, locale }) => { ) }, + { + header: 'Machine', + width: 160, + view: R.path(['machineName']) + }, { header: 'Transaction ID', width: 145, diff --git a/new-lamassu-admin/src/pages/Customers/components/index.js b/new-lamassu-admin/src/pages/Customers/components/index.js index 5e52dd81..7e3c3e19 100644 --- a/new-lamassu-admin/src/pages/Customers/components/index.js +++ b/new-lamassu-admin/src/pages/Customers/components/index.js @@ -5,10 +5,12 @@ import CustomerSidebar from './CustomerSidebar' import EditableCard from './EditableCard' import Field from './Field' import IdDataCard from './IdDataCard' +import PhotosCarousel from './PhotosCarousel' import TransactionsList from './TransactionsList' import Upload from './Upload' export { + PhotosCarousel, CustomerDetails, IdDataCard, TransactionsList, diff --git a/new-lamassu-admin/src/pages/Customers/helper.js b/new-lamassu-admin/src/pages/Customers/helper.js index a5d776cc..719ae628 100644 --- a/new-lamassu-admin/src/pages/Customers/helper.js +++ b/new-lamassu-admin/src/pages/Customers/helper.js @@ -209,10 +209,41 @@ const entryType = { initialValues: { entryType: '' } } +const mapKeys = pair => { + const [key, value] = pair + if (key === 'txCustomerPhotoPath' || key === 'frontCameraPath') { + return ['path', value] + } + if (key === 'txCustomerPhotoAt' || key === 'frontCameraAt') { + return ['date', value] + } + return pair +} + +const addPhotoDir = R.map(it => { + const hasFrontCameraData = R.has('id')(it) + return hasFrontCameraData + ? { ...it, photoDir: 'operator-data/customersphotos' } + : { ...it, photoDir: 'front-camera-photo' } +}) + +const standardizeKeys = R.map(R.compose(R.fromPairs, R.map(mapKeys), R.toPairs)) + +const filterByPhotoAvailable = R.filter( + tx => !R.isNil(tx.date) && !R.isNil(tx.path) +) + +const formatPhotosData = R.compose( + filterByPhotoAvailable, + addPhotoDir, + standardizeKeys +) + export { getAuthorizedStatus, getFormattedPhone, getName, entryType, - customElements + customElements, + formatPhotosData } diff --git a/new-lamassu-admin/src/pages/LoyaltyPanel/IndividualDiscounts.js b/new-lamassu-admin/src/pages/LoyaltyPanel/IndividualDiscounts.js index b9585d76..ad245ebd 100644 --- a/new-lamassu-admin/src/pages/LoyaltyPanel/IndividualDiscounts.js +++ b/new-lamassu-admin/src/pages/LoyaltyPanel/IndividualDiscounts.js @@ -64,7 +64,9 @@ const IndividualDiscounts = () => { const [showModal, setShowModal] = useState(false) const toggleModal = () => setShowModal(!showModal) - const { data: discountResponse, loading } = useQuery(GET_INDIVIDUAL_DISCOUNTS) + const { data: discountResponse, loading: discountLoading } = useQuery( + GET_INDIVIDUAL_DISCOUNTS + ) const { data: customerData, loading: customerLoading } = useQuery( GET_CUSTOMERS ) @@ -160,24 +162,22 @@ const IndividualDiscounts = () => { } ] - const isLoading = loading || customerLoading + const loading = discountLoading || customerLoading return ( <> - {!isLoading && !R.isEmpty(discountResponse.individualDiscounts) && ( - - - Add new code - - - )} - {!isLoading && !R.isEmpty(discountResponse.individualDiscounts) && ( + {!loading && !R.isEmpty(discountResponse.individualDiscounts) && ( <> + + + Add new code + + { /> )} - {!isLoading && R.isEmpty(discountResponse.individualDiscounts) && ( + {!loading && R.isEmpty(discountResponse.individualDiscounts) && ( It seems there are no active individual customer discounts on your diff --git a/new-lamassu-admin/src/pages/MachineLogs.js b/new-lamassu-admin/src/pages/MachineLogs.js index 277b82c5..d06f4a2c 100644 --- a/new-lamassu-admin/src/pages/MachineLogs.js +++ b/new-lamassu-admin/src/pages/MachineLogs.js @@ -81,16 +81,21 @@ const Logs = () => { const deviceId = selected?.deviceId - const { data: machineResponse } = useQuery(GET_MACHINES) + const { data: machineResponse, loading: machinesLoading } = useQuery( + GET_MACHINES + ) - const { data: configResponse } = useQuery(GET_DATA) + const { data: configResponse, loading: configLoading } = useQuery(GET_DATA) const timezone = R.path(['config', 'locale_timezone'], configResponse) - const { data: logsResponse, loading } = useQuery(GET_MACHINE_LOGS, { - variables: { deviceId, limit: NUM_LOG_RESULTS }, - skip: !selected, - onCompleted: () => setSaveMessage('') - }) + const { data: logsResponse, loading: logsLoading } = useQuery( + GET_MACHINE_LOGS, + { + variables: { deviceId, limit: NUM_LOG_RESULTS }, + skip: !selected, + onCompleted: () => setSaveMessage('') + } + ) if (machineResponse?.machines?.length && !selected) { setSelected(machineResponse?.machines[0]) @@ -100,6 +105,8 @@ const Logs = () => { return R.path(['deviceId'])(selected) === it.deviceId } + const loading = machinesLoading || configLoading || logsLoading + return ( <>
diff --git a/new-lamassu-admin/src/pages/Machines/MachineComponents/Transactions/Transactions.js b/new-lamassu-admin/src/pages/Machines/MachineComponents/Transactions/Transactions.js index dedd15e0..a5902611 100644 --- a/new-lamassu-admin/src/pages/Machines/MachineComponents/Transactions/Transactions.js +++ b/new-lamassu-admin/src/pages/Machines/MachineComponents/Transactions/Transactions.js @@ -82,7 +82,7 @@ const Transactions = ({ id }) => { const { data: configData, loading: configLoading } = useQuery(GET_DATA) const timezone = R.path(['config', 'locale_timezone'], configData) - const loading = txLoading && configLoading + const loading = txLoading || configLoading if (!loading && txResponse) { txResponse.transactions = txResponse.transactions.splice(0, 5) diff --git a/new-lamassu-admin/src/pages/Maintenance/CashboxHistory.js b/new-lamassu-admin/src/pages/Maintenance/CashboxHistory.js index edc11a17..6e232f01 100644 --- a/new-lamassu-admin/src/pages/Maintenance/CashboxHistory.js +++ b/new-lamassu-admin/src/pages/Maintenance/CashboxHistory.js @@ -85,7 +85,7 @@ const CashboxHistory = ({ machines, currency }) => { const { data: configData, loading: configLoading } = useQuery(GET_DATA) const timezone = R.path(['config', 'locale_timezone'], configData) - const loading = batchesLoading && configLoading + const loading = batchesLoading || configLoading const batches = R.path(['cashboxBatches'])(batchesData) @@ -252,16 +252,13 @@ const CashboxHistory = ({ machines, currency }) => { ] return ( - <> - {!loading && ( - - )} - + ) } diff --git a/new-lamassu-admin/src/pages/Maintenance/MachineStatus.js b/new-lamassu-admin/src/pages/Maintenance/MachineStatus.js index 2c3ac5da..23512947 100644 --- a/new-lamassu-admin/src/pages/Maintenance/MachineStatus.js +++ b/new-lamassu-admin/src/pages/Maintenance/MachineStatus.js @@ -54,7 +54,11 @@ const MachineStatus = () => { const history = useHistory() const { state } = useLocation() const addedMachineId = state?.id - const { data: machinesResponse, refetch, loading } = useQuery(GET_MACHINES) + const { + data: machinesResponse, + refetch, + loading: machinesLoading + } = useQuery(GET_MACHINES) const { data: configResponse, configLoading } = useQuery(GET_DATA) const timezone = R.path(['config', 'locale_timezone'], configResponse) @@ -114,6 +118,8 @@ const MachineStatus = () => { ) + const loading = machinesLoading || configLoading + return ( <>
@@ -132,7 +138,7 @@ const MachineStatus = () => {
{ const [saveMessage, setSaveMessage] = useState(null) const [logLevel, setLogLevel] = useState(SHOW_ALL) - const { data, loading } = useQuery(GET_SERVER_DATA, { + const { data, loading: dataLoading } = useQuery(GET_SERVER_DATA, { onCompleted: () => setSaveMessage(''), variables: { limit: NUM_LOG_RESULTS } }) - const { data: configResponse, configLoading } = useQuery(GET_DATA) + const { data: configResponse, loading: configLoading } = useQuery(GET_DATA) const timezone = R.path(['config', 'locale_timezone'], configResponse) const defaultLogLevels = [ @@ -132,6 +132,8 @@ const Logs = () => { setLogLevel(logLevel) } + const loading = dataLoading || configLoading + return ( <>
@@ -206,8 +208,8 @@ const Logs = () => { ))} - {loading && configLoading &&

{'Loading...'}

} - {!loading && !configLoading && !data?.serverLogs?.length && ( + {loading &&

{'Loading...'}

} + {!loading && !data?.serverLogs?.length && (

{'No activity so far'}

)}
diff --git a/new-lamassu-admin/src/pages/SessionManagement/SessionManagement.js b/new-lamassu-admin/src/pages/SessionManagement/SessionManagement.js index 9ce5ab12..d40c5e0a 100644 --- a/new-lamassu-admin/src/pages/SessionManagement/SessionManagement.js +++ b/new-lamassu-admin/src/pages/SessionManagement/SessionManagement.js @@ -48,7 +48,7 @@ const SessionManagement = () => { const { data: configResponse, loading: configLoading } = useQuery(GET_DATA) const timezone = R.path(['config', 'locale_timezone'], configResponse) - const loading = sessionsLoading && configLoading + const loading = sessionsLoading || configLoading const elements = [ { @@ -107,15 +107,14 @@ const SessionManagement = () => { ] return ( - !loading && ( - <> - - - - ) + <> + + + ) } diff --git a/new-lamassu-admin/src/pages/Transactions/Transactions.js b/new-lamassu-admin/src/pages/Transactions/Transactions.js index 1ea2b927..016c8b37 100644 --- a/new-lamassu-admin/src/pages/Transactions/Transactions.js +++ b/new-lamassu-admin/src/pages/Transactions/Transactions.js @@ -15,6 +15,8 @@ import DataTable from 'src/components/tables/DataTable' import { ReactComponent as TxInIcon } from 'src/styling/icons/direction/cash-in.svg' import { ReactComponent as TxOutIcon } from 'src/styling/icons/direction/cash-out.svg' import { ReactComponent as CustomerLinkIcon } from 'src/styling/icons/month arrows/right.svg' +import { ReactComponent as CustomerLinkWhiteIcon } from 'src/styling/icons/month arrows/right_white.svg' +import { errorColor } from 'src/styling/variables' import { formatDate } from 'src/utils/timezones' import DetailsRow from './DetailsCard' @@ -124,13 +126,13 @@ const Transactions = () => { const history = useHistory() const [filters, setFilters] = useState([]) - const { data: filtersResponse, loading: loadingFilters } = useQuery( + const { data: filtersResponse, loading: filtersLoading } = useQuery( GET_TRANSACTION_FILTERS ) const [variables, setVariables] = useState({ limit: NUM_LOG_RESULTS }) const { data: txData, - loading: loadingTransactions, + loading: transactionsLoading, refetch, startPolling, stopPolling @@ -185,7 +187,11 @@ const Transactions = () => {
{getCustomerDisplayName(it)}
{!it.isAnonymous && (
redirect(it.customerId)}> - + {it.hasError ? ( + + ) : ( + + )}
)}
@@ -294,6 +300,14 @@ const Transactions = () => { const filterOptions = R.path(['transactionFilters'])(filtersResponse) + const loading = transactionsLoading || filtersLoading || configLoading + + const errorLabel = ( + + + + ) + return ( <>
@@ -301,7 +315,7 @@ const Transactions = () => { Transactions
{ Cash-out
+
+ {errorLabel} + Transaction error +
{filters.length > 0 && ( @@ -342,7 +360,7 @@ const Transactions = () => { /> )} div': { + marginLeft: 24 + }, '& > div:first-child': { - marginRight: 24 + marginLeft: 0 }, '& span': { extend: label1, diff --git a/new-lamassu-admin/src/pages/UserManagement/modals/Input2FAModal.js b/new-lamassu-admin/src/pages/UserManagement/modals/Input2FAModal.js index d3773fbb..f64b32e9 100644 --- a/new-lamassu-admin/src/pages/UserManagement/modals/Input2FAModal.js +++ b/new-lamassu-admin/src/pages/UserManagement/modals/Input2FAModal.js @@ -1,5 +1,6 @@ import { useLazyQuery } from '@apollo/react-hooks' import { makeStyles } from '@material-ui/core/styles' +import { Form, Formik } from 'formik' import gql from 'graphql-tag' import React, { useState } from 'react' @@ -48,6 +49,14 @@ const Input2FAModal = ({ showModal, handleClose, setConfirmation }) => { return null } + const handleSubmit = () => { + if (twoFACode.length !== 6) { + setInvalidCode(true) + return + } + confirm2FA({ variables: { code: twoFACode } }) + } + return ( showModal && ( { To make changes on this user, please confirm this action by entering your two-factor authentication code below.

- + {/* TODO: refactor the 2FA CodeInput to properly use Formik */} + {}} initialValues={{}}> +
+ +
diff --git a/new-lamassu-admin/src/pages/Wizard/components/Wallet/ChooseExchange.js b/new-lamassu-admin/src/pages/Wizard/components/Wallet/ChooseExchange.js index ff4e8959..5c3bb08b 100644 --- a/new-lamassu-admin/src/pages/Wizard/components/Wallet/ChooseExchange.js +++ b/new-lamassu-admin/src/pages/Wizard/components/Wallet/ChooseExchange.js @@ -38,7 +38,8 @@ const SAVE_ACCOUNTS = gql` } ` -const isConfigurable = it => !R.isNil(it) && !R.contains(it)(['mock-exchange']) +const isConfigurable = it => + !R.isNil(it) && !R.contains(it)(['mock-exchange', 'no-exchange']) const ChooseExchange = ({ data: currentData, addData }) => { const classes = useStyles() diff --git a/new-lamassu-admin/src/styling/icons/customer-nav/photos/comet.svg b/new-lamassu-admin/src/styling/icons/customer-nav/photos/comet.svg new file mode 100644 index 00000000..95ee5f2c --- /dev/null +++ b/new-lamassu-admin/src/styling/icons/customer-nav/photos/comet.svg @@ -0,0 +1,10 @@ + + + icon/customer-nav/photos/comet + + + + + + + \ No newline at end of file diff --git a/new-lamassu-admin/src/styling/icons/customer-nav/photos/white.svg b/new-lamassu-admin/src/styling/icons/customer-nav/photos/white.svg new file mode 100644 index 00000000..e27fef8f --- /dev/null +++ b/new-lamassu-admin/src/styling/icons/customer-nav/photos/white.svg @@ -0,0 +1,10 @@ + + + icon/customer-nav/photos/white + + + + + + + \ No newline at end of file diff --git a/new-lamassu-admin/src/styling/icons/month arrows/right_white.svg b/new-lamassu-admin/src/styling/icons/month arrows/right_white.svg new file mode 100644 index 00000000..9d8cae10 --- /dev/null +++ b/new-lamassu-admin/src/styling/icons/month arrows/right_white.svg @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/package.json b/package.json index 030bf13b..52cb226e 100644 --- a/package.json +++ b/package.json @@ -77,7 +77,6 @@ "socket.io-client": "^2.0.3", "talisman": "^0.20.0", "twilio": "^3.6.1", - "ua-parser-js": "^0.7.22", "uuid": "8.3.2", "web3": "^0.20.6", "winston": "^2.4.2",