toggleClear(id)}\n className={classnames(iconClass)}\n />\n \n {!valid &&
}\n \n )\n}\n\nexport default NotificationRow\n","import { useQuery, useMutation } from '@apollo/react-hooks'\nimport { makeStyles } from '@material-ui/core/styles'\nimport gql from 'graphql-tag'\nimport * as R from 'ramda'\nimport React, { useState, useEffect } from 'react'\n\nimport ActionButton from 'src/components/buttons/ActionButton'\nimport { H5 } from 'src/components/typography'\nimport { ReactComponent as NotificationIconZodiac } from 'src/styling/icons/menu/notification-zodiac.svg'\nimport { ReactComponent as ClearAllIconInverse } from 'src/styling/icons/stage/spring/empty.svg'\nimport { ReactComponent as ClearAllIcon } from 'src/styling/icons/stage/zodiac/empty.svg'\nimport { ReactComponent as ShowUnreadIcon } from 'src/styling/icons/stage/zodiac/full.svg'\n\nimport styles from './NotificationCenter.styles'\nimport NotificationRow from './NotificationRow'\n\nconst useStyles = makeStyles(styles)\n\nconst GET_NOTIFICATIONS = gql`\n query getNotifications {\n notifications {\n id\n type\n detail\n message\n created\n read\n valid\n }\n hasUnreadNotifications\n machines {\n deviceId\n name\n }\n }\n`\n\nconst TOGGLE_CLEAR_NOTIFICATION = gql`\n mutation toggleClearNotification($id: ID!, $read: Boolean!) {\n toggleClearNotification(id: $id, read: $read) {\n id\n read\n }\n }\n`\n\nconst CLEAR_ALL_NOTIFICATIONS = gql`\n mutation clearAllNotifications {\n clearAllNotifications {\n id\n }\n }\n`\n\nconst NotificationCenter = ({\n close,\n hasUnreadProp,\n buttonCoords,\n popperRef,\n refetchHasUnreadHeader\n}) => {\n const { data, loading } = useQuery(GET_NOTIFICATIONS, {\n pollInterval: 60000\n })\n const [xOffset, setXoffset] = useState(300)\n\n const [showingUnread, setShowingUnread] = useState(false)\n const classes = useStyles({ buttonCoords, xOffset })\n const machines = R.compose(\n R.map(R.prop('name')),\n R.indexBy(R.prop('deviceId'))\n )(R.path(['machines'])(data) ?? [])\n const notifications = R.path(['notifications'])(data) ?? []\n const [hasUnread, setHasUnread] = useState(hasUnreadProp)\n\n const [toggleClearNotification] = useMutation(TOGGLE_CLEAR_NOTIFICATION, {\n onError: () => console.error('Error while clearing notification'),\n refetchQueries: () => ['getNotifications']\n })\n const [clearAllNotifications] = useMutation(CLEAR_ALL_NOTIFICATIONS, {\n onError: () => console.error('Error while clearing all notifications'),\n refetchQueries: () => ['getNotifications']\n })\n\n useEffect(() => {\n setXoffset(popperRef.current.getBoundingClientRect().x)\n if (data && data.hasUnreadNotifications !== hasUnread) {\n refetchHasUnreadHeader()\n setHasUnread(!hasUnread)\n }\n }, [popperRef, data, hasUnread, refetchHasUnreadHeader])\n\n const buildNotifications = () => {\n const notificationsToShow =\n !showingUnread || !hasUnread\n ? notifications\n : R.filter(R.propEq('read', false))(notifications)\n return notificationsToShow.map(n => {\n return (\n
\n toggleClearNotification({\n variables: { id: n.id, read: !n.read }\n })\n }\n />\n )\n })\n }\n\n return (\n <>\n \n
\n
Notifications \n
\n \n {hasUnread &&
}\n \n
\n
\n {hasUnread && (\n
setShowingUnread(!showingUnread)}>\n {showingUnread ? 'Show all' : 'Show unread'}\n \n )}\n {hasUnread && (\n
\n Mark all as read\n \n )}\n
\n
\n {!loading && buildNotifications()}\n
\n
\n
\n >\n )\n}\n\nexport default NotificationCenter\n","import NotificationCenter from './NotificationCenter'\nexport default NotificationCenter\n","import { bySize, bold } from 'src/styling/helpers'\nimport { secondaryColor } from 'src/styling/variables'\n\nexport default {\n size: ({ size }) => ({\n marginTop: size === 'lg' ? 0 : 2,\n ...bySize(size)\n }),\n bold,\n root: ({ width, textAlign }) => ({\n width,\n '& input': {\n textAlign\n }\n }),\n underline: {\n '&:before': {\n borderBottomColor: secondaryColor\n },\n '&:hover:not(.Mui-disabled)::before': {\n borderBottomColor: secondaryColor\n }\n }\n}\n","import { makeStyles } from '@material-ui/core'\nimport TextField from '@material-ui/core/TextField'\nimport classnames from 'classnames'\nimport * as R from 'ramda'\nimport React, { memo } from 'react'\n\nimport styles from './TextInput.styles'\n\nconst useStyles = makeStyles(styles)\n\nconst TextInput = memo(\n ({\n name,\n isPasswordFilled,\n onChange,\n onBlur,\n value,\n error,\n suffix,\n textAlign,\n width,\n // lg or sm\n size,\n bold,\n className,\n InputProps,\n ...props\n }) => {\n const classes = useStyles({ textAlign, width, size })\n const isTextFilled = !error && !R.isNil(value) && !R.isEmpty(value)\n const filled = isPasswordFilled || isTextFilled\n const inputClasses = {\n [classes.bold]: bold\n }\n\n return (\n \n )\n }\n)\n\nexport default TextInput\n","import MAutocomplete from '@material-ui/lab/Autocomplete'\nimport sort from 'match-sorter'\nimport * as R from 'ramda'\nimport React from 'react'\n\nimport TextInput from './TextInput'\n\nconst Autocomplete = ({\n optionsLimit = 5, // set limit = null for no limit\n limit,\n options,\n label,\n valueProp,\n multiple,\n onChange,\n labelProp,\n shouldStayOpen,\n value: outsideValue,\n error,\n fullWidth,\n textAlign,\n size,\n autoFocus,\n ...props\n}) => {\n const mapFromValue = options => it => R.find(R.propEq(valueProp, it))(options)\n const mapToValue = R.prop(valueProp)\n\n const getValue = () => {\n if (!valueProp) return outsideValue\n\n const transform = multiple\n ? R.map(mapFromValue(options))\n : mapFromValue(options)\n\n return transform(outsideValue)\n }\n\n const value = getValue()\n\n const innerOnChange = (evt, value) => {\n if (!valueProp) return onChange(evt, value)\n\n const rValue = multiple ? R.map(mapToValue)(value) : mapToValue(value)\n onChange(evt, rValue)\n }\n\n const valueArray = () => {\n if (R.isNil(value)) return []\n return multiple ? value : [value]\n }\n\n const filter = (array, input) => {\n if (!input) return array\n return sort(array, input, { keys: [valueProp, labelProp] })\n }\n\n const filterOptions = (array, { inputValue }) =>\n R.union(\n R.isEmpty(inputValue) ? valueArray() : [],\n filter(array, inputValue)\n ).slice(\n 0,\n R.defaultTo(undefined)(limit) &&\n Math.max(limit, R.isEmpty(inputValue) ? valueArray().length : 0)\n )\n\n return (\n {\n return (\n \n )\n }}\n />\n )\n}\n\nexport default Autocomplete\n","import Checkbox from '@material-ui/core/Checkbox'\nimport { makeStyles } from '@material-ui/core/styles'\nimport CheckBoxIcon from '@material-ui/icons/CheckBox'\nimport CheckBoxOutlineBlankIcon from '@material-ui/icons/CheckBoxOutlineBlank'\nimport React from 'react'\n\nimport { fontSize2, fontSize3, secondaryColor } from 'src/styling/variables'\n\nconst useStyles = makeStyles({\n root: {\n color: secondaryColor,\n '&$checked': {\n color: secondaryColor\n }\n },\n checked: {}\n})\n\nconst CheckboxInput = ({ name, onChange, value, label, ...props }) => {\n const classes = useStyles()\n\n return (\n \n }\n checkedIcon={ }\n disableRipple\n {...props}\n />\n )\n}\n\nexport default CheckboxInput\n","import React, { memo } from 'react'\nimport NumberFormat from 'react-number-format'\n\nimport TextInput from './TextInput'\n\nconst NumberInput = memo(\n ({\n name,\n onChange,\n onBlur,\n value,\n error,\n suffix,\n textAlign,\n width,\n // lg or sm\n size,\n bold,\n className,\n decimalPlaces,\n InputProps,\n ...props\n }) => {\n return (\n {\n onChange({\n target: {\n id: name,\n value: values.floatValue\n }\n })\n }}\n {...props}\n />\n )\n }\n)\n\nexport default NumberInput\n","import {\n Radio,\n RadioGroup as MRadioGroup,\n FormControlLabel,\n makeStyles\n} from '@material-ui/core'\nimport classnames from 'classnames'\nimport React from 'react'\n\nimport { Label1 } from 'src/components/typography'\n\nconst styles = {\n label: {\n height: 16,\n lineHeight: '16px',\n margin: [[0, 0, 4, 0]],\n paddingLeft: 3\n }\n}\n\nconst useStyles = makeStyles(styles)\n\nconst RadioGroup = ({\n name,\n label,\n value,\n options,\n onChange,\n className,\n labelClassName,\n radioClassName\n}) => {\n const classes = useStyles()\n\n return (\n <>\n {label && {label} }\n \n {options.map((option, idx) => (\n }\n label={option.display}\n className={classnames(labelClassName)}\n />\n ))}\n \n >\n )\n}\n\nexport default RadioGroup\n","import React, { memo, useState } from 'react'\n\nimport { TextInput } from '../base'\n\nconst SecretInput = memo(\n ({ value, onFocus, isPasswordFilled, onBlur, ...props }) => {\n const [focused, setFocused] = useState(false)\n const placeholder = '⚬ ⚬ ⚬ This field is set ⚬ ⚬ ⚬'\n const innerOnFocus = event => {\n setFocused(true)\n onFocus && onFocus(event)\n }\n\n const innerOnBlur = event => {\n setFocused(false)\n onBlur && onBlur(event)\n }\n\n return (\n \n )\n }\n)\n\nexport default SecretInput\n","import Switch from '@material-ui/core/Switch'\nimport { makeStyles } from '@material-ui/core/styles'\nimport React, { memo } from 'react'\n\nimport {\n secondaryColor,\n offColor,\n disabledColor,\n disabledColor2\n} from '../../../styling/variables'\n\nconst useStyles = makeStyles(theme => ({\n root: {\n width: 32,\n height: 20,\n padding: 0,\n margin: theme.spacing(1)\n },\n switchBase: {\n padding: 2,\n '&$disabled': {\n color: disabledColor2,\n '& + $track': {\n backgroundColor: disabledColor,\n opacity: 1\n }\n },\n '&$checked': {\n transform: 'translateX(58%)',\n color: theme.palette.common.white,\n '&$disabled': {\n color: disabledColor2\n },\n '& + $track': {\n backgroundColor: secondaryColor,\n opacity: 1,\n border: 'none'\n }\n },\n '&$focusVisible $thumb': {\n border: '6px solid #fff'\n }\n },\n thumb: {\n width: 16,\n height: 16\n },\n track: {\n borderRadius: 17,\n border: 'none',\n backgroundColor: offColor,\n opacity: 1,\n transition: theme.transitions.create(['background-color', 'border'])\n },\n disabled: {},\n checked: {},\n focusVisible: {}\n}))\n\nconst SwitchInput = memo(({ ...props }) => {\n const classes = useStyles()\n return (\n \n )\n})\n\nexport default SwitchInput\n","import { useFormikContext } from 'formik'\nimport * as R from 'ramda'\nimport React, { useState } from 'react'\n\nimport { Autocomplete } from '../base'\n\nconst AutocompleteFormik = ({ options, onChange, ...props }) => {\n const [open, setOpen] = useState(false)\n\n const { name, onBlur, value } = props.field\n const { touched, errors, setFieldValue, setFieldTouched } = props.form\n const error = !!(touched[name] && errors[name])\n const { initialValues, values } = useFormikContext()\n\n const innerOptions =\n R.type(options) === 'Function' ? options(initialValues, values) : options\n\n const innerOnBlur = event => {\n name && setFieldTouched(name, true)\n onBlur && onBlur(event)\n }\n\n const onChangeHandler = value => setFieldValue(name, value)\n const shouldStayOpen = !!props.shouldStayOpen\n\n return (\n {\n if (onChange) return onChange(value, item, onChangeHandler)\n setFieldValue(name, item)\n }}\n onBlur={innerOnBlur}\n value={value}\n error={error}\n open={open}\n options={innerOptions}\n onOpen={() => {\n if (!props.multiple) return setOpen(true)\n setOpen(value?.length !== props.limit)\n }}\n onClose={(event, reason) => {\n if (shouldStayOpen && reason !== 'blur') setOpen(true)\n else setOpen(false)\n }}\n {...props}\n />\n )\n}\n\nexport default AutocompleteFormik\n","import Chip from '@material-ui/core/Chip'\nimport { withStyles } from '@material-ui/core/styles'\nimport React, { memo } from 'react'\n\nimport {\n fontColor,\n inputFontWeight,\n subheaderColor,\n smallestFontSize,\n inputFontFamily\n} from 'src/styling/variables'\n\nconst styles = theme => ({\n root: {\n backgroundColor: subheaderColor,\n borderRadius: 4,\n margin: theme.spacing(0.5, 0.25),\n height: 18\n },\n label: {\n fontSize: smallestFontSize,\n color: fontColor,\n fontWeight: inputFontWeight,\n fontFamily: inputFontFamily,\n paddingRight: 4,\n paddingLeft: 4\n }\n})\n\nconst LsChip = memo(({ classes, ...props }) => (\n \n))\n\nexport default withStyles(styles)(LsChip)\n","import { spacer, tomato, primaryColor as zodiac } from 'src/styling/variables'\n\nconst colors = {\n cashOut: {\n empty: tomato,\n full: zodiac\n },\n cashIn: {\n empty: zodiac,\n full: tomato\n }\n}\n\nconst colorPicker = ({ percent, cashOut }) =>\n colors[cashOut ? 'cashOut' : 'cashIn'][percent >= 50 ? 'full' : 'empty']\n\nconst cashboxStyles = {\n cashbox: {\n borderColor: colorPicker,\n backgroundColor: colorPicker,\n height: 118,\n width: 80,\n border: '2px solid',\n textAlign: 'end',\n display: 'inline-block'\n },\n emptyPart: {\n backgroundColor: 'white',\n height: ({ percent }) => `${100 - percent}%`,\n position: 'relative',\n '& > p': {\n color: colorPicker,\n display: 'inline-block',\n position: 'absolute',\n margin: 0,\n bottom: 0,\n right: 0\n }\n },\n fullPart: {\n backgroundColor: colorPicker,\n '& > p': {\n color: 'white',\n display: 'inline'\n }\n }\n}\n\nconst gridStyles = {\n row: {\n display: 'flex'\n },\n innerRow: {\n display: 'flex',\n justifyContent: 'flex-start'\n },\n col2: {\n marginLeft: 16\n },\n noMarginText: {\n marginTop: 0,\n marginBottom: 0\n },\n link: {\n marginTop: spacer\n },\n chip: {\n margin: [[0, 0, 0, 7]]\n }\n}\n\nexport { cashboxStyles, gridStyles }\n","import { makeStyles } from '@material-ui/core/styles'\nimport classnames from 'classnames'\nimport React from 'react'\n\nimport Chip from 'src/components/Chip'\nimport { Link } from 'src/components/buttons'\nimport { Info2, Label1, Label2 } from 'src/components/typography'\n\nimport TextInputFormik from '../base/TextInput'\n\nimport { cashboxStyles, gridStyles } from './Cashbox.styles'\n\nconst cashboxClasses = makeStyles(cashboxStyles)\nconst gridClasses = makeStyles(gridStyles)\n\nconst Cashbox = ({\n percent = 0,\n cashOut = false,\n className,\n emptyPartClassName,\n labelClassName\n}) => {\n const classes = cashboxClasses({ percent, cashOut })\n const threshold = 51\n\n return (\n \n
\n {percent <= threshold && (\n {percent.toFixed(0)}% \n )}\n
\n
\n {percent > threshold && (\n {percent.toFixed(0)}% \n )}\n
\n
\n )\n}\n\n// https://support.lamassu.is/hc/en-us/articles/360025595552-Installing-the-Sintra-Forte\n// Sintra and Sintra Forte can have up to 500 notes per cashOut box and up to 1000 per cashIn box\nconst CashIn = ({ currency, notes, total }) => {\n const classes = gridClasses()\n return (\n <>\n \n
\n
\n {notes} notes \n
\n
\n {/* Feature on hold until this can be calculated\n \n {total} {currency.code}\n \n */}\n
\n
\n
\n >\n )\n}\n\nconst CashInFormik = ({\n capacity = 1000,\n onEmpty,\n field: {\n value: { notes, deviceId }\n },\n form: { setFieldValue }\n}) => {\n const classes = gridClasses()\n\n return (\n <>\n \n
\n \n
\n
\n
\n {\n onEmpty({\n variables: {\n deviceId,\n action: 'emptyCashInBills'\n }\n }).then(() => setFieldValue('cashin.notes', 0))\n }}\n className={classes.link}\n color={'primary'}>\n Empty\n \n
\n
\n
\n >\n )\n}\n\nconst CashOut = ({\n capacity = 500,\n denomination = 0,\n currency,\n notes,\n className,\n editingMode = false\n}) => {\n const percent = (100 * notes) / capacity\n const classes = gridClasses()\n return (\n <>\n \n
\n \n
\n {!editingMode && (\n
\n
\n {notes} \n \n
\n
\n \n {notes * denomination} {currency.code}\n \n
\n
\n )}\n
\n >\n )\n}\n\nconst CashOutFormik = ({ capacity = 500, ...props }) => {\n const {\n name,\n onChange,\n onBlur,\n value: { notes }\n } = props.field\n const { touched, errors } = props.form\n\n const error = !!(touched[name] && errors[name])\n\n const percent = (100 * notes) / capacity\n const classes = gridClasses()\n\n return (\n <>\n \n >\n )\n}\n\nexport { Cashbox, CashIn, CashInFormik, CashOut, CashOutFormik }\n","import { makeStyles } from '@material-ui/core'\nimport React, { memo, useState } from 'react'\n\nimport { CashOut } from 'src/components/inputs/cashbox/Cashbox'\n\nimport { NumberInput } from '../base'\nconst useStyles = makeStyles({\n flex: {\n display: 'flex'\n },\n cashCassette: {\n width: 80,\n height: 36,\n marginRight: 16\n }\n})\n\nconst CashCassetteInput = memo(({ decimalPlaces, ...props }) => {\n const classes = useStyles()\n const { name, onChange, onBlur, value } = props.field\n const { touched, errors } = props.form\n const [notes, setNotes] = useState(value)\n const error = !!(touched[name] && errors[name])\n return (\n \n \n {\n setNotes(e.target.value)\n return onChange(e)\n }}\n onBlur={onBlur}\n value={value}\n error={error}\n decimalPlaces={decimalPlaces}\n {...props}\n />\n
\n )\n})\n\nexport default CashCassetteInput\n","import React, { memo } from 'react'\n\nimport { NumberInput } from '../base'\n\nconst NumberInputFormik = memo(({ decimalPlaces, ...props }) => {\n const { name, onChange, onBlur, value } = props.field\n const { touched, errors } = props.form\n\n const error = !!(touched[name] && errors[name])\n\n return (\n \n )\n})\n\nexport default NumberInputFormik\n","import React, { memo } from 'react'\n\nimport { RadioGroup } from '../base'\n\nconst RadioGroupFormik = memo(({ label, ...props }) => {\n const { name, onChange, value } = props.field\n\n return (\n {\n onChange(e)\n props.resetError && props.resetError()\n }}\n className={props.className}\n {...props}\n />\n )\n})\n\nexport default RadioGroupFormik\n","import React, { memo } from 'react'\r\n\r\nimport { SecretInput } from '../base'\r\n\r\nconst SecretInputFormik = memo(({ isPasswordFilled, ...props }) => {\r\n const { name, onChange, onBlur, value } = props.field\r\n const { touched, errors } = props.form\r\n\r\n const error = !isPasswordFilled && !!(touched[name] && errors[name])\r\n\r\n return (\r\n \r\n )\r\n})\r\n\r\nexport default SecretInputFormik\r\n","import React, { memo } from 'react'\n\nimport { TextInput } from '../base'\n\nconst TextInputFormik = memo(({ ...props }) => {\n const { name, onChange, onBlur, value } = props.field\n const { touched, errors } = props.form\n\n const error = !!(touched[name] && errors[name])\n\n return (\n \n )\n})\n\nexport default TextInputFormik\n","function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport * as React from \"react\";\n\nvar _ref2 = /*#__PURE__*/React.createElement(\"style\", {\n type: \"text/css\"\n}, \"\\n\\t.st0{fill-rule:evenodd;clip-rule:evenodd;fill:#1B2559;}\\n\");\n\nvar _ref3 = /*#__PURE__*/React.createElement(\"desc\", null, \"Created with Sketch.\");\n\nvar _ref4 = /*#__PURE__*/React.createElement(\"g\", {\n id: \"color_x2F_primary_x2F_zodiac\",\n transform: \"translate(-0.000000, 0.000000)\"\n}, /*#__PURE__*/React.createElement(\"g\", {\n id: \"Mask\"\n}, /*#__PURE__*/React.createElement(\"path\", {\n id: \"path-1_1_\",\n className: \"st0\",\n d: \"M11.1,9l6.5,6.5c0.6,0.6,0.6,1.5,0,2.1c-0.3,0.3-0.7,0.4-1.1,0.4c-0.4,0-0.8-0.2-1.1-0.4 L9,11.1l-6.5,6.5C2.3,17.8,1.9,18,1.5,18c-0.4,0-0.8-0.2-1.1-0.4c-0.6-0.6-0.6-1.5,0-2.1L6.9,9L0.4,2.5C-0.1,2-0.1,1,0.4,0.4 C1-0.1,2-0.1,2.5,0.4L9,6.9l6.5-6.5c0.6-0.6,1.5-0.6,2.1,0c0.6,0.6,0.6,1.5,0,2.1L11.1,9z\"\n})));\n\nfunction SvgZodiac(_ref, svgRef) {\n var title = _ref.title,\n titleId = _ref.titleId,\n props = _objectWithoutProperties(_ref, [\"title\", \"titleId\"]);\n\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n id: \"Layer_1\",\n xmlns: \"http://www.w3.org/2000/svg\",\n xmlnsXlink: \"http://www.w3.org/1999/xlink\",\n x: \"0px\",\n y: \"0px\",\n viewBox: \"0 0 18 18\",\n style: {\n enableBackground: \"new 0 0 18 18\"\n },\n xmlSpace: \"preserve\",\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, _ref2, _ref3, _ref4);\n}\n\nvar ForwardRef = /*#__PURE__*/React.forwardRef(SvgZodiac);\nexport default __webpack_public_path__ + \"static/media/zodiac.5547e32c.svg\";\nexport { ForwardRef as ReactComponent };","function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport * as React from \"react\";\n\nvar _ref2 = /*#__PURE__*/React.createElement(\"desc\", null, \"Created with Sketch.\");\n\nvar _ref3 = /*#__PURE__*/React.createElement(\"g\", {\n id: \"icon/stage/spring/complete\",\n stroke: \"none\",\n strokeWidth: 1,\n fill: \"none\",\n fillRule: \"evenodd\"\n}, /*#__PURE__*/React.createElement(\"circle\", {\n id: \"Oval\",\n stroke: \"#48F694\",\n strokeWidth: 2,\n transform: \"translate(9.000000, 9.000000) rotate(-270.000000) translate(-9.000000, -9.000000) \",\n cx: 9,\n cy: 9,\n r: 8\n}), /*#__PURE__*/React.createElement(\"path\", {\n d: \"M7.80983711,12 C7.54819546,12 7.28655382,11.9032616 7.08725647,11.710772 L5.29971255,9.98428824 C4.90009582,9.59832189 4.90009582,8.97445811 5.29971255,8.58849175 C5.69932929,8.2025254 6.34525711,8.2025254 6.74487384,8.58849175 L7.80983711,9.61707728 L11.2551262,6.28947477 C11.6547429,5.90350841 12.3016927,5.90350841 12.7002874,6.28947477 C13.0999042,6.674454 13.0999042,7.2993049 12.7002874,7.68527125 L8.53241776,11.710772 C8.33312041,11.9032616 8.07147876,12 7.80983711,12\",\n id: \"Path\",\n fill: \"#48F694\"\n}));\n\nfunction SvgComplete(_ref, svgRef) {\n var title = _ref.title,\n titleId = _ref.titleId,\n props = _objectWithoutProperties(_ref, [\"title\", \"titleId\"]);\n\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n width: \"18px\",\n height: \"18px\",\n viewBox: \"0 0 18 18\",\n xmlns: \"http://www.w3.org/2000/svg\",\n xmlnsXlink: \"http://www.w3.org/1999/xlink\",\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, _ref2, _ref3);\n}\n\nvar ForwardRef = /*#__PURE__*/React.forwardRef(SvgComplete);\nexport default __webpack_public_path__ + \"static/media/complete.d94d5045.svg\";\nexport { ForwardRef as ReactComponent };","function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport * as React from \"react\";\n\nvar _ref2 = /*#__PURE__*/React.createElement(\"desc\", null, \"Created with Sketch.\");\n\nvar _ref3 = /*#__PURE__*/React.createElement(\"g\", {\n id: \"Symbols\",\n stroke: \"none\",\n strokeWidth: 1,\n fill: \"none\",\n fillRule: \"evenodd\"\n}, /*#__PURE__*/React.createElement(\"g\", {\n id: \"icon/warning-icon/comet\"\n}, /*#__PURE__*/React.createElement(\"rect\", {\n id: \"Rectangle\",\n stroke: \"#5F668A\",\n strokeWidth: 2,\n x: 1,\n y: 1,\n width: 22,\n height: 22,\n rx: 11\n}), /*#__PURE__*/React.createElement(\"path\", {\n d: \"M11.2971429,14.4857143 L11.1085714,5.82857143 L13.3714286,5.82857143 L13.2,14.4857143 L11.2971429,14.4857143 Z M11.1942857,18 L11.1942857,15.9771429 L13.3028571,15.9771429 L13.3028571,18 L11.1942857,18 Z\",\n id: \"!\",\n fill: \"#5F668A\",\n fillRule: \"nonzero\"\n})));\n\nfunction SvgComet(_ref, svgRef) {\n var title = _ref.title,\n titleId = _ref.titleId,\n props = _objectWithoutProperties(_ref, [\"title\", \"titleId\"]);\n\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n width: \"24px\",\n height: \"24px\",\n viewBox: \"0 0 24 24\",\n xmlns: \"http://www.w3.org/2000/svg\",\n xmlnsXlink: \"http://www.w3.org/1999/xlink\",\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, _ref2, _ref3);\n}\n\nvar ForwardRef = /*#__PURE__*/React.forwardRef(SvgComet);\nexport default __webpack_public_path__ + \"static/media/comet.9dc291f2.svg\";\nexport { ForwardRef as ReactComponent };","import typographyStyles from 'src/components/typography/styles'\nimport {\n placeholderColor,\n backgroundColor,\n primaryColor,\n mainWidth,\n spring2,\n spring3\n} from 'src/styling/variables'\n\nconst { tl2, p } = typographyStyles\n\nconst fill = '100%'\nconst flexDirection = 'column'\n\nconst styles = {\n dialog: {\n backgroundColor,\n width: fill,\n minHeight: fill,\n display: 'flex',\n flexDirection,\n padding: 0\n },\n wrapper: {\n width: mainWidth,\n height: fill,\n margin: '0 auto',\n flex: 1,\n display: 'flex',\n flexDirection\n },\n contentDiv: {\n display: 'flex',\n flex: 1,\n flexDirection: 'row'\n },\n headerDiv: {\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'center'\n },\n contentWrapper: {\n marginLeft: 48\n },\n button: {\n marginTop: 64\n },\n nameTitle: {\n marginTop: 16,\n marginBottom: 25\n },\n qrTitle: {\n marginTop: 12,\n marginBottom: 40\n },\n qrCodeWrapper: {\n display: 'flex'\n },\n qrTextInfoWrapper: {\n display: 'flex',\n flexDirection: 'row'\n },\n qrTextWrapper: {\n width: 381,\n marginLeft: 80,\n display: 'flex',\n flexDirection: 'column'\n },\n textWrapper: {\n display: 'flex',\n flexDirection: 'column'\n },\n qrTextIcon: {\n marginRight: 16\n },\n qrText: {\n marginTop: 0\n },\n item: {\n position: 'relative',\n margin: '12px 0 12px 0',\n display: 'flex'\n },\n itemText: {\n extend: p,\n color: placeholderColor,\n marginRight: 24\n },\n itemTextActive: {\n extend: tl2,\n color: primaryColor\n },\n itemTextPast: {\n color: primaryColor\n },\n stepperPath: {\n position: 'absolute',\n height: 25,\n width: 1,\n border: [[1, 'solid', placeholderColor]],\n right: 8,\n top: 18\n },\n stepperPast: {\n border: [[1, 'solid', primaryColor]]\n },\n successMessageWrapper: {\n backgroundColor: spring3,\n display: 'flex',\n flexDirection: 'row',\n padding: '0px 10px',\n borderRadius: '8px'\n },\n successMessage: {\n color: spring2,\n margin: '8px 0px'\n },\n successMessageIcon: {\n marginRight: 16,\n marginBottom: 2,\n display: 'flex',\n flexDirection: 'col',\n alignItems: 'center'\n }\n}\n\nexport default styles\n","import { useMutation, useQuery } from '@apollo/react-hooks'\nimport { Dialog, DialogContent, SvgIcon, IconButton } from '@material-ui/core'\nimport { makeStyles } from '@material-ui/core/styles'\nimport classnames from 'classnames'\nimport { Form, Formik, FastField } from 'formik'\nimport gql from 'graphql-tag'\nimport QRCode from 'qrcode.react'\nimport * as R from 'ramda'\nimport React, { memo, useState, useEffect, useRef } from 'react'\nimport * as Yup from 'yup'\n\nimport Title from 'src/components/Title'\nimport { Button } from 'src/components/buttons'\nimport { TextInput } from 'src/components/inputs/formik'\nimport Sidebar from 'src/components/layout/Sidebar'\nimport { Info2, P } from 'src/components/typography'\nimport { ReactComponent as CloseIcon } from 'src/styling/icons/action/close/zodiac.svg'\nimport { ReactComponent as CompleteStageIconSpring } from 'src/styling/icons/stage/spring/complete.svg'\nimport { ReactComponent as CompleteStageIconZodiac } from 'src/styling/icons/stage/zodiac/complete.svg'\nimport { ReactComponent as CurrentStageIconZodiac } from 'src/styling/icons/stage/zodiac/current.svg'\nimport { ReactComponent as EmptyStageIconZodiac } from 'src/styling/icons/stage/zodiac/empty.svg'\nimport { ReactComponent as WarningIcon } from 'src/styling/icons/warning-icon/comet.svg'\nimport { primaryColor } from 'src/styling/variables'\n\nimport styles from './styles'\n\nconst SAVE_CONFIG = gql`\n mutation createPairingTotem($name: String!) {\n createPairingTotem(name: $name)\n }\n`\nconst GET_MACHINES = gql`\n {\n machines {\n name\n deviceId\n }\n }\n`\n\nconst useStyles = makeStyles(styles)\n\nconst getSize = R.compose(R.length, R.pathOr([], ['machines']))\n\nconst QrCodeComponent = ({ classes, qrCode, name, count, onPaired }) => {\n const timeout = useRef(null)\n const CLOSE_SCREEN_TIMEOUT = 2000\n const { data } = useQuery(GET_MACHINES, { pollInterval: 10000 })\n\n useEffect(() => {\n return () => {\n if (timeout.current) {\n clearTimeout(timeout.current)\n }\n }\n }, [])\n\n const addedMachine = data?.machines?.find(m => m.name === name)\n const hasNewMachine = getSize(data) > count && addedMachine\n if (hasNewMachine) {\n timeout.current = setTimeout(\n () => onPaired(addedMachine),\n CLOSE_SCREEN_TIMEOUT\n )\n }\n\n return (\n <>\n \n Scan QR code with your new cryptomat\n \n \n
\n \n
\n
\n
\n
\n \n
\n
\n
\n To pair the machine you need scan the QR code with your machine.\n To do this either snap a picture of this QR code or download it\n through the button above and scan it with the scanning bay on\n your machine.\n
\n
\n
\n {hasNewMachine && (\n
\n
\n \n
\n
\n Machine has been successfully paired!\n \n
\n )}\n
\n
\n >\n )\n}\n\nconst initialValues = {\n name: ''\n}\n\nconst validationSchema = Yup.object().shape({\n name: Yup.string()\n .required()\n .max(50)\n})\n\nconst MachineNameComponent = ({ nextStep, classes, setQrCode, setName }) => {\n const [register] = useMutation(SAVE_CONFIG, {\n onCompleted: ({ createPairingTotem }) => {\n if (process.env.NODE_ENV === 'development') {\n console.log(`totem: \"${createPairingTotem}\" `)\n }\n setQrCode(createPairingTotem)\n nextStep()\n },\n onError: e => console.log(e)\n })\n\n return (\n <>\n \n Machine Name (ex: Coffee shop 01)\n \n {\n setName(name)\n register({ variables: { name } })\n }}>\n \n \n >\n )\n}\n\nconst steps = [\n {\n label: 'Machine name',\n component: MachineNameComponent\n },\n {\n label: 'Scan QR code',\n component: QrCodeComponent\n }\n]\n\nconst renderStepper = (step, it, idx, classes) => {\n const active = step === idx\n const past = idx < step\n const future = idx > step\n\n return (\n \n
\n {it.label}\n \n {active &&
}\n {past &&
}\n {future &&
}\n {idx < steps.length - 1 && (\n
\n )}\n
\n )\n}\n\nconst AddMachine = memo(({ close, onPaired }) => {\n const classes = useStyles()\n const { data } = useQuery(GET_MACHINES)\n const [qrCode, setQrCode] = useState('')\n const [name, setName] = useState('')\n const [step, setStep] = useState(0)\n const count = getSize(data)\n\n const Component = steps[step].component\n\n return (\n \n
\n \n \n
\n
Add Machine \n \n \n \n \n \n \n
\n
\n {steps.map((it, idx) => renderStepper(step, it, idx, classes))}\n \n
\n setStep(1)}\n count={count}\n onPaired={onPaired}\n qrCode={qrCode}\n setQrCode={setQrCode}\n name={name}\n setName={setName}\n />\n
\n
\n
\n \n \n
\n )\n})\n\nexport default AddMachine\n","import AddMachine from './AddMachine'\n\nexport default AddMachine\n","function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport * as React from \"react\";\n\nvar _ref2 = /*#__PURE__*/React.createElement(\"desc\", null, \"Created with Sketch.\");\n\nvar _ref3 = /*#__PURE__*/React.createElement(\"g\", {\n id: \"icon/button/add/white\",\n stroke: \"none\",\n strokeWidth: 1,\n fill: \"none\",\n fillRule: \"evenodd\",\n strokeLinecap: \"round\",\n strokeLinejoin: \"round\"\n}, /*#__PURE__*/React.createElement(\"path\", {\n d: \"M11.5384615,6 C11.5384615,9.05815385 9.05815385,11.5384615 6,11.5384615 C2.94184615,11.5384615 0.461538462,9.05815385 0.461538462,6 C0.461538462,2.94184615 2.94184615,0.461538462 6,0.461538462 C9.05815385,0.461538462 11.5384615,2.94184615 11.5384615,6 Z\",\n id: \"Stroke-1\",\n stroke: \"#FFFFFF\"\n}), /*#__PURE__*/React.createElement(\"line\", {\n x1: 6,\n y1: 3.69230769,\n x2: 6,\n y2: 8.30769231,\n id: \"Stroke-3\",\n stroke: \"#FFFFFF\"\n}), /*#__PURE__*/React.createElement(\"line\", {\n x1: 3.69230769,\n y1: 6,\n x2: 8.30769231,\n y2: 6,\n id: \"Stroke-5\",\n stroke: \"#FFFFFF\"\n}));\n\nfunction SvgWhite(_ref, svgRef) {\n var title = _ref.title,\n titleId = _ref.titleId,\n props = _objectWithoutProperties(_ref, [\"title\", \"titleId\"]);\n\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n width: \"12px\",\n height: \"12px\",\n viewBox: \"0 0 12 12\",\n xmlns: \"http://www.w3.org/2000/svg\",\n xmlnsXlink: \"http://www.w3.org/1999/xlink\",\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, _ref2, _ref3);\n}\n\nvar ForwardRef = /*#__PURE__*/React.forwardRef(SvgWhite);\nexport default __webpack_public_path__ + \"static/media/white.cc7667ff.svg\";\nexport { ForwardRef as ReactComponent };","function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport * as React from \"react\";\n\nvar _ref2 = /*#__PURE__*/React.createElement(\"desc\", null, \"Created with Sketch.\");\n\nvar _ref3 = /*#__PURE__*/React.createElement(\"defs\", null, /*#__PURE__*/React.createElement(\"path\", {\n d: \"M17.8413132,12.8764646 C17.8413132,12.8764646 16.6555879,12.5091919 15.661533,12.2855556 C15.661533,12.2855556 15.3477198,10.3246465 14.8939121,8.23646465 C14.8939121,8.23646465 15.1560495,8.21373737 15.3383242,8.8710101 L16.0223242,12.0219192 C16.0223242,12.0219192 17.2343571,12.2991919 18.1795549,12.6537374 L17.8413132,12.8764646 Z M15.2603407,6.10282828 L15.5328132,5.80555556 C16.0627253,5.87828283 16.3483516,6.02828283 16.3483516,6.02828283 L16.291978,6.11191919 L16.3972088,6.9310101 C16.2440604,6.93646465 16.0091703,7.05919192 16.0091703,7.05919192 L15.8315934,6.95010101 L15.8315934,6.38282828 C15.3026209,6.29919192 15.2556429,6.21828283 15.2556429,6.21828283 L15.2603407,6.10282828 Z M12.4557527,18.2873737 C11.2831813,18.4964646 9.84565385,18.2237374 9.84565385,18.2237374 L9.89732967,17.9991919 C9.89732967,17.9991919 11.6496099,18.1955556 12.6248736,17.8973737 C12.5553462,18.0628283 12.5356154,18.1137374 12.4557527,18.2873737 L12.4557527,18.2873737 Z M9.18984066,14.5464646 C8.379,15.1364646 7.56064286,15.6791919 7.00442308,16.1091919 C6.9705989,16.6955556 6.91516484,17.6464646 6.91516484,17.6464646 L5.46448352,18.5182828 L5.22207692,18.3737374 C5.27845055,17.9219192 5.34891758,17.5882828 5.34891758,17.5882828 L5.55186264,17.4410101 C5.50676374,17.7282828 5.48515385,18.1346465 5.48515385,18.1346465 L6.5928956,17.440101 C6.63705495,16.7019192 6.72443407,15.960101 6.72443407,15.960101 C6.9705989,15.7373737 8.73697253,14.5237374 10.0100803,13.6864646 C10.0100803,13.6864646 10.018533,13.9437374 9.18984066,14.5464646 L9.18984066,14.5464646 Z M14.977533,0.195555556 C15.2612802,0.167373737 15.5065055,0.184646465 15.7103901,0.228282828 L15.7103901,0.228282828 L15.8813901,0.697373737 L16.1003077,0.361919192 C16.2694286,0.447373737 16.3746593,0.547373737 16.4056648,0.624646465 C16.4056648,0.624646465 16.3615055,0.909191919 16.4319725,1.36464646 C16.5005604,1.80373737 16.6988077,2.78191919 16.6988077,2.78191919 C16.9740989,3.00646465 17.2850934,3.51282828 17.2850934,3.51282828 C17.4758242,4.41737374 17.4645495,5.04919192 17.4636099,5.1210101 C16.6734396,4.68646465 15.6173736,4.58555556 15.6173736,4.58555556 L15.6173736,4.58555556 L15.2481264,4.90828283 C15.9753462,5.00828283 16.8792033,5.26555556 17.1122143,5.44555556 C17.2484505,5.74737374 17.3386484,6.22828283 17.3386484,6.22828283 L17.3386484,6.22828283 L17.0445659,6.58919192 L17.3198571,6.8810101 C17.3386484,7.22464646 17.2183846,7.56919192 17.2183846,7.56919192 C17.7905769,7.93010101 17.9512418,8.79373737 18.3101538,10.250101 C18.6700055,11.7064646 18.9903956,12.9055556 18.9903956,12.9055556 L18.9903956,12.9055556 L18.4567253,13.2019192 C19.1623352,15.7282828 18.444511,17.7391919 17.5378352,19.0664646 C16.6320989,20.3946465 16.0862143,21.7137374 16.1031264,22.8910101 L16.1031264,22.8910101 L16.5475385,23.2346465 L16.7749121,23.9491919 L14.3048077,23.9491919 L14.293533,23.2728283 C14.2925934,21.5619192 14.9230385,20.1328283 14.9230385,20.1328283 C15.2857088,20.0473737 15.6596538,19.7628283 15.6596538,19.7628283 C15.0733681,19.8828283 14.3414505,19.7964646 14.3414505,19.7964646 C14.8676044,18.8537374 15.0292088,18.1773737 15.0292088,18.1773737 L15.0292088,18.1773737 L14.7811648,18.1228283 C14.6956648,18.310101 14.6073462,18.4937374 14.5133901,18.6710101 C13.8754286,19.8864646 13.1735769,20.6628283 12.7554725,22.4055556 L12.7554725,22.4055556 L13.1933077,22.7455556 L13.6987912,23.9491919 L10.8509835,23.9491919 C10.8340714,21.8246465 11.495522,20.2273737 11.7341703,19.7628283 C10.2233571,19.9264646 8.42128022,19.1782828 6.99314835,19.4664646 C6.60041209,21.9473737 4.59257143,22.4355556 3.65019231,22.300101 L3.65019231,22.300101 L2.97652747,23.4146465 L3.58724176,23.9491919 L1.33135714,23.9491919 C1.32008242,23.8546465 1.2918956,23.7537374 1.22988462,23.6591919 C1.22988462,23.6591919 1.97401648,22.5882828 2.48231868,21.150101 C2.89008791,21.3255556 3.75166484,20.9928283 3.78736813,20.1055556 C3.82401099,19.2191919 3.67086264,17.8419192 4.46854945,16.7891919 C5.2652967,15.7355556 6.12687363,15.1655556 7.25152747,14.3328283 C7.98250549,13.7910101 9.22084615,12.8755556 9.99974176,12.3010101 L9.99974176,12.3010101 L9.61546154,12.3864646 L6.81087363,14.6491919 L5.82997253,14.6491919 L8.66368681,12.1164646 L8.29725824,12.1091919 L5.33576374,14.6491919 L4.34170879,14.6491919 L7.27313736,11.720101 L6.9208022,11.7173737 L3.88038462,14.6491919 L2.86565934,14.6491919 L5.8093022,11.3037374 L5.46918132,11.3055556 L2.43534066,14.6491919 L1.36706044,14.6491919 L4.22614286,10.8528283 L3.89635714,10.8573737 L0.963989011,14.6491919 L0,14.6491919 C0,14.6491919 4.11809341,8.22464646 4.92893407,7.00737374 C5.73883516,5.79010101 6.6192033,4.62282828 8.06894505,4.38464646 C9.53465934,4.14282828 10.5343516,4.46646465 11.2502967,5.63373737 C11.636456,6.2610101 12.1034176,6.97828283 12.4698462,7.55919192 C12.0968407,8.1510101 11.6298791,8.6110101 11.5857198,9.32282828 C11.534044,10.1419192 12.0921429,10.6373737 12.6558791,10.6773737 C12.2321374,10.5282828 11.8976538,10.0337374 12.0489231,9.37646465 C12.2058297,8.69737374 12.7554725,8.35191919 13.1726374,7.80282828 C13.5315495,7.32828283 13.5371868,6.63282828 13.5108791,6.4010101 C13.4836319,6.16919192 13.2167967,5.98828283 13.2167967,5.98828283 C13.2167967,5.98828283 13.2252527,5.52373737 13.2167967,5.01646465 C13.2083407,4.51010101 13.4300769,4.21828283 13.4300769,4.21828283 C13.4300769,4.21828283 13.4216209,3.4610101 13.3943736,2.57646465 C13.3671264,1.72555556 13.2863242,1.46828283 13.205522,1.35464646 C13.205522,1.35464646 13.2694121,1.10919192 13.5099396,0.844646465 L13.5099396,0.844646465 L13.7542253,1.06282828 L13.8284505,0.571919192 C13.9825385,0.469191919 14.1723297,0.375555556 14.4072198,0.307373737 C14.4325879,0.30010101 14.4570165,0.294646465 14.4823846,0.288282828 L14.4823846,0.288282828 L14.7896209,0.644646465 Z M7.71628243,19.8937938 C8.32897736,19.8402566 9.02386307,19.9393405 9.75797621,20.0432188 L9.75797621,20.0432188 L9.86538462,20.058401 C9.7449004,20.8103202 9.02106112,21.7691969 7.79193531,22.0896215 L7.79193531,22.0896215 L9.01358923,23.5151515 L7.36136769,23.5151515 C7.15589073,23.2226941 6.50396838,22.32135 6.16586538,21.9681638 C6.72065317,21.6525335 7.42954868,21.0388524 7.71628243,19.8937938 Z\",\n id: \"path-1\"\n}));\n\nvar _ref4 = /*#__PURE__*/React.createElement(\"g\", {\n id: \"Symbols\",\n stroke: \"none\",\n strokeWidth: 1,\n fill: \"none\",\n fillRule: \"evenodd\"\n}, /*#__PURE__*/React.createElement(\"g\", {\n id: \"nav-/-primary-/-1440\",\n transform: \"translate(-128.000000, -14.000000)\"\n}, /*#__PURE__*/React.createElement(\"g\", {\n id: \"icon/lamassu-logo\",\n transform: \"translate(128.000000, 14.000000)\"\n}, /*#__PURE__*/React.createElement(\"g\", {\n id: \"color/amaz/default\"\n}, /*#__PURE__*/React.createElement(\"mask\", {\n id: \"mask-2\",\n fill: \"white\"\n}, /*#__PURE__*/React.createElement(\"use\", {\n xlinkHref: \"#path-1\"\n})), /*#__PURE__*/React.createElement(\"use\", {\n id: \"Mask\",\n fill: \"#16D6D3\",\n xlinkHref: \"#path-1\"\n})))));\n\nfunction SvgLogo(_ref, svgRef) {\n var title = _ref.title,\n titleId = _ref.titleId,\n props = _objectWithoutProperties(_ref, [\"title\", \"titleId\"]);\n\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n width: \"19px\",\n height: \"24px\",\n viewBox: \"0 0 19 24\",\n xmlns: \"http://www.w3.org/2000/svg\",\n xmlnsXlink: \"http://www.w3.org/1999/xlink\",\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, _ref2, _ref3, _ref4);\n}\n\nvar ForwardRef = /*#__PURE__*/React.forwardRef(SvgLogo);\nexport default __webpack_public_path__ + \"static/media/logo.8ee79eab.svg\";\nexport { ForwardRef as ReactComponent };","function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport * as React from \"react\";\n\nvar _ref2 = /*#__PURE__*/React.createElement(\"desc\", null, \"Created with Sketch.\");\n\nvar _ref3 = /*#__PURE__*/React.createElement(\"g\", {\n id: \"Symbols\",\n stroke: \"none\",\n strokeWidth: 1,\n fill: \"none\",\n fillRule: \"evenodd\"\n}, /*#__PURE__*/React.createElement(\"g\", {\n id: \"nav-/-primary-/-1440\",\n transform: \"translate(-1295.000000, -19.000000)\",\n stroke: \"#FFFFFF\",\n strokeWidth: 2\n}, /*#__PURE__*/React.createElement(\"g\", {\n id: \"icon/menu/notification\",\n transform: \"translate(1296.000000, 20.000000)\"\n}, /*#__PURE__*/React.createElement(\"path\", {\n d: \"M10.1052632,14.3157895 C10.1052632,15.2454737 9.35073684,16 8.42105263,16 C7.49136842,16 6.73684211,15.2454737 6.73684211,14.3157895\",\n id: \"Stroke-1\"\n}), /*#__PURE__*/React.createElement(\"path\", {\n d: \"M1.6,14.3157895 C0.7168,14.3157895 0,13.6031813 0,12.7251462 C0,11.8471111 0.7168,11.1345029 1.6,11.1345029 L1.6,6.3625731 C1.6,2.84884211 4.4656,0 8,0 C11.5344,0 14.4,2.84884211 14.4,6.3625731 L14.4,11.1345029 C15.2832,11.1345029 16,11.8471111 16,12.7251462 C16,13.6031813 15.2832,14.3157895 14.4,14.3157895 L1.6,14.3157895 Z\",\n id: \"Stroke-3\",\n strokeLinejoin: \"round\"\n}))));\n\nfunction SvgNotification(_ref, svgRef) {\n var title = _ref.title,\n titleId = _ref.titleId,\n props = _objectWithoutProperties(_ref, [\"title\", \"titleId\"]);\n\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n width: \"18px\",\n height: \"18px\",\n viewBox: \"0 0 18 18\",\n xmlns: \"http://www.w3.org/2000/svg\",\n xmlnsXlink: \"http://www.w3.org/1999/xlink\",\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, _ref2, _ref3);\n}\n\nvar ForwardRef = /*#__PURE__*/React.forwardRef(SvgNotification);\nexport default __webpack_public_path__ + \"static/media/notification.a9712ffd.svg\";\nexport { ForwardRef as ReactComponent };","import typographyStyles from 'src/components/typography/styles'\nimport {\n version,\n mainWidth,\n spacer,\n white,\n primaryColor,\n secondaryColor,\n placeholderColor,\n subheaderColor,\n fontColor\n} from 'src/styling/variables'\n\nconst { tl2, p } = typographyStyles\n\nlet headerHeight = spacer * 7\nlet subheaderHeight = spacer * 5\n\nif (version === 8) {\n headerHeight = spacer * 8\n subheaderHeight = spacer * 7\n}\n\nconst styles = {\n headerContainer: {\n position: 'relative'\n },\n header: {\n backgroundColor: primaryColor,\n color: white,\n height: headerHeight,\n display: 'flex'\n },\n content: {\n maxWidth: mainWidth,\n flex: 1,\n display: 'flex',\n alignItems: 'center',\n margin: '0 auto'\n },\n nav: {\n flex: 1,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between'\n },\n ul: {\n display: 'flex',\n paddingLeft: spacer * 4.5,\n height: spacer * 7,\n margin: 0\n },\n li: {\n // extend: tl2,\n // height: spacer * 7,\n listStyle: 'none',\n color: white,\n margin: [[spacer * 2.5, spacer * 2.5, 0, spacer * 2.5]],\n '&:hover': {\n color: white\n },\n '&:hover::after': {\n width: '50%',\n marginLeft: '-25%'\n },\n position: 'relative',\n '&:after': {\n content: '\"\"',\n display: 'block',\n background: white,\n width: 0,\n height: 4,\n left: '50%',\n marginLeft: 0,\n bottom: -8,\n position: 'absolute',\n borderRadius: 1000,\n transition: [['all', '0.2s', 'cubic-bezier(0.95, 0.1, 0.45, 0.94)']]\n }\n },\n link: {\n extend: p,\n textDecoration: 'none',\n border: 'none',\n color: white,\n backgroundColor: 'transparent'\n },\n forceSize: {\n display: 'inline-block',\n textAlign: 'center',\n '&:after': {\n display: 'block',\n content: 'attr(forcesize)',\n fontWeight: 700,\n height: 0,\n overflow: 'hidden',\n visibility: 'hidden'\n }\n },\n activeLink: {\n color: white,\n '& li::after': {\n width: '50%',\n marginLeft: '-25%'\n }\n },\n addMachine: {\n marginLeft: 'auto'\n },\n subheader: {\n backgroundColor: subheaderColor,\n color: white,\n height: subheaderHeight,\n display: 'flex'\n },\n subheaderUl: {\n display: 'flex',\n paddingLeft: 0\n },\n subheaderLi: {\n extend: tl2,\n display: 'flex',\n alignItems: 'center',\n height: spacer * 3,\n listStyle: 'none',\n padding: [[0, spacer * 2.5]],\n '&:first-child': {\n paddingLeft: 0\n }\n },\n subheaderLink: {\n extend: p,\n textDecoration: 'none',\n border: 'none',\n color: placeholderColor\n },\n activeSubheaderLink: {\n extend: tl2,\n color: fontColor\n },\n white: {\n color: white\n },\n logo: {\n display: 'flex',\n alignItems: 'center',\n '& > svg': {\n marginRight: 16\n }\n },\n logoLink: {\n cursor: 'pointer'\n },\n actionButtonsContainer: {\n zIndex: 1,\n position: 'relative',\n display: 'flex',\n justifyContent: 'space-between',\n minWidth: 200,\n transform: 'translateZ(0)'\n },\n notificationIcon: {\n marginTop: spacer / 2,\n cursor: 'pointer',\n background: 'transparent',\n boxShadow: '0px 0px 0px transparent',\n border: '0px solid transparent',\n textShadow: '0px 0px 0px transparent',\n outline: 'none'\n },\n hasUnread: {\n position: 'absolute',\n top: 4,\n left: 182,\n width: '9px',\n height: '9px',\n backgroundColor: secondaryColor,\n borderRadius: '50%'\n },\n popper: {\n zIndex: 1\n }\n}\n\nexport default styles\n","import { useQuery } from '@apollo/react-hooks'\nimport ClickAwayListener from '@material-ui/core/ClickAwayListener'\nimport Popper from '@material-ui/core/Popper'\nimport { makeStyles } from '@material-ui/core/styles'\nimport classnames from 'classnames'\nimport gql from 'graphql-tag'\nimport * as R from 'ramda'\nimport React, { memo, useState, useEffect, useRef } from 'react'\nimport { NavLink, useHistory } from 'react-router-dom'\n\nimport NotificationCenter from 'src/components/NotificationCenter'\nimport ActionButton from 'src/components/buttons/ActionButton'\nimport { H4 } from 'src/components/typography'\nimport AddMachine from 'src/pages/AddMachine'\nimport { ReactComponent as AddIconReverse } from 'src/styling/icons/button/add/white.svg'\nimport { ReactComponent as AddIcon } from 'src/styling/icons/button/add/zodiac.svg'\nimport { ReactComponent as Logo } from 'src/styling/icons/menu/logo.svg'\nimport { ReactComponent as NotificationIcon } from 'src/styling/icons/menu/notification.svg'\n\nimport styles from './Header.styles'\n\nconst useStyles = makeStyles(styles)\n\nconst HAS_UNREAD = gql`\n query getUnread {\n hasUnreadNotifications\n }\n`\n\nconst Subheader = ({ item, classes }) => {\n const [prev, setPrev] = useState(null)\n\n return (\n \n
\n
\n \n {item.children.map((it, idx) => (\n \n {\n if (!match) return false\n setPrev(it.route)\n return true\n }}>\n {it.label}\n \n \n ))}\n \n \n
\n
\n )\n}\n\nconst notNil = R.compose(R.not, R.isNil)\n\nconst Header = memo(({ tree }) => {\n const [open, setOpen] = useState(false)\n const [anchorEl, setAnchorEl] = useState(null)\n const [notifButtonCoords, setNotifButtonCoords] = useState({ x: 0, y: 0 })\n const [active, setActive] = useState()\n const [hasUnread, setHasUnread] = useState(false)\n\n const { data, refetch } = useQuery(HAS_UNREAD, { pollInterval: 60000 })\n const notifCenterButtonRef = useRef()\n const popperRef = useRef()\n const history = useHistory()\n const classes = useStyles()\n\n useEffect(() => {\n if (data?.hasUnreadNotifications) return setHasUnread(true)\n // if not true, make sure it's false and not undefined\n if (notNil(data?.hasUnreadNotifications)) return setHasUnread(false)\n }, [data])\n\n const onPaired = machine => {\n setOpen(false)\n history.push('/maintenance/machine-status', { id: machine.deviceId })\n }\n\n // these inline styles prevent scroll bubbling: when the user reaches the bottom of the notifications list and keeps scrolling,\n // the body scrolls, stealing the focus from the notification center, preventing the admin from scrolling the notifications back up\n // on the first scroll, needing to move the mouse to recapture the focus on the notification center\n // it also disables the scrollbars caused by the notification center's background to the right of the page, but keeps the scrolling on the body enabled\n const onClickAway = () => {\n setAnchorEl(null)\n document.querySelector('#root').classList.remove('root-notifcenter-open')\n document.querySelector('body').classList.remove('body-notifcenter-open')\n }\n\n const handleClick = event => {\n const coords = notifCenterButtonRef.current.getBoundingClientRect()\n setNotifButtonCoords({ x: coords.x, y: coords.y })\n\n setAnchorEl(anchorEl ? null : event.currentTarget)\n document.querySelector('#root').classList.add('root-notifcenter-open')\n document.querySelector('body').classList.add('body-notifcenter-open')\n }\n\n const popperOpen = Boolean(anchorEl)\n const id = popperOpen ? 'notifications-popper' : undefined\n return (\n \n \n
\n
{\n setActive(false)\n history.push('/dashboard')\n }}\n className={classnames(classes.logo, classes.logoLink)}>\n \n
Lamassu Admin \n \n
\n \n {tree.map((it, idx) => (\n {\n if (!match) return false\n setActive(it)\n return true\n }}\n className={classnames(classes.link, classes.whiteLink)}\n activeClassName={classes.activeLink}>\n \n \n {it.label}\n \n \n \n ))}\n \n \n
\n
setOpen(true)}>\n Add machine\n \n
\n \n
\n \n {hasUnread &&
}\n \n
\n \n \n
\n \n
\n
\n
\n {active && active.children && (\n \n )}\n {open && setOpen(false)} onPaired={onPaired} />}\n \n )\n})\n\nexport default Header\n","import useAxios from '@use-hooks/axios'\nimport React from 'react'\nimport { useLocation, useHistory } from 'react-router-dom'\n\nconst useQuery = () => new URLSearchParams(useLocation().search)\nconst url =\n process.env.NODE_ENV === 'development' ? 'https://localhost:8070' : ''\n\nconst AuthRegister = () => {\n const history = useHistory()\n const query = useQuery()\n\n useAxios({\n url: `${url}/api/register?otp=${query.get('otp')}`,\n method: 'GET',\n options: {\n withCredentials: true\n },\n trigger: [],\n customHandler: (err, res) => {\n if (err) return\n if (res) {\n history.push('/wizard', { fromAuthRegister: true })\n }\n }\n })\n\n return registering... \n}\n\nexport default AuthRegister\n","function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport * as React from \"react\";\n\nvar _ref2 = /*#__PURE__*/React.createElement(\"desc\", null, \"Created with Sketch.\");\n\nvar _ref3 = /*#__PURE__*/React.createElement(\"g\", {\n id: \"icon/action/help/zodiac\",\n stroke: \"none\",\n strokeWidth: 1,\n fill: \"none\",\n fillRule: \"evenodd\"\n}, /*#__PURE__*/React.createElement(\"path\", {\n d: \"M20.0004,11 C20.0004,6.03028475 15.9701153,2 11.0004,2 C6.03004556,2 2.0004,6.02992391 2.0004,11 C2.0004,15.9700761 6.03004556,20 11.0004,20 C15.9701153,20 20.0004,15.9697153 20.0004,11 Z M22.0004,11 C22.0004,17.0742847 17.0746847,22 11.0004,22 C4.92544514,22 0.000400000001,17.0746147 0.000400000001,11 C0.000400000001,4.92538534 4.92544514,0 11.0004,0 C17.0746847,0 22.0004,4.92571525 22.0004,11 Z\",\n id: \"Stroke-1\",\n fill: \"#1B2559\",\n fillRule: \"nonzero\"\n}), /*#__PURE__*/React.createElement(\"path\", {\n d: \"M9.9164,8.9063 C9.9164,9.45858475 9.46868475,9.9063 8.9164,9.9063 C8.36411525,9.9063 7.9164,9.45858475 7.9164,8.9063 C7.9164,6.89094438 9.72972438,5.35290249 11.7463843,5.7072003 C13.0663562,5.93764844 14.1348314,7.00654285 14.3652323,8.32479116 C14.6130182,9.7312185 13.941375,11.0876584 12.732214,11.7545735 C12.370484,11.9534687 12.1664,12.2664153 12.1664,12.5913 L12.1664,12.6563 C12.1664,13.2085847 11.7186847,13.6563 11.1664,13.6563 C10.6141153,13.6563 10.1664,13.2085847 10.1664,12.6563 L10.1664,12.5913 C10.1664,11.5009567 10.7946963,10.5375141 11.7674377,10.0026589 C12.2360927,9.74417086 12.493064,9.22519581 12.3953326,8.67046887 C12.3098185,8.1811985 11.8915858,7.76280177 11.4013649,7.67721566 C10.6126181,7.53864454 9.9164,8.1291691 9.9164,8.9063 Z\",\n id: \"Stroke-3\",\n fill: \"#1B2559\",\n fillRule: \"nonzero\"\n}), /*#__PURE__*/React.createElement(\"path\", {\n d: \"M10.1039,15.2188 C10.1039,14.6318 10.5799,14.1568 11.1659,14.1568 C11.7529,14.1568 12.2289,14.6318 12.2289,15.2188 C12.2289,15.8058 11.7529,16.2808 11.1659,16.2808 C10.5799,16.2808 10.1039,15.8058 10.1039,15.2188\",\n id: \"Fill-5\",\n fill: \"#1B2559\"\n}));\n\nfunction SvgZodiac(_ref, svgRef) {\n var title = _ref.title,\n titleId = _ref.titleId,\n props = _objectWithoutProperties(_ref, [\"title\", \"titleId\"]);\n\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n width: \"22px\",\n height: \"22px\",\n viewBox: \"0 0 22 22\",\n xmlns: \"http://www.w3.org/2000/svg\",\n xmlnsXlink: \"http://www.w3.org/1999/xlink\",\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, _ref2, _ref3);\n}\n\nvar ForwardRef = /*#__PURE__*/React.forwardRef(SvgZodiac);\nexport default __webpack_public_path__ + \"static/media/zodiac.1bd00dea.svg\";\nexport { ForwardRef as ReactComponent };","import { makeStyles, ClickAwayListener } from '@material-ui/core'\nimport React, { useState, memo } from 'react'\n\nimport Popper from 'src/components/Popper'\nimport { ReactComponent as HelpIcon } from 'src/styling/icons/action/help/zodiac.svg'\n\nconst useStyles = makeStyles({\n transparentButton: {\n border: 'none',\n backgroundColor: 'transparent',\n marginTop: 4,\n outline: 'none',\n cursor: 'pointer'\n },\n popoverContent: ({ width }) => ({\n width,\n padding: [[10, 15]]\n })\n})\n\nconst usePopperHandler = width => {\n const classes = useStyles({ width })\n const [helpPopperAnchorEl, setHelpPopperAnchorEl] = useState(null)\n\n const handleOpenHelpPopper = event => {\n setHelpPopperAnchorEl(helpPopperAnchorEl ? null : event.currentTarget)\n }\n\n const handleCloseHelpPopper = () => {\n setHelpPopperAnchorEl(null)\n }\n\n const helpPopperOpen = Boolean(helpPopperAnchorEl)\n\n return {\n classes,\n helpPopperAnchorEl,\n helpPopperOpen,\n handleOpenHelpPopper,\n handleCloseHelpPopper\n }\n}\n\nconst Tooltip = memo(({ children, width, Icon = HelpIcon }) => {\n const handler = usePopperHandler(width)\n\n return (\n \n \n
\n \n \n
\n {children}
\n \n
\n \n )\n})\n\nconst HoverableTooltip = memo(({ parentElements, children, width }) => {\n const handler = usePopperHandler(width)\n\n return (\n \n
\n {parentElements}\n
\n
\n {children}
\n \n
\n )\n})\n\nexport { Tooltip, HoverableTooltip }\n","function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport * as React from \"react\";\n\nvar _ref2 = /*#__PURE__*/React.createElement(\"desc\", null, \"Created with Sketch.\");\n\nvar _ref3 = /*#__PURE__*/React.createElement(\"defs\", null, /*#__PURE__*/React.createElement(\"path\", {\n id: \"arrow-path\",\n d: \"M5.3501239,7.53208616 L0.473798314,2.73082122 C-0.158421727,2.1051411 -0.158421727,1.0952488 0.476737158,0.466675069 C1.11220338,-0.155816755 2.1378971,-0.155816755 2.77494316,0.468226909 L6.49990857,4.13723769 L10.2264532,0.466675069 C10.8619195,-0.155816755 11.8876132,-0.155816755 12.5260183,0.469568675 C13.1582383,1.0952488 13.1582383,2.1051411 12.5245507,2.73226987 L7.64673876,7.53497972 C7.33802629,7.83583835 6.92590837,8 6.49990828,8 C6.0739082,8 5.66179027,7.83583835 5.3501239,7.53208616 Z\"\n}));\n\nvar _ref4 = /*#__PURE__*/React.createElement(\"g\", {\n id: \"Styleguide\",\n stroke: \"none\",\n strokeWidth: 1,\n fillRule: \"evenodd\"\n}, /*#__PURE__*/React.createElement(\"g\", {\n id: \"icon/action/arrow/regular\"\n}, /*#__PURE__*/React.createElement(\"mask\", {\n id: \"mask-2\",\n fill: \"white\"\n}, /*#__PURE__*/React.createElement(\"use\", {\n xlinkHref: \"#path-1\"\n})), /*#__PURE__*/React.createElement(\"use\", {\n id: \"Mask\",\n fillRule: \"nonzero\",\n xlinkHref: \"#arrow-path\"\n})));\n\nfunction SvgRegular(_ref, svgRef) {\n var title = _ref.title,\n titleId = _ref.titleId,\n props = _objectWithoutProperties(_ref, [\"title\", \"titleId\"]);\n\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n width: \"13px\",\n height: \"8px\",\n viewBox: \"0 0 13 8\",\n xmlns: \"http://www.w3.org/2000/svg\",\n xmlnsXlink: \"http://www.w3.org/1999/xlink\",\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, _ref2, _ref3, _ref4);\n}\n\nvar ForwardRef = /*#__PURE__*/React.forwardRef(SvgRegular);\nexport default __webpack_public_path__ + \"static/media/regular.3140e691.svg\";\nexport { ForwardRef as ReactComponent };","import { subheaderColor, offColor, white } from '../../../styling/variables'\nimport typographyStyles from '../../typography/styles'\n\nconst { p, label1 } = typographyStyles\n\nconst WIDTH = 152\n\nexport default {\n selectedItem: {\n width: WIDTH - 41,\n display: 'block',\n whiteSpace: 'nowrap',\n overflow: 'hidden'\n },\n select: {\n width: WIDTH,\n zIndex: 2,\n '& label': {\n extend: label1,\n color: offColor,\n paddingLeft: 10\n },\n '& button': {\n extend: p,\n position: 'relative',\n border: 0,\n backgroundColor: subheaderColor,\n width: WIDTH,\n padding: [[6, 0, 6, 12]],\n borderRadius: 20,\n lineHeight: '1.14',\n textAlign: 'left',\n color: offColor,\n cursor: 'pointer',\n outline: '0 none'\n },\n '& ul': {\n maxHeight: '200px',\n width: WIDTH,\n overflowY: 'auto',\n position: 'absolute',\n margin: 0,\n borderTop: 0,\n padding: 0,\n borderRadius: [[0, 0, 8, 8]],\n backgroundColor: subheaderColor,\n outline: '0 none',\n '& li': {\n extend: p,\n listStyleType: 'none',\n padding: [[6, 12]],\n cursor: 'pointer',\n '& span': {\n width: '100%',\n display: 'block',\n overflow: 'hidden',\n whiteSpace: 'nowrap'\n }\n },\n '& li:hover': {\n backgroundColor: offColor,\n color: white\n }\n },\n '& svg': {\n position: 'absolute',\n top: 12,\n right: 14,\n fill: offColor\n }\n },\n selectFiltered: {\n '& button': {\n backgroundColor: offColor,\n color: white\n },\n '& ul': {\n '& li': {\n backgroundColor: offColor,\n color: white\n },\n '& li:hover': {\n backgroundColor: subheaderColor,\n color: offColor\n }\n },\n '& svg': {\n fill: [[white], '!important']\n }\n },\n open: {\n '& button': {\n borderRadius: [[8, 8, 0, 0]]\n }\n }\n}\n","import { makeStyles } from '@material-ui/core'\nimport classnames from 'classnames'\nimport { useSelect } from 'downshift'\nimport React from 'react'\n\nimport { ReactComponent as Arrowdown } from 'src/styling/icons/action/arrow/regular.svg'\n\nimport styles from './Select.styles'\n\nconst useStyles = makeStyles(styles)\n\nfunction Select({ className, label, items, ...props }) {\n const classes = useStyles()\n\n const {\n isOpen,\n selectedItem,\n getToggleButtonProps,\n getLabelProps,\n getMenuProps,\n getItemProps\n } = useSelect({\n items,\n selectedItem: props.selectedItem,\n onSelectedItemChange: item => {\n props.onSelectedItemChange(item.selectedItem)\n }\n })\n\n const selectClassNames = {\n [classes.select]: true,\n [classes.selectFiltered]: selectedItem !== props.default,\n [classes.open]: isOpen\n }\n\n return (\n \n
{label} \n
\n {selectedItem.display} \n \n \n
\n {isOpen &&\n items.map(({ code, display }, index) => (\n \n {display} \n \n ))}\n \n
\n )\n}\n\nexport default Select\n","import * as R from 'ramda'\n\nconst namespaces = {\n CASH_OUT: 'cashOut',\n WALLETS: 'wallets',\n OPERATOR_INFO: 'operatorInfo',\n NOTIFICATIONS: 'notifications',\n LOCALE: 'locale',\n COMMISSIONS: 'commissions',\n RECEIPT: 'receipt',\n COIN_ATM_RADAR: 'coinAtmRadar',\n TERMS_CONDITIONS: 'termsConditions'\n}\n\nconst mapKeys = R.curry((fn, obj) =>\n R.fromPairs(R.map(R.adjust(0, fn), R.toPairs(obj)))\n)\n\nconst filterByKey = R.curry((fn, obj) =>\n R.fromPairs(R.filter(it => fn(it[0]), R.toPairs(obj)))\n)\n\nconst stripl = R.curry((q, str) =>\n R.startsWith(q, str) ? str.slice(q.length) : str\n)\n\nconst filtered = key => filterByKey(R.startsWith(`${key}_`))\nconst stripped = key => mapKeys(stripl(`${key}_`))\n\nconst fromNamespace = R.curry((key, config) =>\n R.compose(stripped(key), filtered(key))(config)\n)\n\nconst toNamespace = R.curry((key, config) =>\n mapKeys(it => `${key}_${it}`)(config)\n)\n\nexport { fromNamespace, toNamespace, namespaces }\n","import {\n spacer,\n fontPrimary,\n primaryColor,\n white,\n errorColor\n} from 'src/styling/variables'\nconst styles = {\n grid: {\n flex: 1,\n height: '100%'\n },\n content: {\n display: 'flex',\n flexDirection: 'column',\n flex: 1,\n marginLeft: spacer * 6\n },\n footer: {\n margin: [['auto', 0, spacer * 3, 'auto']]\n },\n modalTitle: {\n lineHeight: '120%',\n color: primaryColor,\n fontSize: 14,\n fontFamily: fontPrimary,\n fontWeight: 900\n },\n subtitle: {\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'center',\n flexDirection: 'row'\n },\n white: {\n color: white\n },\n deleteButton: {\n paddingLeft: 13\n },\n addressRow: {\n marginLeft: 8\n },\n error: {\n color: errorColor\n }\n}\n\nexport default styles\n","import { makeStyles, Modal as MaterialModal, Paper } from '@material-ui/core'\nimport classnames from 'classnames'\nimport React from 'react'\n\nimport { IconButton } from 'src/components/buttons'\nimport { H1, H4 } from 'src/components/typography'\nimport { ReactComponent as CloseIcon } from 'src/styling/icons/action/close/zodiac.svg'\n\nconst styles = {\n modal: {\n display: 'flex',\n justifyContent: 'center',\n flexDirection: 'column',\n alignItems: 'center'\n },\n wrapper: ({ width, height }) => ({\n width,\n height,\n display: 'flex',\n flexDirection: 'column',\n minHeight: height ?? 400,\n maxHeight: '90vh',\n overflowY: 'auto',\n borderRadius: 8,\n outline: 0\n }),\n infoPanelWrapper: ({ width, infoPanelHeight }) => ({\n width,\n height: infoPanelHeight,\n marginTop: 16,\n display: 'flex',\n flexDirection: 'column',\n minHeight: infoPanelHeight ?? 200,\n maxHeight: '90vh',\n overflowY: 'auto',\n borderRadius: 8,\n outline: 0\n }),\n panelContent: {\n width: '100%',\n display: 'flex',\n flexDirection: 'column',\n flex: 1,\n padding: [[0, 24]]\n },\n content: ({ small, xl }) => ({\n width: '100%',\n display: 'flex',\n flexDirection: 'column',\n flex: 1,\n padding: xl ? [[0, 60 + 28]] : small ? [[0, 16]] : [[0, 32]]\n }),\n button: ({ small, xl }) => ({\n padding: [[0, 0, xl ? 26 : 0, 0]],\n margin: xl\n ? [[0, 0, 'auto', 'auto']]\n : small\n ? [[12, 12, 'auto', 'auto']]\n : [[16, 16, 'auto', 'auto']]\n }),\n header: {\n display: 'flex'\n },\n title: ({ small }) => ({\n margin: small ? [[20, 0, 8, 16]] : [[28, 0, 8, 32]]\n })\n}\n\nconst useStyles = makeStyles(styles)\n\nconst Modal = ({\n width,\n height,\n infoPanelHeight,\n title,\n small,\n xl,\n infoPanel,\n handleClose,\n children,\n secondaryModal,\n className,\n closeOnEscape,\n closeOnBackdropClick,\n ...props\n}) => {\n const classes = useStyles({ width, height, small, infoPanelHeight, xl })\n const TitleCase = small ? H4 : H1\n const closeSize = xl ? 28 : small ? 16 : 20\n\n const innerClose = (evt, reason) => {\n if (!closeOnBackdropClick && reason === 'backdropClick') return\n if (!closeOnEscape && reason === 'escapeKeyDown') return\n handleClose()\n }\n\n return (\n \n <>\n \n \n {title && {title} }\n handleClose()}>\n \n \n
\n {children}
\n \n {infoPanel && (\n \n {infoPanel}
\n \n )}\n >\n \n )\n}\n\nexport default Modal\n","import { makeStyles } from '@material-ui/core/styles'\nimport { Formik, Form, Field } from 'formik'\nimport * as R from 'ramda'\nimport React from 'react'\nimport * as Yup from 'yup'\n\nimport Modal from 'src/components/Modal'\nimport { Link } from 'src/components/buttons'\nimport { TextInput } from 'src/components/inputs/formik'\nimport { H3 } from 'src/components/typography'\n\nimport styles from './Blacklist.styles'\nconst useStyles = makeStyles(styles)\n\nconst BlackListModal = ({\n onClose,\n selectedCoin,\n addToBlacklist,\n errorMsg\n}) => {\n const classes = useStyles()\n const handleAddToBlacklist = address => {\n if (selectedCoin.code === 'BCH' && !address.startsWith('bitcoincash:')) {\n address = 'bitcoincash:' + address\n }\n addToBlacklist(selectedCoin.code, address)\n }\n const placeholderAddress = {\n BTC: '1ADwinnimZKGgQ3dpyfoUZvJh4p1UWSSpD',\n ETH: '0x71C7656EC7ab88b098defB751B7401B5f6d8976F',\n LTC: 'LPKvbjwV1Kaksktzkr7TMK3FQtQEEe6Wqa',\n DASH: 'XqQ7gU8eM76rEfey726cJpT2RGKyJyBrcn',\n ZEC: 't1KGyyv24eL354C9gjveBGEe8Xz9UoPKvHR',\n BCH: 'qrd6za97wm03lfyg82w0c9vqgc727rhemg5yd9k3dm'\n }\n\n return (\n \n {\n handleAddToBlacklist(address.trim())\n resetForm()\n }}>\n \n \n \n \n Blacklist address\n \n
\n \n )\n}\n\nexport default BlackListModal\n","import {\r\n Dialog,\r\n DialogActions,\r\n DialogContent,\r\n makeStyles\r\n} from '@material-ui/core'\r\nimport React from 'react'\r\n\r\nimport { Button, IconButton } from 'src/components/buttons'\r\nimport { H4, P } from 'src/components/typography'\r\nimport { ReactComponent as CloseIcon } from 'src/styling/icons/action/close/zodiac.svg'\r\nimport { spacer } from 'src/styling/variables'\r\n\r\nimport ErrorMessage from './ErrorMessage'\r\n\r\nconst useStyles = makeStyles({\r\n content: {\r\n width: 434,\r\n padding: spacer * 2,\r\n paddingRight: spacer * 3.5\r\n },\r\n titleSection: {\r\n padding: spacer * 2,\r\n paddingRight: spacer * 1.5,\r\n display: 'flex',\r\n justifyContent: 'space-between',\r\n margin: 0\r\n },\r\n actions: {\r\n padding: spacer * 4,\r\n paddingTop: spacer * 2\r\n },\r\n title: {\r\n margin: 0\r\n },\r\n closeButton: {\r\n padding: 0,\r\n marginTop: -(spacer / 2)\r\n }\r\n})\r\n\r\nexport const DialogTitle = ({ children, close }) => {\r\n const classes = useStyles()\r\n return (\r\n \r\n {children}\r\n {close && (\r\n \r\n \r\n \r\n )}\r\n
\r\n )\r\n}\r\n\r\nexport const DeleteDialog = ({\r\n title = 'Confirm Delete',\r\n open = false,\r\n onConfirmed,\r\n onDismissed,\r\n item = 'item',\r\n confirmationMessage = `Are you sure you want to delete this ${item}?`,\r\n errorMessage = ''\r\n}) => {\r\n const classes = useStyles()\r\n\r\n return (\r\n \r\n onDismissed()}>\r\n {title} \r\n \r\n {errorMessage && (\r\n \r\n \r\n {errorMessage.split(':').map(error => (\r\n <>\r\n {error}\r\n \r\n >\r\n ))}\r\n \r\n \r\n )}\r\n \r\n {confirmationMessage && {confirmationMessage}
}\r\n \r\n \r\n Confirm \r\n \r\n \r\n )\r\n}\r\n","import typographyStyles from 'src/components/typography/styles'\nimport { bySize, bold } from 'src/styling/helpers'\nimport {\n tableHeaderColor,\n tableHeaderHeight,\n tableErrorColor,\n tableSuccessColor,\n spacer,\n white,\n tableDoubleHeaderHeight,\n offColor,\n errorColor\n} from 'src/styling/variables'\n\nconst { tl2, p, label1 } = typographyStyles\n\nexport default {\n size: ({ size }) => bySize(size),\n bold,\n header: {\n extend: tl2,\n backgroundColor: tableHeaderColor,\n height: tableHeaderHeight,\n textAlign: 'left',\n color: white,\n display: 'flex',\n alignItems: 'center'\n },\n doubleHeader: {\n extend: tl2,\n backgroundColor: tableHeaderColor,\n height: tableDoubleHeaderHeight,\n color: white,\n display: 'table-row'\n },\n thDoubleLevel: ({ width }) => ({\n width,\n display: 'table-cell',\n '& > :first-child': {\n margin: [[0, 10]],\n extend: label1,\n fontWeight: 700,\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center',\n backgroundColor: offColor,\n color: white,\n borderRadius: [[0, 0, 8, 8]],\n height: 28\n },\n '& > :last-child': {\n padding: [[0, 11]],\n display: 'table-cell',\n verticalAlign: 'middle',\n height: tableDoubleHeaderHeight - 28\n }\n }),\n cellDoubleLevel: {\n display: 'flex',\n padding: [[0, spacer * 2]]\n },\n td: ({ textAlign, width }) => ({\n width,\n padding: [[1, spacer * 3, 0, spacer * 3]],\n textAlign\n }),\n tdHeader: {\n verticalAlign: 'middle',\n display: 'table-cell',\n padding: [[0, spacer * 3]]\n },\n trError: {\n backgroundColor: tableErrorColor\n },\n trAdding: {\n backgroundColor: tableSuccessColor\n },\n mainContent: ({ size }) => {\n const sizes = {\n sm: 34,\n lg: 68\n }\n const minHeight = sizes[size] || 48\n return {\n display: 'flex',\n alignItems: 'center',\n minHeight\n }\n },\n // mui-overrides\n cardContentRoot: {\n margin: 0,\n padding: 0,\n '&:last-child': {\n padding: 0\n }\n },\n card: {\n extend: p,\n '&:before': {\n height: 0\n },\n margin: [[4, 0, 0, 0]],\n width: '100%',\n boxShadow: [[0, 0, 4, 0, 'rgba(0, 0, 0, 0.08)']]\n },\n actionCol: {\n marginLeft: 'auto'\n },\n errorContent: {\n padding: [[12, 0, 12, 24]],\n color: errorColor\n }\n}\n","import Card from '@material-ui/core/Card'\nimport CardContent from '@material-ui/core/CardContent'\nimport { makeStyles } from '@material-ui/core/styles'\nimport classnames from 'classnames'\nimport React from 'react'\n\nimport { Link } from 'src/components/buttons'\n\nimport styles from './Table.styles'\n\nconst useStyles = makeStyles(styles)\n\nconst Table = ({ children, className, ...props }) => (\n \n {children}\n
\n)\n\nconst THead = ({ children, className }) => {\n const classes = useStyles()\n return {children}
\n}\n\nconst TDoubleLevelHead = ({ children, className }) => {\n const classes = useStyles()\n\n return (\n \n {children}\n
\n )\n}\n\nconst TBody = ({ children, className }) => {\n return {children}
\n}\n\nconst Td = ({\n children,\n header,\n className,\n width = 100,\n size,\n bold,\n textAlign,\n action\n}) => {\n const classes = useStyles({ textAlign, width, size })\n const classNames = {\n [classes.td]: true,\n [classes.tdHeader]: header,\n [classes.actionCol]: action,\n [classes.size]: !header,\n [classes.bold]: !header && bold\n }\n return {children}
\n}\n\nconst Th = ({ children, ...props }) => {\n return (\n \n {children}\n \n )\n}\n\nconst ThDoubleLevel = ({ title, children, className, width }) => {\n const classes = useStyles({ width })\n\n return (\n \n
{title}
\n
{children}
\n
\n )\n}\n\nconst Tr = ({\n onClick,\n error,\n errorMessage,\n children,\n className,\n size,\n newRow\n}) => {\n const classes = useStyles({ size })\n const cardClasses = { root: classes.cardContentRoot }\n const classNames = {\n [classes.tr]: true,\n [classes.trError]: error,\n [classes.card]: true,\n [classes.trAdding]: newRow,\n className\n }\n\n return (\n <>\n \n \n {children}
\n {error && {errorMessage}
}\n \n \n >\n )\n}\n\nconst EditCell = ({ save, cancel }) => (\n \n \n Cancel\n \n \n Save\n \n \n)\n\nexport {\n Table,\n THead,\n TDoubleLevelHead,\n TBody,\n Tr,\n Td,\n Th,\n ThDoubleLevel,\n EditCell\n}\n","function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport * as React from \"react\";\n\nvar _ref2 = /*#__PURE__*/React.createElement(\"defs\", null, /*#__PURE__*/React.createElement(\"circle\", {\n id: \"path-100\",\n cx: 80,\n cy: 80,\n r: 80\n}), /*#__PURE__*/React.createElement(\"rect\", {\n id: \"path-300\",\n x: 28,\n y: 44,\n width: 104,\n height: 116,\n rx: 4\n}), /*#__PURE__*/React.createElement(\"filter\", {\n x: \"-23.1%\",\n y: \"-20.7%\",\n width: \"146.2%\",\n height: \"141.4%\",\n filterUnits: \"objectBoundingBox\",\n id: \"filter-4\"\n}, /*#__PURE__*/React.createElement(\"feOffset\", {\n dx: 0,\n dy: 0,\n in: \"SourceAlpha\",\n result: \"shadowOffsetOuter1\"\n}), /*#__PURE__*/React.createElement(\"feGaussianBlur\", {\n stdDeviation: 8,\n in: \"shadowOffsetOuter1\",\n result: \"shadowBlurOuter1\"\n}), /*#__PURE__*/React.createElement(\"feColorMatrix\", {\n values: \"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.08 0\",\n type: \"matrix\",\n in: \"shadowBlurOuter1\"\n})), /*#__PURE__*/React.createElement(\"rect\", {\n id: \"path-5\",\n x: 37,\n y: 66,\n width: 84,\n height: 8,\n rx: 2\n}), /*#__PURE__*/React.createElement(\"mask\", {\n id: \"mask-6\",\n maskContentUnits: \"userSpaceOnUse\",\n maskUnits: \"objectBoundingBox\",\n x: 0,\n y: 0,\n width: 84,\n height: 8,\n fill: \"white\"\n}, /*#__PURE__*/React.createElement(\"use\", {\n xlinkHref: \"#path-5\"\n})), /*#__PURE__*/React.createElement(\"rect\", {\n id: \"path-7\",\n x: 37,\n y: 78,\n width: 84,\n height: 8,\n rx: 2\n}), /*#__PURE__*/React.createElement(\"mask\", {\n id: \"mask-8\",\n maskContentUnits: \"userSpaceOnUse\",\n maskUnits: \"objectBoundingBox\",\n x: 0,\n y: 0,\n width: 84,\n height: 8,\n fill: \"white\"\n}, /*#__PURE__*/React.createElement(\"use\", {\n xlinkHref: \"#path-7\"\n})), /*#__PURE__*/React.createElement(\"rect\", {\n id: \"path-9\",\n x: 37,\n y: 90,\n width: 84,\n height: 8,\n rx: 2\n}), /*#__PURE__*/React.createElement(\"mask\", {\n id: \"mask-10\",\n maskContentUnits: \"userSpaceOnUse\",\n maskUnits: \"objectBoundingBox\",\n x: 0,\n y: 0,\n width: 84,\n height: 8,\n fill: \"white\"\n}, /*#__PURE__*/React.createElement(\"use\", {\n xlinkHref: \"#path-9\"\n})), /*#__PURE__*/React.createElement(\"rect\", {\n id: \"path-11\",\n x: 37,\n y: 102,\n width: 84,\n height: 8,\n rx: 2\n}), /*#__PURE__*/React.createElement(\"mask\", {\n id: \"mask-12\",\n maskContentUnits: \"userSpaceOnUse\",\n maskUnits: \"objectBoundingBox\",\n x: 0,\n y: 0,\n width: 84,\n height: 8,\n fill: \"white\"\n}, /*#__PURE__*/React.createElement(\"use\", {\n xlinkHref: \"#path-11\"\n})));\n\nvar _ref3 = /*#__PURE__*/React.createElement(\"g\", {\n id: \"\\\\u21B3-v13a\",\n stroke: \"none\",\n strokeWidth: 1,\n fill: \"none\",\n fillRule: \"evenodd\"\n}, /*#__PURE__*/React.createElement(\"g\", {\n id: \"transactions_v13a#1-(empty-table)\",\n transform: \"translate(-640.000000, -220.000000)\"\n}, /*#__PURE__*/React.createElement(\"g\", {\n id: \"Group-2\",\n transform: \"translate(640.000000, 220.000000)\"\n}, /*#__PURE__*/React.createElement(\"g\", {\n id: \"Rectangle\"\n}, /*#__PURE__*/React.createElement(\"mask\", {\n id: \"mask-200\",\n fill: \"white\"\n}, /*#__PURE__*/React.createElement(\"use\", {\n xlinkHref: \"#path-100\"\n})), /*#__PURE__*/React.createElement(\"use\", {\n id: \"Mask\",\n fill: \"#EBEFFF\",\n xlinkHref: \"#path-100\"\n}), /*#__PURE__*/React.createElement(\"g\", {\n mask: \"url(#mask-200)\"\n}, /*#__PURE__*/React.createElement(\"use\", {\n fill: \"black\",\n fillOpacity: 1,\n filter: \"url(#filter-4)\",\n xlinkHref: \"#path-300\"\n}), /*#__PURE__*/React.createElement(\"use\", {\n fill: \"#FFFFFF\",\n fillRule: \"evenodd\",\n xlinkHref: \"#path-300\"\n}))), /*#__PURE__*/React.createElement(\"use\", {\n id: \"Rectangle\",\n stroke: \"#5F668A\",\n mask: \"url(#mask-6)\",\n strokeDasharray: 1,\n xlinkHref: \"#path-5\"\n}), /*#__PURE__*/React.createElement(\"use\", {\n id: \"Rectangle-Copy\",\n stroke: \"#5F668A\",\n mask: \"url(#mask-8)\",\n strokeDasharray: 1,\n xlinkHref: \"#path-7\"\n}), /*#__PURE__*/React.createElement(\"use\", {\n id: \"Rectangle-Copy-2\",\n stroke: \"#5F668A\",\n mask: \"url(#mask-10)\",\n strokeDasharray: 1,\n xlinkHref: \"#path-9\"\n}), /*#__PURE__*/React.createElement(\"use\", {\n id: \"Rectangle-Copy-3\",\n stroke: \"#5F668A\",\n mask: \"url(#mask-12)\",\n strokeDasharray: 1,\n xlinkHref: \"#path-11\"\n}), /*#__PURE__*/React.createElement(\"rect\", {\n id: \"Rectangle\",\n fill: \"#EBEFFF\",\n x: 37,\n y: 56,\n width: 84,\n height: 6,\n rx: 2\n}))));\n\nfunction SvgEmptyTable(_ref, svgRef) {\n var title = _ref.title,\n titleId = _ref.titleId,\n props = _objectWithoutProperties(_ref, [\"title\", \"titleId\"]);\n\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n width: \"160px\",\n height: \"160px\",\n viewBox: \"0 0 160 160\",\n xmlns: \"http://www.w3.org/2000/svg\",\n xmlnsXlink: \"http://www.w3.org/1999/xlink\",\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, _ref2, _ref3);\n}\n\nvar ForwardRef = /*#__PURE__*/React.forwardRef(SvgEmptyTable);\nexport default __webpack_public_path__ + \"static/media/empty-table.250884a9.svg\";\nexport { ForwardRef as ReactComponent };","import { makeStyles } from '@material-ui/core'\nimport React, { memo } from 'react'\n\nimport { H4 } from 'src/components/typography'\nimport { ReactComponent as EmptyTableIcon } from 'src/styling/icons/table/empty-table.svg'\n\nconst styles = {\n emptyTable: {\n width: '100%',\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n marginTop: 52\n }\n}\n\nconst useStyles = makeStyles(styles)\n\nconst EmptyTable = memo(({ message }) => {\n const classes = useStyles()\n\n return (\n \n \n
{message} \n \n )\n})\n\nexport default EmptyTable\n","import { makeStyles } from '@material-ui/core/styles'\nimport classnames from 'classnames'\nimport React, { memo } from 'react'\n\nconst useStyles = makeStyles({\n table: {\n // backgroundColor: tableHeaderColor,\n tableLayout: 'fixed',\n borderCollapse: 'separate',\n borderSpacing: '0 0'\n }\n})\n\nconst Table = memo(({ className, children, ...props }) => {\n const classes = useStyles()\n return (\n \n )\n})\n\nexport default Table\n","import React, { memo } from 'react'\n\nconst TableBody = memo(({ children, ...props }) => (\n {children} \n))\n\nexport default TableBody\n","import { makeStyles } from '@material-ui/core/styles'\nimport classnames from 'classnames'\nimport React, { memo } from 'react'\n\nimport { spacer } from 'src/styling/variables'\n\nconst useStyles = makeStyles({\n td: {\n padding: [[0, spacer * 3]]\n },\n alignRight: {\n textAlign: 'right'\n }\n})\n\nconst TableCell = memo(\n ({ colspan, rightAlign, className, children, ...props }) => {\n const classes = useStyles()\n const styles = {\n [classes.td]: true,\n [classes.alignRight]: rightAlign\n }\n\n return (\n \n {children}\n \n )\n }\n)\n\nexport default TableCell\n","import React, { memo } from 'react'\n\nconst TableHead = memo(({ children, ...props }) => (\n {children} \n))\n\nexport default TableHead\n","import { makeStyles } from '@material-ui/core/styles'\nimport classnames from 'classnames'\nimport React, { memo } from 'react'\n\nimport typographyStyles from 'src/components/typography/styles'\nimport {\n tableHeaderColor,\n tableHeaderHeight,\n spacer,\n white\n} from 'src/styling/variables'\n\nconst { tl2 } = typographyStyles\n\nconst useStyles = makeStyles({\n th: {\n extend: tl2,\n backgroundColor: tableHeaderColor,\n height: tableHeaderHeight,\n textAlign: 'left',\n color: white,\n padding: `0 ${spacer * 3}px`\n },\n alignRight: {\n textAlign: 'right'\n }\n})\n\nconst TableHeaderCell = memo(\n ({ rightAlign, children, className, ...props }) => {\n const classes = useStyles()\n const styles = {\n [classes.th]: true,\n [classes.alignRight]: rightAlign\n }\n\n return (\n \n {children}\n \n )\n }\n)\n\nexport default TableHeaderCell\n","import { makeStyles } from '@material-ui/core/styles'\nimport classnames from 'classnames'\nimport React, { memo } from 'react'\n\nimport typographyStyles from 'src/components/typography/styles'\nimport {\n tableCellColor,\n tableCellHeight,\n tableSmCellHeight,\n tableLgCellHeight,\n tableErrorColor,\n tableSuccessColor\n} from 'src/styling/variables'\n\nconst { info2, p } = typographyStyles\n\nconst useStyles = makeStyles({\n tr: {\n extend: p,\n padding: 4,\n height: tableCellHeight,\n backgroundColor: tableCellColor\n },\n lg: {\n extend: info2,\n height: tableLgCellHeight\n },\n sm: {\n height: tableSmCellHeight\n },\n error: {\n backgroundColor: tableErrorColor\n },\n success: {\n backgroundColor: tableSuccessColor\n }\n})\n\nconst TableRow = memo(\n ({ className, children, header, error, success, size = 'sm', ...props }) => {\n const classes = useStyles()\n const classnamesObj = {\n [classes.tr]: !header,\n [classes.sm]: !header && size === 'sm',\n [classes.lg]: !header && size === 'lg',\n [classes.error]: error,\n [classes.success]: success\n }\n\n return (\n \n {children}\n \n )\n }\n)\n\nexport default TableRow\n","function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport * as React from \"react\";\n\nvar _ref2 = /*#__PURE__*/React.createElement(\"desc\", null, \"Created with Sketch.\");\n\nvar _ref3 = /*#__PURE__*/React.createElement(\"g\", {\n id: \"Styleguide\",\n stroke: \"none\",\n strokeWidth: 1,\n fill: \"none\",\n fillRule: \"evenodd\"\n}, /*#__PURE__*/React.createElement(\"g\", {\n id: \"icon/action/expand/closed\",\n transform: \"translate(1.000000, 1.000000)\",\n stroke: \"#1B2559\",\n strokeWidth: 1.5\n}, /*#__PURE__*/React.createElement(\"circle\", {\n id: \"Oval-4\",\n cx: 14,\n cy: 2,\n r: 2\n}), /*#__PURE__*/React.createElement(\"circle\", {\n id: \"Oval-4-Copy\",\n cx: 8,\n cy: 2,\n r: 2\n}), /*#__PURE__*/React.createElement(\"circle\", {\n id: \"Oval-4-Copy-2\",\n cx: 2,\n cy: 2,\n r: 2\n})));\n\nfunction SvgClosed(_ref, svgRef) {\n var title = _ref.title,\n titleId = _ref.titleId,\n props = _objectWithoutProperties(_ref, [\"title\", \"titleId\"]);\n\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n width: \"18px\",\n height: \"6px\",\n viewBox: \"0 0 18 6\",\n xmlns: \"http://www.w3.org/2000/svg\",\n xmlnsXlink: \"http://www.w3.org/1999/xlink\",\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, _ref2, _ref3);\n}\n\nvar ForwardRef = /*#__PURE__*/React.forwardRef(SvgClosed);\nexport default __webpack_public_path__ + \"static/media/closed.b853a619.svg\";\nexport { ForwardRef as ReactComponent };","function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport * as React from \"react\";\n\nvar _ref2 = /*#__PURE__*/React.createElement(\"desc\", null, \"Created with Sketch.\");\n\nvar _ref3 = /*#__PURE__*/React.createElement(\"g\", {\n id: \"Styleguide\",\n stroke: \"none\",\n strokeWidth: 1,\n fill: \"none\",\n fillRule: \"evenodd\"\n}, /*#__PURE__*/React.createElement(\"g\", {\n id: \"icon/action/expand/open\",\n transform: \"translate(1.000000, 1.000000)\",\n fill: \"#1B2559\",\n stroke: \"#1B2559\",\n strokeWidth: 1.5\n}, /*#__PURE__*/React.createElement(\"circle\", {\n id: \"Oval-4\",\n cx: 14,\n cy: 2,\n r: 2\n}), /*#__PURE__*/React.createElement(\"circle\", {\n id: \"Oval-4-Copy\",\n cx: 8,\n cy: 2,\n r: 2\n}), /*#__PURE__*/React.createElement(\"circle\", {\n id: \"Oval-4-Copy-2\",\n cx: 2,\n cy: 2,\n r: 2\n})));\n\nfunction SvgOpen(_ref, svgRef) {\n var title = _ref.title,\n titleId = _ref.titleId,\n props = _objectWithoutProperties(_ref, [\"title\", \"titleId\"]);\n\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n width: \"18px\",\n height: \"6px\",\n viewBox: \"0 0 18 6\",\n xmlns: \"http://www.w3.org/2000/svg\",\n xmlnsXlink: \"http://www.w3.org/1999/xlink\",\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, _ref2, _ref3);\n}\n\nvar ForwardRef = /*#__PURE__*/React.forwardRef(SvgOpen);\nexport default __webpack_public_path__ + \"static/media/open.7196c113.svg\";\nexport { ForwardRef as ReactComponent };","import { zircon } from 'src/styling/variables'\n\nexport default {\n expandButton: {\n outline: 'none',\n border: 'none',\n backgroundColor: 'transparent',\n cursor: 'pointer',\n padding: 4\n },\n rowWrapper: {\n // workaround to shadows cut by r-virtualized when scroll is visible\n padding: 1\n },\n row: {\n border: [[2, 'solid', 'transparent']],\n borderRadius: 0\n },\n expanded: {\n border: [[2, 'solid', zircon]],\n boxShadow: '0 0 8px 0 rgba(0,0,0,0.08)'\n },\n before: {\n paddingTop: 12\n },\n after: {\n paddingBottom: 12\n },\n pointer: {\n cursor: 'pointer'\n },\n body: {\n flex: [[1, 1, 'auto']]\n },\n table: ({ width }) => ({\n marginBottom: 30,\n minHeight: 200,\n width,\n flex: 1,\n display: 'flex',\n flexDirection: 'column'\n }),\n emptyTable: {\n width: '100%',\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n marginTop: 52\n }\n}\n","import { makeStyles, Box } from '@material-ui/core'\nimport classnames from 'classnames'\nimport * as R from 'ramda'\nimport React, { useState, useEffect } from 'react'\nimport {\n AutoSizer,\n List,\n CellMeasurer,\n CellMeasurerCache\n} from 'react-virtualized'\n\nimport {\n Table,\n TBody,\n THead,\n Tr,\n Td,\n Th\n} from 'src/components/fake-table/Table'\nimport { EmptyTable } from 'src/components/table'\nimport { H4 } from 'src/components/typography'\nimport { ReactComponent as ExpandClosedIcon } from 'src/styling/icons/action/expand/closed.svg'\nimport { ReactComponent as ExpandOpenIcon } from 'src/styling/icons/action/expand/open.svg'\n\nimport styles from './DataTable.styles'\n\nconst useStyles = makeStyles(styles)\n\nconst Row = ({\n id,\n elements,\n data,\n width,\n Details,\n expanded,\n expandRow,\n expWidth,\n expandable,\n onClick,\n size\n}) => {\n const classes = useStyles()\n\n const hasPointer = onClick || expandable\n const trClasses = {\n [classes.pointer]: hasPointer,\n [classes.row]: true,\n [classes.expanded]: expanded\n }\n return (\n \n
\n
{\n expandable && expandRow(id, data)\n onClick && onClick(data)\n }}\n error={data.error}\n errorMessage={data.errorMessage}>\n {elements.map(({ view = it => it?.toString(), ...props }, idx) => (\n \n {view(data)}\n \n ))}\n {expandable && (\n \n expandRow(id, data)}\n className={classes.expandButton}>\n {expanded && }\n {!expanded && }\n \n \n )}\n \n \n {expandable && expanded && (\n
\n
\n \n \n \n \n \n )}\n
\n )\n}\n\nconst DataTable = ({\n elements = [],\n data = [],\n Details,\n className,\n expandable,\n initialExpanded,\n onClick,\n loading,\n emptyText,\n rowSize,\n ...props\n}) => {\n const [expanded, setExpanded] = useState(initialExpanded)\n\n useEffect(() => setExpanded(initialExpanded), [initialExpanded])\n\n const coreWidth = R.compose(R.sum, R.map(R.prop('width')))(elements)\n const expWidth = 1200 - coreWidth\n const width = coreWidth + (expandable ? expWidth : 0)\n\n const classes = useStyles({ width })\n\n const expandRow = (id, data) => {\n if (data.id) {\n cache.clear(data.id)\n setExpanded(data.id === expanded ? null : data.id)\n } else {\n cache.clear(id)\n setExpanded(id === expanded ? null : id)\n }\n }\n\n const cache = new CellMeasurerCache({\n defaultHeight: 58,\n fixedWidth: true\n })\n\n function rowRenderer({ index, key, parent, style }) {\n return (\n \n {({ registerChild }) => (\n \n
\n
\n )}\n \n )\n }\n\n return (\n \n \n \n {elements.map(({ width, className, textAlign, header }, idx) => (\n \n {header}\n \n ))}\n {expandable && }\n \n \n {loading && Loading... }\n {!loading && R.isEmpty(data) && }\n \n {({ height }) => (\n
\n )}\n \n \n
\n \n )\n}\n\nexport default DataTable\n","function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport * as React from \"react\";\n\nvar _ref2 = /*#__PURE__*/React.createElement(\"desc\", null, \"Created with Sketch.\");\n\nvar _ref3 = /*#__PURE__*/React.createElement(\"g\", {\n id: \"Styleguide\",\n stroke: \"none\",\n strokeWidth: 1,\n fill: \"none\",\n fillRule: \"evenodd\",\n strokeLinejoin: \"round\"\n}, /*#__PURE__*/React.createElement(\"g\", {\n id: \"icon/action/copy\",\n transform: \"translate(1.000000, 1.000000)\",\n stroke: \"#1B2559\"\n}, /*#__PURE__*/React.createElement(\"g\", {\n id: \"Group-5-Copy-2\"\n}, /*#__PURE__*/React.createElement(\"polyline\", {\n id: \"Stroke-1\",\n strokeWidth: 2,\n points: \"6 1.2 6 -0.00024 16 -0.00024 16 13.06376 12 13.06376\"\n}), /*#__PURE__*/React.createElement(\"polygon\", {\n id: \"Stroke-3\",\n strokeWidth: 2,\n strokeLinecap: \"round\",\n points: \"0 15.9368 10 15.9368 10 2.9368 0 2.9368\"\n}))));\n\nfunction SvgCopy(_ref, svgRef) {\n var title = _ref.title,\n titleId = _ref.titleId,\n props = _objectWithoutProperties(_ref, [\"title\", \"titleId\"]);\n\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n width: \"18px\",\n height: \"18px\",\n viewBox: \"0 0 18 18\",\n xmlns: \"http://www.w3.org/2000/svg\",\n xmlnsXlink: \"http://www.w3.org/1999/xlink\",\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, _ref2, _ref3);\n}\n\nvar ForwardRef = /*#__PURE__*/React.forwardRef(SvgCopy);\nexport default __webpack_public_path__ + \"static/media/copy.f4cea549.svg\";\nexport { ForwardRef as ReactComponent };","import { fontSize5 } from 'src/styling/variables'\n\nexport default {\n titleWrapper: {\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'center',\n flexDirection: 'row'\n },\n wrapper: {\n flex: 1,\n display: 'flex',\n flexDirection: 'row',\n height: '100%'\n },\n tableWrapper: {\n flex: 1,\n marginLeft: 40,\n display: 'block',\n overflowX: 'auto',\n width: '100%',\n maxWidth: '78%',\n maxHeight: '70vh'\n },\n table: {\n whiteSpace: 'nowrap',\n display: 'block',\n '& th': {\n position: 'sticky',\n top: 0\n }\n },\n dateColumn: {\n minWidth: 160\n },\n levelColumn: {\n minWidth: 100\n },\n fillColumn: {\n width: '100%'\n },\n shareButton: {\n margin: 8,\n display: 'flex',\n alignItems: 'center',\n fontSize: fontSize5,\n padding: [[0, 12]]\n },\n shareIcon: {\n marginRight: 6\n },\n button: {\n margin: 8\n },\n titleAndButtonsContainer: {\n display: 'flex'\n },\n buttonsWrapper: {\n display: 'flex',\n marginLeft: 16,\n '& > *': {\n margin: 'auto 6px'\n }\n }\n}\n","import typographyStyles from 'src/components/typography/styles'\nimport baseStyles from 'src/pages/Logs.styles'\nimport { offColor, white } from 'src/styling/variables'\n\nconst { label1, mono, p } = typographyStyles\nconst { titleWrapper, titleAndButtonsContainer, buttonsWrapper } = baseStyles\n\nconst cpcStyles = {\n wrapper: {\n extend: mono,\n display: 'flex',\n alignItems: 'center'\n },\n address: {\n lineBreak: 'anywhere'\n },\n buttonWrapper: {\n '& button': {\n border: 'none',\n backgroundColor: 'transparent',\n cursor: 'pointer'\n }\n },\n popoverContent: {\n extend: label1,\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center',\n color: white,\n borderRadius: 4,\n padding: [[5, 9]]\n }\n}\n\nconst detailsRowStyles = {\n idCardDataCard: {\n extend: p,\n display: 'flex',\n padding: [[11, 8]],\n '& > div': {\n display: 'flex',\n flexDirection: 'column',\n '& > div': {\n width: 144,\n height: 37,\n marginBottom: 15,\n '&:last-child': {\n marginBottom: 0\n }\n }\n }\n }\n}\n\nconst labelStyles = {\n label: {\n extend: label1,\n color: offColor,\n marginBottom: 4\n }\n}\n\nconst mainStyles = {\n titleWrapper,\n titleAndButtonsContainer,\n buttonsWrapper,\n headerLabels: {\n display: 'flex',\n flexDirection: 'row',\n '& div': {\n display: 'flex',\n alignItems: 'center'\n },\n '& > div:first-child': {\n marginRight: 24\n },\n '& span': {\n extend: label1,\n marginLeft: 6\n }\n },\n overflowTd: {\n overflow: 'hidden',\n whiteSpace: 'nowrap',\n textOverflow: 'ellipsis'\n },\n flexWrapper: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n marginRight: 16\n },\n customerLinkIcon: {\n marginLeft: 2\n }\n}\n\nexport { cpcStyles, detailsRowStyles, labelStyles, mainStyles }\n","import { makeStyles } from '@material-ui/core/styles'\nimport classnames from 'classnames'\nimport * as R from 'ramda'\nimport React, { useState, useEffect } from 'react'\nimport { CopyToClipboard as ReactCopyToClipboard } from 'react-copy-to-clipboard'\n\nimport Popover from 'src/components/Popper'\nimport { ReactComponent as CopyIcon } from 'src/styling/icons/action/copy/copy.svg'\nimport { comet } from 'src/styling/variables'\n\nimport { cpcStyles } from './Transactions.styles'\n\nconst useStyles = makeStyles(cpcStyles)\n\nconst CopyToClipboard = ({\n className,\n buttonClassname,\n children,\n ...props\n}) => {\n const [anchorEl, setAnchorEl] = useState(null)\n\n useEffect(() => {\n if (anchorEl) setTimeout(() => setAnchorEl(null), 3000)\n }, [anchorEl])\n\n const classes = useStyles()\n\n const handleClick = event => {\n setAnchorEl(anchorEl ? null : event.currentTarget)\n }\n\n const handleClose = () => {\n setAnchorEl(null)\n }\n\n const open = Boolean(anchorEl)\n const id = open ? 'simple-popper' : undefined\n\n return (\n \n {children && (\n <>\n
\n {children}\n
\n
\n \n handleClick(event)}>\n \n \n \n
\n
\n \n
Copied to clipboard!
\n
\n \n >\n )}\n
\n )\n}\n\nexport default CopyToClipboard\n","function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport * as React from \"react\";\n\nvar _ref2 = /*#__PURE__*/React.createElement(\"desc\", null, \"Created with Sketch.\");\n\nvar _ref3 = /*#__PURE__*/React.createElement(\"g\", {\n id: \"icon/action/delete/enabled\",\n stroke: \"none\",\n strokeWidth: 1,\n fill: \"none\",\n fillRule: \"evenodd\",\n strokeLinecap: \"round\"\n}, /*#__PURE__*/React.createElement(\"line\", {\n x1: 9,\n y1: 9,\n x2: 9,\n y2: 18,\n id: \"Stroke-1\",\n stroke: \"#1B2559\",\n strokeWidth: 2\n}), /*#__PURE__*/React.createElement(\"line\", {\n x1: 13,\n y1: 9,\n x2: 13,\n y2: 18,\n id: \"Stroke-2\",\n stroke: \"#1B2559\",\n strokeWidth: 2\n}), /*#__PURE__*/React.createElement(\"polyline\", {\n id: \"Stroke-3\",\n stroke: \"#1B2559\",\n strokeWidth: 2,\n strokeLinejoin: \"round\",\n points: \"3 6 5 21 17 21 19 6\"\n}), /*#__PURE__*/React.createElement(\"line\", {\n x1: 1,\n y1: 5,\n x2: 21,\n y2: 5,\n id: \"Stroke-5\",\n stroke: \"#1B2559\",\n strokeWidth: 2\n}), /*#__PURE__*/React.createElement(\"path\", {\n d: \"M14,4 C14,2.343 12.657,1 11,1 C9.343,1 8,2.343 8,4\",\n id: \"Stroke-7\",\n stroke: \"#1B2559\",\n strokeWidth: 2\n}));\n\nfunction SvgEnabled(_ref, svgRef) {\n var title = _ref.title,\n titleId = _ref.titleId,\n props = _objectWithoutProperties(_ref, [\"title\", \"titleId\"]);\n\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n width: \"22px\",\n height: \"22px\",\n viewBox: \"0 0 22 22\",\n xmlns: \"http://www.w3.org/2000/svg\",\n xmlnsXlink: \"http://www.w3.org/1999/xlink\",\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, _ref2, _ref3);\n}\n\nvar ForwardRef = /*#__PURE__*/React.forwardRef(SvgEnabled);\nexport default __webpack_public_path__ + \"static/media/enabled.a058fdfc.svg\";\nexport { ForwardRef as ReactComponent };","import { makeStyles } from '@material-ui/core/styles'\nimport * as R from 'ramda'\nimport React, { useState } from 'react'\n\nimport { DeleteDialog } from 'src/components/DeleteDialog'\nimport { IconButton } from 'src/components/buttons'\nimport DataTable from 'src/components/tables/DataTable'\nimport { Label1 } from 'src/components/typography'\nimport CopyToClipboard from 'src/pages/Transactions/CopyToClipboard'\nimport { ReactComponent as DeleteIcon } from 'src/styling/icons/action/delete/enabled.svg'\n\nimport styles from './Blacklist.styles'\n\nconst useStyles = makeStyles(styles)\n\nconst BlacklistTable = ({\n data,\n selectedCoin,\n handleDeleteEntry,\n errorMessage,\n setErrorMessage,\n deleteDialog,\n setDeleteDialog\n}) => {\n const classes = useStyles()\n\n const [toBeDeleted, setToBeDeleted] = useState()\n\n const elements = [\n {\n name: 'address',\n header: {'Addresses'} ,\n width: 800,\n textAlign: 'left',\n size: 'sm',\n view: it => (\n \n {R.path(['address'], it)} \n
\n )\n },\n {\n name: 'deleteButton',\n header: {'Delete'} ,\n width: 130,\n textAlign: 'center',\n size: 'sm',\n view: it => (\n {\n setDeleteDialog(true)\n setToBeDeleted(it)\n }}>\n \n \n )\n }\n ]\n const dataToShow = selectedCoin\n ? data[selectedCoin.code]\n : data[R.keys(data)[0]]\n\n return (\n <>\n \n {\n setDeleteDialog(false)\n setErrorMessage(null)\n }}\n onConfirmed={() => {\n setErrorMessage(null)\n handleDeleteEntry(\n R.path(['cryptoCode'], toBeDeleted),\n R.path(['address'], toBeDeleted)\n )\n }}\n errorMessage={errorMessage}\n />\n >\n )\n}\n\nexport default BlacklistTable\n","import { useQuery, useMutation } from '@apollo/react-hooks'\nimport { Box } from '@material-ui/core'\nimport Grid from '@material-ui/core/Grid'\nimport { makeStyles } from '@material-ui/core/styles'\nimport gql from 'graphql-tag'\nimport * as R from 'ramda'\nimport React, { useState } from 'react'\n\nimport { Tooltip } from 'src/components/Tooltip'\nimport { Link } from 'src/components/buttons'\nimport { Switch } from 'src/components/inputs'\nimport Sidebar from 'src/components/layout/Sidebar'\nimport TitleSection from 'src/components/layout/TitleSection'\nimport { H4, Label2, P } from 'src/components/typography'\nimport { fromNamespace, toNamespace } from 'src/utils/config'\n\nimport styles from './Blacklist.styles'\nimport BlackListModal from './BlacklistModal'\nimport BlacklistTable from './BlacklistTable'\n\nconst useStyles = makeStyles(styles)\n\nconst groupByCode = R.groupBy(obj => obj.cryptoCode)\n\nconst DELETE_ROW = gql`\n mutation DeleteBlacklistRow($cryptoCode: String!, $address: String!) {\n deleteBlacklistRow(cryptoCode: $cryptoCode, address: $address) {\n cryptoCode\n address\n }\n }\n`\n\nconst GET_BLACKLIST = gql`\n query getBlacklistData {\n blacklist {\n cryptoCode\n address\n }\n cryptoCurrencies {\n display\n code\n }\n }\n`\n\nconst SAVE_CONFIG = gql`\n mutation Save($config: JSONObject) {\n saveConfig(config: $config)\n }\n`\n\nconst GET_INFO = gql`\n query getData {\n config\n }\n`\n\nconst ADD_ROW = gql`\n mutation InsertBlacklistRow($cryptoCode: String!, $address: String!) {\n insertBlacklistRow(cryptoCode: $cryptoCode, address: $address) {\n cryptoCode\n address\n }\n }\n`\n\nconst Blacklist = () => {\n const { data: blacklistResponse } = useQuery(GET_BLACKLIST)\n const { data: configData } = useQuery(GET_INFO)\n const [showModal, setShowModal] = useState(false)\n const [clickedItem, setClickedItem] = useState({\n code: 'BTC',\n display: 'Bitcoin'\n })\n const [errorMsg, setErrorMsg] = useState(null)\n const [deleteDialog, setDeleteDialog] = useState(false)\n\n const [deleteEntry] = useMutation(DELETE_ROW, {\n onError: ({ message }) => {\n const errorMessage = message ?? 'Error while deleting row'\n setErrorMsg(errorMessage)\n },\n onCompleted: () => setDeleteDialog(false),\n refetchQueries: () => ['getBlacklistData']\n })\n\n const [addEntry] = useMutation(ADD_ROW, {\n onError: () => console.log('Error while adding row'),\n refetchQueries: () => ['getBlacklistData']\n })\n\n const [saveConfig] = useMutation(SAVE_CONFIG, {\n refetchQueries: () => ['getData']\n })\n\n const classes = useStyles()\n\n const blacklistData = R.path(['blacklist'])(blacklistResponse) ?? []\n const availableCurrencies =\n R.path(['cryptoCurrencies'], blacklistResponse) ?? []\n\n const formattedData = groupByCode(blacklistData)\n\n const complianceConfig =\n configData?.config && fromNamespace('compliance')(configData.config)\n\n const rejectAddressReuse = complianceConfig?.rejectAddressReuse ?? false\n\n const addressReuseSave = rawConfig => {\n const config = toNamespace('compliance')(rawConfig)\n return saveConfig({ variables: { config } })\n }\n\n const onClickSidebarItem = e => {\n setClickedItem({ code: e.code, display: e.display })\n }\n\n const handleDeleteEntry = (cryptoCode, address) => {\n deleteEntry({ variables: { cryptoCode, address } })\n }\n\n const addToBlacklist = async (cryptoCode, address) => {\n setErrorMsg(null)\n const res = await addEntry({ variables: { cryptoCode, address } })\n if (!res.errors) {\n return setShowModal(false)\n }\n const duplicateKeyError = res.errors.some(e => {\n return e.message.includes('duplicate')\n })\n if (duplicateKeyError) {\n setErrorMsg('This address is already being blocked')\n } else {\n setErrorMsg('Server error')\n }\n }\n\n return (\n <>\n \n \n setShowModal(true)}>\n Blacklist new addresses\n \n \n \n \n it.display}\n onClick={onClickSidebarItem}\n />\n \n
\n \n {clickedItem.display\n ? `${clickedItem.display} blacklisted addresses`\n : ''}{' '}\n \n \n Reject reused addresses
\n {\n addressReuseSave({ rejectAddressReuse: event.target.checked })\n }}\n value={rejectAddressReuse}\n />\n {rejectAddressReuse ? 'On' : 'Off'} \n \n \n The \"Reject reused addresses\" option means that all addresses\n that are used once will be automatically rejected if there's\n an attempt to use them again on a new transaction.\n
\n \n \n \n
\n
\n \n {showModal && (\n {\n setErrorMsg(null)\n setShowModal(false)\n }}\n errorMsg={errorMsg}\n selectedCoin={clickedItem}\n addToBlacklist={addToBlacklist}\n />\n )}\n >\n )\n}\n\nexport default Blacklist\n","import Blacklist from './Blacklist'\n\nexport default Blacklist\n","import { useFormikContext } from 'formik'\nimport React, { useEffect } from 'react'\nimport { Prompt } from 'react-router-dom'\n\nconst PROMPT_DEFAULT_MESSAGE =\n 'You have unsaved changes on this page. Are you sure you want to leave?'\n\nconst PromptWhenDirty = ({ message = PROMPT_DEFAULT_MESSAGE }) => {\n const formik = useFormikContext()\n\n const hasChanges = formik.dirty && formik.submitCount === 0\n\n useEffect(() => {\n if (hasChanges) {\n window.onbeforeunload = confirmExit\n } else {\n window.onbeforeunload = undefined\n }\n }, [hasChanges])\n\n const confirmExit = () => {\n return PROMPT_DEFAULT_MESSAGE\n }\n\n return \n}\n\nexport default PromptWhenDirty\n","import React from 'react'\n\nexport default React.createContext()\n","import * as sanctuary from 'sanctuary'\n\nconst checkOnlyDev = () => {\n if (process.env.NODE_ENV !== 'production') return false\n\n return (\n process.env.NODE_ENV === 'development' &&\n process.env.REACT_APP_TYPE_CHECK_SANCTUARY === 'true'\n )\n}\n\nconst S = sanctuary.create({\n checkTypes: checkOnlyDev(),\n env: sanctuary.env\n})\n\nexport default S\n","import * as R from 'ramda'\n\nimport S from './sanctuary'\n\nconst formatLong = value => {\n if (!value || value.length <= 20) return value\n\n return `${value.slice(0, 8)}(...)${value.slice(\n value.length - 8,\n value.length\n )}`\n}\n\nconst toFirstLower = S.compose(S.joinWith(''))(R.adjust(0, S.toLower))\nconst toFirstUpper = S.compose(S.joinWith(''))(R.adjust(0, S.toUpper))\nconst onlyFirstToUpper = S.compose(toFirstUpper)(S.toLower)\n\nconst splitOnUpper = R.compose(\n S.splitOn(' '),\n R.replace(/([A-Z])/g, ' $1'),\n toFirstLower\n)\nconst startCase = R.compose(\n S.joinWith(' '),\n S.map(onlyFirstToUpper),\n splitOnUpper\n)\n\nconst singularOrPlural = (amount, singularStr, pluralStr) =>\n parseInt(amount) === 1 ? singularStr : pluralStr\n\nexport { startCase, onlyFirstToUpper, formatLong, singularOrPlural }\n","import * as R from 'ramda'\nimport React, { useContext } from 'react'\n\nimport {\n Td,\n THead,\n TDoubleLevelHead,\n ThDoubleLevel\n} from 'src/components/fake-table/Table'\nimport { startCase } from 'src/utils/string'\n\nimport TableCtx from './Context'\n\nconst groupSecondHeader = elements => {\n const [toSHeader, noSHeader] = R.partition(R.has('doubleHeader'))(elements)\n\n if (!toSHeader.length) {\n return [elements, THead]\n }\n\n const index = R.indexOf(toSHeader[0], elements)\n const width = R.compose(R.sum, R.map(R.path(['width'])))(toSHeader)\n\n const innerElements = R.insert(\n index,\n { width, elements: toSHeader, name: toSHeader[0].doubleHeader },\n noSHeader\n )\n\n return [innerElements, TDoubleLevelHead]\n}\n\nconst Header = () => {\n const {\n elements,\n enableEdit,\n editWidth,\n enableDelete,\n deleteWidth,\n enableToggle,\n toggleWidth,\n DEFAULT_COL_SIZE\n } = useContext(TableCtx)\n\n const mapElement2 = (it, idx) => {\n const { width, elements, name } = it\n\n if (elements && elements.length) {\n return (\n \n {elements.map(mapElement)}\n \n )\n }\n\n return mapElement(it, idx)\n }\n\n const mapElement = (\n { name, width = DEFAULT_COL_SIZE, header, textAlign },\n idx\n ) => (\n \n {header || startCase(name)}\n \n )\n\n const [innerElements, HeaderElement] = groupSecondHeader(elements)\n\n return (\n \n {innerElements.map(mapElement2)}\n {enableEdit && (\n \n Edit\n \n )}\n {enableDelete && (\n \n Delete\n \n )}\n {enableToggle && (\n \n Enable\n \n )}\n \n )\n}\n\nexport default Header\n","function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport * as React from \"react\";\n\nvar _ref2 = /*#__PURE__*/React.createElement(\"defs\", null, /*#__PURE__*/React.createElement(\"path\", {\n id: \"a\",\n d: \"M0 0h22v22H0z\"\n}));\n\nvar _ref3 = /*#__PURE__*/React.createElement(\"g\", {\n fill: \"none\",\n fillRule: \"evenodd\"\n}, /*#__PURE__*/React.createElement(\"mask\", {\n id: \"b\",\n fill: \"#fff\"\n}, /*#__PURE__*/React.createElement(\"use\", {\n xlinkHref: \"#a\"\n})), /*#__PURE__*/React.createElement(\"path\", {\n stroke: \"#9B9B9B\",\n strokeWidth: 2,\n strokeLinecap: \"round\",\n mask: \"url(#b)\",\n d: \"M9 9v9M13 9v9\"\n}), /*#__PURE__*/React.createElement(\"g\", {\n mask: \"url(#b)\",\n stroke: \"#9B9B9B\",\n strokeLinecap: \"round\",\n strokeWidth: 2\n}, /*#__PURE__*/React.createElement(\"path\", {\n strokeLinejoin: \"round\",\n d: \"M3 6l2 15h12l2-15\"\n}), /*#__PURE__*/React.createElement(\"path\", {\n d: \"M1 5h20M14 4a3 3 0 10-6 0\"\n})));\n\nfunction SvgDisabled(_ref, svgRef) {\n var title = _ref.title,\n titleId = _ref.titleId,\n props = _objectWithoutProperties(_ref, [\"title\", \"titleId\"]);\n\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n width: 22,\n height: 22,\n xmlns: \"http://www.w3.org/2000/svg\",\n xmlnsXlink: \"http://www.w3.org/1999/xlink\",\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, _ref2, _ref3);\n}\n\nvar ForwardRef = /*#__PURE__*/React.forwardRef(SvgDisabled);\nexport default __webpack_public_path__ + \"static/media/disabled.347e2b5e.svg\";\nexport { ForwardRef as ReactComponent };","function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport * as React from \"react\";\n\nvar _ref2 = /*#__PURE__*/React.createElement(\"desc\", null, \"Created with Sketch.\");\n\nvar _ref3 = /*#__PURE__*/React.createElement(\"g\", {\n id: \"icon/action/edit/disabled\",\n stroke: \"none\",\n strokeWidth: 1,\n fill: \"none\",\n fillRule: \"evenodd\",\n strokeLinecap: \"round\",\n strokeLinejoin: \"round\"\n}, /*#__PURE__*/React.createElement(\"path\", {\n d: \"M1,18 L1,18 C1,19.657 2.343,21 4,21 L18,21 C19.657,21 21,19.657 21,18\",\n id: \"Stroke-1\",\n stroke: \"#9B9B9B\",\n strokeWidth: 2\n}), /*#__PURE__*/React.createElement(\"polygon\", {\n id: \"Stroke-3\",\n stroke: \"#9B9B9B\",\n strokeWidth: 2,\n points: \"6 12 17 1 21 5 10 16 6 16\"\n}));\n\nfunction SvgDisabled(_ref, svgRef) {\n var title = _ref.title,\n titleId = _ref.titleId,\n props = _objectWithoutProperties(_ref, [\"title\", \"titleId\"]);\n\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n width: \"22px\",\n height: \"22px\",\n viewBox: \"0 0 22 22\",\n xmlns: \"http://www.w3.org/2000/svg\",\n xmlnsXlink: \"http://www.w3.org/1999/xlink\",\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, _ref2, _ref3);\n}\n\nvar ForwardRef = /*#__PURE__*/React.forwardRef(SvgDisabled);\nexport default __webpack_public_path__ + \"static/media/disabled.aede2073.svg\";\nexport { ForwardRef as ReactComponent };","function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport * as React from \"react\";\n\nvar _ref2 = /*#__PURE__*/React.createElement(\"desc\", null, \"Created with Sketch.\");\n\nvar _ref3 = /*#__PURE__*/React.createElement(\"g\", {\n id: \"icon/action/edit/enabled\",\n stroke: \"none\",\n strokeWidth: 1,\n fill: \"none\",\n fillRule: \"evenodd\",\n strokeLinecap: \"round\",\n strokeLinejoin: \"round\"\n}, /*#__PURE__*/React.createElement(\"path\", {\n d: \"M1,18 L1,18 C1,19.657 2.343,21 4,21 L18,21 C19.657,21 21,19.657 21,18\",\n id: \"Stroke-1\",\n stroke: \"#1B2559\",\n strokeWidth: 2\n}), /*#__PURE__*/React.createElement(\"polygon\", {\n id: \"Stroke-3\",\n stroke: \"#1B2559\",\n strokeWidth: 2,\n points: \"6 12 17 1 21 5 10 16 6 16\"\n}));\n\nfunction SvgEnabled(_ref, svgRef) {\n var title = _ref.title,\n titleId = _ref.titleId,\n props = _objectWithoutProperties(_ref, [\"title\", \"titleId\"]);\n\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n width: \"22px\",\n height: \"22px\",\n viewBox: \"0 0 22 22\",\n xmlns: \"http://www.w3.org/2000/svg\",\n xmlnsXlink: \"http://www.w3.org/1999/xlink\",\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, _ref2, _ref3);\n}\n\nvar ForwardRef = /*#__PURE__*/React.forwardRef(SvgEnabled);\nexport default __webpack_public_path__ + \"static/media/enabled.5aae4510.svg\";\nexport { ForwardRef as ReactComponent };","import { bySize, bold } from 'src/styling/helpers'\n\nexport default {\n saveButton: {\n marginRight: 20\n },\n lastOfGroup: {\n marginBottom: 24\n },\n extraPadding: {\n paddingLeft: 35,\n paddingRight: 30\n },\n extraPaddingRight: {\n paddingRight: 39\n },\n withSuffix: ({ textAlign }) => {\n const justifyContent = textAlign === 'right' ? 'end' : textAlign\n return {\n display: 'flex',\n alignItems: 'baseline',\n justifyContent\n }\n },\n suffix: {\n marginLeft: 7\n },\n size: ({ size }) => bySize(size),\n bold\n}\n","import { makeStyles } from '@material-ui/core'\r\nimport classnames from 'classnames'\r\nimport { Field, useFormikContext } from 'formik'\r\nimport * as R from 'ramda'\r\nimport React, { useContext, useState } from 'react'\r\n\r\nimport { DeleteDialog } from 'src/components/DeleteDialog'\r\nimport { Link, IconButton } from 'src/components/buttons'\r\nimport { Td, Tr } from 'src/components/fake-table/Table'\r\nimport { Switch } from 'src/components/inputs'\r\nimport { TL2 } from 'src/components/typography'\r\nimport { ReactComponent as DisabledDeleteIcon } from 'src/styling/icons/action/delete/disabled.svg'\r\nimport { ReactComponent as DeleteIcon } from 'src/styling/icons/action/delete/enabled.svg'\r\nimport { ReactComponent as DisabledEditIcon } from 'src/styling/icons/action/edit/disabled.svg'\r\nimport { ReactComponent as EditIcon } from 'src/styling/icons/action/edit/enabled.svg'\r\nimport { ReactComponent as StripesSvg } from 'src/styling/icons/stripes.svg'\r\n\r\nimport TableCtx from './Context'\r\nimport styles from './Row.styles'\r\n\r\nconst useStyles = makeStyles(styles)\r\n\r\nconst ActionCol = ({ disabled, editing }) => {\r\n const classes = useStyles()\r\n const { values, submitForm, resetForm } = useFormikContext()\r\n const {\r\n editWidth,\r\n onEdit,\r\n enableEdit,\r\n enableDelete,\r\n disableRowEdit,\r\n onDelete,\r\n deleteWidth,\r\n enableToggle,\r\n onToggle,\r\n toggleWidth,\r\n forceAdd,\r\n clearError,\r\n actionColSize,\r\n error\r\n } = useContext(TableCtx)\r\n\r\n const disableEdit = disabled || (disableRowEdit && disableRowEdit(values))\r\n const cancel = () => {\r\n clearError()\r\n resetForm()\r\n }\r\n\r\n const [deleteDialog, setDeleteDialog] = useState(false)\r\n\r\n const onConfirmed = () => {\r\n onDelete(values.id).then(res => {\r\n if (!R.isNil(res)) setDeleteDialog(false)\r\n })\r\n }\r\n\r\n return (\r\n <>\r\n {editing && (\r\n \r\n \r\n Save\r\n \r\n {!forceAdd && (\r\n \r\n Cancel\r\n \r\n )}\r\n \r\n )}\r\n {!editing && enableEdit && (\r\n \r\n onEdit && onEdit(values.id)}>\r\n {disableEdit ? : }\r\n \r\n \r\n )}\r\n {!editing && enableDelete && (\r\n \r\n {\r\n setDeleteDialog(true)\r\n }}>\r\n {disabled ? : }\r\n \r\n {\r\n setDeleteDialog(false)\r\n clearError()\r\n }}\r\n errorMessage={error}\r\n />\r\n \r\n )}\r\n {!editing && enableToggle && (\r\n \r\n onToggle(values.id)}\r\n />\r\n \r\n )}\r\n >\r\n )\r\n}\r\n\r\nconst ECol = ({ editing, focus, config, extraPaddingRight, extraPadding }) => {\r\n const {\r\n name,\r\n bypassField,\r\n input,\r\n editable = true,\r\n size,\r\n bold,\r\n width,\r\n textAlign,\r\n editingAlign = textAlign,\r\n suffix,\r\n SuffixComponent = TL2,\r\n textStyle = it => {},\r\n view = it => it?.toString(),\r\n inputProps = {}\r\n } = config\r\n\r\n const { values } = useFormikContext()\r\n\r\n const isEditing = editing && editable\r\n const isField = !bypassField\r\n\r\n const classes = useStyles({\r\n textAlign: isEditing ? editingAlign : textAlign,\r\n size\r\n })\r\n\r\n const innerProps = {\r\n fullWidth: true,\r\n autoFocus: focus,\r\n size,\r\n bold,\r\n textAlign: isEditing ? editingAlign : textAlign,\r\n ...inputProps\r\n }\r\n\r\n return (\r\n \r\n {isEditing && isField && (\r\n \r\n )}\r\n {isEditing && !isField && }\r\n {!isEditing && values && (\r\n \r\n {view(values[name], values)}\r\n
\r\n )}\r\n {suffix && (\r\n \r\n {suffix}\r\n \r\n )}\r\n \r\n )\r\n}\r\n\r\nconst groupStriped = elements => {\r\n const [toStripe, noStripe] = R.partition(R.propEq('stripe', true))(elements)\r\n\r\n if (!toStripe.length) {\r\n return elements\r\n }\r\n\r\n const index = R.indexOf(toStripe[0], elements)\r\n const width = R.compose(R.sum, R.map(R.path(['width'])))(toStripe)\r\n\r\n return R.insert(\r\n index,\r\n { width, editable: false, view: () => },\r\n noStripe\r\n )\r\n}\r\n\r\nconst ERow = ({ editing, disabled, lastOfGroup, newRow }) => {\r\n const { touched, errors, values } = useFormikContext()\r\n const {\r\n elements,\r\n enableEdit,\r\n enableDelete,\r\n error,\r\n enableToggle,\r\n rowSize,\r\n stripeWhen\r\n } = useContext(TableCtx)\r\n\r\n const classes = useStyles()\r\n\r\n const shouldStripe = stripeWhen && stripeWhen(values)\r\n\r\n const innerElements = shouldStripe ? groupStriped(elements) : elements\r\n const [toSHeader] = R.partition(R.has('doubleHeader'))(elements)\r\n\r\n const extraPaddingIndex = toSHeader?.length\r\n ? R.indexOf(toSHeader[0], elements)\r\n : -1\r\n\r\n const extraPaddingRightIndex = toSHeader?.length\r\n ? R.indexOf(toSHeader[toSHeader.length - 1], elements)\r\n : -1\r\n\r\n const elementToFocusIndex = innerElements.findIndex(\r\n it => it.editable === undefined || it.editable\r\n )\r\n\r\n const classNames = {\r\n [classes.lastOfGroup]: lastOfGroup\r\n }\r\n\r\n const touchedErrors = R.pick(R.keys(touched), errors)\r\n const hasTouchedErrors = touchedErrors && R.keys(touchedErrors).length > 0\r\n const hasErrors = hasTouchedErrors || !!error\r\n\r\n const errorMessage =\r\n error || (touchedErrors && R.values(touchedErrors).join(', '))\r\n\r\n return (\r\n \r\n {innerElements.map((it, idx) => {\r\n return (\r\n \r\n )\r\n })}\r\n {(enableEdit || enableDelete || enableToggle) && (\r\n \r\n )}\r\n \r\n )\r\n}\r\n\r\nexport default ERow\r\n","import { offColor } from 'src/styling/variables'\n\nexport default {\n wrapper: ({ width }) => ({\n width: width\n }),\n addLink: {\n marginLeft: 'auto'\n },\n title: {\n margin: 0,\n color: offColor\n },\n outerHeader: {\n minHeight: 16,\n marginBottom: 24,\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'center'\n }\n}\n","import { makeStyles } from '@material-ui/core'\nimport { Form, Formik } from 'formik'\nimport * as R from 'ramda'\nimport React, { useState, useEffect } from 'react'\nimport { v4 } from 'uuid'\n\nimport PromptWhenDirty from 'src/components/PromptWhenDirty'\nimport Link from 'src/components/buttons/Link.js'\nimport { AddButton } from 'src/components/buttons/index.js'\nimport { TBody, Table } from 'src/components/fake-table/Table'\nimport { Info2, TL1 } from 'src/components/typography'\n\nimport TableCtx from './Context'\nimport Header from './Header'\nimport ERow from './Row'\nimport styles from './Table.styles'\n\nconst ACTION_COL_SIZE = 87\nconst DEFAULT_COL_SIZE = 100\n\nconst useStyles = makeStyles(styles)\n\nconst getWidth = R.compose(\n R.reduce(R.add)(0),\n R.map(it => it.width ?? DEFAULT_COL_SIZE)\n)\n\nconst ETable = ({\n name,\n title,\n titleLg,\n elements = [],\n data = [],\n save,\n error: externalError,\n rowSize = 'md',\n validationSchema,\n enableCreate,\n enableEdit,\n editWidth: outerEditWidth,\n enableDelete,\n deleteWidth = ACTION_COL_SIZE,\n enableToggle,\n toggleWidth = ACTION_COL_SIZE,\n onToggle,\n forceDisable,\n disableAdd,\n initialValues,\n setEditing,\n shouldOverrideEdit,\n editOverride,\n stripeWhen,\n disableRowEdit,\n groupBy,\n sortBy,\n createText = 'Add override',\n forceAdd = false,\n tbodyWrapperClass\n}) => {\n const [editingId, setEditingId] = useState(null)\n const [adding, setAdding] = useState(false)\n const [saving, setSaving] = useState(false)\n const [error, setError] = useState(null)\n\n useEffect(() => setError(externalError), [externalError])\n useEffect(() => {\n setError(null)\n setAdding(forceAdd)\n }, [forceAdd])\n\n const innerSave = async value => {\n if (saving) return\n\n setSaving(true)\n\n const it = validationSchema.cast(value)\n const index = R.findIndex(R.propEq('id', it.id))(data)\n const list = index !== -1 ? R.update(index, it, data) : R.prepend(it, data)\n\n if (!R.equals(data[index], it)) {\n try {\n await save({ [name]: list }, it)\n } catch (err) {\n setSaving(false)\n return\n }\n }\n\n setAdding(false)\n setEditingId(null)\n setEditing && setEditing(false)\n setSaving(false)\n }\n\n const onDelete = id => {\n const list = R.reject(it => it.id === id, data)\n return save({ [name]: list })\n }\n\n const onReset = () => {\n setAdding(false)\n setEditingId(null)\n setEditing && setEditing(false)\n }\n\n const onEdit = it => {\n if (shouldOverrideEdit && shouldOverrideEdit(it)) return editOverride(it)\n setEditingId(it)\n setError(null)\n setEditing && setEditing(it, true)\n }\n\n const addField = () => {\n setAdding(true)\n setError(null)\n setEditing && setEditing(true, true)\n }\n\n const widthIfEditNull =\n enableDelete || enableToggle ? ACTION_COL_SIZE : ACTION_COL_SIZE * 2\n\n const editWidth = R.defaultTo(widthIfEditNull)(outerEditWidth)\n\n const actionColSize =\n ((enableDelete && deleteWidth) ?? 0) +\n ((enableEdit && editWidth) ?? 0) +\n ((enableToggle && toggleWidth) ?? 0)\n\n const width = getWidth(elements) + actionColSize\n const classes = useStyles({ width })\n\n const showButtonOnEmpty = !data.length && enableCreate && !adding\n const canAdd = !forceDisable && !editingId && !disableAdd && !adding\n const showTable = adding || data.length !== 0\n\n const innerData = sortBy ? R.sortWith(sortBy)(data) : data\n\n const ctxValue = {\n elements,\n enableEdit,\n onEdit,\n clearError: () => setError(null),\n error: error,\n disableRowEdit,\n editWidth,\n enableDelete,\n onDelete,\n deleteWidth,\n enableToggle,\n rowSize,\n onToggle,\n toggleWidth,\n actionColSize,\n stripeWhen,\n forceAdd,\n DEFAULT_COL_SIZE\n }\n\n return (\n \n \n {showButtonOnEmpty && canAdd && (\n
{createText} \n )}\n {showTable && (\n <>\n {(title || enableCreate) && (\n
\n {title && titleLg && (\n {title} \n )}\n {title && !titleLg && (\n {title} \n )}\n {enableCreate && canAdd && (\n \n {createText}\n \n )}\n
\n )}\n
\n \n \n
\n {adding && (\n \n \n \n )}\n {innerData.map((it, idx) => {\n const nextElement = innerData[idx + 1]\n\n const canGroup = !!groupBy && nextElement\n const isFunction = R.type(groupBy) === 'Function'\n const groupFunction = isFunction ? groupBy : R.prop(groupBy)\n\n const isLastOfGroup =\n canGroup &&\n groupFunction(it) !== groupFunction(nextElement)\n\n return (\n \n \n \n )\n })}\n \n
\n
\n >\n )}\n
\n \n )\n}\n\nexport default ETable\n","import * as R from 'ramda'\nimport React from 'react'\n\nimport { fromNamespace, toNamespace } from 'src/utils/config'\n\nimport EditableTable from './Table'\n\nconst NamespacedTable = ({\n name,\n save,\n data = {},\n namespaces = [],\n ...props\n}) => {\n const innerSave = (...[, it]) => {\n return save(toNamespace(it.id)(R.omit(['id2'], it)))\n }\n\n const innerData = R.map(it => ({\n id: it,\n ...fromNamespace(it)(data)\n }))(namespaces)\n\n return (\n \n )\n}\n\nexport default NamespacedTable\n","const denomiations = {\n AUD: {\n 5: 130,\n 10: 137,\n 20: 144,\n 50: 151,\n 100: 158\n },\n BBD: {\n 2: 150,\n 5: 150,\n 10: 150,\n 20: 150,\n 50: 150,\n 100: 150\n },\n CAD: {\n 5: 152,\n 10: 152,\n 20: 152,\n 50: 152,\n 100: 152\n },\n CHF: {\n 10: 126,\n 20: 137,\n 50: 148,\n 100: 159,\n 200: 170,\n 1000: 181\n },\n DKK: {\n 50: 125,\n 100: 135,\n 200: 145,\n 500: 155,\n 1000: 165\n },\n EUR: {\n 5: 120,\n 10: 127,\n 20: 133,\n 50: 140,\n 100: 147,\n 200: 153,\n 500: 160\n },\n GBP: {\n 5: 135,\n 10: 142,\n 20: 149,\n 50: 156\n },\n HKD: {\n 10: 134,\n 20: 143,\n 50: 148,\n 100: 153,\n 500: 158,\n 1000: 163\n },\n HUF: {\n 200: 154,\n 500: 154,\n 1000: 154,\n 2000: 154,\n 5000: 154,\n 10000: 154,\n 20000: 154\n },\n ILS: {\n 20: 129,\n 50: 136,\n 100: 143,\n 200: 150\n },\n JMD: {\n 50: 145,\n 100: 145,\n 500: 145,\n 1000: 145,\n 5000: 145\n },\n JPY: {\n 1000: 150,\n 2000: 154,\n 5000: 156,\n 10000: 160\n },\n KZT: {\n 200: 126,\n 500: 130,\n 1000: 134,\n 2000: 139,\n 5000: 144,\n 10000: 155,\n 20000: 155\n },\n MXN: {\n 20: 120,\n 50: 127,\n 100: 134,\n 200: 141,\n 500: 148,\n 1000: 155\n },\n MYR: {\n 1: 120,\n 5: 135,\n 10: 140,\n 20: 145,\n 50: 145,\n 100: 150\n },\n NZD: {\n 5: 135,\n 10: 140,\n 20: 145,\n 50: 150,\n 100: 155\n },\n PHP: {\n 20: 160,\n 50: 160,\n 100: 160,\n 200: 160,\n 500: 160,\n 1000: 160\n },\n PLN: {\n 10: 120,\n 20: 126,\n 50: 132,\n 100: 138,\n 200: 144,\n 500: 150\n },\n SGD: {\n 2: 126,\n 5: 133,\n 10: 141,\n 50: 156,\n 100: 162,\n 1000: 170\n },\n TWD: {\n 100: 145,\n 200: 150,\n 500: 155,\n 1000: 160,\n 2000: 165\n },\n UAH: {\n 1: 118,\n 2: 118,\n 5: 118,\n 10: 124,\n 20: 130,\n 50: 136,\n 100: 142,\n 200: 148,\n 500: 154\n },\n USD: {\n 1: 156,\n 5: 156,\n 10: 156,\n 20: 156,\n 50: 156,\n 100: 156\n },\n VND: {\n 10000: 132,\n 20000: 136,\n 50000: 140,\n 100000: 144,\n 200000: 148,\n 500000: 152\n },\n ZAR: {\n 10: 128,\n 20: 134,\n 50: 140,\n 100: 146,\n 200: 152\n }\n}\n\nexport default denomiations\n","function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport * as React from \"react\";\n\nvar _ref2 = /*#__PURE__*/React.createElement(\"desc\", null, \"Created with Sketch.\");\n\nvar _ref3 = /*#__PURE__*/React.createElement(\"g\", {\n id: \"Styleguide\",\n stroke: \"none\",\n strokeWidth: 1,\n fill: \"none\",\n fillRule: \"evenodd\"\n}, /*#__PURE__*/React.createElement(\"g\", {\n id: \"icon/direction/cash-out\",\n transform: \"translate(-1.000000, 0.000000)\",\n fill: \"#5A67FF\"\n}, /*#__PURE__*/React.createElement(\"path\", {\n d: \"M3.99134364,0.321790399 L10.1430099,4.40569595 C11.0271728,4.99266501 11.2660914,6.1822461 10.6766494,7.06269968 C10.5357408,7.27317585 10.3543728,7.45378298 10.1430099,7.59410043 L3.99134364,11.678006 C3.10718075,12.264975 1.91258801,12.0270588 1.32314609,11.1466052 C1.11243854,10.8318699 1,10.4620686 1,10.0838037 L1,1.91599264 C1,0.857819122 1.86143307,0 2.92406462,0 C3.30392305,0 3.67528233,0.11196683 3.99134364,0.321790399 Z\",\n id: \"Path-3\",\n transform: \"translate(6.000000, 6.000000) scale(-1, 1) translate(-6.000000, -6.000000) \"\n})));\n\nfunction SvgCashOut(_ref, svgRef) {\n var title = _ref.title,\n titleId = _ref.titleId,\n props = _objectWithoutProperties(_ref, [\"title\", \"titleId\"]);\n\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n width: \"10px\",\n height: \"12px\",\n viewBox: \"0 0 10 12\",\n xmlns: \"http://www.w3.org/2000/svg\",\n xmlnsXlink: \"http://www.w3.org/1999/xlink\",\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, _ref2, _ref3);\n}\n\nvar ForwardRef = /*#__PURE__*/React.forwardRef(SvgCashOut);\nexport default __webpack_public_path__ + \"static/media/cash-out.f029ae96.svg\";\nexport { ForwardRef as ReactComponent };","import { makeStyles } from '@material-ui/core'\nimport React from 'react'\n\nimport { Button } from 'src/components/buttons'\nimport { H1, P, Info2 } from 'src/components/typography'\nimport { ReactComponent as TxOutIcon } from 'src/styling/icons/direction/cash-out.svg'\nimport { neon, spacer } from 'src/styling/variables'\n\nconst styles = {\n logo: {\n maxHeight: 80,\n maxWidth: 200\n },\n subtitle: {\n margin: 0,\n marginBottom: 42,\n textAlign: 'center'\n },\n text: {\n margin: 0\n },\n button: {\n margin: [[0, 'auto']]\n },\n modalContent: {\n display: 'flex',\n flexDirection: 'column',\n justifyContent: 'space-between',\n flex: 1,\n padding: [[0, 34, 107, 34]]\n },\n innerContent: {\n paddingBottom: 72\n },\n title: {\n color: neon,\n marginBottom: 12,\n marginTop: 30,\n textAlign: 'center'\n },\n titleDecorator: {\n verticalAlign: 'bottom',\n marginRight: spacer * 1.5,\n width: spacer * 3,\n height: spacer * 3.25\n }\n}\n\nconst useStyles = makeStyles(styles)\n\nconst WizardSplash = ({ name, onContinue }) => {\n const classes = useStyles()\n\n return (\n \n
\n
\n \n Enable cash-out \n \n
{name} \n
\n You are about to activate cash-out functionality on your {name}{' '}\n machine which will allow your customers to sell crypto to you.\n
\n
\n In order to activate cash-out for this machine, please enter the\n denominations for the machine.\n
\n
\n
\n Start configuration\n \n
\n )\n}\n\nexport default WizardSplash\n","function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport * as React from \"react\";\n\nvar _ref2 = /*#__PURE__*/React.createElement(\"desc\", null, \"Created with Sketch.\");\n\nvar _ref3 = /*#__PURE__*/React.createElement(\"g\", {\n id: \"icon/stage/spring/current\",\n stroke: \"none\",\n strokeWidth: 1,\n fill: \"none\",\n fillRule: \"evenodd\"\n}, /*#__PURE__*/React.createElement(\"circle\", {\n id: \"Oval-2-Copy\",\n fill: \"#48F694\",\n cx: 9,\n cy: 9,\n r: 4\n}), /*#__PURE__*/React.createElement(\"circle\", {\n id: \"Oval-Copy-5\",\n stroke: \"#48F694\",\n strokeWidth: 2,\n transform: \"translate(9.000000, 9.000000) rotate(-270.000000) translate(-9.000000, -9.000000) \",\n cx: 9,\n cy: 9,\n r: 8\n}));\n\nfunction SvgCurrent(_ref, svgRef) {\n var title = _ref.title,\n titleId = _ref.titleId,\n props = _objectWithoutProperties(_ref, [\"title\", \"titleId\"]);\n\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n width: \"18px\",\n height: \"18px\",\n viewBox: \"0 0 18 18\",\n xmlns: \"http://www.w3.org/2000/svg\",\n xmlnsXlink: \"http://www.w3.org/1999/xlink\",\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, _ref2, _ref3);\n}\n\nvar ForwardRef = /*#__PURE__*/React.forwardRef(SvgCurrent);\nexport default __webpack_public_path__ + \"static/media/current.9bbfa93f.svg\";\nexport { ForwardRef as ReactComponent };","import { makeStyles } from '@material-ui/core'\nimport classnames from 'classnames'\nimport * as R from 'ramda'\nimport React, { memo } from 'react'\n\nimport { ReactComponent as CompleteStageIconSpring } from 'src/styling/icons/stage/spring/complete.svg'\nimport { ReactComponent as CurrentStageIconSpring } from 'src/styling/icons/stage/spring/current.svg'\nimport { ReactComponent as EmptyStageIconSpring } from 'src/styling/icons/stage/spring/empty.svg'\nimport { ReactComponent as CompleteStageIconZodiac } from 'src/styling/icons/stage/zodiac/complete.svg'\nimport { ReactComponent as CurrentStageIconZodiac } from 'src/styling/icons/stage/zodiac/current.svg'\nimport { ReactComponent as EmptyStageIconZodiac } from 'src/styling/icons/stage/zodiac/empty.svg'\nimport {\n primaryColor,\n secondaryColor,\n offColor,\n disabledColor\n} from 'src/styling/variables'\n\nconst styles = {\n stages: {\n display: 'flex',\n alignItems: 'center'\n },\n wrapper: {\n display: 'flex',\n alignItems: 'center',\n margin: 0\n },\n stage: {\n display: 'flex',\n height: 28,\n width: 28,\n zIndex: 2,\n '& > svg': {\n height: '100%',\n width: '100%',\n overflow: 'visible'\n }\n },\n separator: {\n width: 28,\n height: 2,\n border: [[2, 'solid']],\n zIndex: 1\n },\n separatorSpring: {\n borderColor: secondaryColor\n },\n separatorZodiac: {\n borderColor: primaryColor\n },\n separatorSpringEmpty: {\n borderColor: disabledColor\n },\n separatorZodiacEmpty: {\n borderColor: offColor\n }\n}\n\nconst useStyles = makeStyles(styles)\n\nconst Stepper = memo(({ steps, currentStep, color = 'spring', className }) => {\n if (currentStep < 1 || currentStep > steps)\n throw Error('Value of currentStage is invalid')\n if (steps < 1) throw Error('Value of stages is invalid')\n\n const classes = useStyles()\n\n const separatorClasses = {\n [classes.separator]: true,\n [classes.separatorSpring]: color === 'spring',\n [classes.separatorZodiac]: color === 'zodiac'\n }\n\n const separatorEmptyClasses = {\n [classes.separator]: true,\n [classes.separatorSpringEmpty]: color === 'spring',\n [classes.separatorZodiacEmpty]: color === 'zodiac'\n }\n\n return (\n \n {R.range(1, currentStep).map(idx => (\n
\n {idx > 1 &&
}\n
\n {color === 'spring' && }\n {color === 'zodiac' && }\n
\n
\n ))}\n
\n {currentStep > 1 &&
}\n
\n {color === 'spring' && }\n {color === 'zodiac' && }\n
\n
\n {R.range(currentStep + 1, steps + 1).map(idx => (\n
\n
\n
\n {color === 'spring' && }\n {color === 'zodiac' && }\n
\n
\n ))}\n
\n )\n})\n\nexport default Stepper\n","export default __webpack_public_path__ + \"static/media/cashout-cassette-1.fac6c691.svg\";","export default __webpack_public_path__ + \"static/media/cashout-cassette-2.34a98cfa.svg\";","import { errorColor, spacer } from 'src/styling/variables'\n\nconst LABEL_WIDTH = 150\n\nexport default {\n title: {\n margin: [[0, 0, 12, 0]]\n },\n titleDiv: {\n paddingBottom: 32\n },\n subtitle: {\n margin: [[32, 0, 21, 0]]\n },\n edit: {\n margin: [[0, 0, 0, 0]]\n },\n error: {\n color: errorColor\n },\n bill: {\n width: 131,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'end'\n },\n billInput: {\n width: '100%'\n },\n suffix: {\n paddingLeft: spacer * 2\n },\n button: {\n marginLeft: 'auto'\n },\n submit: {\n float: 'right'\n },\n picker: {\n width: LABEL_WIDTH\n },\n header: {\n display: 'flex',\n paddingBottom: 95\n },\n thirdStepHeader: {\n display: 'flex',\n paddingBottom: 188\n },\n step: {\n flex: 1\n },\n stepImage: {\n position: 'relative',\n top: -20,\n right: 14\n },\n content: {\n display: 'flex',\n flexDirection: 'column',\n justifyContent: 'space-between',\n flex: 1,\n paddingBottom: 32\n },\n disclaimer: {\n display: 'flex',\n flex: 1,\n flexDirection: 'column',\n justifyContent: 'space-between'\n },\n disclaimerIcon: {\n float: 'left',\n margin: [[-4, 16, 48, 0]]\n }\n}\n","import { makeStyles } from '@material-ui/core'\nimport { Formik, Form, Field } from 'formik'\nimport React from 'react'\n\nimport ErrorMessage from 'src/components/ErrorMessage'\nimport Stepper from 'src/components/Stepper'\nimport { Button } from 'src/components/buttons'\nimport { NumberInput } from 'src/components/inputs/formik'\nimport { Info2, H4, P, Info1, Label1 } from 'src/components/typography'\nimport cassetteOne from 'src/styling/icons/cassettes/cashout-cassette-1.svg'\nimport cassetteTwo from 'src/styling/icons/cassettes/cashout-cassette-2.svg'\nimport { ReactComponent as WarningIcon } from 'src/styling/icons/warning-icon/comet.svg'\n\nimport styles from './WizardStep.styles'\nconst useStyles = makeStyles(styles)\n\nconst WizardStep = ({\n name,\n step,\n schema,\n error,\n lastStep,\n onContinue,\n steps,\n fiatCurrency,\n options\n}) => {\n const classes = useStyles()\n\n const label = lastStep ? 'Finish' : 'Next'\n\n const cassetesArtworks = {\n 1: cassetteOne,\n 2: cassetteTwo\n }\n\n return (\n \n
\n {name} \n \n
\n\n {step <= 2 && (\n
\n \n \n )}\n\n {step === 3 && (\n
\n \n \n )}\n\n {lastStep && (\n
\n
Cash-out Bill Count \n
\n \n When enabling cash-out, your bill count will be automatically set to\n zero. Make sure you physically put cash inside the cash cassettes to\n allow the machine to dispense it to your users. If you already did,\n make sure you set the correct cash-out bill count for this machine\n on your Cash Cassettes tab under Maintenance.\n
\n\n
Default Commissions \n
\n \n When enabling cash-out, default commissions will be set. To change\n commissions for this machine, please go to the Commissions tab under\n Settings where you can set exceptions for each of the available\n cryptocurrencies.\n
\n
\n {error && Failed to save }\n onContinue()}>\n {label}\n \n
\n
\n )}\n
\n )\n}\n\nexport default WizardStep\n","import * as Yup from 'yup'\n\nimport { NumberInput } from 'src/components/inputs/formik'\n\nconst currencyMax = 999999999\nconst DenominationsSchema = Yup.object().shape({\n top: Yup.number()\n .label('Cassette 1 (Top)')\n .required()\n .min(1)\n .max(currencyMax),\n bottom: Yup.number()\n .label('Cassette 2 (Bottom)')\n .required()\n .min(1)\n .max(currencyMax),\n zeroConfLimit: Yup.number()\n .label('0-conf Limit')\n .required()\n .min(0)\n .max(currencyMax)\n})\n\nconst getElements = (machines, { fiatCurrency } = {}) => {\n return [\n {\n name: 'id',\n header: 'Machine',\n width: 200,\n view: it => machines.find(({ deviceId }) => deviceId === it).name,\n size: 'sm',\n editable: false\n },\n {\n name: 'top',\n header: 'Cassette 1 (Top)',\n size: 'sm',\n stripe: true,\n width: 200,\n textAlign: 'right',\n input: NumberInput,\n inputProps: {\n decimalPlaces: 0\n },\n suffix: fiatCurrency\n },\n {\n name: 'bottom',\n header: 'Cassette 2 (Bottom)',\n size: 'sm',\n stripe: true,\n textAlign: 'right',\n width: 200,\n input: NumberInput,\n inputProps: {\n decimalPlaces: 0\n },\n suffix: fiatCurrency\n },\n {\n name: 'zeroConfLimit',\n header: '0-conf Limit',\n size: 'sm',\n stripe: true,\n textAlign: 'right',\n width: 200,\n input: NumberInput,\n inputProps: {\n decimalPlaces: 0\n },\n suffix: fiatCurrency\n }\n ]\n}\n\nexport { DenominationsSchema, getElements }\n","import * as R from 'ramda'\nimport React, { useState } from 'react'\nimport * as Yup from 'yup'\n\nimport Modal from 'src/components/Modal'\nimport { Autocomplete } from 'src/components/inputs/formik'\nimport denominations from 'src/utils/bill-denominations'\nimport { toNamespace } from 'src/utils/config'\n\nimport WizardSplash from './WizardSplash'\nimport WizardStep from './WizardStep'\nimport { DenominationsSchema } from './helper'\n\nconst LAST_STEP = 4\nconst MODAL_WIDTH = 554\nconst MODAL_HEIGHT = 520\n\nconst getOptions = R.curry((locale, denomiations) => {\n const currency = R.prop('fiatCurrency')(locale)\n return R.compose(\n R.map(code => ({ code, display: code })),\n R.keys,\n R.path([currency])\n )(denomiations)\n})\n\nconst Wizard = ({ machine, locale, onClose, save, error }) => {\n const [{ step, config }, setState] = useState({\n step: 0,\n config: { active: true }\n })\n\n const options = getOptions(locale, denominations)\n\n const title = `Enable cash-out`\n const isLastStep = step === LAST_STEP\n\n const onContinue = async it => {\n if (isLastStep) {\n return save(\n toNamespace(machine.deviceId, DenominationsSchema.cast(config))\n )\n }\n\n const newConfig = R.merge(config, it)\n\n setState({\n step: step + 1,\n config: newConfig\n })\n }\n\n const steps = [\n {\n type: 'top',\n display: 'Cassette 1 (Top)',\n component: Autocomplete,\n inputProps: {\n options: R.map(it => ({ code: it, display: it }))(options),\n labelProp: 'display',\n valueProp: 'code'\n }\n },\n {\n type: 'bottom',\n display: 'Cassette 2',\n component: Autocomplete,\n inputProps: {\n options: R.map(it => ({ code: it, display: it }))(options),\n labelProp: 'display',\n valueProp: 'code'\n }\n },\n {\n type: 'zeroConfLimit',\n display: '0-conf Limit',\n schema: Yup.object().shape({\n zeroConfLimit: Yup.number().required()\n })\n }\n ]\n\n const schema = () =>\n Yup.object().shape({\n top: Yup.number().required(),\n bottom: step >= 2 ? Yup.number().required() : Yup.number()\n })\n\n return (\n \n {step === 0 && (\n onContinue()} />\n )}\n {step !== 0 && (\n \n )}\n \n )\n}\n\nexport default Wizard\n","import { useQuery, useMutation } from '@apollo/react-hooks'\nimport { makeStyles } from '@material-ui/core/styles'\nimport gql from 'graphql-tag'\nimport * as R from 'ramda'\nimport React, { useState } from 'react'\n\nimport { Tooltip } from 'src/components/Tooltip'\nimport { NamespacedTable as EditableTable } from 'src/components/editableTable'\nimport { Switch } from 'src/components/inputs'\nimport TitleSection from 'src/components/layout/TitleSection'\nimport { EmptyTable } from 'src/components/table'\nimport { P, Label2 } from 'src/components/typography'\nimport { fromNamespace, toNamespace } from 'src/utils/config'\n\nimport Wizard from './Wizard'\nimport { DenominationsSchema, getElements } from './helper'\n\nconst useStyles = makeStyles({\n fudgeFactor: {\n display: 'flex',\n alignItems: 'center',\n marginRight: 156\n },\n switchLabel: {\n margin: 6,\n width: 24\n }\n})\n\nconst SAVE_CONFIG = gql`\n mutation Save($config: JSONObject) {\n saveConfig(config: $config)\n }\n`\n\nconst GET_INFO = gql`\n query getData {\n machines {\n name\n deviceId\n cashbox\n cassette1\n cassette2\n }\n config\n }\n`\n\nconst CashOut = ({ name: SCREEN_KEY }) => {\n const classes = useStyles()\n const [wizard, setWizard] = useState(false)\n const { data } = useQuery(GET_INFO)\n\n const [saveConfig, { error }] = useMutation(SAVE_CONFIG, {\n onCompleted: () => setWizard(false),\n refetchQueries: () => ['getData']\n })\n\n const save = (rawConfig, accounts) => {\n const config = toNamespace(SCREEN_KEY)(rawConfig)\n return saveConfig({ variables: { config, accounts } })\n }\n\n const config = data?.config && fromNamespace(SCREEN_KEY)(data.config)\n const fudgeFactorActive = config?.fudgeFactorActive ?? false\n const locale = data?.config && fromNamespace('locale')(data.config)\n const machines = data?.machines ?? []\n\n const onToggle = id => {\n const namespaced = fromNamespace(id)(config)\n if (!DenominationsSchema.isValidSync(namespaced)) return setWizard(id)\n save(toNamespace(id, { active: !namespaced?.active }))\n }\n\n const wasNeverEnabled = it => R.compose(R.length, R.keys)(it) === 1\n\n return (\n <>\n \n \n
Transaction fudge factor
\n
{\n save({ fudgeFactorActive: event.target.checked })\n }}\n value={fudgeFactorActive}\n />\n \n {fudgeFactorActive ? 'On' : 'Off'}\n \n \n \n Automatically accept customer deposits as complete if their\n received amount is 100 crypto atoms or less.\n
\n \n (Crypto atoms are the smallest unit in each cryptocurrency. E.g.,\n satoshis in Bitcoin, or wei in Ethereum.)\n
\n \n \n \n \n {R.isEmpty(machines) && }\n {wizard && (\n setWizard(false)}\n save={save}\n error={error?.message}\n locale={locale}\n />\n )}\n >\n )\n}\n\nexport default CashOut\n","import Cashout from './Cashout'\n\nexport default Cashout\n","function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport * as React from \"react\";\n\nvar _ref2 = /*#__PURE__*/React.createElement(\"desc\", null, \"Created with Sketch.\");\n\nvar _ref3 = /*#__PURE__*/React.createElement(\"g\", {\n id: \"icon/sf-small/listing/white\",\n stroke: \"none\",\n strokeWidth: 1,\n fill: \"none\",\n fillRule: \"evenodd\",\n strokeLinecap: \"round\",\n strokeLinejoin: \"round\"\n}, /*#__PURE__*/React.createElement(\"line\", {\n x1: 0,\n y1: 1,\n x2: 20,\n y2: 1,\n id: \"Path-4\",\n stroke: \"#FFFFFF\",\n strokeWidth: 2\n}), /*#__PURE__*/React.createElement(\"line\", {\n x1: 0,\n y1: 7,\n x2: 9,\n y2: 7,\n id: \"Path-4-Copy\",\n stroke: \"#FFFFFF\",\n strokeWidth: 2\n}), /*#__PURE__*/React.createElement(\"line\", {\n x1: 0,\n y1: 13,\n x2: 20,\n y2: 13,\n id: \"Path-4-Copy-2\",\n stroke: \"#FFFFFF\",\n strokeWidth: 2\n}), /*#__PURE__*/React.createElement(\"line\", {\n x1: 0,\n y1: 19,\n x2: 12,\n y2: 19,\n id: \"Path-4-Copy-3\",\n stroke: \"#FFFFFF\",\n strokeWidth: 2\n}));\n\nfunction SvgWhite(_ref, svgRef) {\n var title = _ref.title,\n titleId = _ref.titleId,\n props = _objectWithoutProperties(_ref, [\"title\", \"titleId\"]);\n\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n width: \"20px\",\n height: \"20px\",\n viewBox: \"0 0 20 20\",\n xmlns: \"http://www.w3.org/2000/svg\",\n xmlnsXlink: \"http://www.w3.org/1999/xlink\",\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, _ref2, _ref3);\n}\n\nvar ForwardRef = /*#__PURE__*/React.forwardRef(SvgWhite);\nexport default __webpack_public_path__ + \"static/media/white.20ca66ec.svg\";\nexport { ForwardRef as ReactComponent };","function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport * as React from \"react\";\n\nvar _ref2 = /*#__PURE__*/React.createElement(\"desc\", null, \"Created with Sketch.\");\n\nvar _ref3 = /*#__PURE__*/React.createElement(\"g\", {\n id: \"icon/sf-small/listing/zodiac\",\n stroke: \"none\",\n strokeWidth: 1,\n fill: \"none\",\n fillRule: \"evenodd\",\n strokeLinecap: \"round\",\n strokeLinejoin: \"round\"\n}, /*#__PURE__*/React.createElement(\"line\", {\n x1: 0,\n y1: 1,\n x2: 20,\n y2: 1,\n id: \"Path-4\",\n stroke: \"#1B2559\",\n strokeWidth: 2\n}), /*#__PURE__*/React.createElement(\"line\", {\n x1: 0,\n y1: 7,\n x2: 9,\n y2: 7,\n id: \"Path-4-Copy\",\n stroke: \"#1B2559\",\n strokeWidth: 2\n}), /*#__PURE__*/React.createElement(\"line\", {\n x1: 0,\n y1: 13,\n x2: 20,\n y2: 13,\n id: \"Path-4-Copy-2\",\n stroke: \"#1B2559\",\n strokeWidth: 2\n}), /*#__PURE__*/React.createElement(\"line\", {\n x1: 0,\n y1: 19,\n x2: 12,\n y2: 19,\n id: \"Path-4-Copy-3\",\n stroke: \"#1B2559\",\n strokeWidth: 2\n}));\n\nfunction SvgZodiac(_ref, svgRef) {\n var title = _ref.title,\n titleId = _ref.titleId,\n props = _objectWithoutProperties(_ref, [\"title\", \"titleId\"]);\n\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n width: \"20px\",\n height: \"20px\",\n viewBox: \"0 0 20 20\",\n xmlns: \"http://www.w3.org/2000/svg\",\n xmlnsXlink: \"http://www.w3.org/1999/xlink\",\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, _ref2, _ref3);\n}\n\nvar ForwardRef = /*#__PURE__*/React.forwardRef(SvgZodiac);\nexport default __webpack_public_path__ + \"static/media/zodiac.e161cf6b.svg\";\nexport { ForwardRef as ReactComponent };","function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport * as React from \"react\";\n\nvar _ref2 = /*#__PURE__*/React.createElement(\"rect\", {\n width: 12,\n height: 12,\n rx: 3,\n ry: 3,\n fill: \"#44e188\"\n});\n\nfunction SvgSpring2(_ref, svgRef) {\n var title = _ref.title,\n titleId = _ref.titleId,\n props = _objectWithoutProperties(_ref, [\"title\", \"titleId\"]);\n\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n width: 12,\n height: 12,\n viewBox: \"0 0 12 12\",\n xmlns: \"http://www.w3.org/2000/svg\",\n xmlnsXlink: \"http://www.w3.org/1999/xlink\",\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, _ref2);\n}\n\nvar ForwardRef = /*#__PURE__*/React.forwardRef(SvgSpring2);\nexport default __webpack_public_path__ + \"static/media/spring2.9f3bb2f7.svg\";\nexport { ForwardRef as ReactComponent };","import { makeStyles } from '@material-ui/core/styles'\nimport classnames from 'classnames'\nimport React, { memo } from 'react'\n\nimport { spacer, offColor } from 'src/styling/variables'\n\nimport { TL1 } from './typography'\n\nconst useStyles = makeStyles({\n subtitle: {\n color: offColor,\n marginTop: spacer * 2,\n marginBottom: spacer * 2\n },\n extraMarginTop: {\n marginTop: spacer * 9\n }\n})\n\nconst Subtitle = memo(({ children, className, extraMarginTop }) => {\n const classes = useStyles()\n const classNames = {\n [classes.subtitle]: true,\n [classes.extraMarginTop]: extraMarginTop\n }\n\n return {children} \n})\n\nexport default Subtitle\n","import { makeStyles } from '@material-ui/core'\nimport React from 'react'\n\nimport ErrorMessage from 'src/components/ErrorMessage'\nimport Subtitle from 'src/components/Subtitle'\n\nimport styles from './Section.styles'\n\nconst useStyles = makeStyles(styles)\n\nconst Section = ({ error, children, title }) => {\n const classes = useStyles()\n return (\n \n {(title || error) && (\n
\n {title} \n {error && Failed to save changes }\n
\n )}\n {children}\n
\n )\n}\n\nexport default Section\n","export default {\n section: {\n marginBottom: 72\n },\n sectionHeader: {\n display: 'flex',\n alignItems: 'center'\n },\n sectionTitle: {\n margin: [[16, 20, 23, 0]]\n }\n}\n","function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport * as React from \"react\";\n\nvar _ref2 = /*#__PURE__*/React.createElement(\"desc\", null, \"Created with Sketch.\");\n\nvar _ref3 = /*#__PURE__*/React.createElement(\"g\", {\n id: \"Styleguide\",\n stroke: \"none\",\n strokeWidth: 1,\n fill: \"none\",\n fillRule: \"evenodd\"\n}, /*#__PURE__*/React.createElement(\"g\", {\n id: \"icon/direction/cash-in\",\n transform: \"translate(-1.000000, 0.000000)\",\n fill: \"#16D6D3\"\n}, /*#__PURE__*/React.createElement(\"path\", {\n d: \"M3.99134364,0.321790399 L10.1430099,4.40569595 C11.0271728,4.99266501 11.2660914,6.1822461 10.6766494,7.06269968 C10.5357408,7.27317585 10.3543728,7.45378298 10.1430099,7.59410043 L3.99134364,11.678006 C3.10718075,12.264975 1.91258801,12.0270588 1.32314609,11.1466052 C1.11243854,10.8318699 1,10.4620686 1,10.0838037 L1,1.91599264 C1,0.857819122 1.86143307,0 2.92406462,0 C3.30392305,0 3.67528233,0.11196683 3.99134364,0.321790399 Z\",\n id: \"Path-3\"\n})));\n\nfunction SvgCashIn(_ref, svgRef) {\n var title = _ref.title,\n titleId = _ref.titleId,\n props = _objectWithoutProperties(_ref, [\"title\", \"titleId\"]);\n\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n width: \"10px\",\n height: \"12px\",\n viewBox: \"0 0 10 12\",\n xmlns: \"http://www.w3.org/2000/svg\",\n xmlnsXlink: \"http://www.w3.org/1999/xlink\",\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, _ref2, _ref3);\n}\n\nvar ForwardRef = /*#__PURE__*/React.forwardRef(SvgCashIn);\nexport default __webpack_public_path__ + \"static/media/cash-in.c06970a7.svg\";\nexport { ForwardRef as ReactComponent };","import * as _ from 'lodash/fp'\nimport * as R from 'ramda'\nimport React from 'react'\nimport { v4 } from 'uuid'\nimport * as Yup from 'yup'\n\nimport { NumberInput } from 'src/components/inputs/formik'\nimport Autocomplete from 'src/components/inputs/formik/Autocomplete.js'\nimport { ReactComponent as TxInIcon } from 'src/styling/icons/direction/cash-in.svg'\nimport { ReactComponent as TxOutIcon } from 'src/styling/icons/direction/cash-out.svg'\nimport { primaryColor, secondaryColorDark } from 'src/styling/variables'\n\nconst ALL_MACHINES = {\n name: 'All Machines',\n deviceId: 'ALL_MACHINES'\n}\n\nconst ALL_COINS = {\n display: 'All Coins',\n code: 'ALL_COINS'\n}\n\nconst cashInAndOutHeaderStyle = { marginLeft: 6 }\n\nconst cashInHeader = (\n \n \n Cash-in \n
\n)\n\nconst cashOutHeader = (\n \n \n Cash-out \n
\n)\n\nconst getView = (data, code, compare) => it => {\n if (!data) return ''\n\n // The following boolean should come undefined if it is rendering an unpaired machine\n const attribute = R.find(R.propEq(compare ?? 'code', it))(data)\n\n return attribute ? R.prop(code, attribute) : 'Unpaired machine'\n}\n\nconst displayCodeArray = data => it => {\n if (!it) return it\n\n return R.compose(R.join(', '), R.map(getView(data, 'display')))(it)\n}\n\nconst onCryptoChange = (prev, curr, setValue) => {\n const hasAllCoins = R.includes(ALL_COINS.code)(curr)\n const hadAllCoins = R.includes(ALL_COINS.code)(prev)\n\n if (hasAllCoins && hadAllCoins && R.length(curr) > 1) {\n return setValue(R.reject(R.equals(ALL_COINS.code))(curr))\n }\n\n if (hasAllCoins && !hadAllCoins) {\n return setValue([ALL_COINS.code])\n }\n\n setValue(curr)\n}\n\nconst boldStyle = () => {\n return {\n fontWeight: 'bold'\n }\n}\n\nconst getOverridesFields = (getData, currency, auxElements) => {\n const machineData = [ALL_MACHINES].concat(getData(['machines']))\n const rawCryptos = getData(['cryptoCurrencies'])\n const cryptoData = [ALL_COINS].concat(\n R.map(it => ({ display: it.code, code: it.code }))(rawCryptos ?? [])\n )\n\n return [\n {\n name: 'machine',\n width: 196,\n size: 'sm',\n view: getView(machineData, 'name', 'deviceId'),\n input: Autocomplete,\n inputProps: {\n options: machineData,\n valueProp: 'deviceId',\n labelProp: 'name'\n }\n },\n {\n name: 'cryptoCurrencies',\n width: 280,\n size: 'sm',\n view: displayCodeArray(cryptoData),\n input: Autocomplete,\n inputProps: {\n options: cryptoData,\n valueProp: 'code',\n labelProp: 'display',\n multiple: true,\n onChange: onCryptoChange,\n shouldStayOpen: true\n }\n },\n {\n header: cashInHeader,\n name: 'cashIn',\n display: 'Cash-in',\n width: 130,\n input: NumberInput,\n textAlign: 'right',\n suffix: '%',\n textStyle: boldStyle,\n inputProps: {\n decimalPlaces: 3\n }\n },\n {\n header: cashOutHeader,\n name: 'cashOut',\n display: 'Cash-out',\n width: 130,\n input: NumberInput,\n textAlign: 'right',\n suffix: '%',\n textStyle: boldStyle,\n inputProps: {\n decimalPlaces: 3\n }\n },\n {\n name: 'fixedFee',\n display: 'Fixed fee',\n width: 144,\n input: NumberInput,\n doubleHeader: 'Cash-in only',\n textAlign: 'right',\n suffix: currency,\n textStyle: boldStyle,\n inputProps: {\n decimalPlaces: 2\n }\n },\n {\n name: 'minimumTx',\n display: 'Minimun Tx',\n width: 144,\n input: NumberInput,\n doubleHeader: 'Cash-in only',\n textAlign: 'right',\n suffix: currency,\n textStyle: boldStyle,\n inputProps: {\n decimalPlaces: 2\n }\n }\n ]\n}\n\nconst mainFields = currency => [\n {\n header: cashInHeader,\n name: 'cashIn',\n display: 'Cash-in',\n width: 169,\n size: 'lg',\n editingAlign: 'right',\n input: NumberInput,\n suffix: '%',\n textStyle: boldStyle,\n inputProps: {\n decimalPlaces: 3\n }\n },\n {\n header: cashOutHeader,\n name: 'cashOut',\n display: 'Cash-out',\n width: 169,\n size: 'lg',\n editingAlign: 'right',\n input: NumberInput,\n suffix: '%',\n textStyle: boldStyle,\n inputProps: {\n decimalPlaces: 3\n }\n },\n {\n name: 'fixedFee',\n display: 'Fixed fee',\n width: 169,\n size: 'lg',\n doubleHeader: 'Cash-in only',\n textAlign: 'center',\n editingAlign: 'right',\n input: NumberInput,\n suffix: currency,\n textStyle: boldStyle,\n inputProps: {\n decimalPlaces: 2\n }\n },\n {\n name: 'minimumTx',\n display: 'Minimun Tx',\n width: 169,\n size: 'lg',\n doubleHeader: 'Cash-in only',\n textAlign: 'center',\n editingAlign: 'right',\n input: NumberInput,\n suffix: currency,\n textStyle: boldStyle,\n inputProps: {\n decimalPlaces: 2\n }\n }\n]\n\nconst overrides = (auxData, currency, auxElements) => {\n const getData = R.path(R.__, auxData)\n\n return getOverridesFields(getData, currency, auxElements)\n}\n\nconst percentMax = 100\nconst currencyMax = 9999999\nconst schema = Yup.object().shape({\n cashIn: Yup.number()\n .label('Cash-in')\n .min(0)\n .max(percentMax)\n .required(),\n cashOut: Yup.number()\n .label('Cash-out')\n .min(0)\n .max(percentMax)\n .required(),\n fixedFee: Yup.number()\n .label('Fixed Fee')\n .min(0)\n .max(currencyMax)\n .required(),\n minimumTx: Yup.number()\n .label('Minimum Tx')\n .min(0)\n .max(currencyMax)\n .required()\n})\n\nconst getAlreadyUsed = (id, machine, values) => {\n const getCrypto = R.prop('cryptoCurrencies')\n const getMachineId = R.prop('machine')\n\n const filteredOverrides = R.filter(R.propEq('machine', machine))(values)\n const originalValue = R.find(R.propEq('id', id))(values)\n\n const originalCryptos = getCrypto(originalValue)\n const originalMachineId = getMachineId(originalValue)\n\n const alreadyUsed = R.compose(\n R.uniq,\n R.flatten,\n R.map(getCrypto)\n )(filteredOverrides)\n\n if (machine !== originalMachineId) return alreadyUsed ?? []\n\n return R.difference(alreadyUsed, originalCryptos)\n}\n\nconst getOverridesSchema = (values, rawData) => {\n const getData = R.path(R.__, rawData)\n const machineData = [ALL_MACHINES].concat(getData(['machines']))\n const rawCryptos = getData(['cryptoCurrencies'])\n const cryptoData = [ALL_COINS].concat(\n R.map(it => ({ display: it.code, code: it.code }))(rawCryptos ?? [])\n )\n\n return Yup.object().shape({\n machine: Yup.string()\n .nullable()\n .label('Machine')\n .required(),\n cryptoCurrencies: Yup.array()\n .test({\n test() {\n const { id, machine, cryptoCurrencies } = this.parent\n const alreadyUsed = getAlreadyUsed(id, machine, values)\n\n const isAllMachines = machine === ALL_MACHINES.deviceId\n const isAllCoins = R.includes(ALL_COINS.code, cryptoCurrencies)\n if (isAllMachines && isAllCoins) {\n return this.createError({\n message: `All machines and all coins should be configured in the default setup table`\n })\n }\n\n const repeated = R.intersection(alreadyUsed, cryptoCurrencies)\n if (!R.isEmpty(repeated)) {\n const codes = displayCodeArray(cryptoData)(repeated)\n const machineView = getView(\n machineData,\n 'name',\n 'deviceId'\n )(machine)\n\n const message = `${codes} already overriden for machine: ${machineView}`\n\n return this.createError({ message })\n }\n return true\n }\n })\n .label('Crypto Currencies')\n .required()\n .min(1),\n cashIn: Yup.number()\n .label('Cash-in')\n .min(0)\n .max(percentMax)\n .required(),\n cashOut: Yup.number()\n .label('Cash-out')\n .min(0)\n .max(percentMax)\n .required(),\n fixedFee: Yup.number()\n .label('Fixed Fee')\n .min(0)\n .max(currencyMax)\n .required(),\n minimumTx: Yup.number()\n .label('Minimum Tx')\n .min(0)\n .max(currencyMax)\n .required()\n })\n}\n\nconst defaults = {\n cashIn: '',\n cashOut: '',\n fixedFee: '',\n minimumTx: ''\n}\n\nconst overridesDefaults = {\n machine: null,\n cryptoCurrencies: [],\n cashIn: '',\n cashOut: '',\n fixedFee: '',\n minimumTx: ''\n}\n\nconst getOrder = ({ machine, cryptoCurrencies }) => {\n const isAllMachines = machine === ALL_MACHINES.deviceId\n const isAllCoins = R.contains(ALL_COINS.code, cryptoCurrencies)\n\n if (isAllMachines && isAllCoins) return 0\n if (isAllMachines) return 1\n if (isAllCoins) return 2\n\n return 3\n}\n\nconst createCommissions = (cryptoCode, deviceId, isDefault, config) => {\n return {\n minimumTx: config.minimumTx,\n fixedFee: config.fixedFee,\n cashOut: config.cashOut,\n cashIn: config.cashIn,\n machine: deviceId,\n cryptoCurrencies: [cryptoCode],\n default: isDefault,\n id: v4()\n }\n}\n\nconst getCommissions = (cryptoCode, deviceId, config) => {\n const overrides = R.prop('overrides', config) ?? []\n\n if (!overrides && R.isEmpty(overrides)) {\n return createCommissions(cryptoCode, deviceId, true, config)\n }\n\n const specificOverride = R.find(\n it => it.machine === deviceId && _.includes(cryptoCode)(it.cryptoCurrencies)\n )(overrides)\n\n if (specificOverride !== undefined)\n return createCommissions(cryptoCode, deviceId, false, specificOverride)\n\n const machineOverride = R.find(\n it =>\n it.machine === deviceId && _.includes('ALL_COINS')(it.cryptoCurrencies)\n )(overrides)\n\n if (machineOverride !== undefined)\n return createCommissions(cryptoCode, deviceId, false, machineOverride)\n\n const coinOverride = R.find(\n it =>\n it.machine === 'ALL_MACHINES' &&\n _.includes(cryptoCode)(it.cryptoCurrencies)\n )(overrides)\n\n if (coinOverride !== undefined)\n return createCommissions(cryptoCode, deviceId, false, coinOverride)\n\n return createCommissions(cryptoCode, deviceId, true, config)\n}\n\nconst getListCommissionsSchema = () => {\n return Yup.object().shape({\n machine: Yup.string()\n .label('Machine')\n .required(),\n cryptoCurrencies: Yup.array()\n .label('Crypto Currency')\n .required()\n .min(1),\n cashIn: Yup.number()\n .label('Cash-in')\n .min(0)\n .max(percentMax)\n .required(),\n cashOut: Yup.number()\n .label('Cash-out')\n .min(0)\n .max(percentMax)\n .required(),\n fixedFee: Yup.number()\n .label('Fixed Fee')\n .min(0)\n .max(currencyMax)\n .required(),\n minimumTx: Yup.number()\n .label('Minimum Tx')\n .min(0)\n .max(currencyMax)\n .required()\n })\n}\n\nconst getTextStyle = (obj, isEditing) => {\n return { color: obj.default ? primaryColor : secondaryColorDark }\n}\n\nconst commissionsList = (auxData, currency, auxElements) => {\n const getData = R.path(R.__, auxData)\n\n return getListCommissionsFields(getData, currency, defaults)\n}\n\nconst getListCommissionsFields = (getData, currency, defaults) => {\n const machineData = [ALL_MACHINES].concat(getData(['machines']))\n\n return [\n {\n name: 'machine',\n width: 196,\n size: 'sm',\n view: getView(machineData, 'name', 'deviceId'),\n editable: false\n },\n {\n name: 'cryptoCurrencies',\n display: 'Crypto Currency',\n width: 265,\n view: R.prop(0),\n size: 'sm',\n editable: false\n },\n {\n header: cashInHeader,\n name: 'cashIn',\n display: 'Cash-in',\n width: 130,\n input: NumberInput,\n textAlign: 'right',\n suffix: '%',\n textStyle: obj => getTextStyle(obj),\n inputProps: {\n decimalPlaces: 3\n }\n },\n {\n header: cashOutHeader,\n name: 'cashOut',\n display: 'Cash-out',\n width: 130,\n input: NumberInput,\n textAlign: 'right',\n greenText: true,\n suffix: '%',\n textStyle: obj => getTextStyle(obj),\n inputProps: {\n decimalPlaces: 3\n }\n },\n {\n name: 'fixedFee',\n display: 'Fixed fee',\n width: 144,\n input: NumberInput,\n doubleHeader: 'Cash-in only',\n textAlign: 'right',\n suffix: currency,\n textStyle: obj => getTextStyle(obj),\n inputProps: {\n decimalPlaces: 2\n }\n },\n {\n name: 'minimumTx',\n display: 'Minimun Tx',\n width: 144,\n input: NumberInput,\n doubleHeader: 'Cash-in only',\n textAlign: 'right',\n suffix: currency,\n textStyle: obj => getTextStyle(obj),\n inputProps: {\n decimalPlaces: 2\n }\n }\n ]\n}\n\nexport {\n mainFields,\n overrides,\n schema,\n getOverridesSchema,\n defaults,\n overridesDefaults,\n getOrder,\n getCommissions,\n getListCommissionsSchema,\n commissionsList\n}\n","import * as R from 'ramda'\nimport React, { useState, memo } from 'react'\n\nimport { Table as EditableTable } from 'src/components/editableTable'\nimport Section from 'src/components/layout/Section'\nimport {\n mainFields,\n overrides,\n schema,\n getOverridesSchema,\n defaults,\n overridesDefaults,\n getOrder\n} from 'src/pages/Commissions/helper'\n\nconst CommissionsDetails = memo(\n ({ config, currency, data, error, save, saveOverrides }) => {\n const [isEditingDefault, setEditingDefault] = useState(false)\n const [isEditingOverrides, setEditingOverrides] = useState(false)\n\n const commission = config && !R.isEmpty(config) ? config : defaults\n const commissionOverrides = commission?.overrides ?? []\n\n const orderedCommissionsOverrides = R.sortWith([\n R.ascend(getOrder),\n R.ascend(R.prop('machine'))\n ])(commissionOverrides)\n\n const onEditingDefault = (it, editing) => setEditingDefault(editing)\n const onEditingOverrides = (it, editing) => setEditingOverrides(editing)\n\n return (\n <>\n \n \n >\n )\n }\n)\n\nexport default CommissionsDetails\n","import { makeStyles } from '@material-ui/core'\nimport * as R from 'ramda'\nimport React, { memo, useState } from 'react'\n\nimport { Table as EditableTable } from 'src/components/editableTable'\nimport { Select } from 'src/components/inputs'\nimport {\n overridesDefaults,\n getCommissions,\n getListCommissionsSchema,\n commissionsList\n} from 'src/pages/Commissions/helper'\n\nconst styles = {\n headerLine: {\n display: 'flex',\n justifyContent: '',\n marginBottom: 24\n },\n select: {\n marginRight: 24\n },\n tableWrapper: {\n flex: 1,\n display: 'block',\n overflowY: 'auto',\n width: '100%',\n maxHeight: '70vh'\n }\n}\n\nconst SHOW_ALL = {\n code: 'SHOW_ALL',\n display: 'Show all'\n}\n\nconst ORDER_OPTIONS = [\n {\n code: 'machine',\n display: 'Machine Name'\n },\n {\n code: 'cryptoCurrencies',\n display: 'Cryptocurrency'\n },\n {\n code: 'cashIn',\n display: 'Cash-in'\n },\n {\n code: 'cashOut',\n display: 'Cash-out'\n },\n {\n code: 'fixedFee',\n display: 'Fixed Fee'\n },\n {\n code: 'minimumTx',\n display: 'Minimum Tx'\n }\n]\n\nconst useStyles = makeStyles(styles)\n\nconst getElement = (code, display) => ({\n code: code,\n display: display || code\n})\n\nconst sortCommissionsBy = prop => {\n switch (prop) {\n case ORDER_OPTIONS[0]:\n return R.sortBy(R.find(R.propEq('code', R.prop('machine'))))\n case ORDER_OPTIONS[1]:\n return R.sortBy(R.path(['cryptoCurrencies', 0]))\n default:\n return R.sortBy(R.prop(prop.code))\n }\n}\n\nconst filterCommissions = (coinFilter, machineFilter) =>\n R.compose(\n R.filter(\n it => (machineFilter === SHOW_ALL) | (machineFilter.code === it.machine)\n ),\n R.filter(\n it =>\n (coinFilter === SHOW_ALL) | (coinFilter.code === it.cryptoCurrencies[0])\n )\n )\n\nconst CommissionsList = memo(\n ({ config, localeConfig, currency, data, error, saveOverrides }) => {\n const classes = useStyles()\n\n const [machineFilter, setMachineFilter] = useState(SHOW_ALL)\n const [coinFilter, setCoinFilter] = useState(SHOW_ALL)\n const [orderProp, setOrderProp] = useState(ORDER_OPTIONS[0])\n\n const coins = R.prop('cryptoCurrencies', localeConfig) ?? []\n\n const getMachineCoins = deviceId => {\n const override = R.prop('overrides', localeConfig)?.find(\n R.propEq('machine', deviceId)\n )\n\n const machineCoins = override\n ? R.prop('cryptoCurrencies', override)\n : coins\n\n return R.xprod([deviceId], machineCoins)\n }\n\n const getMachineElement = it =>\n getElement(R.prop('deviceId', it), R.prop('name', it))\n\n const cryptoData = R.map(getElement)(coins)\n\n const machineData = R.sortBy(\n R.prop('display'),\n R.map(getMachineElement)(R.prop('machines', data))\n )\n\n const machinesCoinsTuples = R.unnest(\n R.map(getMachineCoins)(machineData.map(R.prop('code')))\n )\n\n const commissions = R.map(([deviceId, cryptoCode]) =>\n getCommissions(cryptoCode, deviceId, config)\n )(machinesCoinsTuples)\n\n const tableData = R.compose(\n sortCommissionsBy(orderProp),\n filterCommissions(coinFilter, machineFilter)\n )(commissions)\n\n return (\n \n
\n \n \n \n
\n
\n \n
\n
\n )\n }\n)\n\nexport default CommissionsList\n","import { useQuery, useMutation } from '@apollo/react-hooks'\nimport { makeStyles } from '@material-ui/core'\nimport gql from 'graphql-tag'\nimport * as R from 'ramda'\nimport React, { useState } from 'react'\n\nimport TitleSection from 'src/components/layout/TitleSection'\nimport { ReactComponent as ReverseListingViewIcon } from 'src/styling/icons/circle buttons/listing-view/white.svg'\nimport { ReactComponent as ListingViewIcon } from 'src/styling/icons/circle buttons/listing-view/zodiac.svg'\nimport { ReactComponent as OverrideLabelIcon } from 'src/styling/icons/status/spring2.svg'\nimport { fromNamespace, toNamespace, namespaces } from 'src/utils/config'\n\nimport CommissionsDetails from './components/CommissionsDetails'\nimport CommissionsList from './components/CommissionsList'\n\nconst styles = {\n listViewButton: {\n marginLeft: 4\n }\n}\n\nconst useStyles = makeStyles(styles)\n\nconst GET_DATA = gql`\n query getData {\n config\n cryptoCurrencies {\n code\n display\n }\n machines {\n name\n deviceId\n }\n }\n`\n\nconst SAVE_CONFIG = gql`\n mutation Save($config: JSONObject) {\n saveConfig(config: $config)\n }\n`\nconst removeCoinFromOverride = crypto => override =>\n R.mergeRight(override, {\n cryptoCurrencies: R.without([crypto], override.cryptoCurrencies)\n })\n\nconst Commissions = ({ name: SCREEN_KEY }) => {\n const classes = useStyles()\n const [showMachines, setShowMachines] = useState(false)\n const [error, setError] = useState(null)\n const { data, loading } = useQuery(GET_DATA)\n const [saveConfig] = useMutation(SAVE_CONFIG, {\n refetchQueries: () => ['getData'],\n onError: error => setError(error)\n })\n\n const config = data?.config && fromNamespace(SCREEN_KEY)(data.config)\n const localeConfig =\n data?.config && fromNamespace(namespaces.LOCALE)(data.config)\n\n const currency = R.prop('fiatCurrency')(localeConfig)\n const overrides = R.prop('overrides')(config)\n\n const save = it => {\n const config = toNamespace(SCREEN_KEY)(it.commissions[0])\n return saveConfig({ variables: { config } })\n }\n\n const saveOverrides = it => {\n const config = toNamespace(SCREEN_KEY)(it)\n setError(null)\n return saveConfig({ variables: { config } })\n }\n\n const saveOverridesFromList = it => (_, override) => {\n const cryptoOverriden = R.path(['cryptoCurrencies', 0], override)\n\n const sameMachine = R.eqProps('machine', override)\n const notSameOverride = it => !R.eqProps('cryptoCurrencies', override, it)\n\n const filterMachine = R.filter(R.both(sameMachine, notSameOverride))\n const removeCoin = removeCoinFromOverride(cryptoOverriden)\n\n const machineOverrides = R.map(removeCoin)(filterMachine(it))\n\n const overrides = machineOverrides.concat(\n R.filter(it => !sameMachine(it), it)\n )\n\n const config = {\n commissions_overrides: R.prepend(override, overrides)\n }\n\n return saveConfig({ variables: { config } })\n }\n\n const labels = showMachines\n ? [\n {\n label: 'Override value',\n icon: \n }\n ]\n : []\n\n return (\n <>\n \n\n {!showMachines && !loading && (\n \n )}\n {showMachines && !loading && (\n \n )}\n >\n )\n}\n\nexport default Commissions\n","import Commissions from './Commissions'\n\nexport default Commissions\n","import Chip from '@material-ui/core/Chip'\nimport { makeStyles } from '@material-ui/core/styles'\nimport React from 'react'\n\nimport {\n tomato,\n mistyRose,\n pumpkin,\n secondaryColorDarker as spring4,\n inputFontWeight,\n spring3,\n zircon,\n primaryColor,\n smallestFontSize,\n inputFontFamily,\n spacer,\n linen\n} from '../styling/variables'\n\nconst colors = {\n error: tomato,\n warning: pumpkin,\n success: spring4,\n neutral: primaryColor\n}\n\nconst backgroundColors = {\n error: mistyRose,\n warning: linen,\n success: spring3,\n neutral: zircon\n}\n\nconst useStyles = makeStyles({\n root: {\n borderRadius: spacer / 2,\n marginTop: spacer / 2,\n marginRight: spacer / 4,\n marginBottom: spacer / 2,\n marginLeft: spacer / 4,\n height: spacer * 3,\n backgroundColor: ({ type }) => backgroundColors[type]\n },\n label: {\n fontSize: smallestFontSize,\n fontWeight: inputFontWeight,\n fontFamily: inputFontFamily,\n paddingRight: spacer / 2,\n paddingLeft: spacer / 2,\n color: ({ type }) => colors[type]\n }\n})\n\nconst Status = ({ status }) => {\n const classes = useStyles({ type: status.type })\n return \n}\n\nconst MainStatus = ({ statuses }) => {\n const mainStatus =\n statuses.find(s => s.type === 'error') ||\n statuses.find(s => s.type === 'warning') ||\n statuses[0]\n const plus = { label: `+${statuses.length - 1}`, type: mainStatus.type }\n\n return (\n \n \n {statuses.length > 1 && }\n
\n )\n}\n\nexport { Status, MainStatus }\n","function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport * as React from \"react\";\n\nvar _ref2 = /*#__PURE__*/React.createElement(\"desc\", null, \"Created with Sketch.\");\n\nvar _ref3 = /*#__PURE__*/React.createElement(\"g\", {\n id: \"icon/button/authorize/white\",\n stroke: \"none\",\n strokeWidth: 1,\n fill: \"none\",\n fillRule: \"evenodd\"\n}, /*#__PURE__*/React.createElement(\"circle\", {\n id: \"Oval\",\n stroke: \"#FFFFFF\",\n cx: 6,\n cy: 6,\n r: 5\n}), /*#__PURE__*/React.createElement(\"polyline\", {\n id: \"Stroke-13\",\n stroke: \"#FFFFFF\",\n strokeLinecap: \"round\",\n strokeLinejoin: \"round\",\n points: \"4 6.66666667 5 8 8 4\"\n}));\n\nfunction SvgWhite(_ref, svgRef) {\n var title = _ref.title,\n titleId = _ref.titleId,\n props = _objectWithoutProperties(_ref, [\"title\", \"titleId\"]);\n\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n viewBox: \"0 0 12 12\",\n xmlns: \"http://www.w3.org/2000/svg\",\n xmlnsXlink: \"http://www.w3.org/1999/xlink\",\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, _ref2, _ref3);\n}\n\nvar ForwardRef = /*#__PURE__*/React.forwardRef(SvgWhite);\nexport default __webpack_public_path__ + \"static/media/white.51296906.svg\";\nexport { ForwardRef as ReactComponent };","function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport * as React from \"react\";\n\nvar _ref2 = /*#__PURE__*/React.createElement(\"desc\", null, \"Created with Sketch.\");\n\nvar _ref3 = /*#__PURE__*/React.createElement(\"g\", {\n id: \"icon/button/authorize/zodiac\",\n stroke: \"none\",\n strokeWidth: 1,\n fill: \"none\",\n fillRule: \"evenodd\"\n}, /*#__PURE__*/React.createElement(\"g\", {\n id: \"Group-9\",\n stroke: \"#1B2559\"\n}, /*#__PURE__*/React.createElement(\"circle\", {\n id: \"Oval\",\n cx: 6,\n cy: 6,\n r: 5\n})), /*#__PURE__*/React.createElement(\"polyline\", {\n id: \"Stroke-13\",\n stroke: \"#1B2559\",\n strokeLinecap: \"round\",\n strokeLinejoin: \"round\",\n points: \"4 6.66666667 5 8 8 4\"\n}));\n\nfunction SvgZodiac(_ref, svgRef) {\n var title = _ref.title,\n titleId = _ref.titleId,\n props = _objectWithoutProperties(_ref, [\"title\", \"titleId\"]);\n\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n viewBox: \"0 0 12 12\",\n xmlns: \"http://www.w3.org/2000/svg\",\n xmlnsXlink: \"http://www.w3.org/1999/xlink\",\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, _ref2, _ref3);\n}\n\nvar ForwardRef = /*#__PURE__*/React.forwardRef(SvgZodiac);\nexport default __webpack_public_path__ + \"static/media/zodiac.2fe856d5.svg\";\nexport { ForwardRef as ReactComponent };","function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport * as React from \"react\";\n\nvar _ref2 = /*#__PURE__*/React.createElement(\"desc\", null, \"Created with Sketch.\");\n\nvar _ref3 = /*#__PURE__*/React.createElement(\"g\", {\n id: \"icon/button/cancel/zodiac\",\n stroke: \"none\",\n strokeWidth: 1,\n fill: \"none\",\n fillRule: \"evenodd\",\n strokeLinecap: \"round\",\n strokeLinejoin: \"round\"\n}, /*#__PURE__*/React.createElement(\"g\", {\n id: \"Group-5\",\n stroke: \"#1B2559\",\n strokeWidth: 1.2\n}, /*#__PURE__*/React.createElement(\"line\", {\n x1: 12,\n y1: 0,\n x2: 0,\n y2: 12,\n id: \"Stroke-1\"\n}), /*#__PURE__*/React.createElement(\"line\", {\n x1: 0,\n y1: 0,\n x2: 12,\n y2: 12,\n id: \"Stroke-3\"\n})));\n\nfunction SvgZodiac(_ref, svgRef) {\n var title = _ref.title,\n titleId = _ref.titleId,\n props = _objectWithoutProperties(_ref, [\"title\", \"titleId\"]);\n\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n width: \"12px\",\n height: \"12px\",\n viewBox: \"0 0 12 12\",\n xmlns: \"http://www.w3.org/2000/svg\",\n xmlnsXlink: \"http://www.w3.org/1999/xlink\",\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, _ref2, _ref3);\n}\n\nvar ForwardRef = /*#__PURE__*/React.forwardRef(SvgZodiac);\nexport default __webpack_public_path__ + \"static/media/zodiac.3b13c0b7.svg\";\nexport { ForwardRef as ReactComponent };","import { white, tomato, spring4, comet } from 'src/styling/variables'\n\nconst propertyCardStyles = {\n label1: {\n display: 'flex',\n marginBottom: 2,\n marginTop: 'auto',\n width: 85\n },\n label1Pending: {\n color: comet\n },\n label1Rejected: {\n color: tomato\n },\n label1Accepted: {\n color: spring4\n },\n cardActionButton: {\n display: 'flex',\n height: 28,\n marginRight: 'auto',\n marginLeft: 12\n },\n propertyCardTopRow: {\n display: 'flex',\n margin: [[0, 10, 5, 0]]\n },\n propertyCardBottomRow: {\n display: 'flex',\n flexDirection: 'row',\n height: 45\n },\n propertyCard: {\n display: 'flex',\n flexDirection: 'column',\n borderRadius: 8,\n width: '100%',\n height: 100,\n padding: [[20]],\n boxSizing: 'border-box',\n boxShadow: '0 0 8px 0 rgba(0, 0, 0, 0.04)',\n border: 'solid 0',\n backgroundColor: white,\n margin: [[20, 0, 0, 0]]\n },\n rowSpaceBetween: {\n display: 'flex',\n flexFlow: 'row nowrap',\n alignItems: 'center',\n justifyContent: 'space-between'\n },\n columnSpaceBetween: {\n display: 'flex',\n flexFlow: 'column nowrap',\n alignItems: 'center',\n justifyContent: 'space-between',\n width: 90\n },\n buttonsWrapper: {\n display: 'flex',\n flexDirection: 'row',\n justifyContent: 'flex-end',\n marginLeft: 'auto',\n marginTop: 'auto'\n }\n}\n\nexport { propertyCardStyles }\n","import { Paper } from '@material-ui/core'\nimport { makeStyles } from '@material-ui/core/styles'\nimport classnames from 'classnames'\nimport React, { memo } from 'react'\n\nimport { MainStatus } from 'src/components/Status'\nimport { ActionButton } from 'src/components/buttons'\nimport { H3 } from 'src/components/typography'\nimport { ReactComponent as AuthorizeReversedIcon } from 'src/styling/icons/button/authorize/white.svg'\nimport { ReactComponent as AuthorizeIcon } from 'src/styling/icons/button/authorize/zodiac.svg'\nimport { ReactComponent as RejectReversedIcon } from 'src/styling/icons/button/cancel/white.svg'\nimport { ReactComponent as RejectIcon } from 'src/styling/icons/button/cancel/zodiac.svg'\n\nimport { propertyCardStyles } from './PropertyCard.styles'\n\nconst useStyles = makeStyles(propertyCardStyles)\n\nconst OVERRIDE_PENDING = 'automatic'\nconst OVERRIDE_AUTHORIZED = 'verified'\nconst OVERRIDE_REJECTED = 'blocked'\n\nconst PropertyCard = memo(\n ({ className, title, state, authorize, reject, children }) => {\n const classes = useStyles()\n\n const label1ClassNames = {\n [classes.label1]: true,\n [classes.label1Pending]: state === OVERRIDE_PENDING,\n [classes.label1Rejected]: state === OVERRIDE_REJECTED,\n [classes.label1Accepted]: state === OVERRIDE_AUTHORIZED\n }\n\n const AuthorizeButton = () => (\n authorize()}>\n Authorize\n \n )\n\n const RejectButton = () => (\n reject()}>\n Reject\n \n )\n\n const authorized =\n state === OVERRIDE_PENDING\n ? { label: 'Pending', type: 'neutral' }\n : state === OVERRIDE_REJECTED\n ? { label: 'Rejected', type: 'error' }\n : { label: 'Accepted', type: 'success' }\n\n return (\n \n {title} \n \n
\n \n
\n {children}\n
\n {authorize && state !== OVERRIDE_AUTHORIZED && AuthorizeButton()}\n {reject && state !== OVERRIDE_REJECTED && RejectButton()}\n
\n
\n \n )\n }\n)\n\nexport {\n PropertyCard,\n OVERRIDE_PENDING,\n OVERRIDE_AUTHORIZED,\n OVERRIDE_REJECTED\n}\n","function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport * as React from \"react\";\n\nvar _ref2 = /*#__PURE__*/React.createElement(\"desc\", null, \"Created with Sketch.\");\n\nvar _ref3 = /*#__PURE__*/React.createElement(\"g\", {\n id: \"icon/button/block/white\",\n stroke: \"none\",\n strokeWidth: 1,\n fill: \"none\",\n fillRule: \"evenodd\",\n strokeLinecap: \"round\",\n strokeLinejoin: \"round\"\n}, /*#__PURE__*/React.createElement(\"g\", {\n id: \"Group-5\",\n stroke: \"#FFFFFF\"\n}, /*#__PURE__*/React.createElement(\"circle\", {\n id: \"Oval\",\n cx: 6,\n cy: 6,\n r: 5\n}), /*#__PURE__*/React.createElement(\"line\", {\n x1: 9,\n y1: 3,\n x2: 3,\n y2: 9,\n id: \"Stroke-3\"\n})));\n\nfunction SvgWhite(_ref, svgRef) {\n var title = _ref.title,\n titleId = _ref.titleId,\n props = _objectWithoutProperties(_ref, [\"title\", \"titleId\"]);\n\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n viewBox: \"0 0 12 12\",\n xmlns: \"http://www.w3.org/2000/svg\",\n xmlnsXlink: \"http://www.w3.org/1999/xlink\",\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, _ref2, _ref3);\n}\n\nvar ForwardRef = /*#__PURE__*/React.forwardRef(SvgWhite);\nexport default __webpack_public_path__ + \"static/media/white.e72682b5.svg\";\nexport { ForwardRef as ReactComponent };","function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport * as React from \"react\";\n\nvar _ref2 = /*#__PURE__*/React.createElement(\"desc\", null, \"Created with Sketch.\");\n\nvar _ref3 = /*#__PURE__*/React.createElement(\"g\", {\n id: \"icon/button/block/zodiac\",\n stroke: \"none\",\n strokeWidth: 1,\n fill: \"none\",\n fillRule: \"evenodd\",\n strokeLinecap: \"round\",\n strokeLinejoin: \"round\"\n}, /*#__PURE__*/React.createElement(\"g\", {\n id: \"Group-5\",\n stroke: \"#1B2559\"\n}, /*#__PURE__*/React.createElement(\"circle\", {\n id: \"Oval\",\n cx: 6,\n cy: 6,\n r: 5\n}), /*#__PURE__*/React.createElement(\"line\", {\n x1: 9,\n y1: 3,\n x2: 3,\n y2: 9,\n id: \"Stroke-3\"\n})));\n\nfunction SvgZodiac(_ref, svgRef) {\n var title = _ref.title,\n titleId = _ref.titleId,\n props = _objectWithoutProperties(_ref, [\"title\", \"titleId\"]);\n\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n viewBox: \"0 0 12 12\",\n xmlns: \"http://www.w3.org/2000/svg\",\n xmlnsXlink: \"http://www.w3.org/1999/xlink\",\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, _ref2, _ref3);\n}\n\nvar ForwardRef = /*#__PURE__*/React.forwardRef(SvgZodiac);\nexport default __webpack_public_path__ + \"static/media/zodiac.bb7722c5.svg\";\nexport { ForwardRef as ReactComponent };","import { comet } from 'src/styling/variables'\n\nexport default {\n labelLink: {\n cursor: 'pointer',\n color: comet\n },\n breadcrumbs: {\n margin: [[20, 0]]\n },\n actionLabel: {\n color: comet,\n margin: [[4, 0]]\n },\n customerDetails: {\n marginBottom: 18\n },\n customerActions: {\n display: 'flex',\n flexDirection: 'row',\n '& button': {\n marginRight: 15\n },\n '& > :last-child': {\n marginRight: 0\n }\n }\n}\n","function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport * as React from \"react\";\n\nvar _ref2 = /*#__PURE__*/React.createElement(\"desc\", null, \"Created with Sketch.\");\n\nvar _ref3 = /*#__PURE__*/React.createElement(\"g\", {\n id: \"icon/sf-small/search/white\",\n stroke: \"none\",\n strokeWidth: 1,\n fill: \"none\",\n fillRule: \"evenodd\"\n}, /*#__PURE__*/React.createElement(\"path\", {\n d: \"M15.8635238,8.17028571 C15.8635238,12.4198095 12.4187619,15.8645714 8.1692381,15.8645714 C3.92066667,15.8645714 0.475904762,12.4198095 0.475904762,8.17028571 C0.475904762,3.9207619 3.92066667,0.476 8.1692381,0.476 C12.4187619,0.476 15.8635238,3.9207619 15.8635238,8.17028571 Z\",\n id: \"Stroke-1\",\n stroke: \"#FFFFFF\",\n strokeWidth: 2\n}), /*#__PURE__*/React.createElement(\"line\", {\n x1: 13.7035238,\n y1: 13.7046667,\n x2: 19.4844762,\n y2: 19.485619,\n id: \"Stroke-3\",\n stroke: \"#FFFFFF\",\n strokeWidth: 2,\n strokeLinecap: \"round\"\n}));\n\nfunction SvgWhite(_ref, svgRef) {\n var title = _ref.title,\n titleId = _ref.titleId,\n props = _objectWithoutProperties(_ref, [\"title\", \"titleId\"]);\n\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n width: \"20px\",\n height: \"20px\",\n viewBox: \"0 0 20 20\",\n xmlns: \"http://www.w3.org/2000/svg\",\n xmlnsXlink: \"http://www.w3.org/1999/xlink\",\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, _ref2, _ref3);\n}\n\nvar ForwardRef = /*#__PURE__*/React.forwardRef(SvgWhite);\nexport default __webpack_public_path__ + \"static/media/white.e8851a0a.svg\";\nexport { ForwardRef as ReactComponent };","function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport * as React from \"react\";\n\nvar _ref2 = /*#__PURE__*/React.createElement(\"desc\", null, \"Created with Sketch.\");\n\nvar _ref3 = /*#__PURE__*/React.createElement(\"g\", {\n id: \"icon/sf-small/search/zodiac\",\n stroke: \"none\",\n strokeWidth: 1,\n fill: \"none\",\n fillRule: \"evenodd\"\n}, /*#__PURE__*/React.createElement(\"path\", {\n d: \"M15.8635238,8.17028571 C15.8635238,12.4198095 12.4187619,15.8645714 8.1692381,15.8645714 C3.92066667,15.8645714 0.475904762,12.4198095 0.475904762,8.17028571 C0.475904762,3.9207619 3.92066667,0.476 8.1692381,0.476 C12.4187619,0.476 15.8635238,3.9207619 15.8635238,8.17028571 Z\",\n id: \"Stroke-1\",\n stroke: \"#1B2559\",\n strokeWidth: 2\n}), /*#__PURE__*/React.createElement(\"line\", {\n x1: 13.7035238,\n y1: 13.7046667,\n x2: 19.4844762,\n y2: 19.485619,\n id: \"Stroke-3\",\n stroke: \"#1B2559\",\n strokeWidth: 2,\n strokeLinecap: \"round\"\n}));\n\nfunction SvgZodiac(_ref, svgRef) {\n var title = _ref.title,\n titleId = _ref.titleId,\n props = _objectWithoutProperties(_ref, [\"title\", \"titleId\"]);\n\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n width: \"20px\",\n height: \"20px\",\n viewBox: \"0 0 20 20\",\n xmlns: \"http://www.w3.org/2000/svg\",\n xmlnsXlink: \"http://www.w3.org/1999/xlink\",\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, _ref2, _ref3);\n}\n\nvar ForwardRef = /*#__PURE__*/React.forwardRef(SvgZodiac);\nexport default __webpack_public_path__ + \"static/media/zodiac.91792e22.svg\";\nexport { ForwardRef as ReactComponent };","import { makeStyles, ClickAwayListener } from '@material-ui/core'\nimport classnames from 'classnames'\nimport React, { memo, useState } from 'react'\n\nimport Popper from 'src/components/Popper'\nimport { FeatureButton } from 'src/components/buttons'\nimport { ReactComponent as ZoomIconInverse } from 'src/styling/icons/circle buttons/search/white.svg'\nimport { ReactComponent as ZoomIcon } from 'src/styling/icons/circle buttons/search/zodiac.svg'\n\nimport imagePopperStyles from './ImagePopper.styles'\n\nconst useStyles = makeStyles(imagePopperStyles)\n\nconst ImagePopper = memo(\n ({ className, width, height, popupWidth, popupHeight, src }) => {\n const classes = useStyles({\n width,\n height,\n popupWidth,\n popupHeight\n })\n const [popperAnchorEl, setPopperAnchorEl] = useState(null)\n\n const handleOpenPopper = event => {\n setPopperAnchorEl(popperAnchorEl ? null : event.currentTarget)\n }\n\n const handleClosePopper = () => {\n setPopperAnchorEl(null)\n }\n\n const popperOpen = Boolean(popperAnchorEl)\n\n const Image = ({ className }) => (\n \n )\n\n return (\n \n \n \n )\n }\n)\n\nexport default ImagePopper\n","export default {\n row: {\n display: 'flex',\n flexDirection: 'row'\n },\n image: ({ width, height }) => ({\n objectFit: 'cover',\n borderRadius: '8px 0px 0px 8px',\n width,\n height\n }),\n popupImage: ({ popupWidth, popupHeight }) => ({\n objectFit: 'cover',\n width: popupWidth,\n height: popupHeight\n }),\n button: ({ height }) => ({\n borderRadius: '0px 8px 8px 0px',\n height\n }),\n popoverContent: {\n display: 'block',\n padding: [[10, 15]]\n }\n}\n","function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport * as React from \"react\";\n\nvar _ref2 = /*#__PURE__*/React.createElement(\"desc\", null, \"Created with Sketch.\");\n\nvar _ref3 = /*#__PURE__*/React.createElement(\"g\", {\n id: \"icon/crossed-camera\",\n stroke: \"none\",\n strokeWidth: 1,\n fill: \"none\",\n fillRule: \"evenodd\"\n}, /*#__PURE__*/React.createElement(\"g\", {\n id: \"crossed-camera\"\n}, /*#__PURE__*/React.createElement(\"g\", {\n id: \"Group-2\"\n}, /*#__PURE__*/React.createElement(\"g\", {\n id: \"icon/ID/cam/zodiac\",\n transform: \"translate(0.000000, 3.657143)\",\n fill: \"#1B2559\",\n fillRule: \"nonzero\"\n}, /*#__PURE__*/React.createElement(\"path\", {\n d: \"M16,19.1876029 C12.4482116,19.1876029 9.56809571,16.389776 9.56809571,12.9394673 C9.56809571,9.48915858 12.4482116,6.69133172 16,6.69133172 C19.5517884,6.69133172 22.4319043,9.48915858 22.4319043,12.9394673 C22.4319043,16.389776 19.5517884,19.1876029 16,19.1876029 Z M16,17.104891 C18.3677075,17.104891 20.2879362,15.239526 20.2879362,12.9394673 C20.2879362,10.6394086 18.3677075,8.77404358 16,8.77404358 C13.6322925,8.77404358 11.7120638,10.6394086 11.7120638,12.9394673 C11.7120638,15.239526 13.6322925,17.104891 16,17.104891 Z M22.7667469,3.30692494 L30.7397807,3.30692494 C31.3318211,3.30692494 31.8117647,3.77315587 31.8117647,4.34828087 L31.8117647,22.0513317 C31.8117647,22.6264567 31.3318211,23.0926877 30.7397807,23.0926877 L1.26021934,23.0926877 C0.6681789,23.0926877 0.188235294,22.6264567 0.188235294,22.0513317 L0.188235294,4.34828087 C0.188235294,3.77315587 0.6681789,3.30692494 1.26021934,3.30692494 L9.23325311,3.30692494 L12.0766705,0.494526627 C12.2782333,0.295162767 12.5538198,0.182857143 12.8414756,0.182857143 L19.1585244,0.182857143 C19.4461802,0.182857143 19.7217667,0.295162767 19.9233295,0.494526627 L22.7667469,3.30692494 Z M29.6677966,5.3896368 L22.3170489,5.3896368 C22.0293931,5.3896368 21.7538065,5.27733118 21.5522438,5.07796732 L18.7088264,2.26556901 L13.2911736,2.26556901 L10.4477562,5.07796732 C10.2461935,5.27733118 9.97060695,5.3896368 9.68295115,5.3896368 L2.33220339,5.3896368 L2.33220339,21.0099758 L29.6677966,21.0099758 L29.6677966,5.3896368 Z\",\n id: \"Stroke-1\"\n})), /*#__PURE__*/React.createElement(\"line\", {\n x1: 32,\n y1: 0,\n x2: 0,\n y2: 32,\n id: \"Line\",\n stroke: \"#FF584A\",\n strokeWidth: 2,\n strokeLinecap: \"square\"\n}))));\n\nfunction SvgCrossedCamera(_ref, svgRef) {\n var title = _ref.title,\n titleId = _ref.titleId,\n props = _objectWithoutProperties(_ref, [\"title\", \"titleId\"]);\n\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n width: \"32px\",\n height: \"32px\",\n viewBox: \"0 0 32 32\",\n xmlns: \"http://www.w3.org/2000/svg\",\n xmlnsXlink: \"http://www.w3.org/1999/xlink\",\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, _ref2, _ref3);\n}\n\nvar ForwardRef = /*#__PURE__*/React.forwardRef(SvgCrossedCamera);\nexport default __webpack_public_path__ + \"static/media/crossed-camera.28e8f7eb.svg\";\nexport { ForwardRef as ReactComponent };","import { makeStyles } from '@material-ui/core/styles'\nimport classnames from 'classnames'\nimport React, { memo } from 'react'\n\nimport { Info3, Label1 } from 'src/components/typography'\nimport { comet } from 'src/styling/variables'\n\nconst useStyles = makeStyles({\n field: {\n height: 46\n },\n label: {\n color: comet,\n margin: [[0, 3]]\n },\n value: {\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n margin: 0,\n paddingLeft: 4\n }\n})\n\nconst Field = memo(({ label, display, size, className }) => {\n const classes = useStyles()\n\n return (\n \n {label} \n {display} \n
\n )\n})\n\nexport default Field\n","import { Box } from '@material-ui/core'\nimport { makeStyles } from '@material-ui/core/styles'\nimport * as R from 'ramda'\nimport React from 'react'\n\nimport ImagePopper from 'src/components/ImagePopper'\nimport { H3, Info3 } from 'src/components/typography'\nimport {\n PropertyCard,\n OVERRIDE_AUTHORIZED,\n OVERRIDE_REJECTED\n} from 'src/pages/Customers/components/propertyCard'\nimport { ReactComponent as CrossedCameraIcon } from 'src/styling/icons/ID/photo/crossed-camera.svg'\nimport { URI } from 'src/utils/apollo'\n\nimport { complianceDetailsStyles } from './ComplianceDetails.styles'\nimport Field from './Field'\n\nimport { IdDataCard } from './'\n\nconst useStyles = makeStyles(complianceDetailsStyles)\n\nconst imageWidth = 165\nconst imageHeight = 45\nconst popupImageWidth = 360\nconst popupImageHeight = 240\n\nconst Photo = ({ show, src }) => {\n const classes = useStyles({ width: imageWidth })\n\n return (\n <>\n {show ? (\n \n ) : (\n \n \n
\n )}\n >\n )\n}\n\nconst ComplianceDetails = ({ customer, updateCustomer }) => {\n const classes = useStyles({ width: imageWidth })\n\n const sanctions = R.path(['sanctions'])(customer)\n const sanctionsAt = R.path(['sanctionsAt'])(customer)\n const sanctionsDisplay = !sanctionsAt\n ? 'Not checked yet'\n : sanctions\n ? 'Passed'\n : 'Failed'\n\n return (\n \n
Compliance details \n
\n
\n
\n \n \n updateCustomer({ idCardPhotoOverride: OVERRIDE_AUTHORIZED })\n }\n reject={() =>\n updateCustomer({ idCardPhotoOverride: OVERRIDE_REJECTED })\n }>\n \n \n \n updateCustomer({ frontCameraOverride: OVERRIDE_AUTHORIZED })\n }\n reject={() =>\n updateCustomer({ frontCameraOverride: OVERRIDE_REJECTED })\n }>\n \n \n \n \n \n updateCustomer({ usSsnOverride: OVERRIDE_AUTHORIZED })\n }\n reject={() =>\n updateCustomer({ usSsnOverride: OVERRIDE_REJECTED })\n }>\n \n \n \n updateCustomer({ sanctionsOverride: OVERRIDE_AUTHORIZED })\n }\n reject={() =>\n updateCustomer({ sanctionsOverride: OVERRIDE_REJECTED })\n }>\n {sanctionsDisplay} \n \n \n \n
\n
\n )\n}\n\nexport default ComplianceDetails\n","const complianceDetailsStyles = {\n complianceDetailsGrid: {\n display: 'flex',\n flexDirection: 'row'\n },\n firstColumn: {\n display: 'flex',\n flexDirection: 'column',\n width: '100%',\n marginRight: 10\n },\n lastColumn: {\n display: 'flex',\n flexDirection: 'column',\n width: '100%',\n marginLeft: 10\n },\n photoWrapper: ({ width }) => ({\n display: 'flex',\n justifyContent: 'center',\n width\n })\n}\n\nexport { complianceDetailsStyles }\n","function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport * as React from \"react\";\n\nvar _ref2 = /*#__PURE__*/React.createElement(\"desc\", null, \"Created with Sketch.\");\n\nvar _ref3 = /*#__PURE__*/React.createElement(\"g\", {\n id: \"icon/ID/card/zodiac\",\n stroke: \"none\",\n strokeWidth: 1,\n fill: \"none\",\n fillRule: \"evenodd\",\n strokeLinecap: \"round\",\n strokeLinejoin: \"round\"\n}, /*#__PURE__*/React.createElement(\"g\", {\n id: \"Group-2\",\n stroke: \"#1B2559\",\n strokeWidth: 1.6\n}, /*#__PURE__*/React.createElement(\"g\", {\n id: \"id-copy\"\n}, /*#__PURE__*/React.createElement(\"polygon\", {\n id: \"Stroke-1\",\n points: \"0 16 22 16 22 0 0 0\"\n}), /*#__PURE__*/React.createElement(\"line\", {\n x1: 11.7857143,\n y1: 4,\n x2: 18.8571429,\n y2: 4,\n id: \"Stroke-3\"\n}), /*#__PURE__*/React.createElement(\"line\", {\n x1: 11.7857143,\n y1: 7.2,\n x2: 18.8571429,\n y2: 7.2,\n id: \"Stroke-4\"\n}), /*#__PURE__*/React.createElement(\"polygon\", {\n id: \"Stroke-5\",\n points: \"3.14285714 11.2 8.64285714 11.2 8.64285714 4 3.14285714 4\"\n}))));\n\nfunction SvgZodiac(_ref, svgRef) {\n var title = _ref.title,\n titleId = _ref.titleId,\n props = _objectWithoutProperties(_ref, [\"title\", \"titleId\"]);\n\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n width: \"22px\",\n height: \"16px\",\n viewBox: \"0 0 22 16\",\n xmlns: \"http://www.w3.org/2000/svg\",\n xmlnsXlink: \"http://www.w3.org/1999/xlink\",\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, _ref2, _ref3);\n}\n\nvar ForwardRef = /*#__PURE__*/React.forwardRef(SvgZodiac);\nexport default __webpack_public_path__ + \"static/media/zodiac.05a22c3a.svg\";\nexport { ForwardRef as ReactComponent };","function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport * as React from \"react\";\n\nvar _ref2 = /*#__PURE__*/React.createElement(\"g\", {\n id: \"icon/sf-small/law/white\",\n stroke: \"none\",\n strokeWidth: 1,\n fill: \"none\",\n fillRule: \"evenodd\",\n strokeLinecap: \"round\",\n strokeLinejoin: \"bevel\"\n}, /*#__PURE__*/React.createElement(\"line\", {\n x1: 8.4141,\n y1: 7.4648,\n x2: 14.0711,\n y2: 1.8078,\n id: \"Stroke-1\",\n stroke: \"#FFFFFF\",\n strokeWidth: 2\n}), /*#__PURE__*/React.createElement(\"line\", {\n x1: 12.6568,\n y1: 0.3936,\n x2: 15.4858,\n y2: 3.2216,\n id: \"Stroke-3\",\n stroke: \"#FFFFFF\",\n strokeWidth: 2\n}), /*#__PURE__*/React.createElement(\"line\", {\n x1: 7,\n y1: 6.0498,\n x2: 9.829,\n y2: 8.8788,\n id: \"Stroke-6\",\n stroke: \"#FFFFFF\",\n strokeWidth: 2\n}), /*#__PURE__*/React.createElement(\"line\", {\n x1: 11.2427,\n y1: 4.6357,\n x2: 19.2427,\n y2: 12.6357,\n id: \"Stroke-7\",\n stroke: \"#FFFFFF\",\n strokeWidth: 2\n}), /*#__PURE__*/React.createElement(\"line\", {\n x1: 3,\n y1: 16.5,\n x2: 10,\n y2: 16.5,\n id: \"Stroke-9\",\n stroke: \"#FFFFFF\",\n strokeWidth: 2\n}), /*#__PURE__*/React.createElement(\"line\", {\n x1: 0,\n y1: 19.5,\n x2: 13,\n y2: 19.5,\n id: \"Stroke-10\",\n stroke: \"#FFFFFF\",\n strokeWidth: 2\n}));\n\nfunction SvgWhite(_ref, svgRef) {\n var title = _ref.title,\n titleId = _ref.titleId,\n props = _objectWithoutProperties(_ref, [\"title\", \"titleId\"]);\n\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n width: \"20px\",\n height: \"20px\",\n viewBox: \"0 0 20 20\",\n xmlns: \"http://www.w3.org/2000/svg\",\n xmlnsXlink: \"http://www.w3.org/1999/xlink\",\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, _ref2);\n}\n\nvar ForwardRef = /*#__PURE__*/React.forwardRef(SvgWhite);\nexport default __webpack_public_path__ + \"static/media/white.06f073be.svg\";\nexport { ForwardRef as ReactComponent };","function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport * as React from \"react\";\n\nvar _ref2 = /*#__PURE__*/React.createElement(\"g\", {\n id: \"icon/sf-small/law/zodiac\",\n stroke: \"none\",\n strokeWidth: 1,\n fill: \"none\",\n fillRule: \"evenodd\",\n strokeLinecap: \"round\",\n strokeLinejoin: \"bevel\"\n}, /*#__PURE__*/React.createElement(\"line\", {\n x1: 8.4141,\n y1: 7.4648,\n x2: 14.0711,\n y2: 1.8078,\n id: \"Stroke-1\",\n stroke: \"#1B2559\",\n strokeWidth: 2\n}), /*#__PURE__*/React.createElement(\"line\", {\n x1: 12.6568,\n y1: 0.3936,\n x2: 15.4858,\n y2: 3.2216,\n id: \"Stroke-3\",\n stroke: \"#1B2559\",\n strokeWidth: 2\n}), /*#__PURE__*/React.createElement(\"line\", {\n x1: 7,\n y1: 6.0498,\n x2: 9.829,\n y2: 8.8788,\n id: \"Stroke-6\",\n stroke: \"#1B2559\",\n strokeWidth: 2\n}), /*#__PURE__*/React.createElement(\"line\", {\n x1: 11.2427,\n y1: 4.6357,\n x2: 19.2427,\n y2: 12.6357,\n id: \"Stroke-7\",\n stroke: \"#1B2559\",\n strokeWidth: 2\n}), /*#__PURE__*/React.createElement(\"line\", {\n x1: 3,\n y1: 16.5,\n x2: 10,\n y2: 16.5,\n id: \"Stroke-9\",\n stroke: \"#1B2559\",\n strokeWidth: 2\n}), /*#__PURE__*/React.createElement(\"line\", {\n x1: 0,\n y1: 19.5,\n x2: 13,\n y2: 19.5,\n id: \"Stroke-10\",\n stroke: \"#1B2559\",\n strokeWidth: 2\n}));\n\nfunction SvgZodiac(_ref, svgRef) {\n var title = _ref.title,\n titleId = _ref.titleId,\n props = _objectWithoutProperties(_ref, [\"title\", \"titleId\"]);\n\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n width: \"20px\",\n height: \"20px\",\n viewBox: \"0 0 20 20\",\n xmlns: \"http://www.w3.org/2000/svg\",\n xmlnsXlink: \"http://www.w3.org/1999/xlink\",\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, _ref2);\n}\n\nvar ForwardRef = /*#__PURE__*/React.forwardRef(SvgZodiac);\nexport default __webpack_public_path__ + \"static/media/zodiac.96d45453.svg\";\nexport { ForwardRef as ReactComponent };","import typographyStyles from 'src/components/typography/styles'\nimport baseStyles from 'src/pages/Logs.styles'\nimport { zircon, comet, primaryColor, fontSize4 } from 'src/styling/variables'\n\nconst { label1 } = typographyStyles\nconst { titleWrapper, titleAndButtonsContainer } = baseStyles\n\nexport default {\n titleWrapper,\n titleAndButtonsContainer,\n row: {\n display: 'flex',\n flexFlow: 'row nowrap'\n },\n rowSpaceBetween: {\n display: 'flex',\n flexFlow: 'row nowrap',\n alignItems: 'center',\n justifyContent: 'space-between'\n },\n column: {\n display: 'flex',\n flexFlow: 'column nowrap',\n width: '100%',\n height: '100%',\n justifyContent: 'space-between'\n },\n textInput: {\n width: 144\n },\n p: {\n fontFamily: 'MuseoSans',\n fontSize: fontSize4,\n fontWeight: 500,\n fontStretch: 'normal',\n fontStyle: 'normal',\n lineHeight: 1.14,\n letterSpacing: 'normal',\n color: primaryColor\n },\n txId: {\n fontFamily: 'MuseoSans',\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis'\n },\n txClassIconLeft: {\n marginRight: 11\n },\n txClassIconRight: {\n marginLeft: 11\n },\n headerLabels: {\n display: 'flex',\n flexDirection: 'row',\n '& div': {\n display: 'flex',\n alignItems: 'center'\n },\n '& > div:first-child': {\n marginRight: 24\n },\n '& span': {\n extend: label1,\n marginLeft: 6\n }\n },\n photo: {\n width: 92,\n height: 92,\n borderRadius: 8,\n backgroundColor: zircon,\n margin: [[0, 28, 0, 0]],\n alignItems: 'center',\n justifyContent: 'center',\n display: 'flex'\n },\n img: {\n width: 80\n },\n customerName: {\n marginBottom: 32\n },\n icon: {\n marginRight: 11\n },\n name: {\n display: 'flex',\n flexDirection: 'row',\n alignItems: 'center'\n },\n value: {\n height: 16\n },\n label: {\n marginBottom: 4,\n color: comet\n },\n idIcon: {\n marginRight: 10\n },\n subpageButton: {\n marginLeft: 16\n }\n}\n","import { parsePhoneNumberFromString } from 'libphonenumber-js'\nimport * as R from 'ramda'\n\nconst CUSTOMER_BLOCKED = 'blocked'\n\nconst getAuthorizedStatus = it =>\n it.authorizedOverride === CUSTOMER_BLOCKED\n ? { label: 'Blocked', type: 'error' }\n : it.isSuspended\n ? it.daysSuspended > 0\n ? { label: `${it.daysSuspended} day suspension`, type: 'warning' }\n : { label: `< 1 day suspension`, type: 'warning' }\n : { label: 'Authorized', type: 'success' }\n\nconst getFormattedPhone = (phone, country) => {\n const phoneNumber =\n phone && country ? parsePhoneNumberFromString(phone, country) : null\n\n return phoneNumber ? phoneNumber.formatInternational() : phone\n}\n\nconst getName = it => {\n const idData = R.path(['idCardData'])(it)\n\n return `${R.path(['firstName'])(idData) ?? ''} ${R.path(['lastName'])(\n idData\n ) ?? ''}`.trim()\n}\n\nexport { getAuthorizedStatus, getFormattedPhone, getName }\n","import { Paper } from '@material-ui/core'\nimport { makeStyles } from '@material-ui/core/styles'\nimport React, { memo } from 'react'\n\nimport { ReactComponent as CrossedCameraIcon } from 'src/styling/icons/ID/photo/crossed-camera.svg'\nimport { URI } from 'src/utils/apollo'\n\nimport mainStyles from '../CustomersList.styles'\n\nconst useStyles = makeStyles(mainStyles)\n\nconst FrontCameraPhoto = memo(({ frontCameraPath }) => {\n const classes = useStyles()\n\n return (\n \n {frontCameraPath ? (\n \n ) : (\n \n )}\n \n )\n})\n\nexport default FrontCameraPhoto\n","import { makeStyles, Box } from '@material-ui/core'\nimport * as R from 'ramda'\nimport React, { memo } from 'react'\n\nimport { SubpageButton } from 'src/components/buttons'\nimport { H2, Label1, P } from 'src/components/typography'\nimport { ReactComponent as IdIcon } from 'src/styling/icons/ID/card/zodiac.svg'\nimport { ReactComponent as LawIconInverse } from 'src/styling/icons/circle buttons/law/white.svg'\nimport { ReactComponent as LawIcon } from 'src/styling/icons/circle buttons/law/zodiac.svg'\n\nimport mainStyles from '../CustomersList.styles'\nimport { getFormattedPhone, getName } from '../helper'\n\nimport FrontCameraPhoto from './FrontCameraPhoto'\n\nconst useStyles = makeStyles(mainStyles)\n\nconst CustomerDetails = memo(({ customer, locale, setShowCompliance }) => {\n const classes = useStyles()\n\n const elements = [\n {\n header: 'Phone number',\n size: 172,\n value: getFormattedPhone(customer.phone, locale.country)\n },\n {\n header: 'ID number',\n size: 172,\n value: R.path(['idCardData', 'documentNumber'])(customer) ?? ''\n },\n {\n header: 'US SSN',\n size: 127,\n value: R.path(['usSsn'])(customer) ?? ''\n }\n ]\n\n const name = getName(customer)\n\n return (\n \n \n \n \n \n
\n {name.length\n ? name\n : getFormattedPhone(R.path(['phone'])(customer), locale.country)}\n \n \n Compliance details\n \n \n \n {elements.map(({ size, header }, idx) => (\n \n {header}\n \n ))}\n \n \n {elements.map(({ size, value }, idx) => (\n \n {value}\n
\n ))}\n \n \n \n )\n})\n\nexport default CustomerDetails\n","import * as R from 'ramda'\n\nconst ifNotNull = (value, valueIfNotNull) => {\n return R.isNil(value) ? '' : valueIfNotNull\n}\n\nexport { ifNotNull }\n","import { Box } from '@material-ui/core'\nimport moment from 'moment'\nimport * as R from 'ramda'\nimport React, { memo } from 'react'\n\nimport {\n PropertyCard,\n OVERRIDE_AUTHORIZED,\n OVERRIDE_REJECTED\n} from 'src/pages/Customers/components/propertyCard'\nimport { ifNotNull } from 'src/utils/nullCheck'\n\nimport { getName } from '../helper'\n\nimport Field from './Field'\n\nconst IdDataCard = memo(({ customerData, updateCustomer }) => {\n const idData = R.path(['idCardData'])(customerData)\n const rawExpirationDate = R.path(['expirationDate'])(idData)\n const country = R.path(['country'])(idData)\n const rawDob = R.path(['dateOfBirth'])(idData)\n\n const elements = [\n {\n header: 'Name',\n display: `${getName(customerData)}`,\n size: 190\n },\n {\n header: 'ID number',\n display: R.path(['documentNumber'])(idData),\n size: 160\n },\n {\n header: 'Birth Date',\n display: ifNotNull(rawDob, moment.utc(rawDob).format('YYYY-MM-DD')),\n size: 110\n },\n {\n header: 'Age',\n display: ifNotNull(\n rawDob,\n moment.utc().diff(moment.utc(rawDob).format('YYYY-MM-DD'), 'years')\n ),\n size: 50\n },\n {\n header: 'Gender',\n display: R.path(['gender'])(idData) ?? R.path(['sex'])(idData),\n size: 80\n },\n {\n header: country === 'Canada' ? 'Province' : 'State',\n display: R.path(['state'])(idData),\n size: 120\n },\n {\n header: 'Expiration Date',\n display: ifNotNull(\n rawExpirationDate,\n moment.utc(rawExpirationDate).format('YYYY-MM-DD')\n )\n }\n ]\n\n return (\n \n updateCustomer({ idCardDataOverride: OVERRIDE_AUTHORIZED })\n }\n reject={() => updateCustomer({ idCardDataOverride: OVERRIDE_REJECTED })}>\n \n {elements.map(({ header, display, size }, idx) => (\n \n ))}\n \n \n )\n})\n\nexport default IdDataCard\n","import * as R from 'ramda'\n\nconst CRYPTO_CURRENCIES = [\n {\n cryptoCode: 'BTC',\n display: 'Bitcoin',\n code: 'bitcoin',\n unitScale: 8\n },\n {\n cryptoCode: 'ETH',\n display: 'Ethereum',\n code: 'ethereum',\n unitScale: 18\n },\n {\n cryptoCode: 'LTC',\n display: 'Litecoin',\n code: 'litecoin',\n unitScale: 8\n },\n {\n cryptoCode: 'DASH',\n display: 'Dash',\n code: 'dash',\n unitScale: 8\n },\n {\n cryptoCode: 'ZEC',\n display: 'Zcash',\n code: 'zcash',\n unitScale: 8\n },\n {\n cryptoCode: 'BCH',\n display: 'Bitcoin Cash',\n code: 'bitcoincash',\n unitScale: 8\n }\n]\n\nfunction getCryptoCurrency(cryptoCode) {\n const coin = R.find(R.propEq('cryptoCode', cryptoCode))(CRYPTO_CURRENCIES)\n\n if (!coin) throw new Error(`Unsupported crypto: ${cryptoCode}`)\n return coin\n}\n\nfunction toUnit(cryptoAtoms, cryptoCode) {\n const cryptoRec = getCryptoCurrency(cryptoCode)\n const unitScale = cryptoRec.unitScale\n return cryptoAtoms.shiftedBy(-unitScale)\n}\n\nfunction formatCryptoAddress(cryptoCode = '', address = '') {\n return cryptoCode === 'BCH' ? address.replace('bitcoincash:', '') : address\n}\n\nexport { toUnit, formatCryptoAddress }\n","import { makeStyles, Box } from '@material-ui/core'\nimport BigNumber from 'bignumber.js'\nimport moment from 'moment'\nimport * as R from 'ramda'\nimport React from 'react'\n\nimport DataTable from 'src/components/tables/DataTable'\nimport { H3, H4, Label1, Label2, P } from 'src/components/typography'\nimport { ReactComponent as TxInIcon } from 'src/styling/icons/direction/cash-in.svg'\nimport { ReactComponent as TxOutIcon } from 'src/styling/icons/direction/cash-out.svg'\nimport { toUnit } from 'src/utils/coin'\nimport { ifNotNull } from 'src/utils/nullCheck'\n\nimport CopyToClipboard from '../../Transactions/CopyToClipboard'\nimport mainStyles from '../CustomersList.styles'\n\nconst useStyles = makeStyles(mainStyles)\n\nconst TransactionsList = ({ customer, data, loading }) => {\n const classes = useStyles()\n const LastTxIcon = customer.lastTxClass === 'cashOut' ? TxOutIcon : TxInIcon\n const hasData = !(R.isEmpty(data) || R.isNil(data))\n\n const summaryElements = [\n {\n header: 'Transactions',\n size: 127,\n value: ifNotNull(\n customer.totalTxs,\n `${Number.parseInt(customer.totalTxs)}`\n )\n },\n {\n header: 'Transaction volume',\n size: 167,\n value: ifNotNull(\n customer.totalSpent,\n `${Number.parseFloat(customer.totalSpent)} ${customer.lastTxFiatCode}`\n )\n },\n {\n header: 'Last active',\n size: 142,\n value: ifNotNull(\n customer.lastActive,\n moment.utc(customer.lastActive).format('YYYY-MM-D')\n )\n },\n {\n header: 'Last transaction',\n size: 198,\n value: ifNotNull(\n customer.lastTxFiat,\n <>\n \n {`${Number.parseFloat(customer.lastTxFiat)} \n ${customer.lastTxFiatCode}`}\n >\n )\n }\n ]\n\n const tableElements = [\n {\n header: 'Direction',\n width: 207,\n view: it => (\n <>\n {it.txClass === 'cashOut' ? (\n \n ) : (\n \n )}\n {it.txClass === 'cashOut' ? 'Cash-out' : 'Cash-in'}\n >\n )\n },\n {\n header: 'Transaction ID',\n width: 414,\n view: it => (\n {it.id} \n )\n },\n {\n header: 'Cash',\n width: 146,\n textAlign: 'right',\n view: it => (\n <>\n {`${Number.parseFloat(it.fiat)} `}\n {it.fiatCode} \n >\n )\n },\n {\n header: 'Crypto',\n width: 142,\n textAlign: 'right',\n view: it => (\n <>\n {`${toUnit(new BigNumber(it.cryptoAtoms), it.cryptoCode).toFormat(\n 5\n )} `}\n {it.cryptoCode} \n >\n )\n },\n {\n header: 'Date',\n width: 157,\n view: it => moment.utc(it.created).format('YYYY-MM-D')\n },\n {\n header: 'Time (h:m:s)',\n width: 134,\n view: it => moment.utc(it.created).format('hh:mm:ss')\n }\n ]\n\n return (\n <>\n Transactions \n \n \n {summaryElements.map(({ size, header }, idx) => (\n \n {header}\n \n ))}\n \n \n {summaryElements.map(({ size, value }, idx) => (\n \n {value}\n
\n ))}\n \n \n \n
\n
\n {loading\n ? 'Loading'\n : hasData\n ? 'All transactions from this customer'\n : 'No transactions so far'}\n \n \n
\n {hasData && }\n >\n )\n}\n\nexport default TransactionsList\n","import { useQuery, useMutation } from '@apollo/react-hooks'\nimport { makeStyles, Breadcrumbs, Box } from '@material-ui/core'\nimport NavigateNextIcon from '@material-ui/icons/NavigateNext'\nimport gql from 'graphql-tag'\nimport * as R from 'ramda'\nimport React, { memo, useState } from 'react'\nimport { useHistory, useParams } from 'react-router-dom'\n\nimport { ActionButton } from 'src/components/buttons'\nimport { Label1, Label2 } from 'src/components/typography'\nimport {\n OVERRIDE_AUTHORIZED,\n OVERRIDE_REJECTED\n} from 'src/pages/Customers/components/propertyCard'\nimport { ReactComponent as AuthorizeReversedIcon } from 'src/styling/icons/button/authorize/white.svg'\nimport { ReactComponent as AuthorizeIcon } from 'src/styling/icons/button/authorize/zodiac.svg'\nimport { ReactComponent as BlockReversedIcon } from 'src/styling/icons/button/block/white.svg'\nimport { ReactComponent as BlockIcon } from 'src/styling/icons/button/block/zodiac.svg'\nimport { fromNamespace, namespaces } from 'src/utils/config'\n\nimport styles from './CustomerProfile.styles'\nimport {\n CustomerDetails,\n TransactionsList,\n ComplianceDetails\n} from './components'\nimport { getFormattedPhone, getName } from './helper'\n\nconst useStyles = makeStyles(styles)\n\nconst GET_CUSTOMER = gql`\n query customer($customerId: ID!) {\n config\n customer(customerId: $customerId) {\n id\n authorizedOverride\n frontCameraPath\n frontCameraOverride\n phone\n isAnonymous\n smsOverride\n idCardData\n idCardDataOverride\n idCardDataExpiration\n idCardPhotoPath\n idCardPhotoOverride\n usSsn\n usSsnOverride\n sanctions\n sanctionsAt\n sanctionsOverride\n totalTxs\n totalSpent\n lastActive\n lastTxFiat\n lastTxFiatCode\n lastTxClass\n daysSuspended\n isSuspended\n transactions {\n txClass\n id\n fiat\n fiatCode\n cryptoAtoms\n cryptoCode\n created\n errorMessage: error\n error: errorCode\n }\n }\n }\n`\n\nconst SET_CUSTOMER = gql`\n mutation setCustomer($customerId: ID!, $customerInput: CustomerInput) {\n setCustomer(customerId: $customerId, customerInput: $customerInput) {\n id\n authorizedOverride\n frontCameraPath\n frontCameraOverride\n phone\n smsOverride\n idCardData\n idCardDataOverride\n idCardDataExpiration\n idCardPhotoPath\n idCardPhotoOverride\n usSsn\n usSsnOverride\n sanctions\n sanctionsAt\n sanctionsOverride\n totalTxs\n totalSpent\n lastActive\n lastTxFiat\n lastTxFiatCode\n lastTxClass\n }\n }\n`\n\nconst CustomerProfile = memo(() => {\n const classes = useStyles()\n const history = useHistory()\n const [showCompliance, setShowCompliance] = useState(false)\n const { id: customerId } = useParams()\n\n const { data: customerResponse, refetch: getCustomer, loading } = useQuery(\n GET_CUSTOMER,\n {\n variables: { customerId }\n }\n )\n\n const [setCustomer] = useMutation(SET_CUSTOMER, {\n onCompleted: () => getCustomer()\n })\n\n const updateCustomer = it =>\n setCustomer({\n variables: {\n customerId,\n customerInput: it\n }\n })\n\n const configData = R.path(['config'])(customerResponse) ?? []\n const locale = configData && fromNamespace(namespaces.LOCALE, configData)\n const customerData = R.path(['customer'])(customerResponse) ?? []\n const rawTransactions = R.path(['transactions'])(customerData) ?? []\n const sortedTransactions = R.sort(R.descend(R.prop('cryptoAtoms')))(\n rawTransactions\n )\n const name = getName(customerData)\n const blocked =\n R.path(['authorizedOverride'])(customerData) === OVERRIDE_REJECTED\n\n const isSuspended = customerData.isSuspended\n\n return (\n <>\n }\n aria-label=\"breadcrumb\">\n history.push('/compliance/customers')}>\n Customers\n \n \n {name.length\n ? name\n : getFormattedPhone(\n R.path(['phone'])(customerData),\n locale.country\n )}\n \n \n \n
\n setShowCompliance(!showCompliance)}\n />\n {!loading && !customerData.isAnonymous && (\n \n
Actions \n
\n {isSuspended && (\n
\n updateCustomer({\n suspendedUntil: null\n })\n }>\n {`Unsuspend customer`}\n \n )}\n
\n updateCustomer({\n authorizedOverride: blocked\n ? OVERRIDE_AUTHORIZED\n : OVERRIDE_REJECTED\n })\n }>\n {`${blocked ? 'Authorize' : 'Block'} customer`}\n \n
\n
\n )}\n \n
\n {!showCompliance && (\n \n )}\n {showCompliance && (\n \n )}\n >\n )\n})\n\nexport default CustomerProfile\n","import { makeStyles } from '@material-ui/core/styles'\nimport moment from 'moment'\nimport * as R from 'ramda'\nimport React from 'react'\n\nimport { MainStatus } from 'src/components/Status'\nimport TitleSection from 'src/components/layout/TitleSection'\nimport DataTable from 'src/components/tables/DataTable'\nimport { ReactComponent as TxInIcon } from 'src/styling/icons/direction/cash-in.svg'\nimport { ReactComponent as TxOutIcon } from 'src/styling/icons/direction/cash-out.svg'\nimport { ifNotNull } from 'src/utils/nullCheck'\n\nimport styles from './CustomersList.styles'\nimport { getAuthorizedStatus, getFormattedPhone, getName } from './helper'\n\nconst useStyles = makeStyles(styles)\n\nconst CustomersList = ({ data, locale, onClick, loading }) => {\n const classes = useStyles()\n\n const elements = [\n {\n header: 'Phone',\n width: 172,\n view: it => getFormattedPhone(it.phone, locale.country)\n },\n {\n header: 'Name',\n width: 241,\n view: getName\n },\n {\n header: 'Total TXs',\n width: 126,\n textAlign: 'right',\n view: it => `${Number.parseInt(it.totalTxs)}`\n },\n {\n header: 'Total spent',\n width: 152,\n textAlign: 'right',\n view: it =>\n `${Number.parseFloat(it.totalSpent)} ${it.lastTxFiatCode ?? ''}`\n },\n {\n header: 'Last active',\n width: 133,\n view: it =>\n ifNotNull(it.lastActive, moment.utc(it.lastActive).format('YYYY-MM-D'))\n },\n {\n header: 'Last transaction',\n width: 161,\n textAlign: 'right',\n view: it => {\n const hasLastTx = !R.isNil(it.lastTxFiatCode)\n const LastTxIcon = it.lastTxClass === 'cashOut' ? TxOutIcon : TxInIcon\n const lastIcon = \n return (\n <>\n {hasLastTx &&\n `${parseFloat(it.lastTxFiat)} ${it.lastTxFiatCode ?? ''}`}\n {hasLastTx && lastIcon}\n >\n )\n }\n },\n {\n header: 'Status',\n width: 188,\n view: it => \n }\n ]\n\n return (\n <>\n },\n { label: 'Cash-out', icon: }\n ]}\n />\n \n >\n )\n}\n\nexport default CustomersList\n","import { useQuery } from '@apollo/react-hooks'\nimport gql from 'graphql-tag'\nimport * as R from 'ramda'\nimport React from 'react'\nimport { useHistory } from 'react-router-dom'\n\nimport { fromNamespace, namespaces } from 'src/utils/config'\n\nimport CustomersList from './CustomersList'\n\nconst GET_CUSTOMERS = gql`\n {\n config\n customers {\n id\n idCardData\n phone\n totalTxs\n totalSpent\n lastActive\n lastTxFiat\n lastTxFiatCode\n lastTxClass\n authorizedOverride\n daysSuspended\n isSuspended\n }\n }\n`\n\nconst Customers = () => {\n const history = useHistory()\n const { data: customersResponse, loading } = useQuery(GET_CUSTOMERS)\n\n const handleCustomerClicked = customer =>\n history.push(`/compliance/customer/${customer.id}`)\n\n const configData = R.path(['config'])(customersResponse) ?? []\n const locale = configData && fromNamespace(namespaces.LOCALE, configData)\n const customersData = R.sortWith([R.descend(R.prop('lastActive'))])(\n R.path(['customers'])(customersResponse) ?? []\n )\n\n return (\n \n )\n}\n\nexport default Customers\n","import typographyStyles from 'src/components/typography/styles'\nimport { spacer, white, primaryColor } from 'src/styling/variables'\nconst { label1 } = typographyStyles\n\nconst styles = {\n headerLabels: {\n display: 'flex',\n flexDirection: 'row'\n },\n headerLabelContainerMargin: {\n marginRight: 24\n },\n headerLabelContainer: {\n display: 'flex',\n alignItems: 'center'\n },\n headerLabelSpan: {\n extend: label1,\n marginLeft: 6\n },\n root: {\n flexGrow: 1,\n display: 'flex',\n marginBottom: 120\n },\n card: {\n wordWrap: 'break-word',\n boxShadow: '0 0 4px 0 rgba(0, 0, 0, 0.08)',\n borderRadius: 12,\n padding: 24,\n backgroundColor: white,\n flex: 1,\n marginRight: 24\n },\n container: {\n display: 'flex',\n justifyContent: 'space-between'\n },\n button: {\n color: primaryColor,\n minHeight: 0,\n minWidth: 0,\n padding: 0,\n textTransform: 'none',\n '&:hover': {\n backgroundColor: 'transparent'\n }\n },\n upperButtonLabel: {\n textAlign: 'center',\n marginBottom: 0,\n marginTop: 0,\n marginLeft: spacer\n },\n alertsCard: {\n marginBottom: spacer\n },\n h4: {\n marginTop: 0\n },\n centerLabel: {\n marginTop: 40,\n marginBottom: 0\n },\n systemStatusCard: {\n flex: 1,\n marginTop: spacer\n },\n expandedCard: {\n flex: 0.9\n },\n shrunkCard: {\n flex: 0.1\n },\n displayFlex: {\n display: 'flex',\n flexDirection: 'column'\n }\n}\n\nexport default styles\n","import { offColor, white, spacer } from 'src/styling/variables'\n\nconst styles = {\n label: {\n color: offColor\n },\n headerLabels: {\n whiteSpace: 'pre',\n display: 'flex',\n flexDirection: 'row',\n marginTop: -20\n },\n headerLabel: {\n display: 'flex',\n alignItems: 'center'\n },\n txOutMargin: {\n marginLeft: spacer * 3\n },\n footer: ({ expanded, bigFooter }) => ({\n height:\n expanded && bigFooter\n ? spacer * 12 * 3 + spacer * 3\n : expanded\n ? spacer * 12 * 2 + spacer * 2\n : spacer * 12,\n left: 0,\n bottom: 0,\n position: 'fixed',\n width: '100vw',\n backgroundColor: white,\n textAlign: 'left',\n boxShadow: '0px -1px 10px 0px rgba(50, 50, 50, 0.1)'\n }),\n tickerLabel: {\n color: offColor,\n marginTop: -5\n },\n content: {\n width: 1200,\n backgroundColor: white,\n zIndex: 1,\n position: 'fixed',\n bottom: -spacer,\n transform: 'translateY(-100%)'\n },\n footerContainer: ({ expanded, bigFooter }) => ({\n marginLeft: spacer * 5,\n height: 100,\n marginTop: expanded && bigFooter ? -300 : expanded ? -200 : -100,\n overflow: !expanded && 'hidden'\n }),\n mouseWatcher: ({ expanded, bigFooter }) => ({\n position: 'fixed',\n bottom: 0,\n left: 0,\n width: '100vw',\n height:\n expanded && bigFooter\n ? spacer * 12 * 3 + spacer * 3\n : expanded\n ? spacer * 12 * 2 + spacer * 2\n : spacer * 12,\n zIndex: 2\n })\n}\n\nexport default styles\n","import { useQuery } from '@apollo/react-hooks'\nimport { makeStyles } from '@material-ui/core'\nimport Grid from '@material-ui/core/Grid'\nimport BigNumber from 'bignumber.js'\nimport classnames from 'classnames'\nimport gql from 'graphql-tag'\nimport * as R from 'ramda'\nimport React, { useState } from 'react'\n\nimport { Label2 } from 'src/components/typography'\nimport { ReactComponent as TxInIcon } from 'src/styling/icons/direction/cash-in.svg'\nimport { ReactComponent as TxOutIcon } from 'src/styling/icons/direction/cash-out.svg'\nimport { fromNamespace } from 'src/utils/config'\n\nimport styles from './Footer.styles'\nconst GET_DATA = gql`\n query getData {\n cryptoRates\n cryptoCurrencies {\n code\n display\n }\n config\n accountsConfig {\n code\n display\n }\n }\n`\nBigNumber.config({ ROUNDING_MODE: BigNumber.ROUND_HALF_UP })\n\nconst useStyles = makeStyles(styles)\nconst Footer = () => {\n const { data } = useQuery(GET_DATA)\n const [expanded, setExpanded] = useState(false)\n const [delayedExpand, setDelayedExpand] = useState(null)\n\n const withCommissions = R.path(['cryptoRates', 'withCommissions'])(data) ?? {}\n const classes = useStyles({\n bigFooter: R.keys(withCommissions).length > 8,\n expanded\n })\n const config = R.path(['config'])(data) ?? {}\n const canExpand = R.keys(withCommissions).length > 4\n\n const wallets = fromNamespace('wallets')(config)\n const cryptoCurrencies = R.path(['cryptoCurrencies'])(data) ?? []\n const accountsConfig = R.path(['accountsConfig'])(data) ?? []\n const localeFiatCurrency = R.path(['locale_fiatCurrency'])(config) ?? ''\n\n const renderFooterItem = key => {\n const idx = R.findIndex(R.propEq('code', key))(cryptoCurrencies)\n const tickerCode = wallets[`${key}_ticker`]\n const tickerIdx = R.findIndex(R.propEq('code', tickerCode))(accountsConfig)\n\n const tickerName = tickerIdx > -1 ? accountsConfig[tickerIdx].display : ''\n\n const cashInNoCommission = parseFloat(\n R.path(['cryptoRates', 'withoutCommissions', key, 'cashIn'])(data)\n )\n const cashOutNoCommission = parseFloat(\n R.path(['cryptoRates', 'withoutCommissions', key, 'cashOut'])(data)\n )\n\n const avgOfAskBid = new BigNumber(\n (cashInNoCommission + cashOutNoCommission) / 2\n ).toFormat(2)\n const cashIn = new BigNumber(\n parseFloat(\n R.path(['cryptoRates', 'withCommissions', key, 'cashIn'])(data)\n )\n ).toFormat(2)\n const cashOut = new BigNumber(\n parseFloat(\n R.path(['cryptoRates', 'withCommissions', key, 'cashOut'])(data)\n )\n ).toFormat(2)\n\n return (\n \n \n {cryptoCurrencies[idx].display}\n \n \n
\n \n {` ${cashIn} ${localeFiatCurrency}`} \n
\n
\n \n {` ${cashOut} ${localeFiatCurrency}`} \n
\n
\n {`${tickerName}: ${avgOfAskBid} ${localeFiatCurrency}`} \n \n )\n }\n\n const handleMouseEnter = () => {\n setDelayedExpand(setTimeout(() => canExpand && setExpanded(true), 300))\n }\n\n const handleMouseLeave = () => {\n clearTimeout(delayedExpand)\n setExpanded(false)\n }\n\n return (\n <>\n
\n \n \n \n {R.keys(withCommissions).map(key => renderFooterItem(key))}\n \n \n
\n
\n >\n )\n}\n\nexport default Footer\n","import Footer from './Footer'\nexport default Footer\n","function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport * as React from \"react\";\n\nvar _ref2 = /*#__PURE__*/React.createElement(\"g\", {\n id: \"icon/label/icon/down\",\n stroke: \"none\",\n strokeWidth: 1,\n fill: \"none\",\n fillRule: \"evenodd\"\n}, /*#__PURE__*/React.createElement(\"g\", {\n id: \"Group-6\"\n}, /*#__PURE__*/React.createElement(\"circle\", {\n id: \"Oval\",\n fill: \"#FFECEB\",\n cx: 6,\n cy: 6,\n r: 6\n}), /*#__PURE__*/React.createElement(\"g\", {\n id: \"Group-5\",\n transform: \"translate(6.096194, 6.096194) rotate(-315.000000) translate(-6.096194, -6.096194) translate(2.596194, 3.096194)\",\n stroke: \"#FF584A\"\n}, /*#__PURE__*/React.createElement(\"polyline\", {\n id: \"Path-2\",\n points: \"3.15780333 -4.54747351e-13 6.15780333 2.82998193 3.15780333 5.65996386\"\n}), /*#__PURE__*/React.createElement(\"line\", {\n x1: 5.42178888,\n y1: 2.82998193,\n x2: -5.45696821e-13,\n y2: 2.82998193,\n id: \"Path-3\"\n}))));\n\nfunction SvgDown(_ref, svgRef) {\n var title = _ref.title,\n titleId = _ref.titleId,\n props = _objectWithoutProperties(_ref, [\"title\", \"titleId\"]);\n\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n width: \"12px\",\n height: \"12px\",\n viewBox: \"0 0 12 12\",\n xmlns: \"http://www.w3.org/2000/svg\",\n xmlnsXlink: \"http://www.w3.org/1999/xlink\",\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, _ref2);\n}\n\nvar ForwardRef = /*#__PURE__*/React.forwardRef(SvgDown);\nexport default __webpack_public_path__ + \"static/media/down.919a0c2a.svg\";\nexport { ForwardRef as ReactComponent };","function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport * as React from \"react\";\n\nvar _ref2 = /*#__PURE__*/React.createElement(\"g\", {\n id: \"icon/label/icon/equal\",\n stroke: \"none\",\n strokeWidth: 1,\n fill: \"none\",\n fillRule: \"evenodd\"\n}, /*#__PURE__*/React.createElement(\"g\", {\n id: \"Group-6\",\n fill: \"#EBEFFF\"\n}, /*#__PURE__*/React.createElement(\"circle\", {\n id: \"Oval\",\n cx: 6,\n cy: 6,\n r: 6\n})), /*#__PURE__*/React.createElement(\"g\", {\n id: \"Group\",\n transform: \"translate(4.000000, 4.000000)\",\n stroke: \"#5F668A\",\n strokeLinecap: \"square\"\n}, /*#__PURE__*/React.createElement(\"line\", {\n x1: 0,\n y1: 1,\n x2: 4,\n y2: 1,\n id: \"Line-12\"\n}), /*#__PURE__*/React.createElement(\"line\", {\n x1: 0,\n y1: 3,\n x2: 4,\n y2: 3,\n id: \"Line-12\"\n})));\n\nfunction SvgEqual(_ref, svgRef) {\n var title = _ref.title,\n titleId = _ref.titleId,\n props = _objectWithoutProperties(_ref, [\"title\", \"titleId\"]);\n\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n width: \"12px\",\n height: \"12px\",\n viewBox: \"0 0 12 12\",\n xmlns: \"http://www.w3.org/2000/svg\",\n xmlnsXlink: \"http://www.w3.org/1999/xlink\",\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, _ref2);\n}\n\nvar ForwardRef = /*#__PURE__*/React.forwardRef(SvgEqual);\nexport default __webpack_public_path__ + \"static/media/equal.f4103789.svg\";\nexport { ForwardRef as ReactComponent };","function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport * as React from \"react\";\n\nvar _ref2 = /*#__PURE__*/React.createElement(\"g\", {\n id: \"icon/label/icon/up\",\n stroke: \"none\",\n strokeWidth: 1,\n fill: \"none\",\n fillRule: \"evenodd\"\n}, /*#__PURE__*/React.createElement(\"g\", {\n id: \"Group-6\"\n}, /*#__PURE__*/React.createElement(\"circle\", {\n id: \"Oval\",\n fill: \"#ECFBEF\",\n cx: 6,\n cy: 6,\n r: 6\n}), /*#__PURE__*/React.createElement(\"g\", {\n id: \"Group-5\",\n transform: \"translate(6.096194, 6.096194) rotate(-45.000000) translate(-6.096194, -6.096194) translate(2.596194, 3.096194)\",\n stroke: \"#00CD5A\"\n}, /*#__PURE__*/React.createElement(\"polyline\", {\n id: \"Path-2\",\n points: \"3.15780333 -4.54747351e-13 6.15780333 2.82998193 3.15780333 5.65996386\"\n}), /*#__PURE__*/React.createElement(\"line\", {\n x1: 5.42178888,\n y1: 2.82998193,\n x2: -5.45696821e-13,\n y2: 2.82998193,\n id: \"Path-3\"\n}))));\n\nfunction SvgUp(_ref, svgRef) {\n var title = _ref.title,\n titleId = _ref.titleId,\n props = _objectWithoutProperties(_ref, [\"title\", \"titleId\"]);\n\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n width: \"12px\",\n height: \"12px\",\n viewBox: \"0 0 12 12\",\n xmlns: \"http://www.w3.org/2000/svg\",\n xmlnsXlink: \"http://www.w3.org/1999/xlink\",\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, _ref2);\n}\n\nvar ForwardRef = /*#__PURE__*/React.forwardRef(SvgUp);\nexport default __webpack_public_path__ + \"static/media/up.bcdf0fc7.svg\";\nexport { ForwardRef as ReactComponent };","import { makeStyles } from '@material-ui/core'\nimport classnames from 'classnames'\nimport React from 'react'\n\nimport { Label1 } from 'src/components/typography/index'\nimport { java, neon, white } from 'src/styling/variables'\n\nconst styles = {\n wrapper: {\n display: 'flex',\n height: 130,\n marginTop: -8\n },\n percentageBox: {\n height: 130,\n borderRadius: 4,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n whiteSpace: 'pre'\n },\n label: {\n color: white\n },\n inColor: {\n backgroundColor: java\n },\n outColor: {\n backgroundColor: neon\n },\n other: {\n minWidth: '6px',\n borderRadius: 2\n },\n inWidth: {\n width: value => `${value}%`\n },\n outWidth: {\n width: value => `${100 - value}%`,\n marginRight: 4\n }\n}\n\nconst useStyles = makeStyles(styles)\n\nconst PercentageChart = ({ cashIn, cashOut }) => {\n const value = cashIn || cashOut !== 0 ? cashIn : 50\n const classes = useStyles(value)\n\n const buildPercentageView = value => {\n if (value <= 15) return\n return {value}% \n }\n\n const percentageClasses = {\n [classes.percentageBox]: true,\n [classes.other]: value < 5 && value > 0\n }\n\n return (\n \n
\n {buildPercentageView(100 - value, 'cashOut')}\n
\n
\n {buildPercentageView(value, 'cashIn')}\n
\n
\n )\n}\n\nexport default PercentageChart\n","import * as d3 from 'd3'\nimport * as R from 'ramda'\nimport React, { useEffect, useRef, useCallback } from 'react'\n\nimport { backgroundColor, zircon, primaryColor } from 'src/styling/variables'\n\nconst transactionProfit = tx => {\n const cashInFee = tx.cashInFee ? Number.parseFloat(tx.cashInFee) : 0\n const commission =\n Number.parseFloat(tx.commissionPercentage) * Number.parseFloat(tx.fiat)\n return commission + cashInFee\n}\n\nconst mockPoint = (tx, offsetMs, profit) => {\n const date = new Date(new Date(tx.created).getTime() + offsetMs).toISOString()\n return { created: date, profit }\n}\n\n// if we're viewing transactions for the past day, then we group by hour. If not, we group by day\nconst formatDay = ({ created }) =>\n new Date(created).toISOString().substring(0, 10)\nconst formatHour = ({ created }) =>\n new Date(created).toISOString().substring(0, 13)\n\nconst reducer = (acc, tx) => {\n const currentProfit = acc.profit || 0\n return { ...tx, profit: currentProfit + transactionProfit(tx) }\n}\n\nconst timeFrameMS = {\n Day: 24 * 3600 * 1000,\n Week: 7 * 24 * 3600 * 1000,\n Month: 30 * 24 * 3600 * 1000\n}\n\nconst RefLineChart = ({\n data: realData,\n previousTimeData,\n previousProfit,\n timeFrame\n}) => {\n const svgRef = useRef()\n\n const drawGraph = useCallback(() => {\n const svg = d3.select(svgRef.current)\n const margin = { top: 0, right: 0, bottom: 0, left: 0 }\n const width = 336 - margin.left - margin.right\n const height = 128 - margin.top - margin.bottom\n\n const massageData = () => {\n // if we're viewing transactions for the past day, then we group by hour. If not, we group by day\n const method = timeFrame === 'Day' ? formatHour : formatDay\n\n const aggregatedTX = R.values(R.reduceBy(reducer, [], method, realData))\n // if no point exists, then return 2 points at y = 0\n if (!aggregatedTX.length && !previousTimeData.length) {\n const mockPoint1 = { created: new Date().toISOString(), profit: 0 }\n const mockPoint2 = mockPoint(mockPoint1, -3600000, 0)\n return [[mockPoint1, mockPoint2], true]\n }\n // if this time period has no txs, but previous time period has, then % change is -100%\n if (!aggregatedTX.length && previousTimeData.length) {\n const mockPoint1 = {\n created: new Date().toISOString(),\n profit: 0\n }\n const mockPoint2 = mockPoint(mockPoint1, -timeFrameMS[timeFrame], 1)\n return [[mockPoint1, mockPoint2], false]\n }\n // if this time period has txs, but previous doesn't, then % change is +100%\n if (aggregatedTX.length && !previousTimeData.length) {\n const mockPoint1 = {\n created: new Date().toISOString(),\n profit: 1\n }\n const mockPoint2 = mockPoint(mockPoint1, -timeFrameMS[timeFrame], 0)\n return [[mockPoint1, mockPoint2], false]\n }\n // if only one point exists, create point on the left - otherwise the line won't be drawn\n if (aggregatedTX.length === 1) {\n return [\n R.append(\n {\n created: new Date(\n Date.now() - timeFrameMS[timeFrame]\n ).toISOString(),\n profit: previousProfit\n },\n aggregatedTX\n ),\n false\n ]\n }\n // the boolean value is for zeroProfit. It makes the line render at y = 0 instead of y = 50% of container height\n return [aggregatedTX, false]\n }\n\n /* Important step to make the graph look good!\n This function groups transactions by either day or hour depending on the time frame\n This makes the line look smooth and not all wonky when there are many transactions in a given time\n */\n const [data, zeroProfit] = massageData()\n\n // sets width of the graph\n svg.attr('width', width)\n\n // background color for the graph\n svg\n .append('rect')\n .attr('x', 0)\n .attr('y', -margin.top)\n .attr('width', width + margin.left + margin.right)\n .attr('height', height + margin.top)\n .attr('fill', backgroundColor)\n .attr('transform', `translate(${0},${margin.top})`)\n\n // gradient color for the graph (creates the \"url\", the color is applied by calling the url, in the area color fill )\n svg\n .append('linearGradient')\n .attr('id', 'area-gradient')\n .attr('gradientUnits', 'userSpaceOnUse')\n .attr('x1', 0)\n .attr('y1', 0)\n .attr('x2', 0)\n .attr('y2', '100%')\n .selectAll('stop')\n .data([\n { offset: '0%', color: zircon },\n { offset: '25%', color: zircon },\n { offset: '100%', color: backgroundColor }\n ])\n .enter()\n .append('stop')\n .attr('offset', function(d) {\n return d.offset\n })\n .attr('stop-color', function(d) {\n return d.color\n })\n\n const g = svg\n .append('g')\n .attr('transform', `translate(${margin.left},${margin.top})`)\n\n const xDomain = d3.extent(data, t => t.created)\n const yDomain = zeroProfit ? [0, 0.1] : [0, d3.max(data, t => t.profit)]\n\n const y = d3\n .scaleLinear()\n // 30 is a margin so that the labels and the percentage change label can fit and not overlay the line path\n .range([height, 30])\n .domain([0, yDomain[1]])\n const x = d3\n .scaleTime()\n .domain([new Date(xDomain[0]), new Date(xDomain[1])])\n .range([0, width])\n\n const line = d3\n .line()\n .x(function(d) {\n return x(new Date(d.created))\n })\n .y(function(d) {\n return y(d.profit)\n })\n\n const area = d3\n .area()\n .x(function(d) {\n return x(new Date(d.created))\n })\n .y0(height)\n .y1(function(d) {\n return y(d.profit)\n })\n\n // area color fill\n g.append('path')\n .datum(data)\n .attr('d', area)\n .attr('fill', 'url(#area-gradient)')\n // draw the line\n g.append('path')\n .datum(data)\n .attr('d', line)\n .attr('fill', 'none')\n .attr('stroke-width', '2')\n .attr('stroke-linejoin', 'round')\n .attr('stroke', primaryColor)\n }, [realData, timeFrame, previousTimeData, previousProfit])\n\n useEffect(() => {\n // first we clear old chart DOM elements on component update\n d3.select(svgRef.current)\n .selectAll('*')\n .remove()\n drawGraph()\n }, [drawGraph, realData])\n\n return (\n <>\n \n >\n )\n}\nexport default RefLineChart\n","import * as d3 from 'd3'\nimport moment from 'moment'\nimport * as R from 'ramda'\nimport React, { useEffect, useRef, useCallback } from 'react'\n\nimport { backgroundColor, java, neon } from 'src/styling/variables'\n\nconst RefScatterplot = ({ data: realData, timeFrame }) => {\n const svgRef = useRef()\n const cashIns = R.filter(R.propEq('txClass', 'cashIn'))(realData)\n const cashOuts = R.filter(R.propEq('txClass', 'cashOut'))(realData)\n const drawGraph = useCallback(() => {\n const svg = d3.select(svgRef.current)\n const margin = { top: 25, right: 0, bottom: 25, left: 15 }\n const width = 555 - margin.left - margin.right\n const height = 150 - margin.top - margin.bottom\n\n // finds maximum value for the Y axis. Minimum value is 100. If value is multiple of 1000, add 100\n // (this is because the Y axis looks best with multiples of 100)\n const findMaxY = () => {\n if (realData.length === 0) return 100\n const maxvalueTx =\n 100 * Math.ceil(d3.max(realData, t => parseFloat(t.fiat)) / 100)\n const maxY = Math.max(100, maxvalueTx)\n if (maxY % 1000 === 0) return maxY + 100\n return maxY\n }\n\n // changes values of arguments in some d3 function calls to make the graph labels look good according to the selected time frame\n const findXAxisSettings = () => {\n // case 'Day' or default\n const res = {\n nice: null,\n ticks: 4,\n subtractDays: 1,\n timeFormat: '%H:%M',\n timeRange: [50, 500]\n }\n switch (timeFrame) {\n case 'Week':\n return {\n nice: 7,\n ticks: 7,\n subtractDays: 7,\n timeFormat: '%a %d',\n timeRange: [50, 500]\n }\n case 'Month':\n return {\n nice: 6,\n ticks: 6,\n subtractDays: 30,\n timeFormat: '%b %d',\n timeRange: [50, 500]\n }\n default:\n return res\n }\n }\n\n // sets width of the graph\n svg.attr('width', width)\n\n // background color for the graph\n svg\n .append('rect')\n .attr('x', 0)\n .attr('y', -margin.top)\n .attr('width', width + margin.left + margin.right)\n .attr('height', height + margin.top)\n .attr('fill', backgroundColor)\n .attr('transform', `translate(${0},${margin.top})`)\n\n // declare g variable where more svg components will be attached\n const g = svg\n .append('g')\n .attr('transform', `translate(${margin.left},${margin.top})`)\n\n // y axis range: round up to 100 highest data value, if rounds up to 1000, add 100.\n // this keeps the vertical axis nice looking\n const maxY = findMaxY()\n const xAxisSettings = findXAxisSettings()\n\n // y and x scales\n const y = d3\n .scaleLinear()\n .range([height, 0])\n .domain([0, maxY])\n .nice(3)\n const x = d3\n .scaleTime()\n .domain([\n moment()\n .add(-xAxisSettings.subtractDays, 'day')\n .valueOf(),\n moment().valueOf()\n ])\n .range(xAxisSettings.timeRange)\n .nice(xAxisSettings.nice)\n\n // horizontal gridlines\n const makeYGridlines = () => {\n return d3.axisLeft(y).ticks(4)\n }\n g.append('g')\n .style('color', '#eef1ff')\n .call(\n makeYGridlines()\n .tickSize(-width)\n .tickFormat('')\n )\n .call(g => g.select('.domain').remove())\n\n /* X AXIS */\n // this one is for the labels at the bottom\n g.append('g')\n .attr('transform', 'translate(0,' + height + ')')\n .style('font-size', '13px')\n .style('color', '#5f668a')\n .style('font-family', 'MuseoSans')\n .style('margin-top', '11px')\n .call(\n d3\n .axisBottom(x)\n .ticks(xAxisSettings.ticks)\n .tickSize(0)\n .tickFormat(d3.timeFormat(xAxisSettings.timeFormat))\n )\n .selectAll('text')\n .attr('dy', '1.5em')\n // this is for the x axis line. It is the same color as the horizontal grid lines\n g.append('g')\n .attr('transform', 'translate(0,' + height + ')')\n .style('color', '#eef1ff')\n .call(\n d3\n .axisBottom(x)\n .ticks(6)\n .tickSize(0)\n .tickFormat('')\n )\n .selectAll('text')\n .attr('dy', '1.5em')\n /* ******************** */\n\n // Y axis\n g.append('g')\n .style('font-size', '13px')\n .style('color', '#5f668a')\n .style('font-family', 'MuseoSans')\n .style('margin-top', '11px')\n .call(\n d3\n .axisLeft(y)\n .ticks(4)\n .tickSize(0)\n )\n .call(g => g.select('.domain').remove())\n .selectAll('text')\n .attr('dy', '-0.40em')\n .attr('dx', '3em')\n\n /* APPEND DOTS */\n svg\n .append('g')\n .selectAll('dot')\n .data(cashIns)\n .enter()\n .append('circle')\n .attr('cx', function(d) {\n return x(new Date(d.created))\n })\n .attr('cy', function(d) {\n return y(d.fiat)\n })\n .attr('r', 4)\n .attr('transform', 'translate(' + margin.left + ',' + 15 + ')')\n .style('fill', java)\n svg\n .append('g')\n .selectAll('dot')\n .data(cashOuts)\n .enter()\n .append('circle')\n .attr('cx', function(d) {\n return x(new Date(d.created))\n })\n .attr('cy', function(d) {\n return y(d.fiat)\n })\n .attr('r', 4)\n .attr('transform', 'translate(' + margin.left + ',' + 15 + ')')\n .style('fill', neon)\n\n /* ************************** */\n }, [cashIns, cashOuts, realData, timeFrame])\n\n useEffect(() => {\n // first we clear old chart DOM elements on component update\n d3.select(svgRef.current)\n .selectAll('*')\n .remove()\n drawGraph()\n }, [drawGraph])\n\n return (\n <>\n \n >\n )\n}\nexport default RefScatterplot\n","import React from 'react'\n\nimport { Info1, Label1 } from 'src/components/typography/index'\nconst InfoWithLabel = ({ info, label }) => {\n return (\n <>\n {info} \n {label} \n >\n )\n}\n\nexport default InfoWithLabel\n","import {\n offColor,\n spacer,\n primaryColor,\n fontSize3,\n fontSecondary,\n fontColor,\n spring4,\n tomato,\n java,\n neon,\n comet\n} from 'src/styling/variables'\n\nconst styles = {\n titleWrapper: {\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'center',\n flexDirection: 'row'\n },\n titleAndButtonsContainer: {\n display: 'flex'\n },\n error: {\n marginLeft: 12\n },\n icon: {\n marginRight: 6\n },\n h4: {\n margin: 0,\n marginRight: spacer * 8\n },\n label: {\n cursor: 'pointer',\n minHeight: 0,\n minWidth: 0,\n padding: 0,\n color: offColor,\n textTransform: 'none',\n borderBottom: `2px solid transparent`,\n display: 'inline-block',\n lineHeight: 1.5,\n '&:hover': {\n backgroundColor: 'transparent'\n }\n },\n newHighlightedLabel: {\n cursor: 'pointer',\n color: primaryColor,\n fontWeight: 700,\n borderRadius: 0,\n minHeight: 0,\n minWidth: 0,\n textTransform: 'none',\n borderBottom: `2px solid ${primaryColor}`,\n display: 'inline-block',\n lineHeight: 1.5,\n '&:hover': {\n backgroundColor: 'transparent'\n }\n },\n navButton: {\n marginLeft: 24\n },\n navContainer: {\n display: 'flex'\n },\n profitLabel: {\n fontSize: fontSize3,\n fontFamily: fontSecondary,\n fontWeight: 700,\n color: fontColor\n },\n percentUp: {\n fontSize: fontSize3,\n fontFamily: fontSecondary,\n fontWeight: 700,\n color: spring4,\n height: 10\n },\n percentDown: {\n fontSize: fontSize3,\n fontFamily: fontSecondary,\n fontWeight: 700,\n color: tomato,\n height: 13\n },\n percentNeutral: {\n fontSize: fontSize3,\n fontFamily: fontSecondary,\n fontWeight: 700,\n color: comet\n },\n profitContainer: {\n display: 'flex',\n justifyContent: 'space-between',\n margin: '0 26px -30px 16px',\n position: 'relative'\n },\n gridContainer: {\n marginTop: 30,\n height: 225\n },\n inSquare: {\n width: 8,\n height: 8,\n borderRadius: 2,\n marginTop: 18,\n marginRight: 4,\n backgroundColor: java\n },\n outSquare: {\n width: 8,\n height: 8,\n borderRadius: 2,\n marginTop: 18,\n marginRight: 4,\n backgroundColor: neon\n },\n directionLabelContainer: {\n display: 'flex'\n },\n dirLabContMargin: {\n marginRight: 20\n },\n directionIcon: {\n width: 16,\n height: 16,\n marginBottom: -2,\n marginRight: 4\n },\n labelMargin: {\n marginBottom: 20,\n marginRight: 32\n }\n}\n\nexport default styles\n","import { makeStyles } from '@material-ui/core/styles'\nimport classnames from 'classnames'\nimport * as R from 'ramda'\nimport React, { useState } from 'react'\n\nimport { H4 } from 'src/components/typography'\n\nimport styles from './SystemPerformance.styles'\n\nconst useStyles = makeStyles(styles)\nconst ranges = ['Month', 'Week', 'Day']\n\nconst Nav = ({ handleSetRange }) => {\n const classes = useStyles()\n const [clickedItem, setClickedItem] = useState('Day')\n\n const isSelected = R.equals(clickedItem)\n const handleClick = range => {\n setClickedItem(range)\n handleSetRange(range)\n }\n\n return (\n \n
\n
{'System performance'} \n \n
\n {ranges.map((it, idx) => {\n return (\n
handleClick(e.target.innerText)}\n className={\n isSelected(it)\n ? classnames(classes.newHighlightedLabel, classes.navButton)\n : classnames(classes.label, classes.navButton)\n }>\n {it}\n
\n )\n })}\n
\n
\n )\n}\n\nexport default Nav\n","import { useQuery } from '@apollo/react-hooks'\nimport Grid from '@material-ui/core/Grid'\nimport { makeStyles } from '@material-ui/core/styles'\nimport BigNumber from 'bignumber.js'\nimport classnames from 'classnames'\nimport gql from 'graphql-tag'\nimport moment from 'moment'\nimport * as R from 'ramda'\nimport React, { useState } from 'react'\n\nimport { Label1, Label2 } from 'src/components/typography/index'\nimport { ReactComponent as PercentDownIcon } from 'src/styling/icons/dashboard/down.svg'\nimport { ReactComponent as PercentNeutralIcon } from 'src/styling/icons/dashboard/equal.svg'\nimport { ReactComponent as PercentUpIcon } from 'src/styling/icons/dashboard/up.svg'\nimport { fromNamespace } from 'src/utils/config'\n\nimport PercentageChart from './Graphs/PercentageChart'\nimport LineChart from './Graphs/RefLineChart'\nimport Scatterplot from './Graphs/RefScatterplot'\nimport InfoWithLabel from './InfoWithLabel'\nimport Nav from './Nav'\nimport styles from './SystemPerformance.styles'\n\nBigNumber.config({ ROUNDING_MODE: BigNumber.ROUND_HALF_UP })\n\nconst getFiats = R.map(R.prop('fiat'))\nconst useStyles = makeStyles(styles)\nconst mapToFee = R.map(R.prop('cashInFee'))\n\nconst getDateSecondsAgo = (seconds = 0, startDate = null) => {\n const date = startDate ? moment(startDate) : moment()\n return date.subtract(seconds, 'second')\n}\n\nconst ranges = {\n Day: {\n left: getDateSecondsAgo(2 * 24 * 3600, moment()),\n right: getDateSecondsAgo(24 * 3600, moment())\n },\n Week: {\n left: getDateSecondsAgo(14 * 24 * 3600, moment()),\n right: getDateSecondsAgo(7 * 24 * 3600, moment())\n },\n Month: {\n left: getDateSecondsAgo(60 * 24 * 3600, moment()),\n right: getDateSecondsAgo(30 * 24 * 3600, moment())\n }\n}\n\nconst GET_DATA = gql`\n query getData {\n transactions {\n fiatCode\n fiat\n cashInFee\n commissionPercentage\n created\n txClass\n error\n }\n fiatRates {\n code\n name\n rate\n }\n config\n }\n`\n\nconst reducer = (acc, it) =>\n (acc +=\n Number.parseFloat(it.commissionPercentage) * Number.parseFloat(it.fiat))\n\nconst SystemPerformance = () => {\n const classes = useStyles()\n const [selectedRange, setSelectedRange] = useState('Day')\n const { data, loading } = useQuery(GET_DATA)\n const fiatLocale = fromNamespace('locale')(data?.config).fiatCurrency\n\n const isInRangeAndNoError = getLastTimePeriod => t => {\n if (t.error !== null) return false\n if (!getLastTimePeriod) {\n return (\n t.error === null &&\n moment(t.created).isBetween(ranges[selectedRange].right, moment())\n )\n }\n return (\n t.error === null &&\n moment(t.created).isBetween(\n ranges[selectedRange].left,\n ranges[selectedRange].right\n )\n )\n }\n\n const convertFiatToLocale = item => {\n if (item.fiatCode === fiatLocale) return item\n const itemRate = R.find(R.propEq('code', item.fiatCode))(data.fiatRates)\n const localeRate = R.find(R.propEq('code', fiatLocale))(data.fiatRates)\n const multiplier = localeRate.rate / itemRate.rate\n return { ...item, fiat: parseFloat(item.fiat) * multiplier }\n }\n\n const transactionsToShow = R.map(convertFiatToLocale)(\n R.filter(isInRangeAndNoError(false), data?.transactions ?? [])\n )\n const transactionsLastTimePeriod = R.map(convertFiatToLocale)(\n R.filter(isInRangeAndNoError(true), data?.transactions ?? [])\n )\n\n const getNumTransactions = () => {\n return R.length(transactionsToShow)\n }\n\n const getFiatVolume = () =>\n new BigNumber(R.sum(getFiats(transactionsToShow))).toFormat(2)\n\n const getProfit = transactions => {\n const cashInFees = R.sum(mapToFee(transactions))\n const commissionFees = R.reduce(reducer, 0, transactions)\n\n return new BigNumber(commissionFees + cashInFees)\n }\n\n const getPercentChange = () => {\n const thisTimePeriodProfit = getProfit(transactionsToShow)\n const previousTimePeriodProfit = getProfit(transactionsLastTimePeriod)\n\n if (thisTimePeriodProfit.eq(previousTimePeriodProfit)) return 0\n if (previousTimePeriodProfit.eq(0)) return 100\n\n return thisTimePeriodProfit\n .minus(previousTimePeriodProfit)\n .times(100)\n .div(previousTimePeriodProfit)\n .toNumber()\n }\n\n const getDirectionPercent = () => {\n const [cashIn, cashOut] = R.partition(R.propEq('txClass', 'cashIn'))(\n transactionsToShow\n )\n const totalLength = cashIn.length + cashOut.length\n if (totalLength === 0) {\n return { cashIn: 0, cashOut: 0 }\n }\n\n return {\n cashIn: Math.round((cashIn.length / totalLength) * 100),\n cashOut: Math.round((cashOut.length / totalLength) * 100)\n }\n }\n\n const percentChange = getPercentChange()\n\n const percentageClasses = {\n [classes.percentDown]: percentChange < 0,\n [classes.percentUp]: percentChange > 0,\n [classes.percentNeutral]: percentChange === 0\n }\n\n const getPercentageIcon = () => {\n if (percentChange === 0)\n return \n if (percentChange > 0)\n return \n return \n }\n\n return (\n <>\n \n {!loading && (\n <>\n \n \n \n \n \n \n \n {/* todo new customers */}\n \n \n \n Transactions \n \n \n \n \n \n \n Profit from commissions\n \n \n
\n {`${getProfit(transactionsToShow).toFormat(2)} ${\n data?.config.locale_fiatCurrency\n }`}\n
\n
\n {getPercentageIcon()}\n {`${new BigNumber(percentChange).toFormat(2)}%`}\n
\n
\n \n \n \n \n \n Direction \n \n \n
\n Out \n \n \n
\n In \n \n \n \n \n \n \n \n >\n )}\n >\n )\n}\n\nexport default SystemPerformance\n","import SystemPerformance from './SystemPerformance'\nexport default SystemPerformance\n","import Grid from '@material-ui/core/Grid'\nimport { makeStyles } from '@material-ui/core/styles'\nimport React from 'react'\n\nimport styles from './Dashboard.styles'\nimport SystemPerformance from './SystemPerformance'\n\nconst useStyles = makeStyles(styles)\n\nconst LeftSide = () => {\n const classes = useStyles()\n\n return (\n \n \n \n
\n \n )\n}\n\nexport default LeftSide\n","import Grid from '@material-ui/core/Grid'\nimport { makeStyles } from '@material-ui/core/styles'\nimport classnames from 'classnames'\nimport PropTypes from 'prop-types'\nimport React from 'react'\n\nimport { white } from 'src/styling/variables'\n\nconst cardState = Object.freeze({\n DEFAULT: 'default',\n SHRUNK: 'shrunk',\n EXPANDED: 'expanded'\n})\n\nconst styles = {\n card: {\n wordWrap: 'break-word',\n boxShadow: '0 0 4px 0 rgba(0, 0, 0, 0.08)',\n borderRadius: 12,\n padding: 24,\n backgroundColor: white\n }\n}\n\nconst useStyles = makeStyles(styles)\n\nconst CollapsibleCard = ({ className, state, shrunkComponent, children }) => {\n const classes = useStyles()\n return (\n \n {state === cardState.SHRUNK ? shrunkComponent : children}\n \n )\n}\n\nCollapsibleCard.propTypes = {\n shrunkComponent: PropTypes.node.isRequired\n}\n\nexport default CollapsibleCard\nexport { cardState }\n","import { primaryColor, comet } from 'src/styling/variables'\n\nconst styles = {\n container: {\n display: 'flex',\n justifyContent: 'space-between'\n },\n h4: {\n margin: 0,\n marginBottom: 10\n },\n centerLabel: {\n marginBottom: 0,\n padding: 0,\n textAlign: 'center'\n },\n upperButtonLabel: {\n marginTop: -3,\n marginBottom: 24\n },\n button: {\n color: primaryColor,\n marginTop: 0,\n minHeight: 0,\n minWidth: 0,\n padding: 0,\n textTransform: 'none',\n '&:hover': {\n backgroundColor: 'transparent'\n }\n },\n alertsTableContainer: {\n margin: 0\n },\n expandedAlertsTableContainer: {\n margin: 0,\n maxHeight: 460\n },\n noAlertsLabel: {\n color: comet,\n marginLeft: -5,\n height: 100\n },\n table: {\n maxHeight: 465,\n overflowX: 'hidden',\n overflowY: 'auto'\n },\n listItemText: {\n margin: '8px 0 8px 0'\n },\n linkIcon: {\n marginLeft: 'auto',\n cursor: 'pointer'\n }\n}\nexport default styles\n","function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport * as React from \"react\";\n\nvar _ref2 = /*#__PURE__*/React.createElement(\"desc\", null, \"Created with Sketch.\");\n\nvar _ref3 = /*#__PURE__*/React.createElement(\"g\", {\n id: \"icon/button/link/zodiac\",\n stroke: \"none\",\n strokeWidth: 1,\n fill: \"none\",\n fillRule: \"evenodd\",\n strokeLinecap: \"round\",\n strokeLinejoin: \"round\"\n}, /*#__PURE__*/React.createElement(\"g\", {\n id: \"Group-7\",\n stroke: \"#1B2559\",\n strokeWidth: 1.2\n}, /*#__PURE__*/React.createElement(\"polyline\", {\n id: \"Stroke-1\",\n points: \"12 6.66678 12 12.00018 0 12.00018 0 0.00018 5.3334 0.00018\"\n}), /*#__PURE__*/React.createElement(\"polyline\", {\n id: \"Stroke-3\",\n points: \"8.66658 0 12.00018 0 12.00018 3.3336\"\n}), /*#__PURE__*/React.createElement(\"line\", {\n x1: 6,\n y1: 6,\n x2: 12,\n y2: 0,\n id: \"Stroke-5\"\n})));\n\nfunction SvgZodiac(_ref, svgRef) {\n var title = _ref.title,\n titleId = _ref.titleId,\n props = _objectWithoutProperties(_ref, [\"title\", \"titleId\"]);\n\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n width: \"12px\",\n height: \"12px\",\n viewBox: \"0 0 12 12\",\n xmlns: \"http://www.w3.org/2000/svg\",\n xmlnsXlink: \"http://www.w3.org/1999/xlink\",\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, _ref2, _ref3);\n}\n\nvar ForwardRef = /*#__PURE__*/React.forwardRef(SvgZodiac);\nexport default __webpack_public_path__ + \"static/media/zodiac.cdf82496.svg\";\nexport { ForwardRef as ReactComponent };","function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport * as React from \"react\";\n\nvar _ref2 = /*#__PURE__*/React.createElement(\"g\", {\n id: \"DASHBOARD\",\n stroke: \"none\",\n strokeWidth: 1,\n fill: \"none\",\n fillRule: \"evenodd\"\n}, /*#__PURE__*/React.createElement(\"g\", {\n id: \"dashboard_v9#1-(week)\",\n transform: \"translate(-772.000000, -212.000000)\"\n}, /*#__PURE__*/React.createElement(\"g\", {\n id: \"dashboard/row/alert/positive\",\n transform: \"translate(756.000000, 204.000000)\"\n}, /*#__PURE__*/React.createElement(\"g\", {\n id: \"Group-2\",\n transform: \"translate(16.000000, 8.000000)\"\n}, /*#__PURE__*/React.createElement(\"polygon\", {\n id: \"Rectangle-2-Copy-45\",\n fill: \"#FF584A\",\n fillRule: \"nonzero\",\n points: \"0 11 16 11 16 16 0 16\"\n}), /*#__PURE__*/React.createElement(\"rect\", {\n id: \"Rectangle-Copy-10\",\n stroke: \"#FF584A\",\n strokeWidth: 2,\n x: 1,\n y: 1,\n width: 14,\n height: 14\n})))));\n\nfunction SvgCashboxEmpty(_ref, svgRef) {\n var title = _ref.title,\n titleId = _ref.titleId,\n props = _objectWithoutProperties(_ref, [\"title\", \"titleId\"]);\n\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n width: \"16px\",\n height: \"16px\",\n viewBox: \"0 0 16 16\",\n xmlns: \"http://www.w3.org/2000/svg\",\n xmlnsXlink: \"http://www.w3.org/1999/xlink\",\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title === undefined ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, \"07E3DD15-D5E4-46A8-BF7B-064F598230CE\") : title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, _ref2);\n}\n\nvar ForwardRef = /*#__PURE__*/React.forwardRef(SvgCashboxEmpty);\nexport default __webpack_public_path__ + \"static/media/cashbox-empty.828bd3b9.svg\";\nexport { ForwardRef as ReactComponent };","import { makeStyles } from '@material-ui/core'\nimport List from '@material-ui/core/List'\nimport ListItem from '@material-ui/core/ListItem'\nimport * as R from 'ramda'\nimport React from 'react'\nimport { useHistory } from 'react-router-dom'\n\nimport { P } from 'src/components/typography/index'\nimport { ReactComponent as Wrench } from 'src/styling/icons/action/wrench/zodiac.svg'\nimport { ReactComponent as LinkIcon } from 'src/styling/icons/button/link/zodiac.svg'\nimport { ReactComponent as CashBoxEmpty } from 'src/styling/icons/cassettes/cashbox-empty.svg'\nimport { ReactComponent as WarningIcon } from 'src/styling/icons/warning-icon/tomato.svg'\n\nimport styles from './Alerts.styles'\nconst useStyles = makeStyles(styles)\n\nconst icons = {\n error: ,\n fiatBalance: (\n \n )\n}\n\nconst links = {\n error: '/maintenance/machine-status',\n fiatBalance: '/maintenance/cash-cassettes',\n cryptoBalance: '/maintenance/funding'\n}\n\nconst AlertsTable = ({ numToRender, alerts, machines }) => {\n const history = useHistory()\n const classes = useStyles()\n const alertsToRender = R.slice(0, numToRender, alerts)\n return (\n \n {alertsToRender.map((alert, idx) => {\n return (\n \n {icons[alert.type] || (\n \n )}\n {`${alert.message}${alert.detail\n .deviceId && ' - ' + machines[alert.detail.deviceId]}`}
\n history.push(links[alert.type] || '/dashboard')}\n />\n \n )\n })}\n
\n )\n}\n\nexport default AlertsTable\n","import { useQuery } from '@apollo/react-hooks'\nimport Button from '@material-ui/core/Button'\nimport Grid from '@material-ui/core/Grid'\nimport { makeStyles } from '@material-ui/core/styles'\nimport classnames from 'classnames'\nimport gql from 'graphql-tag'\nimport * as R from 'ramda'\nimport React from 'react'\n\nimport { cardState } from 'src/components/CollapsibleCard'\nimport { Label1, H4 } from 'src/components/typography'\n\nimport styles from './Alerts.styles'\nimport AlertsTable from './AlertsTable'\n\nconst NUM_TO_RENDER = 3\n\nconst GET_ALERTS = gql`\n query getAlerts {\n alerts {\n id\n type\n detail\n message\n created\n read\n valid\n }\n machines {\n deviceId\n name\n }\n }\n`\n\nconst useStyles = makeStyles(styles)\n\nconst Alerts = ({ onReset, onExpand, size }) => {\n const classes = useStyles()\n const showAllItems = size === cardState.EXPANDED\n const { data } = useQuery(GET_ALERTS)\n const alerts = R.path(['alerts'])(data) ?? []\n const machines = R.compose(\n R.map(R.prop('name')),\n R.indexBy(R.prop('deviceId'))\n )(data?.machines ?? [])\n const alertsLength = alerts.length\n\n const alertsTableContainerClasses = {\n [classes.alertsTableContainer]: !showAllItems,\n [classes.expandedAlertsTableContainer]: showAllItems\n }\n\n return (\n <>\n \n
{`Alerts (${alertsLength})`} \n {showAllItems && (\n \n \n {'Show less'}\n \n \n )}\n \n \n \n {!alerts.length && (\n \n No new alerts. Your system is running smoothly.\n \n )}\n \n \n \n {!showAllItems && alertsLength > NUM_TO_RENDER && (\n \n \n onExpand('alerts')}\n size=\"small\"\n disableRipple\n disableFocusRipple\n className={classes.button}>\n {`Show all (${alerts.length})`}\n \n \n \n )}\n >\n )\n}\nexport default Alerts\n","import Alerts from './Alerts'\nexport default Alerts\n","function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport * as React from \"react\";\n\nvar _ref2 = /*#__PURE__*/React.createElement(\"defs\", null, /*#__PURE__*/React.createElement(\"circle\", {\n id: \"path-1-right\",\n cx: 10,\n cy: 10,\n r: 10\n}));\n\nvar _ref3 = /*#__PURE__*/React.createElement(\"g\", {\n id: \"Symbols\",\n stroke: \"none\",\n strokeWidth: 1,\n fill: \"none\",\n fillRule: \"evenodd\"\n}, /*#__PURE__*/React.createElement(\"g\", {\n id: \"pop-up/action/download-logs/date-range-copy-2\",\n transform: \"translate(-232.000000, -187.000000)\"\n}, /*#__PURE__*/React.createElement(\"g\", {\n id: \"icon/sf-contain-b-copy-4\",\n transform: \"translate(242.000000, 197.000000) scale(-1, 1) rotate(-270.000000) translate(-242.000000, -197.000000) translate(232.000000, 187.000000)\"\n}, /*#__PURE__*/React.createElement(\"mask\", {\n id: \"mask-2\",\n fill: \"white\"\n}, /*#__PURE__*/React.createElement(\"use\", {\n xlinkHref: \"#path-1-right\"\n})), /*#__PURE__*/React.createElement(\"use\", {\n id: \"Mask\",\n fill: \"#EBEFFF\",\n fillRule: \"nonzero\",\n xlinkHref: \"#path-1-right\"\n}), /*#__PURE__*/React.createElement(\"g\", {\n id: \"icon/sf-small/wizzard\",\n mask: \"url(#mask-2)\",\n strokeLinecap: \"round\",\n strokeLinejoin: \"round\"\n}, /*#__PURE__*/React.createElement(\"g\", {\n transform: \"translate(6.666667, 6.000000)\",\n id: \"Group\"\n}, /*#__PURE__*/React.createElement(\"g\", null, /*#__PURE__*/React.createElement(\"polyline\", {\n id: \"Path-3\",\n stroke: \"#1B2559\",\n strokeWidth: 2,\n points: \"0 4.83333333 3.33333333 8.16666667 6.66666667 4.83333333\"\n}), /*#__PURE__*/React.createElement(\"line\", {\n x1: 3.33333333,\n y1: 0.25,\n x2: 3.33333333,\n y2: 6.5,\n id: \"Path-4\",\n stroke: \"#1B2559\",\n strokeWidth: 2\n})))))));\n\nfunction SvgRight(_ref, svgRef) {\n var title = _ref.title,\n titleId = _ref.titleId,\n props = _objectWithoutProperties(_ref, [\"title\", \"titleId\"]);\n\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n width: \"20px\",\n height: \"20px\",\n viewBox: \"0 0 20 20\",\n xmlns: \"http://www.w3.org/2000/svg\",\n xmlnsXlink: \"http://www.w3.org/1999/xlink\",\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, _ref2, _ref3);\n}\n\nvar ForwardRef = /*#__PURE__*/React.forwardRef(SvgRight);\nexport default __webpack_public_path__ + \"static/media/right.d3dd4af6.svg\";\nexport { ForwardRef as ReactComponent };","import {\n backgroundColor,\n offColor,\n errorColor,\n primaryColor\n} from 'src/styling/variables'\n\nconst styles = {\n container: {\n display: 'flex',\n justifyContent: 'space-between'\n },\n label: {\n margin: 0,\n color: offColor\n },\n row: {\n backgroundColor: backgroundColor,\n borderBottom: 'none'\n },\n clickableRow: {\n cursor: 'pointer'\n },\n header: {\n display: 'flex',\n alignItems: 'center',\n whiteSpace: 'pre'\n },\n error: {\n color: errorColor\n },\n button: {\n color: primaryColor,\n minHeight: 0,\n minWidth: 0,\n padding: 0,\n textTransform: 'none',\n '&:hover': {\n backgroundColor: 'transparent'\n },\n marginBottom: -40\n },\n buttonLabel: {\n position: 'absolute',\n bottom: 160,\n marginBottom: 0\n },\n upperButtonLabel: {\n textAlign: 'center',\n marginBottom: 0,\n marginTop: 0\n },\n statusHeader: {\n marginLeft: 2\n },\n table: {\n maxHeight: 440,\n '&::-webkit-scrollbar': {\n width: 7\n },\n '&::-webkit-scrollbar-thumb': {\n backgroundColor: offColor,\n borderRadius: 5\n }\n },\n tableBody: {\n overflow: 'auto'\n },\n h4: {\n marginTop: 0\n },\n tl2: {\n display: 'inline'\n },\n label1: {\n display: 'inline'\n },\n machinesTableContainer: {\n marginTop: 10,\n height: 220\n },\n expandedMachinesTableContainer: {\n marginTop: 10,\n height: 414\n },\n centerLabel: {\n marginBottom: 0,\n padding: 0,\n textAlign: 'center'\n },\n machineNameWrapper: {\n display: 'flex',\n flexDirection: 'row',\n alignItems: 'center'\n },\n machineRedirectIcon: {\n marginLeft: 10\n }\n}\n\nexport default styles\n","import { makeStyles, withStyles } from '@material-ui/core'\nimport Table from '@material-ui/core/Table'\nimport TableBody from '@material-ui/core/TableBody'\nimport TableCell from '@material-ui/core/TableCell'\nimport TableContainer from '@material-ui/core/TableContainer'\nimport TableHead from '@material-ui/core/TableHead'\nimport TableRow from '@material-ui/core/TableRow'\nimport classnames from 'classnames'\nimport React from 'react'\nimport { useHistory } from 'react-router-dom'\n\nimport { Status } from 'src/components/Status'\nimport { Label2, TL2 } from 'src/components/typography'\n// import { ReactComponent as TxInIcon } from 'src/styling/icons/direction/cash-in.svg'\nimport { ReactComponent as TxOutIcon } from 'src/styling/icons/direction/cash-out.svg'\nimport { ReactComponent as MachineLinkIcon } from 'src/styling/icons/month arrows/right.svg'\n\nimport styles from './MachinesTable.styles'\n\n// percentage threshold where below this number the text in the cash cassettes percentage turns red\nconst PERCENTAGE_THRESHOLD = 20\n\nconst useStyles = makeStyles(styles)\n\nconst StyledCell = withStyles({\n root: {\n borderBottom: '4px solid white',\n padding: 0,\n paddingLeft: 15\n }\n})(TableCell)\n\nconst HeaderCell = withStyles({\n root: {\n borderBottom: '4px solid white',\n padding: 0,\n paddingLeft: 15,\n backgroundColor: 'white'\n }\n})(TableCell)\n\nconst MachinesTable = ({ machines, numToRender }) => {\n const classes = useStyles()\n const history = useHistory()\n const getPercent = (notes, capacity = 500) => {\n return Math.round((notes / capacity) * 100)\n }\n\n const makePercentageText = (notes, capacity = 500) => {\n const percent = getPercent(notes, capacity)\n if (percent < PERCENTAGE_THRESHOLD) {\n return {`${percent}%`} \n }\n return {`${percent}%`} \n }\n\n const redirect = ({ name, deviceId }) => {\n return history.push(`/machines/${deviceId}`, {\n selectedMachine: name\n })\n }\n\n return (\n \n \n \n \n \n \n Machines \n
\n \n \n \n Status \n
\n \n {/* \n \n \n
\n */}\n \n \n \n 1 \n
\n \n \n \n \n 2 \n
\n \n \n \n \n {machines.map((machine, idx) => {\n if (idx < numToRender) {\n return (\n redirect(machine)}\n className={classnames(classes.row)}\n key={machine.deviceId + idx}>\n \n {machine.name} \n redirect(machine)}\n />\n \n \n \n \n {/* \n {makePercentageText(machine.cashbox)}\n */}\n \n {makePercentageText(machine.cassette1)}\n \n \n {makePercentageText(machine.cassette2)}\n \n \n )\n }\n return null\n })}\n \n
\n \n )\n}\n\nexport default MachinesTable\n","import { useQuery } from '@apollo/react-hooks'\nimport Button from '@material-ui/core/Button'\nimport Grid from '@material-ui/core/Grid'\nimport { makeStyles } from '@material-ui/core/styles'\nimport classnames from 'classnames'\nimport gql from 'graphql-tag'\nimport * as R from 'ramda'\nimport React from 'react'\n\nimport { cardState as cardState_ } from 'src/components/CollapsibleCard'\n// import ActionButton from 'src/components/buttons/ActionButton'\nimport { H4, TL2, Label1 } from 'src/components/typography'\n\nimport MachinesTable from './MachinesTable'\nimport styles from './MachinesTable.styles'\n\nconst useStyles = makeStyles(styles)\n\n// number of machines in the table to render on page load\nconst NUM_TO_RENDER = 4\n\nconst GET_DATA = gql`\n query getData {\n machines {\n name\n deviceId\n cashbox\n cassette1\n cassette2\n statuses {\n label\n type\n }\n }\n serverVersion\n uptime {\n name\n state\n uptime\n }\n }\n`\n\n/* const parseUptime = time => {\n if (time < 60) return `${time}s`\n if (time < 3600) return `${Math.floor(time / 60)}m`\n if (time < 86400) return `${Math.floor(time / 60 / 60)}h`\n return `${Math.floor(time / 60 / 60 / 24)}d`\n} */\n\nconst SystemStatus = ({ onReset, onExpand, size }) => {\n const classes = useStyles()\n const { data, loading } = useQuery(GET_DATA)\n\n const machines = R.path(['machines'])(data) ?? []\n const showAllItems = size === cardState_.EXPANDED\n\n const machinesTableContainerClasses = {\n [classes.machinesTableContainer]: !showAllItems,\n [classes.expandedMachinesTableContainer]: showAllItems\n }\n // const uptime = data?.uptime ?? [{}]\n return (\n <>\n \n
System status {' '}\n {showAllItems && (\n \n \n {'Show less'}\n \n \n )}\n \n {!loading && (\n <>\n \n {/* \n On hold until system uptime is implemented\n \n \n {parseUptime(uptime[0].time)}\n \n System up time \n */}\n \n {data?.serverVersion} \n server version \n \n \n {/*\n On hold until system update features are implemented\n console.log('Upgrade button clicked')}>\n Update to v10.6.0\n */}\n \n \n \n \n \n \n \n {!showAllItems && machines.length > NUM_TO_RENDER && (\n \n \n onExpand()}\n size=\"small\"\n disableRipple\n disableFocusRipple\n className={classes.button}>\n {`Show all (${machines.length})`}\n \n \n \n )}\n >\n )}\n >\n )\n}\n\nexport default SystemStatus\n","import SystemStatus from './SystemStatus'\nexport default SystemStatus\n","import Button from '@material-ui/core/Button'\nimport Grid from '@material-ui/core/Grid'\nimport { makeStyles } from '@material-ui/core/styles'\nimport classnames from 'classnames'\nimport React, { useState } from 'react'\n\nimport CollapsibleCard, { cardState } from 'src/components/CollapsibleCard'\nimport { H4, Label1 } from 'src/components/typography'\n\nimport Alerts from './Alerts'\nimport styles from './Dashboard.styles'\nimport SystemStatus from './SystemStatus'\n\nconst useStyles = makeStyles(styles)\n\nconst ShrunkCard = ({ title, buttonName, onUnshrink }) => {\n const classes = useStyles()\n return (\n \n
{title} \n \n \n {buttonName}\n \n \n \n )\n}\n\nconst RightSide = () => {\n const classes = useStyles()\n const [systemStatusSize, setSystemStatusSize] = useState(cardState.DEFAULT)\n const [alertsSize, setAlertsSize] = useState(cardState.DEFAULT)\n\n const onReset = () => {\n setAlertsSize(cardState.DEFAULT)\n setSystemStatusSize(cardState.DEFAULT)\n }\n return (\n \n \n <>\n
\n }>\n
{\n setAlertsSize(cardState.EXPANDED)\n setSystemStatusSize(cardState.SHRUNK)\n }}\n onReset={onReset}\n size={alertsSize}\n />\n \n \n }>\n {\n setSystemStatusSize(cardState.EXPANDED)\n setAlertsSize(cardState.SHRUNK)\n }}\n onReset={onReset}\n size={systemStatusSize}\n />\n \n >\n \n \n )\n}\n\nexport default RightSide\n","import Grid from '@material-ui/core/Grid'\nimport { makeStyles } from '@material-ui/core/styles'\nimport classnames from 'classnames'\nimport React from 'react'\n\nimport TitleSection from 'src/components/layout/TitleSection'\nimport { ReactComponent as TxInIcon } from 'src/styling/icons/direction/cash-in.svg'\nimport { ReactComponent as TxOutIcon } from 'src/styling/icons/direction/cash-out.svg'\n\nimport styles from './Dashboard.styles'\nimport Footer from './Footer'\nimport LeftSide from './LeftSide'\nimport RightSide from './RightSide'\nconst useStyles = makeStyles(styles)\n\nconst Dashboard = () => {\n const classes = useStyles()\n\n return (\n <>\n \n \n
\n \n Cash-out \n
\n
\n \n Cash-in \n
\n
\n \n\n \n \n \n \n \n \n \n \n \n
\n \n >\n )\n}\n\nexport default Dashboard\n","import Dashboard from './Dashboard'\nexport default Dashboard\n","import { makeStyles } from '@material-ui/styles'\nimport classnames from 'classnames'\nimport React from 'react'\n\nimport { Label1 } from './typography'\n\nconst useStyles = makeStyles({\n wrapper: {\n display: 'flex',\n alignItems: 'center'\n },\n colorIndicator: {\n borderRadius: 3,\n height: 12,\n width: 12,\n marginRight: 8\n }\n})\n\nconst TableLabel = ({ className, label, color, ...props }) => {\n const classes = useStyles()\n return (\n \n {color && (\n
\n )}\n
{label} \n
\n )\n}\n\nexport default TableLabel\n","import typographyStyles from 'src/components/typography/styles'\nimport {\n disabledColor2,\n spacer,\n subheaderColor,\n errorColor,\n placeholderColor,\n comet\n} from 'src/styling/variables'\n\nconst { label1, mono } = typographyStyles\n\nexport default {\n wrapper: {\n display: 'flex',\n flex: 1,\n flexDirection: 'row',\n height: '100%'\n },\n main: {\n display: 'flex',\n flex: 1\n },\n firstSide: {\n margin: `0 ${spacer * 8}px 0 ${spacer * 6}px`\n },\n secondSide: {\n marginTop: -29\n },\n error: {\n color: errorColor\n },\n coinTotal: {\n margin: `${spacer * 1.5}px 0`\n },\n leftSpacer: {\n marginLeft: spacer\n },\n topSpacer: {\n marginTop: spacer * 5\n },\n addressWrapper: {\n display: 'flex',\n flexDirection: 'column',\n flex: 1,\n backgroundColor: subheaderColor\n },\n address: {\n width: 375,\n margin: `${spacer * 1.5}px ${spacer * 3}px`\n },\n itemWrapper: {\n textAlign: 'end'\n },\n item: {\n extend: label1,\n margin: 2\n },\n inactiveItem: {\n color: comet\n },\n firstItem: {\n fontWeight: 700,\n margin: 2\n },\n total: {\n marginTop: 'auto',\n textAlign: 'right',\n marginRight: 24\n },\n totalPending: {\n marginTop: 2\n },\n totalTitle: {\n color: placeholderColor,\n marginBottom: 2\n },\n table: {\n marginTop: spacer,\n marginLeft: spacer * 6\n },\n tableLabel: {\n justifyContent: 'end',\n marginTop: -38\n },\n pending: {\n backgroundColor: disabledColor2\n },\n copyToClipboard: {\n marginLeft: 'auto',\n paddingTop: 6,\n paddingLeft: 15,\n marginRight: -11\n },\n mono: {\n extend: mono,\n width: 375,\n margin: `${spacer * 1.5}px ${spacer * 3}px`\n }\n}\n","import { useQuery } from '@apollo/react-hooks'\nimport { makeStyles } from '@material-ui/core/styles'\nimport BigNumber from 'bignumber.js'\nimport classnames from 'classnames'\nimport gql from 'graphql-tag'\nimport moment from 'moment'\nimport QRCode from 'qrcode.react'\nimport * as R from 'ramda'\nimport React, { useState } from 'react'\n\nimport TableLabel from 'src/components/TableLabel'\nimport Title from 'src/components/Title'\nimport { Tr, Td, THead, TBody, Table } from 'src/components/fake-table/Table'\nimport Sidebar from 'src/components/layout/Sidebar'\nimport {\n H3,\n Info1,\n Info2,\n Info3,\n Label1,\n Label3\n} from 'src/components/typography'\nimport CopyToClipboard from 'src/pages/Transactions/CopyToClipboard'\nimport { primaryColor } from 'src/styling/variables'\nimport { formatCryptoAddress } from 'src/utils/coin'\n\nimport styles from './Funding.styles'\n\nconst useStyles = makeStyles(styles)\nconst sizes = {\n big: 165,\n time: 140,\n date: 130\n}\n\nconst GET_FUNDING = gql`\n {\n funding {\n cryptoCode\n errorMsg\n fundingAddress\n fundingAddressUrl\n confirmedBalance\n pending\n fiatConfirmedBalance\n fiatPending\n fiatCode\n display\n unitScale\n }\n }\n`\n\nconst formatAddress = (cryptoCode = '', address = '') =>\n formatCryptoAddress(cryptoCode, address).replace(/(.{4})/g, '$1 ')\nconst sumReducer = (acc, value) => acc.plus(value)\nconst formatNumber = it => new BigNumber(it).toFormat(2)\n\nconst getConfirmedTotal = list => {\n return formatNumber(\n list\n .filter(it => !it.errorMsg)\n .map(it => new BigNumber(it.fiatConfirmedBalance))\n .reduce(sumReducer, new BigNumber(0))\n )\n}\n\nconst getPendingTotal = list => {\n return formatNumber(\n list\n .filter(it => !it.errorMsg)\n .map(it => new BigNumber(it.fiatPending))\n .reduce(sumReducer, new BigNumber(0))\n )\n}\n\nconst Funding = () => {\n const [selected, setSelected] = useState(null)\n const [viewHistory] = useState(false)\n const classes = useStyles()\n const fundingHistory = [\n {\n cryptoAmount: 2.0,\n balance: 10.23,\n fiatValue: 1000.0,\n date: new Date(),\n performedBy: null,\n pending: true\n },\n {\n cryptoAmount: 10.0,\n balance: 12.23,\n fiatValue: 12000.0,\n date: new Date(),\n performedBy: null\n },\n {\n cryptoAmount: 5.0,\n balance: 5.0,\n fiatValue: 50000.0,\n date: new Date(),\n performedBy: null\n }\n ]\n\n const isSelected = it => {\n return selected && selected.cryptoCode === it.cryptoCode\n }\n\n const { data: fundingResponse } = useQuery(GET_FUNDING)\n const funding = R.path(['funding'])(fundingResponse) ?? []\n\n if (funding.length && !selected) {\n setSelected(funding[0])\n }\n\n const itemRender = (it, active) => {\n const itemClass = {\n [classes.item]: true,\n [classes.inactiveItem]: !active\n }\n const wrapperClass = {\n [classes.itemWrapper]: true,\n [classes.error]: it.errorMsg\n }\n\n return (\n \n
{it.display}
\n {!it.errorMsg && (\n <>\n
\n {formatNumber(it.fiatConfirmedBalance)} {it.fiatCode}\n
\n
\n {it.confirmedBalance} {it.cryptoCode}\n
\n >\n )}\n
\n )\n }\n\n const pendingTotal = getPendingTotal(funding)\n const signIfPositive = num => (num >= 0 ? '+' : '')\n\n return (\n <>\n \n
Funding \n {/* setViewHistory(!viewHistory)}>history */}\n \n \n
it.display}\n itemRender={itemRender}>\n {funding.length && (\n \n \n Total Crypto Balance\n \n \n {getConfirmedTotal(funding)}\n {funding[0].fiatCode}\n \n \n ({signIfPositive(pendingTotal)} {pendingTotal} pending)\n \n
\n )}\n \n {selected && !viewHistory && selected.errorMsg && (\n
\n
\n {selected.errorMsg} \n
\n
\n )}\n {selected && !viewHistory && !selected.errorMsg && (\n
\n
\n
Balance ({selected.display}) \n
\n \n {`${selected.confirmedBalance} ${selected.cryptoCode}`}\n \n \n {`(${signIfPositive(selected.pending)} ${\n selected.pending\n } pending)`}\n \n
\n\n
\n \n {`= ${formatNumber(selected.fiatConfirmedBalance)} ${\n selected.fiatCode\n }`}\n \n \n {`(${signIfPositive(selected.fiatPending)} ${formatNumber(\n selected.fiatPending\n )} pending)`}\n \n
\n\n
Address \n
\n
\n \n \n {formatAddress(\n selected.cryptoCode,\n selected.fundingAddress\n )}\n \n \n
\n
\n
\n\n
\n Scan to send {selected.display} \n \n
\n
\n )}\n {selected && viewHistory && (\n
\n
\n
\n \n \n Amount Entered\n \n \n Balance After\n \n \n Cash Value\n \n \n Date\n \n \n Time (h:m:s)\n \n \n Performed By\n \n \n \n {fundingHistory.map((it, idx) => (\n \n \n {it.cryptoAmount} {selected.cryptoCode}\n \n \n {it.balance} {selected.cryptoCode}\n \n \n {it.fiatValue} {selected.fiatCode}\n \n \n {moment(it.date).format('YYYY-MM-DD')}\n \n \n {moment(it.date).format('hh:mm:ss')}\n \n add \n \n ))}\n \n
\n
\n )}\n
\n >\n )\n}\n\nexport default Funding\n","import * as R from 'ramda'\r\n\r\nconst secretTest = secret => ({\r\n test(val) {\r\n if (R.isNil(secret) && R.isNil(val)) {\r\n return this.createError()\r\n }\r\n return true\r\n }\r\n})\r\n\r\nexport default secretTest\r\n","import * as Yup from 'yup'\n\nimport {\n TextInput,\n SecretInput,\n Autocomplete\n} from 'src/components/inputs/formik'\n\nimport secretTest from './helper'\n\nconst isDefined = it => it && it.length\n\nconst buildTestValidation = (id, passphrase) => {\n return Yup.string()\n .max(100, 'Too long')\n .when(id, {\n is: isDefined,\n then: Yup.string().test(secretTest(passphrase))\n })\n}\n\nexport default {\n code: 'bitgo',\n name: 'BitGo',\n title: 'BitGo (Wallet)',\n elements: [\n {\n code: 'token',\n display: 'API Token',\n component: TextInput,\n face: true,\n long: true\n },\n {\n code: 'environment',\n display: 'Environment',\n component: Autocomplete,\n inputProps: {\n options: [\n { code: 'prod', display: 'prod' },\n { code: 'test', display: 'test' }\n ],\n labelProp: 'display',\n valueProp: 'code'\n },\n face: true\n },\n {\n code: 'BTCWalletId',\n display: 'BTC Wallet ID',\n component: TextInput\n },\n {\n code: 'BTCWalletPassphrase',\n display: 'BTC Wallet Passphrase',\n component: SecretInput\n },\n {\n code: 'LTCWalletId',\n display: 'LTC Wallet ID',\n component: TextInput\n },\n {\n code: 'LTCWalletPassphrase',\n display: 'LTC Wallet Passphrase',\n component: SecretInput\n },\n {\n code: 'ZECWalletId',\n display: 'ZEC Wallet ID',\n component: TextInput\n },\n {\n code: 'ZECWalletPassphrase',\n display: 'ZEC Wallet Passphrase',\n component: SecretInput\n },\n {\n code: 'BCHWalletId',\n display: 'BCH Wallet ID',\n component: TextInput\n },\n {\n code: 'BCHWalletPassphrase',\n display: 'BCH Wallet Passphrase',\n component: SecretInput\n },\n {\n code: 'DASHWalletId',\n display: 'DASH Wallet ID',\n component: TextInput\n },\n {\n code: 'DASHWalletPassphrase',\n display: 'DASH Wallet Passphrase',\n component: SecretInput\n }\n ],\n getValidationSchema: account => {\n return Yup.object().shape({\n token: Yup.string()\n .max(100, 'Too long')\n .required(),\n BTCWalletId: Yup.string().max(100, 'Too long'),\n BTCWalletPassphrase: buildTestValidation(\n 'BTCWalletId',\n account?.BTCWalletPassphrase\n ),\n LTCWalletId: Yup.string().max(100, 'Too long'),\n LTCWalletPassphrase: buildTestValidation(\n 'LTCWalletId',\n account?.LTCWalletPassphrase\n ),\n ZECWalletId: Yup.string().max(100, 'Too long'),\n ZECWalletPassphrase: buildTestValidation(\n 'ZECWalletId',\n account?.ZECWalletPassphrase\n ),\n BCHWalletId: Yup.string().max(100, 'Too long'),\n BCHWalletPassphrase: buildTestValidation(\n 'BCHWalletId',\n account?.BCHWalletPassphrase\n ),\n DASHWalletId: Yup.string().max(100, 'Too long'),\n DASHWalletPassphrase: buildTestValidation(\n 'DASHWalletId',\n account?.DASHWalletPassphrase\n ),\n environment: Yup.string()\n .matches(/(prod|test)/)\n .required()\n })\n }\n}\n","import * as Yup from 'yup'\n\nimport SecretInputFormik from 'src/components/inputs/formik/SecretInput'\nimport TextInputFormik from 'src/components/inputs/formik/TextInput'\n\nimport secretTest from './helper'\n\nexport default {\n code: 'bitstamp',\n name: 'Bitstamp',\n title: 'Bitstamp (Exchange)',\n elements: [\n {\n code: 'clientId',\n display: 'Client ID',\n component: TextInputFormik,\n face: true,\n long: true\n },\n {\n code: 'key',\n display: 'API Key',\n component: TextInputFormik,\n face: true,\n long: true\n },\n {\n code: 'secret',\n display: 'API Secret',\n component: SecretInputFormik\n }\n ],\n getValidationSchema: account => {\n return Yup.object().shape({\n clientId: Yup.string()\n .max(100, 'Too long')\n .required(),\n key: Yup.string()\n .max(100, 'Too long')\n .required(),\n secret: Yup.string()\n .max(100, 'Too long')\n .test(secretTest(account?.secret))\n })\n }\n}\n","import * as Yup from 'yup'\n\nimport TextInputFormik from 'src/components/inputs/formik/TextInput'\n\nexport default {\n code: 'blockcypher',\n name: 'Blockcypher',\n title: 'Blockcypher (Payments)',\n elements: [\n {\n code: 'token',\n display: 'API Token',\n component: TextInputFormik,\n face: true,\n long: true\n },\n {\n code: 'confidenceFactor',\n display: 'Confidence Factor',\n component: TextInputFormik,\n face: true\n }\n ],\n getValidationSchema: () => {\n return Yup.object().shape({\n token: Yup.string()\n .max(100, 'Too long')\n .required(),\n confidenceFactor: Yup.number()\n .integer('Please input a positive integer')\n .positive('Please input a positive integer')\n .required()\n })\n }\n}\n","import * as Yup from 'yup'\n\nimport SecretInputFormik from 'src/components/inputs/formik/SecretInput'\nimport TextInputFormik from 'src/components/inputs/formik/TextInput'\n\nimport secretTest from './helper'\n\nexport default {\n code: 'infura',\n name: 'Infura',\n title: 'Infura (Wallet)',\n elements: [\n {\n code: 'apiKey',\n display: 'Project ID',\n component: TextInputFormik,\n face: true,\n long: true\n },\n {\n code: 'apiSecret',\n display: 'Project Secret',\n component: SecretInputFormik\n },\n {\n code: 'endpoint',\n display: 'Endpoint',\n component: TextInputFormik,\n face: true\n }\n ],\n getValidationSchema: account => {\n return Yup.object().shape({\n apiKey: Yup.string()\n .max(100, 'Too long')\n .required(),\n apiSecret: Yup.string()\n .max(100, 'Too long')\n .test(secretTest(account?.apiSecret)),\n endpoint: Yup.string()\n .max(100, 'Too long')\n .required()\n })\n }\n}\n","import * as Yup from 'yup'\n\nimport SecretInputFormik from 'src/components/inputs/formik/SecretInput'\nimport TextInputFormik from 'src/components/inputs/formik/TextInput'\n\nimport secretTest from './helper'\n\nexport default {\n code: 'itbit',\n name: 'itBit',\n title: 'itBit (Exchange)',\n elements: [\n {\n code: 'userId',\n display: 'User ID',\n component: TextInputFormik,\n face: true,\n long: true\n },\n {\n code: 'walletId',\n display: 'Wallet ID',\n component: TextInputFormik,\n face: true,\n long: true\n },\n {\n code: 'clientKey',\n display: 'Client Key',\n component: TextInputFormik\n },\n {\n code: 'clientSecret',\n display: 'Client Secret',\n component: SecretInputFormik\n }\n ],\n getValidationSchema: account => {\n return Yup.object().shape({\n userId: Yup.string()\n .max(100, 'Too long')\n .required(),\n walletId: Yup.string()\n .max(100, 'Too long')\n .required(),\n clientKey: Yup.string()\n .max(100, 'Too long')\n .required(),\n clientSecret: Yup.string()\n .max(100, 'Too long')\n .test(secretTest(account?.clientSecret))\n })\n }\n}\n","import * as Yup from 'yup'\n\nimport SecretInputFormik from 'src/components/inputs/formik/SecretInput'\nimport TextInputFormik from 'src/components/inputs/formik/TextInput'\n\nimport secretTest from './helper'\n\nexport default {\n code: 'kraken',\n name: 'Kraken',\n title: 'Kraken (Exchange)',\n elements: [\n {\n code: 'apiKey',\n display: 'API Key',\n component: TextInputFormik,\n face: true,\n long: true\n },\n {\n code: 'privateKey',\n display: 'Private Key',\n component: SecretInputFormik\n }\n ],\n getValidationSchema: account => {\n return Yup.object().shape({\n apiKey: Yup.string()\n .max(100, 'Too long')\n .required(),\n privateKey: Yup.string()\n .max(100, 'Too long')\n .test(secretTest(account?.privateKey))\n })\n }\n}\n","import * as Yup from 'yup'\n\nimport TextInputFormik from 'src/components/inputs/formik/TextInput'\n\nexport default {\n code: 'mailgun',\n name: 'Mailgun',\n title: 'Mailgun (Email)',\n elements: [\n {\n code: 'apiKey',\n display: 'API Key',\n component: TextInputFormik\n },\n {\n code: 'domain',\n display: 'Domain',\n component: TextInputFormik\n },\n {\n code: 'fromEmail',\n display: 'From Email',\n component: TextInputFormik,\n face: true\n },\n {\n code: 'toEmail',\n display: 'To Email',\n component: TextInputFormik,\n face: true\n }\n ],\n getValidationSchema: () => {\n return Yup.object().shape({\n apiKey: Yup.string()\n .max(100, 'Too long')\n .required(),\n domain: Yup.string()\n .max(100, 'Too long')\n .required(),\n fromEmail: Yup.string()\n .max(100, 'Too long')\n .email('Please input a valid email address')\n .required(),\n toEmail: Yup.string()\n .max(100, 'Too long')\n .email('Please input a valid email address')\n .required()\n })\n }\n}\n","import * as Yup from 'yup'\n\nimport SecretInputFormik from 'src/components/inputs/formik/SecretInput'\nimport TextInputFormik from 'src/components/inputs/formik/TextInput'\n\nimport secretTest from './helper'\n\nexport default {\n code: 'twilio',\n name: 'Twilio',\n title: 'Twilio (SMS)',\n elements: [\n {\n code: 'accountSid',\n display: 'Account SID',\n component: TextInputFormik\n },\n {\n code: 'authToken',\n display: 'Auth Token',\n component: SecretInputFormik\n },\n {\n code: 'fromNumber',\n display: 'Twilio Number (international format)',\n component: TextInputFormik,\n face: true\n },\n {\n code: 'toNumber',\n display: 'Notifications Number (international format)',\n component: TextInputFormik,\n face: true\n }\n ],\n getValidationSchema: account => {\n return Yup.object().shape({\n accountSid: Yup.string()\n .max(100, 'Too long')\n .required(),\n authToken: Yup.string()\n .max(100, 'Too long')\n .test(secretTest(account?.authToken)),\n fromNumber: Yup.string()\n .max(100, 'Too long')\n .required(),\n toNumber: Yup.string()\n .max(100, 'Too long')\n .required()\n })\n }\n}\n","import bitgo from './bitgo'\nimport bitstamp from './bitstamp'\nimport blockcypher from './blockcypher'\nimport infura from './infura'\nimport itbit from './itbit'\nimport kraken from './kraken'\nimport mailgun from './mailgun'\nimport twilio from './twilio'\n\nexport default {\n [bitgo.code]: bitgo,\n [bitstamp.code]: bitstamp,\n [blockcypher.code]: blockcypher,\n [infura.code]: infura,\n [itbit.code]: itbit,\n [kraken.code]: kraken,\n [mailgun.code]: mailgun,\n [twilio.code]: twilio\n}\n","function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport * as React from \"react\";\n\nvar _ref2 = /*#__PURE__*/React.createElement(\"circle\", {\n cx: 52,\n cy: 32,\n r: 32,\n fill: \"#F7931A\"\n});\n\nvar _ref3 = /*#__PURE__*/React.createElement(\"path\", {\n d: \"m66.1 27.4c0.6-4.3-2.6-6.5-7-8.1l1.4-5.8-3.5-0.9-1.4 5.6c-0.9-0.2-1.9-0.4-2.8-0.7l1.4-5.7-3.5-0.9-1.4 5.8c-0.8-0.2-1.5-0.3-2.2-0.5l0 0-4.8-1.2-0.9 3.8s2.6 0.6 2.6 0.6c1.4 0.4 1.7 1.3 1.6 2l-1.6 6.6c0.1 0 0.2 0.1 0.4 0.1-0.1 0-0.2-0.1-0.4-0.1l-2.3 9.2c-0.2 0.4-0.6 1.1-1.6 0.8 0 0.1-2.6-0.6-2.6-0.6l-1.7 4 4.6 1.1c0.9 0.2 1.7 0.4 2.5 0.6l-1.5 5.8 3.5 0.9 1.4-5.8c1 0.3 1.9 0.5 2.8 0.7l-1.4 5.7 3.5 0.9 1.5-5.8c6 1.1 10.5 0.7 12.4-4.7 1.5-4.4-0.1-6.9-3.2-8.5 2.3-0.5 4-2 4.5-5.2zm-8 11.2c-1.1 4.4-8.4 2-10.8 1.4l1.9-7.7c2.4 0.6 10 1.8 8.9 6.3zm1.1-11.3c-1 4-7.1 2-9.1 1.5l1.7-7c2 0.5 8.4 1.4 7.3 5.6z\",\n fill: \"#FFF\"\n});\n\nfunction SvgIconBitcoinColour(_ref, svgRef) {\n var title = _ref.title,\n titleId = _ref.titleId,\n props = _objectWithoutProperties(_ref, [\"title\", \"titleId\"]);\n\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n xmlns: \"http://www.w3.org/2000/svg\",\n width: 104,\n height: 64,\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, _ref2, _ref3);\n}\n\nvar ForwardRef = /*#__PURE__*/React.forwardRef(SvgIconBitcoinColour);\nexport default __webpack_public_path__ + \"static/media/icon-bitcoin-colour.bd8da481.svg\";\nexport { ForwardRef as ReactComponent };","function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport * as React from \"react\";\n\nvar _ref2 = /*#__PURE__*/React.createElement(\"path\", {\n fill: \"#0AC18E\",\n d: \"m0,0l29.7,0a39,39,0,0,0,0,64l-29.7,0zm52,0a32,32,0,0,0,0,64a32,32,0,0,0,0,-64m52,0l-29.7,0a39,39,0,0,1,0,64l29.7,0z\"\n});\n\nvar _ref3 = /*#__PURE__*/React.createElement(\"path\", {\n fill: \"#FFF\",\n transform: \"rotate(-28 52 32)\",\n d: \"m66.103,27.444c0.637-4.258-2.605-6.547-7.038-8.074l1.438-5.768-3.511-0.875-1.4,5.616c-0.923-0.23-1.871-0.447-2.813-0.662l1.41-5.653-3.509-0.875-1.439,5.766c-0.764-0.174-1.514-0.346-2.242-0.527l0.004-0.018-4.842-1.209-0.934,3.75s2.605,0.597,2.55,0.634c1.422,0.355,1.679,1.296,1.636,2.042l-1.638,6.571c0.098,0.025,0.225,0.061,0.365,0.117-0.117-0.029-0.242-0.061-0.371-0.092l-2.296,9.205c-0.174,0.432-0.615,1.08-1.609,0.834,0.035,0.051-2.552-0.637-2.552-0.637l-1.743,4.019,4.569,1.139c0.85,0.213,1.683,0.436,2.503,0.646l-1.453,5.834,3.507,0.875,1.439-5.772c0.958,0.26,1.888,0.5,2.798,0.726l-1.434,5.745,3.511,0.875,1.453-5.823c5.987,1.133,10.489,0.676,12.384-4.739,1.527-4.36-0.076-6.875-3.226-8.515,2.294-0.529,4.022-2.038,4.483-5.155zm-8.022,11.249c-1.085,4.36-8.426,2.003-10.806,1.412l1.928-7.729c2.38,0.594,10.012,1.77,8.878,6.317zm1.086-11.312c-0.99,3.966-7.1,1.951-9.082,1.457l1.748-7.01c1.982,0.494,8.365,1.416,7.334,5.553z\"\n});\n\nfunction SvgIconBitcoincashColour(_ref, svgRef) {\n var title = _ref.title,\n titleId = _ref.titleId,\n props = _objectWithoutProperties(_ref, [\"title\", \"titleId\"]);\n\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n xmlns: \"http://www.w3.org/2000/svg\",\n width: 104,\n height: 64,\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, _ref2, _ref3);\n}\n\nvar ForwardRef = /*#__PURE__*/React.forwardRef(SvgIconBitcoincashColour);\nexport default __webpack_public_path__ + \"static/media/icon-bitcoincash-colour.ed917caa.svg\";\nexport { ForwardRef as ReactComponent };","function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport * as React from \"react\";\n\nvar _ref2 = /*#__PURE__*/React.createElement(\"circle\", {\n cx: 1000,\n cy: 1000,\n r: 1000,\n fill: \"#2573c2\"\n});\n\nvar _ref3 = /*#__PURE__*/React.createElement(\"g\", {\n fill: \"#fff\"\n}, /*#__PURE__*/React.createElement(\"path\", {\n d: \"M1652.6 736.8a143.65 143.65 0 0 0-19.2-63.6c-10-20-27.8-35.6-48.6-43.6a143.51 143.51 0 0 0-68.4-15H628.8l-63.6 190.6h804.2l-127 389.6h-804l-63.6 190.6h891.8a246.33 246.33 0 0 0 77.8-15c25-14.2 53.6-28.6 77.8-48.6a382.69 382.69 0 0 0 63.6-63.6 432.2 432.2 0 0 0 39.2-73.4l117.8-370.4a137.38 137.38 0 0 0 9.8-77.6z\"\n}), /*#__PURE__*/React.createElement(\"path\", {\n d: \"M882.2 911.6H409l-63.6 176.2h478z\"\n}));\n\nfunction SvgIconDashColour(_ref, svgRef) {\n var title = _ref.title,\n titleId = _ref.titleId,\n props = _objectWithoutProperties(_ref, [\"title\", \"titleId\"]);\n\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n xmlns: \"http://www.w3.org/2000/svg\",\n viewBox: \"0 0 2000 2000\",\n width: 2500,\n height: 2500,\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, _ref2, _ref3);\n}\n\nvar ForwardRef = /*#__PURE__*/React.forwardRef(SvgIconDashColour);\nexport default __webpack_public_path__ + \"static/media/icon-dash-colour.e01c021b.svg\";\nexport { ForwardRef as ReactComponent };","function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport * as React from \"react\";\n\nvar _ref2 = /*#__PURE__*/React.createElement(\"g\", null, /*#__PURE__*/React.createElement(\"polygon\", {\n fill: \"#343434\",\n points: \"127.9611 0 125.1661 9.5 125.1661 285.168 127.9611 287.958 255.9231 212.32\"\n}), /*#__PURE__*/React.createElement(\"polygon\", {\n fill: \"#8C8C8C\",\n points: \"127.962 0 0 212.32 127.962 287.959 127.962 154.158\"\n}), /*#__PURE__*/React.createElement(\"polygon\", {\n fill: \"#3C3C3B\",\n points: \"127.9611 312.1866 126.3861 314.1066 126.3861 412.3056 127.9611 416.9066 255.9991 236.5866\"\n}), /*#__PURE__*/React.createElement(\"polygon\", {\n fill: \"#8C8C8C\",\n points: \"127.962 416.9052 127.962 312.1852 0 236.5852\"\n}), /*#__PURE__*/React.createElement(\"polygon\", {\n fill: \"#141414\",\n points: \"127.9611 287.9577 255.9211 212.3207 127.9611 154.1587\"\n}), /*#__PURE__*/React.createElement(\"polygon\", {\n fill: \"#393939\",\n points: \"0.0009 212.3208 127.9609 287.9578 127.9609 154.1588\"\n}));\n\nfunction SvgIconEthereumColour(_ref, svgRef) {\n var title = _ref.title,\n titleId = _ref.titleId,\n props = _objectWithoutProperties(_ref, [\"title\", \"titleId\"]);\n\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n width: \"256px\",\n height: \"417px\",\n viewBox: \"0 0 256 417\",\n xmlns: \"http://www.w3.org/2000/svg\",\n xmlnsXlink: \"http://www.w3.org/1999/xlink\",\n preserveAspectRatio: \"xMidYMid\",\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, _ref2);\n}\n\nvar ForwardRef = /*#__PURE__*/React.forwardRef(SvgIconEthereumColour);\nexport default __webpack_public_path__ + \"static/media/icon-ethereum-colour.761723a2.svg\";\nexport { ForwardRef as ReactComponent };","function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport * as React from \"react\";\n\nvar _ref2 = /*#__PURE__*/React.createElement(\"circle\", {\n fill: \"#989898\",\n cx: 52,\n cy: 32,\n r: 32\n});\n\nvar _ref3 = /*#__PURE__*/React.createElement(\"path\", {\n fill: \"#FFF\",\n d: \"m46.92598,12.31703l-4.97801,18.8088l-3.42705,1.32711l-1.64691,6.17189l3.42705,-1.29514l-2.8461,10.76083l30.60893,0l2.09993,-7.98401l-18.42505,0l2.09993,-7.82412l3.3631,-1.26316l1.6469,-6.17188l-3.36309,1.29513l3.6509,-13.83611l-12.21053,0z\"\n});\n\nfunction SvgIconLitecoinColour(_ref, svgRef) {\n var title = _ref.title,\n titleId = _ref.titleId,\n props = _objectWithoutProperties(_ref, [\"title\", \"titleId\"]);\n\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n xmlns: \"http://www.w3.org/2000/svg\",\n width: 104,\n height: 64,\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, _ref2, _ref3);\n}\n\nvar ForwardRef = /*#__PURE__*/React.forwardRef(SvgIconLitecoinColour);\nexport default __webpack_public_path__ + \"static/media/icon-litecoin-colour.bd861b5e.svg\";\nexport { ForwardRef as ReactComponent };","function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport * as React from \"react\";\n\nvar _ref2 = /*#__PURE__*/React.createElement(\"style\", {\n type: \"text/css\"\n}, \"\\n\\t.st0{fill:#231F20;}\\n\\t.st1{fill:#F4B728;}\\n\");\n\nvar _ref3 = /*#__PURE__*/React.createElement(\"path\", {\n className: \"st0\",\n d: \"M245.4,20C121.1,20,20,121.1,20,245.4s101.1,225.4,225.4,225.4s225.4-101.1,225.4-225.4S369.7,20,245.4,20z M245.4,433.6c-103.8,0-188.2-84.4-188.2-188.2S141.6,57.2,245.4,57.2s188.2,84.4,188.2,188.2S349.2,433.6,245.4,433.6z\"\n});\n\nvar _ref4 = /*#__PURE__*/React.createElement(\"circle\", {\n className: \"st1\",\n cx: 245.4,\n cy: 245.4,\n r: 177.6\n});\n\nvar _ref5 = /*#__PURE__*/React.createElement(\"polygon\", {\n className: \"st0\",\n points: \"165,315.5 165,349.9 226.5,349.9 226.5,387.6 264.3,387.6 264.3,349.9 325.8,349.9 325.8,304.4 230.4,304.4 325.8,175 325.8,140.6 264.3,140.6 264.3,103 226.5,103 226.5,140.6 165,140.6 165,186.2 260.4,186.2 \"\n});\n\nfunction SvgIconZcashColour(_ref, svgRef) {\n var title = _ref.title,\n titleId = _ref.titleId,\n props = _objectWithoutProperties(_ref, [\"title\", \"titleId\"]);\n\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n id: \"Layer_1\",\n xmlns: \"http://www.w3.org/2000/svg\",\n xmlnsXlink: \"http://www.w3.org/1999/xlink\",\n x: \"0px\",\n y: \"0px\",\n viewBox: \"0 0 493.3 490.2\",\n style: {\n enableBackground: \"new 0 0 493.3 490.2\"\n },\n xmlSpace: \"preserve\",\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), _ref2, title === undefined ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, \"headerArtboard 7\") : title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, _ref3, _ref4, _ref5);\n}\n\nvar ForwardRef = /*#__PURE__*/React.forwardRef(SvgIconZcashColour);\nexport default __webpack_public_path__ + \"static/media/icon-zcash-colour.68b1c20b.svg\";\nexport { ForwardRef as ReactComponent };","import { makeStyles } from '@material-ui/core'\nimport React from 'react'\n\nimport { Button } from 'src/components/buttons'\nimport { H1, P } from 'src/components/typography'\nimport { ReactComponent as BitcoinLogo } from 'src/styling/logos/icon-bitcoin-colour.svg'\nimport { ReactComponent as BitcoinCashLogo } from 'src/styling/logos/icon-bitcoincash-colour.svg'\nimport { ReactComponent as DashLogo } from 'src/styling/logos/icon-dash-colour.svg'\nimport { ReactComponent as EthereumLogo } from 'src/styling/logos/icon-ethereum-colour.svg'\nimport { ReactComponent as LitecoinLogo } from 'src/styling/logos/icon-litecoin-colour.svg'\nimport { ReactComponent as ZcashLogo } from 'src/styling/logos/icon-zcash-colour.svg'\n\nconst styles = {\n logo: {\n maxHeight: 80,\n maxWidth: 200\n },\n title: {\n margin: [[24, 0, 32, 0]]\n },\n text: {\n margin: 0\n },\n button: {\n marginTop: 'auto',\n marginBottom: 58\n },\n modalContent: {\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n padding: [[0, 42]],\n flex: 1\n }\n}\n\nconst useStyles = makeStyles(styles)\n\nconst getLogo = code => {\n switch (code) {\n case 'BTC':\n return BitcoinLogo\n case 'BCH':\n return BitcoinCashLogo\n case 'DASH':\n return DashLogo\n case 'ETH':\n return EthereumLogo\n case 'LTC':\n return LitecoinLogo\n case 'ZEC':\n return ZcashLogo\n default:\n return null\n }\n}\n\nconst WizardSplash = ({ code, name, onContinue }) => {\n const classes = useStyles()\n const Logo = getLogo(code)\n\n return (\n \n
\n
Enable {name} \n
\n You are about to enable {name} on your system. This will allow you to\n use this cryptocurrency on your machines. To be able to do that, you’ll\n have to set up all the necessary 3rd party services.\n
\n
\n Start configuration\n \n
\n )\n}\n\nexport default WizardSplash\n","import { makeStyles, Grid } from '@material-ui/core'\nimport classnames from 'classnames'\nimport { Formik, Form, FastField } from 'formik'\nimport * as R from 'ramda'\nimport React from 'react'\n\nimport { Button } from 'src/components/buttons'\nimport { SecretInput } from 'src/components/inputs/formik'\n\nconst styles = {\n button: {\n margin: [['auto', 0, 32, 'auto']]\n },\n form: {\n flex: 1,\n display: 'flex',\n flexDirection: 'column'\n },\n grid: {\n marginBottom: 24,\n marginTop: 12\n }\n}\n\nconst useStyles = makeStyles(styles)\nconst FormRenderer = ({\n validationSchema,\n elements,\n value,\n save,\n buttonLabel = 'Save changes',\n buttonClass,\n xs = 12\n}) => {\n const classes = useStyles()\n\n const initialValues = R.compose(\n R.mergeAll,\n R.map(({ code }) => ({ [code]: (value && value[code]) ?? '' }))\n )(elements)\n\n const values = R.merge(initialValues, value)\n\n const saveNonEmptySecret = it => {\n const emptySecretFields = R.compose(\n R.map(R.prop('code')),\n R.filter(\n elem =>\n R.prop('component', elem) === SecretInput &&\n R.isEmpty(it[R.prop('code', elem)])\n )\n )(elements)\n return save(R.omit(emptySecretFields, it))\n }\n\n return (\n \n \n \n )\n}\n\nexport default FormRenderer\n","import { errorColor } from 'src/styling/variables'\n\nconst LABEL_WIDTH = 150\n\nexport default {\n title: {\n margin: [[0, 0, 12, 0]]\n },\n subtitle: {\n margin: [[32, 0, 21, 0]]\n },\n error: {\n color: errorColor\n },\n button: {\n marginLeft: 'auto'\n },\n submit: {\n display: 'flex',\n flexDirection: 'row',\n margin: [['auto', 0, 24]]\n },\n radioGroup: {\n flexDirection: 'row'\n },\n radioLabel: {\n width: LABEL_WIDTH,\n height: 48\n },\n radio: {\n padding: 4,\n margin: 4\n },\n setupNew: {\n display: 'flex',\n alignItems: 'center',\n height: 48\n },\n picker: {\n width: LABEL_WIDTH\n }\n}\n","import { makeStyles } from '@material-ui/core'\nimport classnames from 'classnames'\nimport * as R from 'ramda'\nimport React, { useReducer, useEffect } from 'react'\n\nimport ErrorMessage from 'src/components/ErrorMessage'\nimport Stepper from 'src/components/Stepper'\nimport { Button } from 'src/components/buttons'\nimport { RadioGroup, Autocomplete } from 'src/components/inputs'\nimport { H4, Info2 } from 'src/components/typography'\nimport FormRenderer from 'src/pages/Services/FormRenderer'\nimport schema from 'src/pages/Services/schemas'\nimport { startCase } from 'src/utils/string'\n\nimport styles from './WizardStep.styles'\n\nconst useStyles = makeStyles(styles)\n\nconst initialState = {\n form: null,\n selected: null,\n isNew: false,\n iError: false\n}\n\nconst reducer = (state, action) => {\n switch (action.type) {\n case 'select':\n return {\n form: null,\n selected: action.selected,\n isNew: null,\n iError: false\n }\n case 'new':\n return { form: state.form, selected: null, isNew: true, iError: false }\n case 'form':\n return {\n form: action.form,\n selected: action.form.code,\n isNew: true,\n iError: false\n }\n case 'error':\n return R.merge(state, { innerError: true })\n case 'reset':\n return initialState\n default:\n throw new Error()\n }\n}\n\nconst WizardStep = ({\n type,\n name,\n step,\n error,\n lastStep,\n onContinue,\n filled,\n unfilled,\n getValue\n}) => {\n const classes = useStyles()\n const [{ innerError, selected, form, isNew }, dispatch] = useReducer(\n reducer,\n initialState\n )\n\n useEffect(() => {\n dispatch({ type: 'reset' })\n }, [step])\n\n const innerContinue = (config, account) => {\n if (!config || !config[type]) {\n return dispatch({ type: 'error' })\n }\n onContinue(config, account)\n }\n\n const label = lastStep ? 'Finish' : 'Next'\n const displayName = name ?? type\n const subtitleClass = {\n [classes.subtitle]: true,\n [classes.error]: innerError\n }\n\n return (\n <>\n {startCase(type)} \n \n \n Select a {displayName} or set up a new one\n \n {\n dispatch({ type: 'select', selected: it })\n }}\n labelClassName={classes.radioLabel}\n radioClassName={classes.radio}\n />\n \n {!R.isEmpty(unfilled) && !R.isNil(unfilled) && (\n
{\n dispatch({ type: 'new' })\n }}\n labelClassName={classes.radioLabel}\n radioClassName={classes.radio}\n options={[{ display: 'Set up new', code: true }]}\n />\n )}\n {isNew && (\n {\n dispatch({ type: 'form', form: it })\n }}\n />\n )}\n \n {form && (\n innerContinue({ [type]: form.code }, { [form.code]: it })}\n elements={schema[form.code].elements}\n validationSchema={schema[form.code].validationSchema}\n value={getValue(form.code)}\n buttonLabel={label}\n />\n )}\n {!form && (\n \n {error && Failed to save }\n innerContinue({ [type]: selected })}>\n {label}\n \n
\n )}\n >\n )\n}\n\nexport default WizardStep\n","import * as R from 'ramda'\nimport React, { useState } from 'react'\n\nimport Modal from 'src/components/Modal'\nimport schema from 'src/pages/Services/schemas'\nimport { toNamespace } from 'src/utils/config'\n\nimport WizardSplash from './WizardSplash'\nimport WizardStep from './WizardStep'\n\nconst LAST_STEP = 4\nconst MODAL_WIDTH = 554\n\nconst contains = crypto => R.compose(R.contains(crypto), R.prop('cryptos'))\nconst sameClass = type => R.propEq('class', type)\nconst filterConfig = (crypto, type) =>\n R.filter(it => sameClass(type)(it) && contains(crypto)(it))\nconst removeDeprecated = R.filter(({ deprecated }) => !deprecated)\n\nconst getItems = (accountsConfig, accounts, type, crypto) => {\n const fConfig = removeDeprecated(filterConfig(crypto, type)(accountsConfig))\n\n const find = code => accounts && accounts[code]\n\n const [filled, unfilled] = R.partition(({ code }) => {\n const account = find(code)\n if (!schema[code]) return true\n\n const { getValidationSchema } = schema[code]\n return getValidationSchema(account).isValidSync(account)\n })(fConfig)\n\n return { filled, unfilled }\n}\n\nconst Wizard = ({ coin, onClose, accountsConfig, accounts, save, error }) => {\n const [{ step, config, accountsToSave }, setState] = useState({\n step: 0,\n config: { active: true },\n accountsToSave: {}\n })\n\n const title = `Enable ${coin.display}`\n const isLastStep = step === LAST_STEP\n\n const tickers = { filled: filterConfig(coin.code, 'ticker')(accountsConfig) }\n const wallets = getItems(accountsConfig, accounts, 'wallet', coin.code)\n const exchanges = getItems(accountsConfig, accounts, 'exchange', coin.code)\n const zeroConfs = getItems(accountsConfig, accounts, 'zeroConf', coin.code)\n\n const getValue = code => R.find(R.propEq('code', code))(accounts)\n\n const onContinue = async (stepConfig, stepAccount) => {\n const newConfig = R.merge(config, stepConfig)\n const newAccounts = stepAccount\n ? R.merge(accountsToSave, stepAccount)\n : accountsToSave\n\n if (isLastStep) {\n return save(toNamespace(coin.code, newConfig), newAccounts)\n }\n\n setState({\n step: step + 1,\n config: newConfig,\n accountsToSave: newAccounts\n })\n }\n\n const getStepData = () => {\n switch (step) {\n case 1:\n return { type: 'ticker', ...tickers }\n case 2:\n return { type: 'wallet', ...wallets }\n case 3:\n return { type: 'exchange', ...exchanges }\n case 4:\n return { type: 'zeroConf', name: 'zero conf', ...zeroConfs }\n default:\n return null\n }\n }\n\n return (\n \n {step === 0 && (\n onContinue()}\n />\n )}\n {step !== 0 && (\n \n )}\n \n )\n}\n\nexport default Wizard\n","import * as R from 'ramda'\nimport * as Yup from 'yup'\n\nimport Autocomplete from 'src/components/inputs/formik/Autocomplete.js'\n\nconst filterClass = type => R.filter(it => it.class === type)\nconst filterCoins = ({ id }) => R.filter(it => R.contains(id)(it.cryptos))\n\nconst WalletSchema = Yup.object().shape({\n ticker: Yup.string().required(),\n wallet: Yup.string().required(),\n exchange: Yup.string().required(),\n zeroConf: Yup.string().required()\n})\n\nconst getElements = (cryptoCurrencies, accounts, onChange, wizard = false) => {\n const widthAdjust = wizard ? 11 : 0\n const viewCryptoCurrency = it =>\n R.compose(\n R.prop(['display']),\n R.find(R.propEq('code', it))\n )(cryptoCurrencies)\n\n const filterOptions = type => filterClass(type)(accounts || [])\n\n const getDisplayName = type => it =>\n R.compose(\n R.prop('display'),\n R.find(R.propEq('code', it))\n )(filterOptions(type))\n\n const getOptions = R.curry((option, it) =>\n filterCoins(it)(filterOptions(option))\n )\n\n return [\n {\n name: 'id',\n header: 'Cryptocurrency',\n width: 180 - widthAdjust,\n view: viewCryptoCurrency,\n size: 'sm',\n editable: false\n },\n {\n name: 'ticker',\n size: 'sm',\n stripe: true,\n view: getDisplayName('ticker'),\n width: 190 - widthAdjust,\n input: Autocomplete,\n inputProps: {\n options: getOptions('ticker'),\n valueProp: 'code',\n labelProp: 'display',\n optionsLimit: null\n }\n },\n {\n name: 'wallet',\n size: 'sm',\n stripe: true,\n view: getDisplayName('wallet'),\n width: 190 - widthAdjust,\n input: Autocomplete,\n inputProps: {\n options: getOptions('wallet'),\n valueProp: 'code',\n labelProp: 'display',\n optionsLimit: null,\n onChange\n }\n },\n {\n name: 'exchange',\n size: 'sm',\n stripe: true,\n view: getDisplayName('exchange'),\n width: 190 - widthAdjust,\n input: Autocomplete,\n inputProps: {\n options: getOptions('exchange'),\n valueProp: 'code',\n labelProp: 'display',\n optionsLimit: null,\n onChange\n }\n },\n {\n name: 'zeroConf',\n header: 'Confidence Checking',\n size: 'sm',\n stripe: true,\n view: getDisplayName('zeroConf'),\n input: Autocomplete,\n width: 220 - widthAdjust,\n inputProps: {\n options: getOptions('zeroConf'),\n valueProp: 'code',\n labelProp: 'display',\n optionsLimit: null,\n onChange\n }\n }\n ]\n}\n\nexport { WalletSchema, getElements, filterClass }\n","import * as R from 'ramda'\nimport * as Yup from 'yup'\n\nimport Autocomplete from 'src/components/inputs/formik/Autocomplete.js'\n\nconst getFields = (getData, names, onChange, auxElements = []) => {\n return R.filter(\n it => R.includes(it.name, names),\n allFields(getData, onChange, auxElements)\n )\n}\n\nconst allFields = (getData, onChange, auxElements = []) => {\n const getView = (data, code, compare) => it => {\n if (!data) return ''\n\n return R.compose(\n R.prop(code),\n R.find(R.propEq(compare ?? 'code', it))\n )(data)\n }\n\n const displayCodeArray = data => it => {\n if (!it) return it\n\n return R.compose(R.join(', '), R.map(getView(data, 'code')))(it)\n }\n\n const overridenMachines = R.map(override => override.machine, auxElements)\n\n const suggestionFilter = it =>\n R.differenceWith((x, y) => x.deviceId === y, it, overridenMachines)\n\n const machineData = getData(['machines'])\n const countryData = getData(['countries'])\n const currencyData = getData(['currencies'])\n const languageData = getData(['languages'])\n const cryptoData = getData(['cryptoCurrencies'])\n\n const findSuggestion = it => {\n const machine = R.find(R.propEq('deviceId', it.machine))(machineData)\n return machine ? [machine] : []\n }\n\n return [\n {\n name: 'machine',\n width: 200,\n size: 'sm',\n view: getView(machineData, 'name', 'deviceId'),\n input: Autocomplete,\n inputProps: {\n options: it =>\n R.concat(findSuggestion(it))(suggestionFilter(machineData)),\n valueProp: 'deviceId',\n labelProp: 'name'\n }\n },\n {\n name: 'country',\n width: 200,\n size: 'sm',\n view: getView(countryData, 'display'),\n input: Autocomplete,\n inputProps: {\n options: countryData,\n valueProp: 'code',\n labelProp: 'display'\n }\n },\n {\n name: 'fiatCurrency',\n width: 150,\n size: 'sm',\n view: getView(currencyData, 'code'),\n input: Autocomplete,\n inputProps: {\n options: currencyData,\n valueProp: 'code',\n labelProp: 'code'\n }\n },\n {\n name: 'languages',\n width: 240,\n size: 'sm',\n view: displayCodeArray(languageData),\n input: Autocomplete,\n inputProps: {\n options: languageData,\n valueProp: 'code',\n labelProp: 'display',\n multiple: true\n }\n },\n {\n name: 'cryptoCurrencies',\n width: 290,\n size: 'sm',\n view: displayCodeArray(cryptoData),\n input: Autocomplete,\n inputProps: {\n options: cryptoData,\n valueProp: 'code',\n labelProp: 'code',\n multiple: true,\n optionsLimit: null,\n onChange\n }\n }\n ]\n}\n\nconst mainFields = (auxData, configureCoin) => {\n const getData = R.path(R.__, auxData)\n\n return getFields(\n getData,\n ['country', 'fiatCurrency', 'languages', 'cryptoCurrencies'],\n configureCoin\n )\n}\n\nconst overrides = (auxData, auxElements, configureCoin) => {\n const getData = R.path(R.__, auxData)\n\n return getFields(\n getData,\n ['machine', 'country', 'languages', 'cryptoCurrencies'],\n configureCoin,\n auxElements\n )\n}\n\nconst LocaleSchema = Yup.object().shape({\n country: Yup.string()\n .label('Country')\n .required(),\n fiatCurrency: Yup.string()\n .label('Fiat Currency')\n .required(),\n languages: Yup.array()\n .label('Languages')\n .required()\n .min(1)\n .max(4),\n cryptoCurrencies: Yup.array()\n .label('Crypto Currencies')\n .required()\n .min(1)\n})\n\nconst OverridesSchema = Yup.object().shape({\n machine: Yup.string()\n .label('Machine')\n .required(),\n country: Yup.string()\n .label('Country')\n .required(),\n languages: Yup.array()\n .label('Languages')\n .required()\n .min(1),\n cryptoCurrencies: Yup.array()\n .label('Crypto Currencies')\n .required()\n .min(1)\n})\n\nconst localeDefaults = {\n country: '',\n fiatCurrency: '',\n languages: [],\n cryptoCurrencies: []\n}\n\nconst overridesDefaults = {\n machine: '',\n country: '',\n languages: [],\n cryptoCurrencies: []\n}\n\nexport {\n mainFields,\n overrides,\n LocaleSchema,\n OverridesSchema,\n localeDefaults,\n overridesDefaults\n}\n","import { useQuery, useMutation } from '@apollo/react-hooks'\nimport { makeStyles } from '@material-ui/core/styles'\nimport gql from 'graphql-tag'\nimport * as R from 'ramda'\nimport React, { useState } from 'react'\n\nimport Modal from 'src/components/Modal'\nimport { Link } from 'src/components/buttons'\nimport { Table as EditableTable } from 'src/components/editableTable'\nimport Section from 'src/components/layout/Section'\nimport TitleSection from 'src/components/layout/TitleSection'\nimport { P } from 'src/components/typography'\nimport Wizard from 'src/pages/Wallet/Wizard'\nimport { WalletSchema } from 'src/pages/Wallet/helper'\nimport { fromNamespace, toNamespace, namespaces } from 'src/utils/config'\n\nimport { styles } from './Locales.styles'\nimport {\n mainFields,\n overrides,\n LocaleSchema,\n OverridesSchema,\n localeDefaults,\n overridesDefaults\n} from './helper'\n\nconst useStyles = makeStyles(styles)\n\nconst GET_DATA = gql`\n query getData {\n config\n accounts\n accountsConfig {\n code\n display\n class\n cryptos\n }\n currencies {\n code\n display\n }\n countries {\n code\n display\n }\n cryptoCurrencies {\n code\n display\n }\n languages {\n code\n display\n }\n machines {\n name\n deviceId\n }\n }\n`\n\nconst SAVE_CONFIG = gql`\n mutation Save($config: JSONObject) {\n saveConfig(config: $config)\n }\n`\n\nconst FiatCurrencyChangeAlert = ({ open, close, save }) => {\n const classes = useStyles()\n\n return (\n \n \n Please note that all values you set that were based on your prior fiat\n currency are still the same. If you need to adjust these to reflect the\n new fiat currency (such as minimum transaction amounts, fixed fees, and\n compliance triggers, for example), please do so now.\n
\n \n Also, if you have cash-out enabled, you must define new dispenser bill\n counts for the new currency for cash-out on the new currency to work.\n
\n \n \n Cancel\n \n \n Save\n \n
\n \n )\n}\n\nconst Locales = ({ name: SCREEN_KEY }) => {\n const [wizard, setWizard] = useState(false)\n const [onChangeFunction, setOnChangeFunction] = useState(null)\n const [error, setError] = useState(null)\n const [isEditingDefault, setEditingDefault] = useState(false)\n const [isEditingOverrides, setEditingOverrides] = useState(false)\n const { data } = useQuery(GET_DATA)\n const [saveConfig] = useMutation(SAVE_CONFIG, {\n onCompleted: () => setWizard(false),\n refetchQueries: () => ['getData'],\n onError: error => setError(error)\n })\n\n const [dataToSave, setDataToSave] = useState(null)\n\n const config = data?.config && fromNamespace(SCREEN_KEY)(data.config)\n const wallets = data?.config && fromNamespace(namespaces.WALLETS)(data.config)\n\n const accountsConfig = data?.accountsConfig\n const accounts = data?.accounts ?? []\n const cryptoCurrencies = data?.cryptoCurrencies ?? []\n const locale = config && !R.isEmpty(config) ? config : localeDefaults\n const localeOverrides = locale.overrides ?? []\n\n const handleSave = it => {\n const newConfig = toNamespace(SCREEN_KEY)(it.locale[0])\n\n if (\n config.fiatCurrency &&\n newConfig.locale_fiatCurrency !== config.fiatCurrency\n )\n return setDataToSave(newConfig)\n\n return save(newConfig)\n }\n\n const save = config => {\n setDataToSave(null)\n return saveConfig({ variables: { config } })\n }\n\n const saveOverrides = it => {\n const config = toNamespace(SCREEN_KEY)(it)\n setError(null)\n return saveConfig({ variables: { config } })\n }\n\n const onChangeCoin = (prev, curr, setValue) => {\n const coin = R.difference(curr, prev)[0]\n if (!coin) return setValue(curr)\n\n const namespaced = fromNamespace(coin)(wallets)\n if (!WalletSchema.isValidSync(namespaced)) {\n setOnChangeFunction(() => () => setValue(curr))\n setWizard(coin)\n return\n }\n\n setValue(curr)\n }\n\n const onEditingDefault = (it, editing) => setEditingDefault(editing)\n const onEditingOverrides = (it, editing) => setEditingOverrides(editing)\n\n const wizardSave = it =>\n save(toNamespace(namespaces.WALLETS)(it)).then(it => {\n onChangeFunction()\n setOnChangeFunction(null)\n return it\n })\n\n return (\n <>\n setDataToSave(null)}\n save={() => dataToSave && save(dataToSave)}\n />\n \n \n \n m.deviceId) ?? [],\n localeOverrides?.map(o => o.machine) ?? []\n )}\n setEditing={onEditingOverrides}\n forceDisable={isEditingDefault}\n />\n \n {wizard && (\n setWizard(false)}\n save={wizardSave}\n error={error?.message}\n cryptoCurrencies={cryptoCurrencies}\n userAccounts={data?.config?.accounts}\n accounts={accounts}\n accountsConfig={accountsConfig}\n />\n )}\n >\n )\n}\n\nexport default Locales\n","const styles = {\n rightAligned: {\n marginTop: '20px',\n marginLeft: 'auto',\n marginBottom: '20px'\n },\n rightLink: {\n marginLeft: '20px'\n }\n}\n\nexport { styles }\n","import Locales from './Locales'\n\nexport default Locales\n","import {\n spacer,\n fontPrimary,\n primaryColor,\n errorColor\n} from 'src/styling/variables'\n\nconst styles = {\n footer: {\n display: 'flex',\n flexDirection: 'row',\n margin: [['auto', 0, spacer * 3, 0]]\n },\n modalLabel1: {\n marginTop: 20\n },\n modalLabel2Wrapper: {\n marginTop: 40,\n display: 'flex',\n flexDirection: 'row',\n justifyContent: 'flex-start'\n },\n discountInput: {\n display: 'flex',\n flexDirection: 'row',\n alignItems: 'flex-start'\n },\n inputLabel: {\n color: primaryColor,\n fontFamily: fontPrimary,\n fontSize: 24,\n marginLeft: 8,\n marginTop: 15\n },\n tableWidth: {\n width: 620\n },\n error: {\n color: errorColor\n },\n form: {\n display: 'flex',\n flexDirection: 'column',\n height: '100%'\n },\n submit: {\n margin: [['auto', 0, 0, 'auto']]\n }\n}\n\nexport default styles\n","import { makeStyles } from '@material-ui/core/styles'\nimport { Form, Formik, Field } from 'formik'\nimport * as R from 'ramda'\nimport React from 'react'\nimport * as Yup from 'yup'\n\nimport ErrorMessage from 'src/components/ErrorMessage'\nimport Modal from 'src/components/Modal'\nimport { Tooltip } from 'src/components/Tooltip'\nimport { Button } from 'src/components/buttons'\nimport { TextInput, NumberInput } from 'src/components/inputs/formik'\nimport { H3, TL1, P } from 'src/components/typography'\n\nimport styles from './PromoCodes.styles'\n\nconst useStyles = makeStyles(styles)\n\nconst initialValues = {\n code: '',\n discount: ''\n}\n\nconst validationSchema = Yup.object().shape({\n code: Yup.string()\n .required()\n .trim()\n .max(25),\n discount: Yup.number()\n .required()\n .min(0)\n .max(100)\n})\n\nconst PromoCodesModal = ({ showModal, onClose, errorMsg, addCode }) => {\n const classes = useStyles()\n\n const handleAddCode = (code, discount) => {\n addCode(R.toUpper(code), parseInt(discount))\n }\n\n return (\n <>\n {showModal && (\n \n {\n handleAddCode(code, discount)\n }}>\n \n \n \n )}\n >\n )\n}\n\nexport default PromoCodesModal\n","import { useQuery, useMutation } from '@apollo/react-hooks'\nimport { makeStyles, Box } from '@material-ui/core'\nimport gql from 'graphql-tag'\nimport * as R from 'ramda'\nimport React, { useState } from 'react'\n\nimport { DeleteDialog } from 'src/components/DeleteDialog'\nimport { Link, Button, IconButton } from 'src/components/buttons'\nimport TitleSection from 'src/components/layout/TitleSection'\nimport DataTable from 'src/components/tables/DataTable'\nimport { H2, TL1 } from 'src/components/typography'\nimport { ReactComponent as DeleteIcon } from 'src/styling/icons/action/delete/enabled.svg'\n\nimport styles from './PromoCodes.styles'\nimport PromoCodesModal from './PromoCodesModal'\n\nconst useStyles = makeStyles(styles)\n\nconst DUPLICATE_ERROR_MSG = 'There is already a promotion with that code!'\nconst DEFAULT_ERROR_MSG = 'Failed to save'\n\nconst GET_PROMO_CODES = gql`\n query promoCodes {\n promoCodes {\n id\n code\n discount\n }\n }\n`\n\nconst DELETE_CODE = gql`\n mutation deletePromoCode($codeId: ID!) {\n deletePromoCode(codeId: $codeId) {\n id\n }\n }\n`\n\nconst CREATE_CODE = gql`\n mutation createPromoCode($code: String!, $discount: Int!) {\n createPromoCode(code: $code, discount: $discount) {\n id\n code\n discount\n }\n }\n`\n\nconst PromoCodes = () => {\n const classes = useStyles()\n\n const [deleteDialog, setDeleteDialog] = useState(false)\n const [toBeDeleted, setToBeDeleted] = useState()\n\n const [showModal, setShowModal] = useState(false)\n const [errorMsg, setErrorMsg] = useState(null)\n const toggleModal = () => setShowModal(!showModal)\n\n const { data: codeResponse, loading } = useQuery(GET_PROMO_CODES)\n\n const [deleteCode] = useMutation(DELETE_CODE, {\n onError: ({ message }) => {\n const errorMessage = message ?? 'Error while deleting row'\n setErrorMsg(errorMessage)\n },\n onCompleted: () => setDeleteDialog(false),\n refetchQueries: () => ['promoCodes']\n })\n\n const [createCode] = useMutation(CREATE_CODE, {\n refetchQueries: () => ['promoCodes']\n })\n\n const addCode = (code, discount) => {\n setErrorMsg(null)\n createCode({\n variables: { code: code, discount: discount }\n })\n .then(res => {\n if (!res.errors) return setShowModal(false)\n\n const duplicateCodeError = R.any(it =>\n R.includes('duplicate', it?.message)\n )(res.errors)\n\n const msg = duplicateCodeError ? DUPLICATE_ERROR_MSG : DEFAULT_ERROR_MSG\n setErrorMsg(msg)\n })\n .catch(err => {\n setErrorMsg(DEFAULT_ERROR_MSG)\n console.log(err)\n })\n }\n\n const elements = [\n {\n header: 'Code',\n width: 300,\n textAlign: 'left',\n size: 'sm',\n view: t => t.code\n },\n {\n header: 'Discount',\n width: 220,\n textAlign: 'left',\n size: 'sm',\n view: t => (\n <>\n {t.discount} % in commissions\n >\n )\n },\n {\n header: 'Delete',\n width: 100,\n textAlign: 'center',\n size: 'sm',\n view: t => (\n {\n setDeleteDialog(true)\n setToBeDeleted({ variables: { codeId: t.id } })\n }}>\n \n \n )\n }\n ]\n\n return (\n <>\n \n {!loading && !R.isEmpty(codeResponse.promoCodes) && (\n \n \n Add new code\n \n \n )}\n {!loading && !R.isEmpty(codeResponse.promoCodes) && (\n <>\n \n {\n setDeleteDialog(false)\n setErrorMsg(null)\n }}\n onConfirmed={() => {\n setErrorMsg(null)\n deleteCode(toBeDeleted)\n }}\n errorMessage={errorMsg}\n />\n >\n )}\n {!loading && R.isEmpty(codeResponse.promoCodes) && (\n \n Currently, there are no active promo codes on your network. \n Add Code \n \n )}\n {\n setErrorMsg(null)\n setShowModal(false)\n }}\n errorMsg={errorMsg}\n addCode={addCode}\n />\n >\n )\n}\nexport default PromoCodes\n","function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport * as React from \"react\";\n\nvar _ref2 = /*#__PURE__*/React.createElement(\"desc\", null, \"Created with Sketch.\");\n\nvar _ref3 = /*#__PURE__*/React.createElement(\"g\", {\n id: \"Symbols\",\n stroke: \"none\",\n strokeWidth: 1,\n fill: \"none\",\n fillRule: \"evenodd\",\n strokeLinecap: \"round\",\n strokeLinejoin: \"round\"\n}, /*#__PURE__*/React.createElement(\"g\", {\n id: \"pop-up/action/download-logs/date-range-copy-3\",\n transform: \"translate(-117.000000, -116.000000)\",\n stroke: \"#1B2559\",\n strokeWidth: 2\n}, /*#__PURE__*/React.createElement(\"g\", {\n id: \"arrow-download-logs\",\n transform: \"translate(128.500000, 124.500000) rotate(-90.000000) translate(-128.500000, -124.500000) translate(121.000000, 114.000000)\"\n}, /*#__PURE__*/React.createElement(\"polyline\", {\n id: \"Path-3\",\n points: \"0 13.3571429 7.14285714 20.5 14.2857143 13.3571429\"\n}), /*#__PURE__*/React.createElement(\"line\", {\n x1: 7.14285714,\n y1: 0.142857143,\n x2: 7.14285714,\n y2: 20.1428571,\n id: \"Path-4\"\n}))));\n\nfunction SvgDownloadLogs(_ref, svgRef) {\n var title = _ref.title,\n titleId = _ref.titleId,\n props = _objectWithoutProperties(_ref, [\"title\", \"titleId\"]);\n\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n width: \"23px\",\n height: \"17px\",\n viewBox: \"0 0 23 17\",\n xmlns: \"http://www.w3.org/2000/svg\",\n xmlnsXlink: \"http://www.w3.org/1999/xlink\",\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title === undefined ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, \"arrow download logs\") : title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, _ref2, _ref3);\n}\n\nvar ForwardRef = /*#__PURE__*/React.forwardRef(SvgDownloadLogs);\nexport default __webpack_public_path__ + \"static/media/download_logs.219c88ac.svg\";\nexport { ForwardRef as ReactComponent };","function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport * as React from \"react\";\n\nvar _ref2 = /*#__PURE__*/React.createElement(\"desc\", null, \"Created with Sketch.\");\n\nvar _ref3 = /*#__PURE__*/React.createElement(\"g\", {\n id: \"icon/button/download/white\",\n stroke: \"none\",\n strokeWidth: 1,\n fill: \"none\",\n fillRule: \"evenodd\",\n strokeLinecap: \"round\",\n strokeLinejoin: \"round\"\n}, /*#__PURE__*/React.createElement(\"g\", {\n id: \"icon/sf-small/wizzard\",\n stroke: \"#FFFFFF\"\n}, /*#__PURE__*/React.createElement(\"polyline\", {\n id: \"Path-3\",\n points: \"3.6 5.4 6 7.8 8.4 5.4\"\n}), /*#__PURE__*/React.createElement(\"line\", {\n x1: 6,\n y1: 0.5,\n x2: 6,\n y2: 7.4,\n id: \"Path-4\"\n}), /*#__PURE__*/React.createElement(\"path\", {\n d: \"M0,10 L0,10 C0,10.9942 0.8058,11.8 1.8,11.8 L10.2,11.8 C11.1942,11.8 12,10.9942 12,10\",\n id: \"Stroke-1\"\n})));\n\nfunction SvgWhite(_ref, svgRef) {\n var title = _ref.title,\n titleId = _ref.titleId,\n props = _objectWithoutProperties(_ref, [\"title\", \"titleId\"]);\n\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n width: \"12px\",\n height: \"12px\",\n viewBox: \"0 0 12 12\",\n xmlns: \"http://www.w3.org/2000/svg\",\n xmlnsXlink: \"http://www.w3.org/1999/xlink\",\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, _ref2, _ref3);\n}\n\nvar ForwardRef = /*#__PURE__*/React.forwardRef(SvgWhite);\nexport default __webpack_public_path__ + \"static/media/white.81edd31f.svg\";\nexport { ForwardRef as ReactComponent };","function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport * as React from \"react\";\n\nvar _ref2 = /*#__PURE__*/React.createElement(\"desc\", null, \"Created with Sketch.\");\n\nvar _ref3 = /*#__PURE__*/React.createElement(\"g\", {\n id: \"icon/button/download/zodiac\",\n stroke: \"none\",\n strokeWidth: 1,\n fill: \"none\",\n fillRule: \"evenodd\",\n strokeLinecap: \"round\",\n strokeLinejoin: \"round\"\n}, /*#__PURE__*/React.createElement(\"g\", {\n id: \"icon/sf-small/wizzard\",\n stroke: \"#1B2559\"\n}, /*#__PURE__*/React.createElement(\"polyline\", {\n id: \"Path-3\",\n points: \"3.6 5.4 6 7.8 8.4 5.4\"\n}), /*#__PURE__*/React.createElement(\"line\", {\n x1: 6,\n y1: 0.5,\n x2: 6,\n y2: 7.4,\n id: \"Path-4\"\n}), /*#__PURE__*/React.createElement(\"path\", {\n d: \"M0,10 L0,10 C0,10.9942 0.8058,11.8 1.8,11.8 L10.2,11.8 C11.1942,11.8 12,10.9942 12,10\",\n id: \"Stroke-1\"\n})));\n\nfunction SvgZodiac(_ref, svgRef) {\n var title = _ref.title,\n titleId = _ref.titleId,\n props = _objectWithoutProperties(_ref, [\"title\", \"titleId\"]);\n\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n width: \"12px\",\n height: \"12px\",\n viewBox: \"0 0 12 12\",\n xmlns: \"http://www.w3.org/2000/svg\",\n xmlnsXlink: \"http://www.w3.org/1999/xlink\",\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, _ref2, _ref3);\n}\n\nvar ForwardRef = /*#__PURE__*/React.forwardRef(SvgZodiac);\nexport default __webpack_public_path__ + \"static/media/zodiac.13543418.svg\";\nexport { ForwardRef as ReactComponent };","function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport * as React from \"react\";\n\nvar _ref2 = /*#__PURE__*/React.createElement(\"desc\", null, \"Created with Sketch.\");\n\nvar _ref3 = /*#__PURE__*/React.createElement(\"g\", {\n id: \"Symbols\",\n stroke: \"none\",\n strokeWidth: 1,\n fill: \"none\",\n fillRule: \"evenodd\"\n}, /*#__PURE__*/React.createElement(\"g\", {\n id: \"pop-up/action/download-logs/date-range-copy-2\",\n transform: \"translate(-20.000000, -187.000000)\"\n}, /*#__PURE__*/React.createElement(\"g\", {\n id: \"icon/sf-contain-b-copy-5\",\n transform: \"translate(30.000000, 197.000000) rotate(-270.000000) translate(-30.000000, -197.000000) translate(20.000000, 187.000000)\"\n}, /*#__PURE__*/React.createElement(\"g\", {\n id: \"icon/sf-small/wizzard\",\n strokeLinecap: \"round\",\n strokeLinejoin: \"round\"\n}, /*#__PURE__*/React.createElement(\"g\", {\n transform: \"translate(6.666667, 6.000000)\",\n id: \"Group\"\n}, /*#__PURE__*/React.createElement(\"g\", null, /*#__PURE__*/React.createElement(\"polyline\", {\n id: \"Path-3\",\n stroke: \"#1B2559\",\n strokeWidth: 2,\n points: \"0 4.83333333 3.33333333 8.16666667 6.66666667 4.83333333\"\n}), /*#__PURE__*/React.createElement(\"line\", {\n x1: 3.33333333,\n y1: 0.25,\n x2: 3.33333333,\n y2: 6.5,\n id: \"Path-4\",\n stroke: \"#1B2559\",\n strokeWidth: 2\n})))))));\n\nfunction SvgMonthChange(_ref, svgRef) {\n var title = _ref.title,\n titleId = _ref.titleId,\n props = _objectWithoutProperties(_ref, [\"title\", \"titleId\"]);\n\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n width: \"20px\",\n height: \"20px\",\n viewBox: \"0 0 20 20\",\n xmlns: \"http://www.w3.org/2000/svg\",\n xmlnsXlink: \"http://www.w3.org/1999/xlink\",\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, _ref2, _ref3);\n}\n\nvar ForwardRef = /*#__PURE__*/React.forwardRef(SvgMonthChange);\nexport default __webpack_public_path__ + \"static/media/month_change.58940268.svg\";\nexport { ForwardRef as ReactComponent };","function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport * as React from \"react\";\n\nvar _ref2 = /*#__PURE__*/React.createElement(\"desc\", null, \"Created with Sketch.\");\n\nvar _ref3 = /*#__PURE__*/React.createElement(\"g\", {\n id: \"Symbols\",\n stroke: \"none\",\n strokeWidth: 1,\n fill: \"none\",\n fillRule: \"evenodd\"\n}, /*#__PURE__*/React.createElement(\"g\", {\n id: \"pop-up/action/download-logs/date-range-copy-2\",\n transform: \"translate(-20.000000, -187.000000)\"\n}, /*#__PURE__*/React.createElement(\"g\", {\n id: \"icon/sf-contain-b-copy-5\",\n transform: \"translate(30.000000, 197.000000) rotate(270.000000) translate(-30.000000, -197.000000) translate(20.000000, 187.000000)\"\n}, /*#__PURE__*/React.createElement(\"g\", {\n id: \"icon/sf-small/wizzard\",\n strokeLinecap: \"round\",\n strokeLinejoin: \"round\"\n}, /*#__PURE__*/React.createElement(\"g\", {\n transform: \"translate(6.666667, 6.000000)\",\n id: \"Group\"\n}, /*#__PURE__*/React.createElement(\"g\", null, /*#__PURE__*/React.createElement(\"polyline\", {\n id: \"Path-3\",\n stroke: \"#1B2559\",\n strokeWidth: 2,\n points: \"0 4.83333333 3.33333333 8.16666667 6.66666667 4.83333333\"\n}), /*#__PURE__*/React.createElement(\"line\", {\n x1: 3.33333333,\n y1: 0.25,\n x2: 3.33333333,\n y2: 6.5,\n id: \"Path-4\",\n stroke: \"#1B2559\",\n strokeWidth: 2\n})))))));\n\nfunction SvgMonthChangeRight(_ref, svgRef) {\n var title = _ref.title,\n titleId = _ref.titleId,\n props = _objectWithoutProperties(_ref, [\"title\", \"titleId\"]);\n\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n width: \"20px\",\n height: \"20px\",\n viewBox: \"0 0 20 20\",\n xmlns: \"http://www.w3.org/2000/svg\",\n xmlnsXlink: \"http://www.w3.org/1999/xlink\",\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, _ref2, _ref3);\n}\n\nvar ForwardRef = /*#__PURE__*/React.forwardRef(SvgMonthChangeRight);\nexport default __webpack_public_path__ + \"static/media/month_change_right.0c3eb9a1.svg\";\nexport { ForwardRef as ReactComponent };","import { makeStyles } from '@material-ui/core/styles'\nimport classnames from 'classnames'\nimport React from 'react'\n\nimport typographyStyles from 'src/components/typography/styles'\nimport {\n primaryColor,\n spring2,\n spring3,\n disabledColor\n} from 'src/styling/variables'\n\nconst { label1 } = typographyStyles\n\nconst styles = {\n wrapper: {\n height: 26,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n position: 'relative',\n overflow: 'hidden'\n },\n button: {\n outline: 'none',\n extend: label1,\n border: 'none',\n cursor: 'pointer',\n backgroundColor: 'transparent',\n color: primaryColor,\n zIndex: 2\n },\n lowerBound: {\n left: '50%'\n },\n upperBound: {\n right: '50%'\n },\n selected: {\n width: 26,\n height: 26,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n backgroundColor: spring2,\n borderRadius: '50%',\n position: 'absolute',\n zIndex: 1\n },\n between: {\n position: 'absolute',\n width: '100%',\n height: '100%',\n zIndex: 0,\n backgroundColor: spring3\n },\n disabled: {\n color: disabledColor,\n cursor: 'default'\n }\n}\n\nconst useStyles = makeStyles(styles)\n\nconst Tile = ({\n isLowerBound,\n isUpperBound,\n isBetween,\n isDisabled,\n children,\n ...props\n}) => {\n const classes = useStyles()\n const selected = isLowerBound || isUpperBound\n\n const rangeClasses = {\n [classes.between]: isBetween && !(isLowerBound && isUpperBound),\n [classes.lowerBound]: isLowerBound && !isUpperBound,\n [classes.upperBound]: isUpperBound && !isLowerBound\n }\n\n const buttonWrapperClasses = {\n [classes.wrapper]: true,\n [classes.selected]: selected\n }\n\n const buttonClasses = {\n [classes.button]: true,\n [classes.disabled]: isDisabled\n }\n\n return (\n \n )\n}\n\nexport default Tile\n","import { makeStyles } from '@material-ui/core/styles'\nimport moment from 'moment'\nimport * as R from 'ramda'\nimport React, { useState } from 'react'\n\nimport typographyStyles from 'src/components/typography/styles'\nimport { ReactComponent as Arrow } from 'src/styling/icons/arrow/month_change.svg'\nimport { ReactComponent as RightArrow } from 'src/styling/icons/arrow/month_change_right.svg'\nimport { primaryColor, zircon } from 'src/styling/variables'\n\nimport Tile from './Tile'\n\nconst { p, label2 } = typographyStyles\n\nconst styles = {\n wrapper: {\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center'\n },\n button: {\n outline: 'none'\n },\n navbar: {\n extend: p,\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'center',\n width: '100%',\n padding: [[15, 15]],\n color: primaryColor,\n '& button': {\n display: 'flex',\n alignItems: 'center',\n padding: 0,\n border: 'none',\n backgroundColor: zircon,\n cursor: 'pointer',\n borderRadius: '50%',\n width: 20,\n height: 20,\n position: 'relative',\n overflow: 'hidden',\n '& svg': {\n position: 'absolute',\n left: 0\n }\n }\n },\n table: {\n borderCollapse: 'collapse',\n width: '100%',\n color: primaryColor,\n '& tr': {\n '&:first-child': {\n paddingLeft: 5\n },\n '&:last-child': {\n paddingRight: 5\n }\n },\n '& th, & td': {\n margin: 0,\n padding: [[3, 0, 3, 0]]\n },\n '& th': {\n extend: label2\n }\n }\n}\n\nconst useStyles = makeStyles(styles)\n\nconst Calendar = ({ minDate, maxDate, handleSelect, ...props }) => {\n const [currentDisplayedMonth, setCurrentDisplayedMonth] = useState(moment())\n\n const classes = useStyles()\n\n const weekdays = moment.weekdaysMin().map(day => day.slice(0, 1))\n const monthLength = month =>\n Number.parseInt(\n moment(month)\n .endOf('month')\n .format('D')\n )\n\n const monthdays = month => {\n const lastMonth = moment(month).subtract(1, 'month')\n const lastMonthRange = R.range(\n 0,\n moment(month)\n .startOf('month')\n .weekday()\n ).reverse()\n const lastMonthDays = R.map(i =>\n moment(lastMonth)\n .endOf('month')\n .subtract(i, 'days')\n )(lastMonthRange)\n\n const thisMonthRange = R.range(0, monthLength(month))\n const thisMonthDays = R.map(i =>\n moment(month)\n .startOf('month')\n .add(i, 'days')\n )(thisMonthRange)\n\n const nextMonth = moment(month).add(1, 'month')\n const nextMonthRange = R.range(\n 0,\n 42 - lastMonthDays.length - thisMonthDays.length\n )\n const nextMonthDays = R.map(i =>\n moment(nextMonth)\n .startOf('month')\n .add(i, 'days')\n )(nextMonthRange)\n\n return R.concat(R.concat(lastMonthDays, thisMonthDays), nextMonthDays)\n }\n\n const getRow = (month, row) => monthdays(month).slice(row * 7 - 7, row * 7)\n\n const handleNavPrev = currentMonth => {\n const prevMonth = moment(currentMonth).subtract(1, 'month')\n if (!minDate) setCurrentDisplayedMonth(prevMonth)\n else {\n setCurrentDisplayedMonth(\n prevMonth.isSameOrAfter(minDate, 'month')\n ? prevMonth\n : currentDisplayedMonth\n )\n }\n }\n const handleNavNext = currentMonth => {\n const nextMonth = moment(currentMonth).add(1, 'month')\n if (!maxDate) setCurrentDisplayedMonth(nextMonth)\n else {\n setCurrentDisplayedMonth(\n nextMonth.isSameOrBefore(maxDate, 'month')\n ? nextMonth\n : currentDisplayedMonth\n )\n }\n }\n\n return (\n \n
\n
handleNavPrev(currentDisplayedMonth)}>\n \n \n
\n {`${currentDisplayedMonth.format(\n 'MMMM'\n )} ${currentDisplayedMonth.format('YYYY')}`}\n \n
handleNavNext(currentDisplayedMonth)}>\n \n \n
\n
\n \n \n {weekdays.map((day, key) => (\n {day} \n ))}\n \n \n \n {R.range(1, 8).map((row, key) => (\n \n {getRow(currentDisplayedMonth, row).map((day, key) => (\n handleSelect(day, minDate, maxDate)}>\n \n {day.format('D')}\n \n \n ))}\n \n ))}\n \n
\n
\n )\n}\n\nexport default Calendar\n","import { makeStyles } from '@material-ui/core/styles'\nimport classnames from 'classnames'\nimport moment from 'moment'\nimport React, { useState, useEffect } from 'react'\n\nimport Calendar from './Calendar'\n\nconst styles = {\n wrapper: {\n backgroundColor: 'white',\n borderRadius: 10\n }\n}\n\nconst useStyles = makeStyles(styles)\n\nconst DateRangePicker = ({ minDate, maxDate, className, onRangeChange }) => {\n const [from, setFrom] = useState(null)\n const [to, setTo] = useState(null)\n\n useEffect(() => {\n onRangeChange(from, to)\n }, [from, onRangeChange, to])\n\n const classes = useStyles()\n\n const handleSelect = (day, minDate, maxDate) => {\n if (\n (maxDate && day.isAfter(maxDate, 'day')) ||\n (minDate && day.isBefore(minDate, 'day'))\n )\n return\n\n if (from && !to && day.isBefore(from, 'day')) {\n setTo(from)\n setFrom(day)\n return\n }\n\n if (from && !to && day.isSameOrAfter(from, 'day')) {\n setTo(moment(day.toDate().setHours(23, 59, 59, 999)))\n return\n }\n\n setFrom(day)\n setTo(null)\n }\n\n return (\n <>\n \n \n
\n >\n )\n}\n\nexport default DateRangePicker\n","import { useLazyQuery } from '@apollo/react-hooks'\nimport { makeStyles, ClickAwayListener } from '@material-ui/core'\nimport classnames from 'classnames'\nimport FileSaver from 'file-saver'\nimport moment from 'moment'\nimport * as R from 'ramda'\nimport React, { useState, useCallback } from 'react'\n\nimport { FeatureButton, Link } from 'src/components/buttons'\nimport { ReactComponent as Arrow } from 'src/styling/icons/arrow/download_logs.svg'\nimport { ReactComponent as DownloadInverseIcon } from 'src/styling/icons/button/download/white.svg'\nimport { ReactComponent as Download } from 'src/styling/icons/button/download/zodiac.svg'\nimport { primaryColor, offColor, zircon } from 'src/styling/variables'\n\nimport Popper from './Popper'\nimport DateRangePicker from './date-range-picker/DateRangePicker'\nimport { RadioGroup } from './inputs'\nimport typographyStyles from './typography/styles'\n\nconst { info1, label1, label2, h4 } = typographyStyles\n\nconst dateContainerStyles = {\n wrapper: {\n height: 46,\n width: 99\n },\n container: {\n display: 'flex'\n },\n monthWeekDayContainer: {\n display: 'flex',\n flexDirection: 'column'\n },\n label: {\n extend: label1,\n lineHeight: 1.33,\n color: primaryColor\n },\n bigNumber: {\n extend: info1,\n lineHeight: 1,\n marginRight: 7\n },\n monthYear: {\n extend: label2,\n lineHeight: 1.17,\n color: primaryColor\n },\n weekDay: {\n extend: label1,\n lineHeight: 1.33,\n color: offColor\n }\n}\n\nconst dateContainerUseStyles = makeStyles(dateContainerStyles)\n\nconst DateContainer = ({ date, children, ...props }) => {\n const classes = dateContainerUseStyles()\n\n return (\n \n
{children}
\n {date && (\n <>\n
\n
{date.format('D')}
\n
\n {`${date.format(\n 'MMM'\n )} ${date.format('YYYY')}`} \n {date.format('dddd')} \n
\n
\n >\n )}\n
\n )\n}\n\nconst styles = {\n popoverContent: {\n width: 280\n },\n popoverHeader: {\n extend: h4,\n padding: [[15, 15, 0, 15]]\n },\n radioButtonsContainer: {\n padding: [[5, 15, 5, 15]]\n },\n radioButtons: {\n display: 'flex',\n justifyContent: 'space-between',\n flexDirection: 'row',\n color: primaryColor\n },\n dateRangePickerShowing: {\n display: 'block',\n height: '100%'\n },\n dateRangePickerHidden: {\n display: 'none',\n height: 0\n },\n download: {\n padding: [[10, 15]]\n },\n dateContainerWrapper: {\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'center',\n position: 'relative',\n backgroundColor: zircon,\n padding: [[0, 15]],\n minHeight: 70\n },\n arrowContainer: {\n position: 'absolute',\n left: 125,\n top: 26\n },\n arrow: {\n margin: 'auto'\n }\n}\n\nconst useStyles = makeStyles(styles)\nconst ALL = 'all'\nconst RANGE = 'range'\nconst ADVANCED = 'advanced'\nconst SIMPLIFIED = 'simplified'\n\nconst LogsDownloaderPopover = ({\n name,\n query,\n args,\n title,\n getLogs,\n simplified\n}) => {\n const [selectedRadio, setSelectedRadio] = useState(ALL)\n const [selectedAdvancedRadio, setSelectedAdvancedRadio] = useState(ADVANCED)\n\n const [range, setRange] = useState({ from: null, until: null })\n const [anchorEl, setAnchorEl] = useState(null)\n const [fetchLogs] = useLazyQuery(query, {\n onCompleted: data => createLogsFile(getLogs(data), range)\n })\n\n const classes = useStyles()\n\n const dateRangePickerClasses = {\n [classes.dateRangePickerShowing]: selectedRadio === RANGE,\n [classes.dateRangePickerHidden]: selectedRadio === ALL\n }\n\n const handleRadioButtons = evt => {\n const selectedRadio = R.path(['target', 'value'])(evt)\n setSelectedRadio(selectedRadio)\n if (selectedRadio === ALL) setRange({ from: null, until: null })\n }\n\n const handleAdvancedRadioButtons = evt => {\n const selectedAdvancedRadio = R.path(['target', 'value'])(evt)\n setSelectedAdvancedRadio(selectedAdvancedRadio)\n }\n\n const handleRangeChange = useCallback(\n (from, until) => {\n setRange({ from, until })\n },\n [setRange]\n )\n\n const downloadLogs = (range, args) => {\n if (selectedRadio === ALL) {\n fetchLogs({\n variables: {\n ...args,\n simplified: selectedAdvancedRadio === SIMPLIFIED\n }\n })\n }\n\n if (!range || !range.from) return\n if (range.from && !range.until) range.until = moment()\n\n if (selectedRadio === RANGE) {\n fetchLogs({\n variables: {\n ...args,\n from: range.from,\n until: range.until,\n simplified: selectedAdvancedRadio === SIMPLIFIED\n }\n })\n }\n }\n\n const createLogsFile = (logs, range) => {\n const formatDateFile = date => {\n return moment(date).format('YYYY-MM-DD_HH-mm')\n }\n\n const blob = new window.Blob([logs], {\n type: 'text/plain;charset=utf-8'\n })\n\n FileSaver.saveAs(\n blob,\n selectedRadio === ALL\n ? `${formatDateFile(new Date())}_${name}.csv`\n : `${formatDateFile(range.from)}_${formatDateFile(\n range.until\n )}_${name}.csv`\n )\n }\n\n const handleOpenRangePicker = event => {\n setAnchorEl(anchorEl ? null : event.currentTarget)\n }\n\n const handleClickAway = () => {\n setAnchorEl(null)\n }\n\n const radioButtonOptions = [\n { display: 'All logs', code: ALL },\n { display: 'Date range', code: RANGE }\n ]\n\n const advancedRadioButtonOptions = [\n { display: 'Advanced logs', code: ADVANCED },\n { display: 'Simplified logs', code: SIMPLIFIED }\n ]\n\n const open = Boolean(anchorEl)\n const id = open ? 'date-range-popover' : undefined\n\n return (\n \n \n
\n
\n \n
{title}
\n
\n \n
\n {selectedRadio === RANGE && (\n
\n
\n {range && (\n <>\n
From \n
\n
To \n >\n )}\n
\n
\n
\n )}\n {simplified && (\n
\n \n
\n )}\n
\n downloadLogs(range, args)}>\n Download\n \n
\n
\n \n
\n \n )\n}\n\nexport default LogsDownloaderPopover\n","import { useQuery } from '@apollo/react-hooks'\nimport { makeStyles } from '@material-ui/core/styles'\nimport gql from 'graphql-tag'\nimport moment from 'moment'\nimport * as R from 'ramda'\nimport React, { useState } from 'react'\n\nimport LogsDowloaderPopover from 'src/components/LogsDownloaderPopper'\nimport Title from 'src/components/Title'\nimport Sidebar from 'src/components/layout/Sidebar'\nimport {\n Table,\n TableHead,\n TableRow,\n TableHeader,\n TableBody,\n TableCell\n} from 'src/components/table'\nimport { Info3, H4 } from 'src/components/typography'\n\nimport styles from './Logs.styles'\n\nconst useStyles = makeStyles(styles)\n\nconst GET_MACHINES = gql`\n {\n machines {\n name\n deviceId\n }\n }\n`\n\nconst NUM_LOG_RESULTS = 500\n\nconst GET_MACHINE_LOGS_CSV = gql`\n query MachineLogs($deviceId: ID!, $limit: Int, $from: Date, $until: Date) {\n machineLogsCsv(\n deviceId: $deviceId\n limit: $limit\n from: $from\n until: $until\n )\n }\n`\n\nconst GET_MACHINE_LOGS = gql`\n query MachineLogs($deviceId: ID!, $limit: Int, $from: Date, $until: Date) {\n machineLogs(\n deviceId: $deviceId\n limit: $limit\n from: $from\n until: $until\n ) {\n logLevel\n id\n timestamp\n message\n }\n }\n`\n\nconst formatDate = date => {\n return moment(date).format('YYYY-MM-DD HH:mm')\n}\n\nconst Logs = () => {\n const classes = useStyles()\n\n const [selected, setSelected] = useState(null)\n const [saveMessage, setSaveMessage] = useState(null)\n\n const deviceId = selected?.deviceId\n\n const { data: machineResponse } = useQuery(GET_MACHINES)\n\n const { data: logsResponse, loading } = useQuery(GET_MACHINE_LOGS, {\n variables: { deviceId, limit: NUM_LOG_RESULTS },\n skip: !selected,\n onCompleted: () => setSaveMessage('')\n })\n\n if (machineResponse?.machines?.length && !selected) {\n setSelected(machineResponse?.machines[0])\n }\n\n const isSelected = it => {\n return R.path(['deviceId'])(selected) === it.deviceId\n }\n\n return (\n <>\n \n
\n
Machine Logs \n {logsResponse && (\n
\n R.path(['machineLogsCsv'])(logs)}\n />\n {saveMessage} \n
\n )}\n
\n
\n \n
it.name}\n data={machineResponse?.machines || []}\n isSelected={isSelected}\n onClick={setSelected}\n />\n \n
\n \n \n Date \n Level \n \n \n \n \n {logsResponse &&\n logsResponse.machineLogs.map((log, idx) => (\n \n {formatDate(log.timestamp)} \n {log.logLevel} \n {log.message} \n \n ))}\n \n
\n {loading &&
{'Loading...'} }\n {!loading && !logsResponse?.machineLogs?.length && (\n
{'No activity so far'} \n )}\n
\n \n >\n )\n}\n\nexport default Logs\n","const styles = {\n cashbox: {\n width: 80,\n height: 36\n }\n}\n\nexport default styles\n","import { useMutation } from '@apollo/react-hooks'\nimport { makeStyles } from '@material-ui/core'\nimport gql from 'graphql-tag'\nimport React from 'react'\nimport * as Yup from 'yup'\n\nimport { Table as EditableTable } from 'src/components/editableTable'\nimport { CashOut, CashIn } from 'src/components/inputs/cashbox/Cashbox'\nimport { NumberInput } from 'src/components/inputs/formik'\nimport { fromNamespace } from 'src/utils/config'\n\nimport styles from './Cassettes.styles'\n\nconst useStyles = makeStyles(styles)\n\nconst ValidationSchema = Yup.object().shape({\n name: Yup.string().required('Required'),\n cashbox: Yup.number()\n .label('Cashbox')\n .required()\n .integer()\n .min(0)\n .max(1000),\n cassette1: Yup.number()\n .required('Required')\n .integer()\n .min(0)\n .max(500),\n cassette2: Yup.number()\n .required('Required')\n .integer()\n .min(0)\n .max(500)\n})\n\nconst SET_CASSETTE_BILLS = gql`\n mutation MachineAction(\n $deviceId: ID!\n $action: MachineAction!\n $cashbox: Int!\n $cassette1: Int!\n $cassette2: Int!\n ) {\n machineAction(\n deviceId: $deviceId\n action: $action\n cashbox: $cashbox\n cassette1: $cassette1\n cassette2: $cassette2\n ) {\n deviceId\n cashbox\n cassette1\n cassette2\n }\n }\n`\n\nconst CashCassettes = ({ machine, config, refetchData }) => {\n const data = { machine, config }\n const classes = useStyles()\n\n const cashout = data?.config && fromNamespace('cashOut')(data.config)\n const locale = data?.config && fromNamespace('locale')(data.config)\n const fiatCurrency = locale?.fiatCurrency\n\n const getCashoutSettings = deviceId => fromNamespace(deviceId)(cashout)\n const isCashOutDisabled = ({ deviceId }) =>\n !getCashoutSettings(deviceId).active\n\n const elements = [\n {\n name: 'cashbox',\n header: 'Cashbox',\n width: 240,\n stripe: false,\n view: value => (\n \n ),\n input: NumberInput,\n inputProps: {\n decimalPlaces: 0\n }\n },\n {\n name: 'cassette1',\n header: 'Cash-out 1',\n width: 265,\n stripe: true,\n view: (value, { deviceId }) => (\n \n ),\n input: NumberInput,\n inputProps: {\n decimalPlaces: 0\n }\n },\n {\n name: 'cassette2',\n header: 'Cash-out 2',\n width: 265,\n stripe: true,\n view: (value, { deviceId }) => {\n return (\n \n )\n },\n input: NumberInput,\n inputProps: {\n decimalPlaces: 0\n }\n }\n ]\n\n const [setCassetteBills, { error }] = useMutation(SET_CASSETTE_BILLS, {\n refetchQueries: () => refetchData()\n })\n\n const onSave = (...[, { deviceId, cashbox, cassette1, cassette2 }]) => {\n return setCassetteBills({\n variables: {\n action: 'setCassetteBills',\n deviceId: deviceId,\n cashbox,\n cassette1,\n cassette2\n }\n })\n }\n\n return machine.name ? (\n \n ) : null\n}\n\nexport default CashCassettes\n","import Cassettes from './Cassettes'\nexport default Cassettes\n","import React from 'react'\n\nimport { ReactComponent as TxInIcon } from 'src/styling/icons/direction/cash-in.svg'\nimport { ReactComponent as TxOutIcon } from 'src/styling/icons/direction/cash-out.svg'\n\nconst cashInAndOutHeaderStyle = { marginLeft: 6 }\n\nconst cashInHeader = (\n \n \n Cash-in \n
\n)\n\nconst cashOutHeader = (\n \n \n Cash-out \n
\n)\n\nconst getOverridesFields = currency => {\n return [\n {\n name: 'name',\n width: 280,\n size: 'sm',\n view: it => `${it}`\n },\n {\n header: cashInHeader,\n name: 'cashIn',\n display: 'Cash-in',\n width: 130,\n textAlign: 'right',\n suffix: '%'\n },\n {\n header: cashOutHeader,\n name: 'cashOut',\n display: 'Cash-out',\n width: 130,\n textAlign: 'right',\n suffix: '%',\n inputProps: {\n decimalPlaces: 3\n }\n },\n {\n name: 'fixedFee',\n display: 'Fixed fee',\n width: 144,\n doubleHeader: 'Cash-in only',\n textAlign: 'right',\n suffix: currency\n },\n {\n name: 'minimumTx',\n display: 'Minimun Tx',\n width: 144,\n doubleHeader: 'Cash-in only',\n textAlign: 'right',\n suffix: currency\n }\n ]\n}\n\nconst overrides = currency => {\n return getOverridesFields(currency)\n}\n\nexport { overrides }\n","import { useQuery, useMutation } from '@apollo/react-hooks'\nimport gql from 'graphql-tag'\nimport * as R from 'ramda'\nimport React from 'react'\n\nimport { Table as EditableTable } from 'src/components/editableTable'\nimport { fromNamespace, toNamespace, namespaces } from 'src/utils/config'\n\nimport { overrides } from './helper'\n\nconst GET_DATA = gql`\n query getData {\n config\n cryptoCurrencies {\n code\n display\n }\n machines {\n name\n deviceId\n }\n }\n`\n\nconst SAVE_CONFIG = gql`\n mutation Save($config: JSONObject) {\n saveConfig(config: $config)\n }\n`\n\nconst Commissions = ({ name: SCREEN_KEY, id: deviceId }) => {\n const { data, loading } = useQuery(GET_DATA)\n const [saveConfig] = useMutation(SAVE_CONFIG, {\n refetchQueries: () => ['getData']\n })\n\n const config = data?.config && fromNamespace(SCREEN_KEY)(data.config)\n const currency = R.path(['fiatCurrency'])(\n fromNamespace(namespaces.LOCALE)(data?.config)\n )\n\n const saveOverrides = it => {\n const config = toNamespace(SCREEN_KEY)(it)\n return saveConfig({ variables: { config } })\n }\n\n const getMachineCommissions = () => {\n if (loading || !deviceId || !config) {\n return []\n }\n const commissions = {}\n\n // first, get general non overridden commissions\n const makeInfo = x =>\n (commissions[R.prop('code')(x)] = {\n code: x.code,\n name: x.display,\n cashIn: config.cashIn,\n cashOut: config.cashOut,\n fixedFee: config.fixedFee,\n minimumTx: config.minimumTx\n })\n R.forEach(makeInfo)(data.cryptoCurrencies)\n\n // second, get overrides for all machines\n const isId = id => R.propEq('machine', id)\n const generalOverrides = config.overrides\n ? R.filter(isId('ALL_MACHINES'))(config.overrides)\n : []\n\n const overrideInfo = o => {\n commissions[o.cryptoCurrencies[0]].cashIn = o.cashIn\n commissions[o.cryptoCurrencies[0]].cashOut = o.cashOut\n commissions[o.cryptoCurrencies[0]].fixedFee = o.fixedFee\n commissions[o.cryptoCurrencies[0]].minimumTx = o.minimumTx\n }\n R.forEach(overrideInfo)(generalOverrides)\n\n // third, get overrides for this machine\n const machineOverrides = config.overrides\n ? R.filter(isId(deviceId))(config.overrides)\n : []\n R.forEach(overrideInfo)(machineOverrides)\n\n // in the end, the machine specific overrides overwrite the less general ALL_MACHINE overrides or the general overrides\n return R.values(commissions)\n }\n\n const machineCommissions = getMachineCommissions()\n\n return (\n \n )\n}\n\nexport default Commissions\n","import Commissions from './Commissions'\n\nexport default Commissions\n","import { spacer, comet } from 'src/styling/variables'\n\nconst styles = {\n grid: {\n flex: 1,\n height: '100%'\n },\n content: {\n display: 'flex',\n flexDirection: 'column',\n flex: 1,\n marginLeft: spacer * 6,\n maxWidth: 900\n },\n subtitle: {\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'center',\n flexDirection: 'row',\n color: comet\n },\n label3: {\n color: comet,\n marginTop: 0\n },\n row: {\n display: 'flex',\n flexDirection: 'row',\n justifyContent: 'space-around'\n },\n rowItem: {\n flex: 1,\n marginBottom: spacer * 2\n },\n detailItem: {\n marginBottom: spacer * 4\n },\n actionButtonsContainer: {\n display: 'flex',\n flexDirection: 'row'\n },\n breadcrumbsContainer: {\n marginTop: 32\n },\n breadcrumbLink: {\n textDecoration: 'none'\n },\n detailsMargin: {\n marginTop: 24\n },\n sidebarContainer: {\n height: 400,\n overflowY: 'auto'\n }\n}\n\nexport default styles\n","import { makeStyles } from '@material-ui/core/styles'\nimport moment from 'moment'\nimport React from 'react'\n\nimport { Label3, P } from 'src/components/typography'\n\nimport styles from '../Machines.styles'\nconst useStyles = makeStyles(styles)\n\nconst Details = ({ data }) => {\n const classes = useStyles()\n return (\n \n
\n
Paired at \n
\n {data.pairedAt\n ? moment(data.pairedAt).format('YYYY-MM-DD HH:mm:ss')\n : ''}\n
\n
\n
\n
Machine model \n
{data.model}
\n
\n
\n
Software version \n
{data.version}
\n
\n
\n )\n}\n\nexport default Details\n","import {\n Dialog,\n DialogActions,\n DialogContent,\n makeStyles\n} from '@material-ui/core'\nimport React, { memo, useState } from 'react'\n\nimport { Button, IconButton } from 'src/components/buttons'\nimport { TextInput } from 'src/components/inputs'\nimport { H4, P } from 'src/components/typography'\nimport { ReactComponent as CloseIcon } from 'src/styling/icons/action/close/zodiac.svg'\nimport { spacer } from 'src/styling/variables'\n\nimport ErrorMessage from './ErrorMessage'\n\nconst useStyles = makeStyles({\n dialogContent: {\n width: 434,\n padding: spacer * 2,\n paddingRight: spacer * 3.5\n },\n dialogTitle: {\n padding: spacer * 2,\n paddingRight: spacer * 1.5,\n display: 'flex',\n 'justify-content': 'space-between',\n '& > h4': {\n margin: 0\n },\n '& > button': {\n padding: 0,\n marginTop: -(spacer / 2)\n }\n },\n dialogActions: {\n padding: spacer * 4,\n paddingTop: spacer * 2\n }\n})\n\nexport const DialogTitle = ({ children, onClose }) => {\n const classes = useStyles()\n return (\n \n {children}\n {onClose && (\n \n \n \n )}\n
\n )\n}\n\nexport const ConfirmDialog = memo(\n ({\n title = 'Confirm action',\n errorMessage = 'This action requires confirmation',\n open,\n toBeConfirmed,\n saveButtonAlwaysEnabled = false,\n message,\n confirmationMessage = `Write '${toBeConfirmed}' to confirm this action`,\n onConfirmed,\n onDissmised,\n initialValue = '',\n disabled = false,\n ...props\n }) => {\n const classes = useStyles()\n const [value, setValue] = useState(initialValue)\n const [error, setError] = useState(false)\n const handleChange = event => setValue(event.target.value)\n\n const innerOnClose = () => {\n setValue('')\n setError(false)\n onDissmised()\n }\n\n const isOnErrorState =\n (!saveButtonAlwaysEnabled && toBeConfirmed !== value) || value === ''\n\n return (\n \n \n {title} \n \n {errorMessage && (\n \n \n {errorMessage.split(':').map(error => (\n <>\n {error}\n \n >\n ))}\n \n \n )}\n \n {message && {message}
}\n \n \n \n onConfirmed(value)}>\n Confirm\n \n \n \n )\n }\n)\n","function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport * as React from \"react\";\n\nvar _ref2 = /*#__PURE__*/React.createElement(\"desc\", null, \"Created with Sketch.\");\n\nvar _ref3 = /*#__PURE__*/React.createElement(\"g\", {\n id: \"icon/button/edit/white\",\n stroke: \"none\",\n strokeWidth: 1,\n fill: \"none\",\n fillRule: \"evenodd\",\n strokeLinecap: \"round\",\n strokeLinejoin: \"round\"\n}, /*#__PURE__*/React.createElement(\"path\", {\n d: \"M0,10 L0,10 C0,10.9942 0.8058,11.8 1.8,11.8 L10.2,11.8 C11.1942,11.8 12,10.9942 12,10\",\n id: \"Stroke-1\",\n stroke: \"#FFFFFF\"\n}), /*#__PURE__*/React.createElement(\"polygon\", {\n id: \"Stroke-3\",\n stroke: \"#FFFFFF\",\n points: \"3 6.86666667 8.86666667 1 11 3.13333333 5.13333333 9 3 9\"\n}));\n\nfunction SvgWhite(_ref, svgRef) {\n var title = _ref.title,\n titleId = _ref.titleId,\n props = _objectWithoutProperties(_ref, [\"title\", \"titleId\"]);\n\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n width: \"12px\",\n height: \"12px\",\n viewBox: \"0 0 12 12\",\n xmlns: \"http://www.w3.org/2000/svg\",\n xmlnsXlink: \"http://www.w3.org/1999/xlink\",\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, _ref2, _ref3);\n}\n\nvar ForwardRef = /*#__PURE__*/React.forwardRef(SvgWhite);\nexport default __webpack_public_path__ + \"static/media/white.958fe55d.svg\";\nexport { ForwardRef as ReactComponent };","function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport * as React from \"react\";\n\nvar _ref2 = /*#__PURE__*/React.createElement(\"desc\", null, \"Created with Sketch.\");\n\nvar _ref3 = /*#__PURE__*/React.createElement(\"g\", {\n id: \"icon/button/edit/zodiac\",\n stroke: \"none\",\n strokeWidth: 1,\n fill: \"none\",\n fillRule: \"evenodd\",\n strokeLinecap: \"round\",\n strokeLinejoin: \"round\"\n}, /*#__PURE__*/React.createElement(\"path\", {\n d: \"M0,10 L0,10 C0,10.9942 0.8058,11.8 1.8,11.8 L10.2,11.8 C11.1942,11.8 12,10.9942 12,10\",\n id: \"Stroke-1\",\n stroke: \"#1B2559\"\n}), /*#__PURE__*/React.createElement(\"polygon\", {\n id: \"Stroke-3\",\n stroke: \"#1B2559\",\n points: \"3 6.86666667 8.86666667 1 11 3.13333333 5.13333333 9 3 9\"\n}));\n\nfunction SvgZodiac(_ref, svgRef) {\n var title = _ref.title,\n titleId = _ref.titleId,\n props = _objectWithoutProperties(_ref, [\"title\", \"titleId\"]);\n\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n width: \"12px\",\n height: \"12px\",\n viewBox: \"0 0 12 12\",\n xmlns: \"http://www.w3.org/2000/svg\",\n xmlnsXlink: \"http://www.w3.org/1999/xlink\",\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, _ref2, _ref3);\n}\n\nvar ForwardRef = /*#__PURE__*/React.forwardRef(SvgZodiac);\nexport default __webpack_public_path__ + \"static/media/zodiac.1bc04c23.svg\";\nexport { ForwardRef as ReactComponent };","function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport * as React from \"react\";\n\nvar _ref2 = /*#__PURE__*/React.createElement(\"desc\", null, \"Created with Sketch.\");\n\nvar _ref3 = /*#__PURE__*/React.createElement(\"g\", {\n id: \"icon/button/reboot/white\",\n stroke: \"none\",\n strokeWidth: 1,\n fill: \"none\",\n fillRule: \"evenodd\",\n strokeLinecap: \"round\",\n strokeLinejoin: \"round\"\n}, /*#__PURE__*/React.createElement(\"g\", {\n id: \"Group-3\",\n stroke: \"#FFFFFF\"\n}, /*#__PURE__*/React.createElement(\"g\", {\n id: \"Group-2\"\n}, /*#__PURE__*/React.createElement(\"path\", {\n d: \"M3.57419317,11.1560104 C2.91506589,10.8661403 2.29620875,10.4522182 1.75493083,9.91362078 C-0.568892549,7.60089351 -0.587250991,3.86936104 1.71406849,1.57845195 C2.03057585,1.26367293 2.37407977,0.992496226 2.73740775,0.764921841\",\n id: \"Stroke-1\"\n}), /*#__PURE__*/React.createElement(\"polyline\", {\n id: \"Stroke-3\",\n points: \"3.37563213 1.84831169 3.36911784 0.595324675 2.18174122 4.15223411e-14\"\n})), /*#__PURE__*/React.createElement(\"line\", {\n x1: 5.92223784,\n y1: 7.57277922,\n x2: 5.92223784,\n y2: 3.98212987,\n id: \"Stroke-9\"\n}), /*#__PURE__*/React.createElement(\"g\", {\n id: \"Group-2\",\n transform: \"translate(9.818105, 6.000000) scale(-1, -1) translate(-9.818105, -6.000000) translate(7.636287, 0.000000)\"\n}, /*#__PURE__*/React.createElement(\"path\", {\n d: \"M3.57419317,11.1560104 C2.91506589,10.8661403 2.29620875,10.4522182 1.75493083,9.91362078 C-0.568892549,7.60089351 -0.587250991,3.86936104 1.71406849,1.57845195 C2.03057585,1.26367293 2.37407977,0.992496226 2.73740775,0.764921841\",\n id: \"Stroke-1\"\n}), /*#__PURE__*/React.createElement(\"polyline\", {\n id: \"Stroke-3\",\n points: \"3.37563213 1.84831169 3.36911784 0.595324675 2.18174122 4.15223411e-14\"\n}))));\n\nfunction SvgWhite(_ref, svgRef) {\n var title = _ref.title,\n titleId = _ref.titleId,\n props = _objectWithoutProperties(_ref, [\"title\", \"titleId\"]);\n\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n width: \"12px\",\n height: \"12px\",\n viewBox: \"-0.493 -0.5 12.993 13\",\n xmlns: \"http://www.w3.org/2000/svg\",\n xmlnsXlink: \"http://www.w3.org/1999/xlink\",\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, _ref2, _ref3);\n}\n\nvar ForwardRef = /*#__PURE__*/React.forwardRef(SvgWhite);\nexport default __webpack_public_path__ + \"static/media/white.fe6ed797.svg\";\nexport { ForwardRef as ReactComponent };","function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport * as React from \"react\";\n\nvar _ref2 = /*#__PURE__*/React.createElement(\"desc\", null, \"Created with Sketch.\");\n\nvar _ref3 = /*#__PURE__*/React.createElement(\"g\", {\n id: \"icon/button/reboot/zodiac\",\n stroke: \"none\",\n strokeWidth: 1,\n fill: \"none\",\n fillRule: \"evenodd\",\n strokeLinecap: \"round\",\n strokeLinejoin: \"round\"\n}, /*#__PURE__*/React.createElement(\"g\", {\n id: \"Group-3\",\n stroke: \"#1B2559\"\n}, /*#__PURE__*/React.createElement(\"g\", {\n id: \"Group-2\"\n}, /*#__PURE__*/React.createElement(\"path\", {\n d: \"M3.57419317,11.1560104 C2.91506589,10.8661403 2.29620875,10.4522182 1.75493083,9.91362078 C-0.568892549,7.60089351 -0.587250991,3.86936104 1.71406849,1.57845195 C2.03057585,1.26367293 2.37407977,0.992496226 2.73740775,0.764921841\",\n id: \"Stroke-1\"\n}), /*#__PURE__*/React.createElement(\"polyline\", {\n id: \"Stroke-3\",\n points: \"3.37563213 1.84831169 3.36911784 0.595324675 2.18174122 4.15223411e-14\"\n})), /*#__PURE__*/React.createElement(\"line\", {\n x1: 5.92223784,\n y1: 7.57277922,\n x2: 5.92223784,\n y2: 3.98212987,\n id: \"Stroke-9\"\n}), /*#__PURE__*/React.createElement(\"g\", {\n id: \"Group-2\",\n transform: \"translate(9.818105, 6.000000) scale(-1, -1) translate(-9.818105, -6.000000) translate(7.636287, 0.000000)\"\n}, /*#__PURE__*/React.createElement(\"path\", {\n d: \"M3.57419317,11.1560104 C2.91506589,10.8661403 2.29620875,10.4522182 1.75493083,9.91362078 C-0.568892549,7.60089351 -0.587250991,3.86936104 1.71406849,1.57845195 C2.03057585,1.26367293 2.37407977,0.992496226 2.73740775,0.764921841\",\n id: \"Stroke-1\"\n}), /*#__PURE__*/React.createElement(\"polyline\", {\n id: \"Stroke-3\",\n points: \"3.37563213 1.84831169 3.36911784 0.595324675 2.18174122 4.15223411e-14\"\n}))));\n\nfunction SvgZodiac(_ref, svgRef) {\n var title = _ref.title,\n titleId = _ref.titleId,\n props = _objectWithoutProperties(_ref, [\"title\", \"titleId\"]);\n\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n width: \"12px\",\n height: \"12px\",\n viewBox: \"-0.493 -0.5 12.993 13\",\n xmlns: \"http://www.w3.org/2000/svg\",\n xmlnsXlink: \"http://www.w3.org/1999/xlink\",\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, _ref2, _ref3);\n}\n\nvar ForwardRef = /*#__PURE__*/React.forwardRef(SvgZodiac);\nexport default __webpack_public_path__ + \"static/media/zodiac.9cfc97dd.svg\";\nexport { ForwardRef as ReactComponent };","function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport * as React from \"react\";\n\nvar _ref2 = /*#__PURE__*/React.createElement(\"desc\", null, \"Created with Sketch.\");\n\nvar _ref3 = /*#__PURE__*/React.createElement(\"g\", {\n id: \"icon/button/shut-down/white\",\n stroke: \"none\",\n strokeWidth: 1,\n fill: \"none\",\n fillRule: \"evenodd\",\n strokeLinecap: \"round\",\n strokeLinejoin: \"round\"\n}, /*#__PURE__*/React.createElement(\"g\", {\n id: \"Group-5\",\n transform: \"translate(1.000000, 0.000000)\",\n stroke: \"#FFFFFF\"\n}, /*#__PURE__*/React.createElement(\"path\", {\n d: \"M7.7735,2 C9.116,2.89710351 10,4.4271328 10,6.16330077 C10,8.92665975 7.7615,11.1666667 5,11.1666667 C2.2385,11.1666667 0,8.92665975 0,6.16330077 C0,4.43663919 0.8745,2.91361461 2.204,2.01450976\",\n id: \"Stroke-1\"\n}), /*#__PURE__*/React.createElement(\"line\", {\n x1: 5,\n y1: 0.75,\n x2: 5,\n y2: 3.25,\n id: \"Stroke-3\"\n})));\n\nfunction SvgWhite(_ref, svgRef) {\n var title = _ref.title,\n titleId = _ref.titleId,\n props = _objectWithoutProperties(_ref, [\"title\", \"titleId\"]);\n\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n width: \"12px\",\n height: \"12px\",\n viewBox: \"0 0 12 12\",\n xmlns: \"http://www.w3.org/2000/svg\",\n xmlnsXlink: \"http://www.w3.org/1999/xlink\",\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, _ref2, _ref3);\n}\n\nvar ForwardRef = /*#__PURE__*/React.forwardRef(SvgWhite);\nexport default __webpack_public_path__ + \"static/media/white.fa4681e8.svg\";\nexport { ForwardRef as ReactComponent };","function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport * as React from \"react\";\n\nvar _ref2 = /*#__PURE__*/React.createElement(\"desc\", null, \"Created with Sketch.\");\n\nvar _ref3 = /*#__PURE__*/React.createElement(\"g\", {\n id: \"icon/button/shut-down/zodiac\",\n stroke: \"none\",\n strokeWidth: 1,\n fill: \"none\",\n fillRule: \"evenodd\",\n strokeLinecap: \"round\",\n strokeLinejoin: \"round\"\n}, /*#__PURE__*/React.createElement(\"g\", {\n id: \"Group-5\",\n transform: \"translate(1.000000, 0.000000)\",\n stroke: \"#1B2559\"\n}, /*#__PURE__*/React.createElement(\"path\", {\n d: \"M7.7735,2 C9.116,2.89710351 10,4.4271328 10,6.16330077 C10,8.92665975 7.7615,11.1666667 5,11.1666667 C2.2385,11.1666667 0,8.92665975 0,6.16330077 C0,4.43663919 0.8745,2.91361461 2.204,2.01450976\",\n id: \"Stroke-1\"\n}), /*#__PURE__*/React.createElement(\"line\", {\n x1: 5,\n y1: 0.75,\n x2: 5,\n y2: 3.25,\n id: \"Stroke-3\"\n})));\n\nfunction SvgZodiac(_ref, svgRef) {\n var title = _ref.title,\n titleId = _ref.titleId,\n props = _objectWithoutProperties(_ref, [\"title\", \"titleId\"]);\n\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n width: \"12px\",\n height: \"12px\",\n viewBox: \"0 0 12 12\",\n xmlns: \"http://www.w3.org/2000/svg\",\n xmlnsXlink: \"http://www.w3.org/1999/xlink\",\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, _ref2, _ref3);\n}\n\nvar ForwardRef = /*#__PURE__*/React.forwardRef(SvgZodiac);\nexport default __webpack_public_path__ + \"static/media/zodiac.b27733af.svg\";\nexport { ForwardRef as ReactComponent };","function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport * as React from \"react\";\n\nvar _ref2 = /*#__PURE__*/React.createElement(\"desc\", null, \"Created with Sketch.\");\n\nvar _ref3 = /*#__PURE__*/React.createElement(\"g\", {\n id: \"icon/button/unpair/white\",\n stroke: \"none\",\n strokeWidth: 1,\n fill: \"none\",\n fillRule: \"evenodd\",\n strokeLinecap: \"round\",\n strokeLinejoin: \"round\"\n}, /*#__PURE__*/React.createElement(\"g\", {\n id: \"Group-12\",\n stroke: \"#FFFFFF\"\n}, /*#__PURE__*/React.createElement(\"g\", {\n id: \"Group-5\"\n}, /*#__PURE__*/React.createElement(\"polyline\", {\n id: \"Stroke-1\",\n points: \"3.75 6 2.25 6 0 3.75 3.75 0 6.75 3\"\n}), /*#__PURE__*/React.createElement(\"polyline\", {\n id: \"Stroke-3\",\n points: \"8.25 6 9.75 6 12 8.25 8.25 12 5.25 9\"\n})), /*#__PURE__*/React.createElement(\"line\", {\n x1: 8.25,\n y1: 3,\n x2: 8.25,\n y2: 1.5,\n id: \"Stroke-6\"\n}), /*#__PURE__*/React.createElement(\"line\", {\n x1: 9.75,\n y1: 3,\n x2: 10.5,\n y2: 2.25,\n id: \"Stroke-7\"\n}), /*#__PURE__*/React.createElement(\"line\", {\n x1: 9.75,\n y1: 4.5,\n x2: 11.25,\n y2: 4.5,\n id: \"Stroke-8\"\n}), /*#__PURE__*/React.createElement(\"line\", {\n x1: 2.25,\n y1: 7.5,\n x2: 0.75,\n y2: 7.5,\n id: \"Stroke-9\"\n}), /*#__PURE__*/React.createElement(\"line\", {\n x1: 2.25,\n y1: 9,\n x2: 1.5,\n y2: 9.75,\n id: \"Stroke-10\"\n}), /*#__PURE__*/React.createElement(\"line\", {\n x1: 3.75,\n y1: 9,\n x2: 3.75,\n y2: 10.5,\n id: \"Stroke-11\"\n})));\n\nfunction SvgWhite(_ref, svgRef) {\n var title = _ref.title,\n titleId = _ref.titleId,\n props = _objectWithoutProperties(_ref, [\"title\", \"titleId\"]);\n\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n width: \"12px\",\n height: \"12px\",\n viewBox: \"0 0 12 12\",\n xmlns: \"http://www.w3.org/2000/svg\",\n xmlnsXlink: \"http://www.w3.org/1999/xlink\",\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, _ref2, _ref3);\n}\n\nvar ForwardRef = /*#__PURE__*/React.forwardRef(SvgWhite);\nexport default __webpack_public_path__ + \"static/media/white.f97c75d2.svg\";\nexport { ForwardRef as ReactComponent };","function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport * as React from \"react\";\n\nvar _ref2 = /*#__PURE__*/React.createElement(\"desc\", null, \"Created with Sketch.\");\n\nvar _ref3 = /*#__PURE__*/React.createElement(\"g\", {\n id: \"icon/button/unpair/zodiac\",\n stroke: \"none\",\n strokeWidth: 1,\n fill: \"none\",\n fillRule: \"evenodd\",\n strokeLinecap: \"round\",\n strokeLinejoin: \"round\"\n}, /*#__PURE__*/React.createElement(\"g\", {\n id: \"Group-12\",\n stroke: \"#1B2559\"\n}, /*#__PURE__*/React.createElement(\"g\", {\n id: \"Group-5\"\n}, /*#__PURE__*/React.createElement(\"polyline\", {\n id: \"Stroke-1\",\n points: \"3.75 6 2.25 6 0 3.75 3.75 0 6.75 3\"\n}), /*#__PURE__*/React.createElement(\"polyline\", {\n id: \"Stroke-3\",\n points: \"8.25 6 9.75 6 12 8.25 8.25 12 5.25 9\"\n})), /*#__PURE__*/React.createElement(\"line\", {\n x1: 8.25,\n y1: 3,\n x2: 8.25,\n y2: 1.5,\n id: \"Stroke-6\"\n}), /*#__PURE__*/React.createElement(\"line\", {\n x1: 9.75,\n y1: 3,\n x2: 10.5,\n y2: 2.25,\n id: \"Stroke-7\"\n}), /*#__PURE__*/React.createElement(\"line\", {\n x1: 9.75,\n y1: 4.5,\n x2: 11.25,\n y2: 4.5,\n id: \"Stroke-8\"\n}), /*#__PURE__*/React.createElement(\"line\", {\n x1: 2.25,\n y1: 7.5,\n x2: 0.75,\n y2: 7.5,\n id: \"Stroke-9\"\n}), /*#__PURE__*/React.createElement(\"line\", {\n x1: 2.25,\n y1: 9,\n x2: 1.5,\n y2: 9.75,\n id: \"Stroke-10\"\n}), /*#__PURE__*/React.createElement(\"line\", {\n x1: 3.75,\n y1: 9,\n x2: 3.75,\n y2: 10.5,\n id: \"Stroke-11\"\n})));\n\nfunction SvgZodiac(_ref, svgRef) {\n var title = _ref.title,\n titleId = _ref.titleId,\n props = _objectWithoutProperties(_ref, [\"title\", \"titleId\"]);\n\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n width: \"12px\",\n height: \"12px\",\n viewBox: \"0 0 12 12\",\n xmlns: \"http://www.w3.org/2000/svg\",\n xmlnsXlink: \"http://www.w3.org/1999/xlink\",\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, _ref2, _ref3);\n}\n\nvar ForwardRef = /*#__PURE__*/React.forwardRef(SvgZodiac);\nexport default __webpack_public_path__ + \"static/media/zodiac.aa028a2c.svg\";\nexport { ForwardRef as ReactComponent };","import typographyStyles from 'src/components/typography/styles'\nimport { offColor, spacer, errorColor } from 'src/styling/variables'\n\nconst { label1 } = typographyStyles\n\nconst machineActionsStyles = {\n label: {\n extend: label1,\n color: offColor,\n marginBottom: 4\n },\n inlineChip: {\n marginInlineEnd: '0.25em'\n },\n stack: {\n display: 'flex',\n flexDirection: 'row',\n flexWrap: 'wrap',\n justifyContent: 'start'\n },\n mr: {\n marginRight: spacer,\n marginBottom: spacer\n },\n warning: {\n color: errorColor\n }\n}\n\nexport { machineActionsStyles }\n","import { useMutation, useLazyQuery } from '@apollo/react-hooks'\nimport { makeStyles } from '@material-ui/core/styles'\nimport gql from 'graphql-tag'\nimport React, { memo, useState } from 'react'\n\nimport { ConfirmDialog } from 'src/components/ConfirmDialog'\nimport ActionButton from 'src/components/buttons/ActionButton'\nimport { ReactComponent as EditReversedIcon } from 'src/styling/icons/button/edit/white.svg'\nimport { ReactComponent as EditIcon } from 'src/styling/icons/button/edit/zodiac.svg'\nimport { ReactComponent as RebootReversedIcon } from 'src/styling/icons/button/reboot/white.svg'\nimport { ReactComponent as RebootIcon } from 'src/styling/icons/button/reboot/zodiac.svg'\nimport { ReactComponent as ShutdownReversedIcon } from 'src/styling/icons/button/shut down/white.svg'\nimport { ReactComponent as ShutdownIcon } from 'src/styling/icons/button/shut down/zodiac.svg'\nimport { ReactComponent as UnpairReversedIcon } from 'src/styling/icons/button/unpair/white.svg'\nimport { ReactComponent as UnpairIcon } from 'src/styling/icons/button/unpair/zodiac.svg'\n\nimport { machineActionsStyles } from './MachineActions.styles'\n\nconst useStyles = makeStyles(machineActionsStyles)\n\nconst MACHINE_ACTION = gql`\n mutation MachineAction(\n $deviceId: ID!\n $action: MachineAction!\n $newName: String\n ) {\n machineAction(deviceId: $deviceId, action: $action, newName: $newName) {\n deviceId\n }\n }\n`\n\nconst MACHINE = gql`\n query getMachine($deviceId: ID!) {\n machine(deviceId: $deviceId) {\n latestEvent {\n note\n }\n }\n }\n`\n\nconst isStaticState = machineState => {\n if (!machineState) {\n return true\n }\n const staticStates = [\n 'chooseCoin',\n 'idle',\n 'pendingIdle',\n 'dualIdle',\n 'networkDown',\n 'unpaired',\n 'maintenance',\n 'virgin',\n 'wifiList'\n ]\n return staticStates.includes(machineState)\n}\n\nconst getState = machineEventsLazy =>\n JSON.parse(machineEventsLazy.machine.latestEvent?.note ?? '{\"state\": null}')\n .state\n\nconst Label = ({ children }) => {\n const classes = useStyles()\n\n return {children}
\n}\n\nconst MachineActions = memo(({ machine, onActionSuccess }) => {\n const [action, setAction] = useState({ command: null })\n const [errorMessage, setErrorMessage] = useState(null)\n const classes = useStyles()\n\n const warningMessage = (\n \n A user may be in the middle of a transaction and they could lose their\n funds if you continue.\n \n )\n\n const [fetchMachineEvents, { loading: loadingEvents }] = useLazyQuery(\n MACHINE,\n {\n variables: {\n deviceId: machine.deviceId\n },\n onCompleted: machineEventsLazy => {\n const message = !isStaticState(getState(machineEventsLazy))\n ? warningMessage\n : null\n setAction(action => ({ ...action, message }))\n }\n }\n )\n\n const [machineAction, { loading }] = useMutation(MACHINE_ACTION, {\n onError: ({ message }) => {\n const errorMessage = message ?? 'An error ocurred'\n setErrorMessage(errorMessage)\n },\n onCompleted: () => {\n onActionSuccess && onActionSuccess()\n setAction({ command: null })\n }\n })\n\n const confirmDialogOpen = Boolean(action.command)\n const disabled = !!(action?.command === 'restartServices' && loadingEvents)\n\n return (\n \n
Actions \n
\n
\n setAction({\n command: 'rename',\n display: 'Rename',\n confirmationMessage: 'Write the new name for this machine'\n })\n }>\n Rename\n \n
\n setAction({\n command: 'unpair',\n display: 'Unpair'\n })\n }>\n Unpair\n \n
\n setAction({\n command: 'reboot',\n display: 'Reboot'\n })\n }>\n Reboot\n \n
\n setAction({\n command: 'shutdown',\n display: 'Shutdown',\n message:\n 'In order to bring it back online, the machine will need to be visited and its power reset.'\n })\n }>\n Shutdown\n \n
{\n fetchMachineEvents()\n setAction({\n command: 'restartServices',\n display: 'Restart services for'\n })\n }}>\n Restart Services\n \n
\n
{\n setErrorMessage(null)\n machineAction({\n variables: {\n deviceId: machine.deviceId,\n action: `${action?.command}`,\n ...(action?.command === 'rename' && { newName: value })\n }\n })\n }}\n onDissmised={() => {\n setAction({ command: null })\n setErrorMessage(null)\n }}\n />\n \n )\n})\n\nexport default MachineActions\n","import { makeStyles } from '@material-ui/core/styles'\nimport moment from 'moment'\nimport React from 'react'\n\nimport { Status } from 'src/components/Status'\nimport MachineActions from 'src/components/machineActions/MachineActions'\nimport { H3, Label3, P } from 'src/components/typography'\n\nimport styles from '../Machines.styles'\nconst useStyles = makeStyles(styles)\n\nconst makeLastPing = lastPing => {\n if (!lastPing) return null\n const now = moment()\n const secondsAgo = now.diff(lastPing, 'seconds')\n if (secondsAgo < 60) {\n return `${secondsAgo} ${secondsAgo === 1 ? 'second' : 'seconds'} ago`\n }\n if (secondsAgo < 3600) {\n const minutes = Math.round(secondsAgo / 60)\n return `${minutes} ${minutes === 1 ? 'minute' : 'minutes'} ago`\n }\n if (secondsAgo < 3600 * 24) {\n const hours = Math.round(secondsAgo / 3600)\n return `${hours} ${hours === 1 ? 'hour' : 'hours'} ago`\n }\n const days = Math.round(secondsAgo / 3600 / 24)\n return `${days} ${days === 1 ? 'day' : 'days'} ago`\n}\n\nconst Overview = ({ data, onActionSuccess }) => {\n const classes = useStyles()\n\n return (\n <>\n \n \n
\n Status \n {data && data.statuses ? : null}\n
\n
\n \n
\n
Last ping \n
{makeLastPing(data.lastPing)}
\n
\n
\n \n >\n )\n}\n\nexport default Overview\n","function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport * as React from \"react\";\n\nvar _ref2 = /*#__PURE__*/React.createElement(\"desc\", null, \"Created with Sketch.\");\n\nvar _ref3 = /*#__PURE__*/React.createElement(\"g\", {\n id: \"icon/ID/card/white\",\n stroke: \"none\",\n strokeWidth: 1,\n fill: \"none\",\n fillRule: \"evenodd\",\n strokeLinecap: \"round\",\n strokeLinejoin: \"round\"\n}, /*#__PURE__*/React.createElement(\"polygon\", {\n id: \"Stroke-1\",\n stroke: \"#FFFFFF\",\n strokeWidth: 1.6,\n points: \"0 16 22 16 22 0 0 0\"\n}), /*#__PURE__*/React.createElement(\"line\", {\n x1: 11.7857143,\n y1: 4,\n x2: 18.8571429,\n y2: 4,\n id: \"Stroke-3\",\n stroke: \"#FFFFFF\",\n strokeWidth: 1.6\n}), /*#__PURE__*/React.createElement(\"line\", {\n x1: 11.7857143,\n y1: 7.2,\n x2: 18.8571429,\n y2: 7.2,\n id: \"Stroke-4\",\n stroke: \"#FFFFFF\",\n strokeWidth: 1.6\n}), /*#__PURE__*/React.createElement(\"polygon\", {\n id: \"Stroke-5\",\n stroke: \"#FFFFFF\",\n strokeWidth: 1.6,\n points: \"3.14285714 11.2 8.64285714 11.2 8.64285714 4 3.14285714 4\"\n}));\n\nfunction SvgWhite(_ref, svgRef) {\n var title = _ref.title,\n titleId = _ref.titleId,\n props = _objectWithoutProperties(_ref, [\"title\", \"titleId\"]);\n\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n width: \"22px\",\n height: \"16px\",\n viewBox: \"0 0 22 16\",\n xmlns: \"http://www.w3.org/2000/svg\",\n xmlnsXlink: \"http://www.w3.org/1999/xlink\",\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, _ref2, _ref3);\n}\n\nvar ForwardRef = /*#__PURE__*/React.forwardRef(SvgWhite);\nexport default __webpack_public_path__ + \"static/media/white.aa3a2aa4.svg\";\nexport { ForwardRef as ReactComponent };","function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport * as React from \"react\";\n\nvar _ref2 = /*#__PURE__*/React.createElement(\"desc\", null, \"Created with Sketch.\");\n\nvar _ref3 = /*#__PURE__*/React.createElement(\"g\", {\n id: \"icon/ID/phone/white\",\n stroke: \"none\",\n strokeWidth: 1,\n fill: \"none\",\n fillRule: \"evenodd\",\n strokeLinecap: \"round\",\n strokeLinejoin: \"round\"\n}, /*#__PURE__*/React.createElement(\"path\", {\n d: \"M6.47150618,12.52898 C9.939556,15.9970298 13.7804112,16.1146315 15.4756355,15.9586292 C16.0220434,15.9090285 16.5308507,15.6578249 16.9188563,15.2698193 L19.0004862,13.1881894 L17.0220577,11.210561 L15.0436293,10.5505516 L13.7244104,11.8697705 C13.7244104,11.8697705 12.4059914,13.1881894 9.10914407,9.89054208 C5.81229671,6.59449473 7.13071565,5.27527578 7.13071565,5.27527578 L8.4499346,3.95605683 L7.78992512,1.97842842 L5.81229671,0 L3.73066681,2.0816299 C3.34186123,2.46963548 3.09145763,2.97844279 3.04105691,3.52485063 C2.88585468,5.22007499 3.00345637,9.06013015 6.47150618,12.52898 Z\",\n id: \"Stroke-1-Copy\",\n stroke: \"#FFFFFF\",\n strokeWidth: 1.6\n}));\n\nfunction SvgWhite(_ref, svgRef) {\n var title = _ref.title,\n titleId = _ref.titleId,\n props = _objectWithoutProperties(_ref, [\"title\", \"titleId\"]);\n\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n width: \"22px\",\n height: \"16px\",\n viewBox: \"0 0 22 16\",\n xmlns: \"http://www.w3.org/2000/svg\",\n xmlnsXlink: \"http://www.w3.org/1999/xlink\",\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, _ref2, _ref3);\n}\n\nvar ForwardRef = /*#__PURE__*/React.forwardRef(SvgWhite);\nexport default __webpack_public_path__ + \"static/media/white.d630943a.svg\";\nexport { ForwardRef as ReactComponent };","function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport * as React from \"react\";\n\nvar _ref2 = /*#__PURE__*/React.createElement(\"desc\", null, \"Created with Sketch.\");\n\nvar _ref3 = /*#__PURE__*/React.createElement(\"g\", {\n id: \"icon/ID/phone/zodiac\",\n stroke: \"none\",\n strokeWidth: 1,\n fill: \"none\",\n fillRule: \"evenodd\",\n strokeLinecap: \"round\",\n strokeLinejoin: \"round\"\n}, /*#__PURE__*/React.createElement(\"path\", {\n d: \"M6.47150618,12.52898 C9.939556,15.9970298 13.7804112,16.1146315 15.4756355,15.9586292 C16.0220434,15.9090285 16.5308507,15.6578249 16.9188563,15.2698193 L19.0004862,13.1881894 L17.0220577,11.210561 L15.0436293,10.5505516 L13.7244104,11.8697705 C13.7244104,11.8697705 12.4059914,13.1881894 9.10914407,9.89054208 C5.81229671,6.59449473 7.13071565,5.27527578 7.13071565,5.27527578 L8.4499346,3.95605683 L7.78992512,1.97842842 L5.81229671,0 L3.73066681,2.0816299 C3.34186123,2.46963548 3.09145763,2.97844279 3.04105691,3.52485063 C2.88585468,5.22007499 3.00345637,9.06013015 6.47150618,12.52898 Z\",\n id: \"Stroke-1-Copy\",\n stroke: \"#1B2559\",\n strokeWidth: 1.6\n}));\n\nfunction SvgZodiac(_ref, svgRef) {\n var title = _ref.title,\n titleId = _ref.titleId,\n props = _objectWithoutProperties(_ref, [\"title\", \"titleId\"]);\n\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n width: \"22px\",\n height: \"16px\",\n viewBox: \"0 0 22 16\",\n xmlns: \"http://www.w3.org/2000/svg\",\n xmlnsXlink: \"http://www.w3.org/1999/xlink\",\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, _ref2, _ref3);\n}\n\nvar ForwardRef = /*#__PURE__*/React.forwardRef(SvgZodiac);\nexport default __webpack_public_path__ + \"static/media/zodiac.d95e9bb2.svg\";\nexport { ForwardRef as ReactComponent };","function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport * as React from \"react\";\n\nvar _ref2 = /*#__PURE__*/React.createElement(\"desc\", null, \"Created with Sketch.\");\n\nvar _ref3 = /*#__PURE__*/React.createElement(\"g\", {\n id: \"icon/ID/photo/white\",\n stroke: \"none\",\n strokeWidth: 1,\n fill: \"none\",\n fillRule: \"evenodd\",\n strokeLinecap: \"round\",\n strokeLinejoin: \"round\"\n}, /*#__PURE__*/React.createElement(\"path\", {\n d: \"M11,13 C8.7912,13 7,11.2088 7,9 C7,6.7912 8.7912,5 11,5 C13.2088,5 15,6.7912 15,9 C15,11.2088 13.2088,13 11,13 Z M15.7142857,2.4 L13.3571429,0 L8.64285714,0 L6.28571429,2.4 L0,2.4 L0,16 L22,16 L22,2.4 L15.7142857,2.4 Z\",\n id: \"Stroke-1\",\n stroke: \"#FFFFFF\",\n strokeWidth: 1.6\n}));\n\nfunction SvgWhite(_ref, svgRef) {\n var title = _ref.title,\n titleId = _ref.titleId,\n props = _objectWithoutProperties(_ref, [\"title\", \"titleId\"]);\n\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n width: \"22px\",\n height: \"16px\",\n viewBox: \"0 0 22 16\",\n xmlns: \"http://www.w3.org/2000/svg\",\n xmlnsXlink: \"http://www.w3.org/1999/xlink\",\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, _ref2, _ref3);\n}\n\nvar ForwardRef = /*#__PURE__*/React.forwardRef(SvgWhite);\nexport default __webpack_public_path__ + \"static/media/white.024587b7.svg\";\nexport { ForwardRef as ReactComponent };","function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport * as React from \"react\";\n\nvar _ref2 = /*#__PURE__*/React.createElement(\"desc\", null, \"Created with Sketch.\");\n\nvar _ref3 = /*#__PURE__*/React.createElement(\"g\", {\n id: \"icon/ID/photo/zodiac\",\n stroke: \"none\",\n strokeWidth: 1,\n fill: \"none\",\n fillRule: \"evenodd\",\n strokeLinecap: \"round\",\n strokeLinejoin: \"round\"\n}, /*#__PURE__*/React.createElement(\"path\", {\n d: \"M11,13 C8.7912,13 7,11.2088 7,9 C7,6.7912 8.7912,5 11,5 C13.2088,5 15,6.7912 15,9 C15,11.2088 13.2088,13 11,13 Z M15.7142857,2.4 L13.3571429,0 L8.64285714,0 L6.28571429,2.4 L0,2.4 L0,16 L22,16 L22,2.4 L15.7142857,2.4 Z\",\n id: \"Stroke-1\",\n stroke: \"#1B2559\",\n strokeWidth: 1.6\n}));\n\nfunction SvgZodiac(_ref, svgRef) {\n var title = _ref.title,\n titleId = _ref.titleId,\n props = _objectWithoutProperties(_ref, [\"title\", \"titleId\"]);\n\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n width: \"22px\",\n height: \"16px\",\n viewBox: \"0 0 22 16\",\n xmlns: \"http://www.w3.org/2000/svg\",\n xmlnsXlink: \"http://www.w3.org/1999/xlink\",\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, _ref2, _ref3);\n}\n\nvar ForwardRef = /*#__PURE__*/React.forwardRef(SvgZodiac);\nexport default __webpack_public_path__ + \"static/media/zodiac.4467d30c.svg\";\nexport { ForwardRef as ReactComponent };","import typographyStyles from 'src/components/typography/styles'\nimport { offColor, comet, white } from 'src/styling/variables'\n\nconst { p } = typographyStyles\n\nexport default {\n wrapper: {\n display: 'flex',\n flexDirection: 'column',\n marginTop: 24\n },\n row: {\n display: 'flex',\n flexDirection: 'row',\n marginBottom: 36\n },\n secondRow: {\n display: 'flex',\n flexDirection: 'row',\n justifyContent: 'space-between',\n marginBottom: 36\n },\n lastRow: {\n display: 'flex',\n flexDirection: 'row',\n marginBottom: 32\n },\n label: {\n color: offColor,\n margin: [[0, 0, 6, 0]]\n },\n txIcon: {\n marginRight: 10\n },\n clipboardPopover: {\n height: 164,\n width: 215\n },\n idButton: {\n marginRight: 4\n },\n idCardDataCard: {\n extend: p,\n display: 'flex',\n padding: [[11, 8]],\n '& > div': {\n display: 'flex',\n flexDirection: 'column',\n '& > div': {\n width: 144,\n height: 37,\n marginBottom: 15,\n '&:last-child': {\n marginBottom: 0\n }\n }\n }\n },\n bold: {\n fontWeight: 700\n },\n direction: {\n width: 233\n },\n availableIds: {\n width: 232\n },\n exchangeRate: {\n width: 250\n },\n commission: {\n width: 217\n },\n address: {\n width: 280\n },\n cancelTransaction: {\n width: 160\n },\n status: {\n width: 230,\n '& > button': {\n marginTop: 20\n }\n },\n transactionId: {\n width: 280\n },\n sessionId: {\n width: 215\n },\n container: {\n display: 'flex'\n },\n chip: {\n display: 'flex',\n alignItems: 'center',\n padding: '4px 8px 4px 8px',\n backgroundColor: comet,\n color: white,\n height: 24,\n marginBottom: -24,\n marginTop: -3,\n marginLeft: 7,\n borderRadius: 4\n },\n chipLabel: {\n color: white\n }\n}\n","const getCashOutStatus = it => {\n if (it.hasError) return 'Error'\n if (it.dispense) return 'Success'\n if (it.expired) return 'Expired'\n return 'Pending'\n}\n\nconst getCashInStatus = it => {\n if (it.operatorCompleted) return 'Cancelled'\n if (it.hasError) return 'Error'\n if (it.sendConfirmed) return 'Sent'\n if (it.expired) return 'Expired'\n return 'Pending'\n}\n\nconst getStatus = it => {\n if (it.txClass === 'cashOut') {\n return getCashOutStatus(it)\n }\n return getCashInStatus(it)\n}\n\nconst getStatusDetails = it => {\n return it.hasError ? it.hasError : null\n}\n\nexport { getStatus, getStatusDetails }\n","import { useMutation } from '@apollo/react-hooks'\nimport { makeStyles, Box } from '@material-ui/core'\nimport BigNumber from 'bignumber.js'\nimport gql from 'graphql-tag'\nimport moment from 'moment'\nimport React, { memo, useState } from 'react'\n\nimport { ConfirmDialog } from 'src/components/ConfirmDialog'\nimport { HoverableTooltip } from 'src/components/Tooltip'\nimport { IDButton, ActionButton } from 'src/components/buttons'\nimport { P, Label1 } from 'src/components/typography'\nimport { ReactComponent as CardIdInverseIcon } from 'src/styling/icons/ID/card/white.svg'\nimport { ReactComponent as CardIdIcon } from 'src/styling/icons/ID/card/zodiac.svg'\nimport { ReactComponent as PhoneIdInverseIcon } from 'src/styling/icons/ID/phone/white.svg'\nimport { ReactComponent as PhoneIdIcon } from 'src/styling/icons/ID/phone/zodiac.svg'\nimport { ReactComponent as CamIdInverseIcon } from 'src/styling/icons/ID/photo/white.svg'\nimport { ReactComponent as CamIdIcon } from 'src/styling/icons/ID/photo/zodiac.svg'\nimport { ReactComponent as CancelInverseIcon } from 'src/styling/icons/button/cancel/white.svg'\nimport { ReactComponent as CancelIcon } from 'src/styling/icons/button/cancel/zodiac.svg'\nimport { ReactComponent as TxInIcon } from 'src/styling/icons/direction/cash-in.svg'\nimport { ReactComponent as TxOutIcon } from 'src/styling/icons/direction/cash-out.svg'\nimport { URI } from 'src/utils/apollo'\nimport { toUnit, formatCryptoAddress } from 'src/utils/coin'\nimport { onlyFirstToUpper } from 'src/utils/string'\n\nimport CopyToClipboard from './CopyToClipboard'\nimport styles from './DetailsCard.styles'\nimport { getStatus, getStatusDetails } from './helper'\n\nconst useStyles = makeStyles(styles)\n\nconst CANCEL_TRANSACTION = gql`\n mutation cancelCashOutTransaction($id: ID!) {\n cancelCashOutTransaction(id: $id) {\n id\n }\n }\n`\n\nconst formatAddress = (cryptoCode = '', address = '') =>\n formatCryptoAddress(cryptoCode, address).replace(/(.{5})/g, '$1 ')\n\nconst Label = ({ children }) => {\n const classes = useStyles()\n return {children} \n}\n\nconst DetailsRow = ({ it: tx }) => {\n const classes = useStyles()\n const [action, setAction] = useState({ command: null })\n const [errorMessage, setErrorMessage] = useState('')\n\n const [cancelCashOutTransaction] = useMutation(CANCEL_TRANSACTION, {\n onError: ({ message }) => setErrorMessage(message ?? 'An error occurred.'),\n refetchQueries: () => ['transactions']\n })\n\n const fiat = Number.parseFloat(tx.fiat)\n const crypto = toUnit(new BigNumber(tx.cryptoAtoms), tx.cryptoCode)\n const commissionPercentage = Number.parseFloat(tx.commissionPercentage, 2)\n const commission = Number(fiat * commissionPercentage).toFixed(2)\n const discount = tx.discount ? `-${tx.discount}%` : null\n const exchangeRate = BigNumber(fiat / crypto).toFormat(2)\n const displayExRate = `1 ${tx.cryptoCode} = ${exchangeRate} ${tx.fiatCode}`\n\n const customer = tx.customerIdCardData && {\n name: `${onlyFirstToUpper(\n tx.customerIdCardData.firstName\n )} ${onlyFirstToUpper(tx.customerIdCardData.lastName)}`,\n age: moment().diff(moment(tx.customerIdCardData.dateOfBirth), 'years'),\n country: tx.customerIdCardData.country,\n idCardNumber: tx.customerIdCardData.documentNumber,\n idCardExpirationDate: moment(tx.customerIdCardData.expirationDate).format(\n 'DD-MM-YYYY'\n )\n }\n\n const errorElements = (\n <>\n Transaction status \n {getStatus(tx)} \n >\n )\n\n return (\n \n
\n
\n
Direction \n
\n \n {tx.txClass === 'cashOut' ? : }\n \n {tx.txClass === 'cashOut' ? 'Cash-out' : 'Cash-in'} \n
\n
\n\n
\n
Available IDs \n
\n {tx.customerPhone && (\n \n {tx.customerPhone}\n \n )}\n {tx.customerIdCardPhotoPath && !tx.customerIdCardData && (\n \n \n \n )}\n {tx.customerIdCardData && (\n \n \n
\n
\n
Name \n
{customer.name}
\n
\n
\n
Age \n
{customer.age}
\n
\n
\n
Country \n
{customer.country}
\n
\n
\n
\n
\n
ID number \n
{customer.idCardNumber}
\n
\n
\n
Expiration date \n
{customer.idCardExpirationDate}
\n
\n
\n
\n \n )}\n {tx.customerFrontCameraPath && (\n \n \n \n )}\n \n
\n
\n
Exchange rate \n
{crypto > 0 ? displayExRate : '-'}
\n
\n
\n
Commission \n
\n {`${commission} ${tx.fiatCode} (${commissionPercentage * 100} %)`}\n {discount && (\n
\n {discount} \n
\n )}\n
\n
\n
\n
Fixed fee \n
\n {tx.txClass === 'cashIn'\n ? `${Number.parseFloat(tx.cashInFee)} ${tx.fiatCode}`\n : 'N/A'}\n
\n
\n
\n
\n
\n
Address \n
\n \n {formatAddress(tx.cryptoCode, tx.toAddress)}\n \n
\n
\n
\n
Transaction ID \n
\n {tx.txClass === 'cashOut' ? (\n 'N/A'\n ) : (\n {tx.txHash} \n )}\n
\n
\n
\n Session ID \n {tx.id} \n
\n
\n
\n
\n {getStatusDetails(tx) ? (\n
\n {getStatusDetails(tx)}
\n \n ) : (\n errorElements\n )}\n {tx.txClass === 'cashOut' && getStatus(tx) !== 'Cancelled' && (\n
\n setAction({\n command: 'cancelTx'\n })\n }>\n Cancel transaction\n \n )}\n
\n
\n
{\n setErrorMessage(null)\n setAction({ command: null })\n cancelCashOutTransaction({\n variables: {\n id: tx.id\n }\n })\n }}\n onDissmised={() => {\n setAction({ command: null })\n setErrorMessage(null)\n }}\n />\n \n )\n}\n\nexport default memo(DetailsRow, (prev, next) => prev.id === next.id)\n","import { makeStyles, Box } from '@material-ui/core'\nimport classnames from 'classnames'\nimport * as R from 'ramda'\nimport React, { useState, useEffect } from 'react'\nimport {\n AutoSizer,\n List,\n CellMeasurer,\n CellMeasurerCache\n} from 'react-virtualized'\n\nimport {\n Table,\n TBody,\n THead,\n Tr,\n Td,\n Th\n} from 'src/components/fake-table/Table'\nimport styles from 'src/components/tables/DataTable.styles'\nimport { H4 } from 'src/components/typography'\nimport { ReactComponent as ExpandClosedIcon } from 'src/styling/icons/action/expand/closed.svg'\nimport { ReactComponent as ExpandOpenIcon } from 'src/styling/icons/action/expand/open.svg'\n\nconst useStyles = makeStyles(styles)\n\nconst Row = ({\n id,\n elements,\n data,\n width,\n Details,\n expanded,\n expandRow,\n expWidth,\n expandable,\n onClick\n}) => {\n const classes = useStyles()\n\n const hasPointer = onClick || expandable\n const trClasses = {\n [classes.pointer]: hasPointer,\n [classes.row]: true,\n [classes.expanded]: expanded\n }\n\n return (\n \n
\n
{\n expandable && expandRow(id)\n onClick && onClick(data)\n }}\n error={data.error}\n errorMessage={data.errorMessage}>\n {elements.map(({ view = it => it?.toString(), ...props }, idx) => (\n \n {view(data)}\n \n ))}\n {expandable && (\n \n expandRow(id)}\n className={classes.expandButton}>\n {expanded && }\n {!expanded && }\n \n \n )}\n \n \n {expandable && expanded && (\n
\n
\n \n \n \n \n \n )}\n
\n )\n}\n\nconst DataTable = ({\n elements = [],\n data = [],\n Details,\n className,\n expandable,\n initialExpanded,\n onClick,\n loading,\n emptyText,\n extraHeight,\n ...props\n}) => {\n const [expanded, setExpanded] = useState(initialExpanded)\n\n useEffect(() => setExpanded(initialExpanded), [initialExpanded])\n\n const coreWidth = R.compose(R.sum, R.map(R.prop('width')))(elements)\n const expWidth = 850 - coreWidth\n const width = coreWidth + (expandable ? expWidth : 0)\n\n const classes = useStyles({ width })\n\n const expandRow = id => {\n setExpanded(id === expanded ? null : id)\n }\n\n const cache = new CellMeasurerCache({\n defaultHeight: 62,\n fixedWidth: true\n })\n\n function rowRenderer({ index, key, parent, style }) {\n return (\n \n \n
\n
\n \n )\n }\n\n return (\n \n \n \n {elements.map(({ width, className, textAlign, header }, idx) => (\n \n {header}\n \n ))}\n {expandable && }\n \n \n {loading && Loading... }\n {!loading && R.isEmpty(data) && {emptyText} }\n \n {() => (\n
\n )}\n \n \n
\n \n )\n}\n\nexport default DataTable\n","import { useLazyQuery } from '@apollo/react-hooks'\nimport { makeStyles } from '@material-ui/core'\nimport BigNumber from 'bignumber.js'\nimport gql from 'graphql-tag'\nimport moment from 'moment'\nimport * as R from 'ramda'\nimport React, { useEffect, useState } from 'react'\n\nimport DetailsRow from 'src/pages/Transactions/DetailsCard'\nimport { mainStyles } from 'src/pages/Transactions/Transactions.styles'\nimport { getStatus } from 'src/pages/Transactions/helper'\nimport { ReactComponent as TxInIcon } from 'src/styling/icons/direction/cash-in.svg'\nimport { ReactComponent as TxOutIcon } from 'src/styling/icons/direction/cash-out.svg'\nimport { toUnit, formatCryptoAddress } from 'src/utils/coin'\n\nimport DataTable from './DataTable'\nconst useStyles = makeStyles(mainStyles)\n\nconst NUM_LOG_RESULTS = 5\n\nconst GET_TRANSACTIONS = gql`\n query transactions($limit: Int, $from: Date, $until: Date, $deviceId: ID) {\n transactions(\n limit: $limit\n from: $from\n until: $until\n deviceId: $deviceId\n ) {\n id\n txClass\n txHash\n toAddress\n commissionPercentage\n expired\n machineName\n operatorCompleted\n sendConfirmed\n dispense\n hasError: error\n deviceId\n fiat\n cashInFee\n fiatCode\n cryptoAtoms\n cryptoCode\n toAddress\n created\n customerName\n customerIdCardData\n customerIdCardPhotoPath\n customerFrontCameraPath\n customerPhone\n discount\n customerId\n isAnonymous\n }\n }\n`\n\nconst Transactions = ({ id }) => {\n const classes = useStyles()\n\n const [extraHeight, setExtraHeight] = useState(0)\n const [clickedId, setClickedId] = useState('')\n\n const [getTx, { data: txResponse, loading }] = useLazyQuery(\n GET_TRANSACTIONS,\n {\n variables: {\n limit: NUM_LOG_RESULTS,\n deviceId: id\n }\n }\n )\n\n if (!loading && txResponse) {\n txResponse.transactions = txResponse.transactions.splice(0, 5)\n }\n\n useEffect(() => {\n if (id !== null) {\n getTx()\n }\n }, [getTx, id])\n\n const formatCustomerName = customer => {\n const { firstName, lastName } = customer\n\n return `${R.o(R.toUpper, R.head)(firstName)}. ${lastName}`\n }\n\n const getCustomerDisplayName = tx => {\n if (tx.customerName) return tx.customerName\n if (tx.customerIdCardData) return formatCustomerName(tx.customerIdCardData)\n return tx.customerPhone\n }\n\n const elements = [\n {\n header: '',\n width: 0,\n size: 'sm',\n view: it => (it.txClass === 'cashOut' ? : )\n },\n {\n header: 'Customer',\n width: 122,\n size: 'sm',\n view: getCustomerDisplayName\n },\n {\n header: 'Cash',\n width: 144,\n textAlign: 'right',\n size: 'sm',\n view: it => `${Number.parseFloat(it.fiat)} ${it.fiatCode}`\n },\n {\n header: 'Crypto',\n width: 164,\n textAlign: 'right',\n size: 'sm',\n view: it =>\n `${toUnit(new BigNumber(it.cryptoAtoms), it.cryptoCode).toFormat(5)} ${\n it.cryptoCode\n }`\n },\n {\n header: 'Address',\n view: it => formatCryptoAddress(it.cryptoCode, it.toAddress),\n className: classes.overflowTd,\n size: 'sm',\n textAlign: 'left',\n width: 140\n },\n {\n header: 'Date (UTC)',\n view: it => moment.utc(it.created).format('YYYY-MM-DD'),\n textAlign: 'left',\n size: 'sm',\n width: 140\n },\n {\n header: 'Status',\n view: it => getStatus(it),\n size: 'sm',\n width: 20\n }\n ]\n\n const handleClick = e => {\n if (clickedId === e.id) {\n setClickedId('')\n setExtraHeight(0)\n } else {\n setClickedId(e.id)\n setExtraHeight(310)\n }\n }\n\n return (\n \n )\n}\n\nexport default Transactions\n","import Transactions from './Transactions'\nexport default Transactions\n","import { useQuery } from '@apollo/react-hooks'\nimport Breadcrumbs from '@material-ui/core/Breadcrumbs'\nimport Grid from '@material-ui/core/Grid'\nimport { makeStyles } from '@material-ui/core/styles'\nimport NavigateNextIcon from '@material-ui/icons/NavigateNext'\nimport classnames from 'classnames'\nimport gql from 'graphql-tag'\nimport * as R from 'ramda'\nimport React from 'react'\nimport { Link, useLocation } from 'react-router-dom'\n\nimport { TL1, TL2, Label3 } from 'src/components/typography'\n\nimport Cassettes from './MachineComponents/Cassettes'\nimport Commissions from './MachineComponents/Commissions'\nimport Details from './MachineComponents/Details'\nimport Overview from './MachineComponents/Overview'\nimport Transactions from './MachineComponents/Transactions'\nimport styles from './Machines.styles'\nconst useStyles = makeStyles(styles)\n\nconst GET_INFO = gql`\n query getMachine($deviceId: ID!) {\n machine(deviceId: $deviceId) {\n name\n deviceId\n paired\n lastPing\n pairedAt\n version\n model\n cashbox\n cassette1\n cassette2\n statuses {\n label\n type\n }\n latestEvent {\n note\n }\n }\n config\n }\n`\n\nconst getMachineID = path => path.slice(path.lastIndexOf('/') + 1)\n\nconst Machines = () => {\n const location = useLocation()\n const { data, refetch } = useQuery(GET_INFO, {\n variables: {\n deviceId: getMachineID(location.pathname)\n }\n })\n const classes = useStyles()\n\n const machine = R.path(['machine'])(data) ?? {}\n const config = R.path(['config'])(data) ?? {}\n\n const machineName = R.path(['name'])(machine) ?? null\n const machineID = R.path(['deviceId'])(machine) ?? null\n\n return (\n \n \n \n \n }>\n \n \n Dashboard\n \n \n \n {machineName}\n \n \n \n
\n \n \n {/* on hold for now */}\n \n \n \n \n
\n {'Details'} \n \n
\n
\n {'Cash cassettes'} \n \n
\n
\n {'Latest transactions'} \n \n
\n
\n {'Commissions'} \n \n
\n
\n \n \n )\n}\n\nexport default Machines\n","import Machines from './Machines'\n\nexport default Machines\n","import { comet } from 'src/styling/variables'\n\nexport default {\n footerLabel: {\n color: comet,\n alignSelf: 'center'\n },\n footerContent: {\n width: 1200,\n maxHeight: 64,\n display: 'flex',\n justifyContent: 'space-around',\n position: 'fixed'\n },\n footerContainer: {\n position: 'fixed',\n height: 64,\n left: 0,\n bottom: 0,\n width: '100vw',\n backgroundColor: 'white',\n display: 'flex',\n justifyContent: 'space-around',\n boxShadow: [[0, -1, 10, 0, 'rgba(50, 50, 50, 0.1)']]\n },\n flex: {\n display: 'flex',\n // temp marginLeft until cashIn square is enabled\n marginLeft: -640\n },\n icon: {\n alignSelf: 'center',\n height: 20,\n width: 20,\n marginRight: 8\n },\n iconLabel: {\n alignSelf: 'center',\n marginRight: 8\n },\n valueDisplay: {\n alignSelf: 'center'\n }\n}\n","import { makeStyles } from '@material-ui/core'\n// import BigNumber from 'bignumber.js'\nimport * as R from 'ramda'\nimport React from 'react'\n\nimport { Info1, Info2, Info3 } from 'src/components/typography/index'\n// import { ReactComponent as TxInIcon } from 'src/styling/icons/direction/cash-in.svg'\nimport { ReactComponent as TxOutIcon } from 'src/styling/icons/direction/cash-out.svg'\nimport { fromNamespace } from 'src/utils/config'\n\nimport styles from './CashCassettesFooter.styles.js'\nconst useStyles = makeStyles(styles)\n\n/* const sortDate = function(a, b) {\n return new Date(b.created).getTime() - new Date(a.created).getTime()\n} */\n\nconst CashCassettesFooter = ({\n machines,\n config,\n currencyCode,\n bills,\n deviceIds\n}) => {\n const classes = useStyles()\n const cashout = config && fromNamespace('cashOut')(config)\n const getCashoutSettings = id => fromNamespace(id)(cashout)\n const reducerFn = (acc, { cassette1, cassette2, id }) => {\n const topDenomination = getCashoutSettings(id).top ?? 0\n const bottomDenomination = getCashoutSettings(id).bottom ?? 0\n return [\n (acc[0] += cassette1 * topDenomination),\n (acc[1] += cassette2 * bottomDenomination)\n ]\n }\n\n const totalInCassettes = R.sum(R.reduce(reducerFn, [0, 0], machines))\n\n /* const totalInCashBox = R.sum(\n R.flatten(\n R.map(id => {\n const sliceIdx = R.path([id, 0, 'cashbox'])(bills) ?? 0\n return R.map(\n R.prop('fiat'),\n R.slice(0, sliceIdx, R.sort(sortDate, bills[id] ?? []))\n )\n }, deviceIds)\n )\n ) */\n\n // const total = new BigNumber(totalInCassettes + totalInCashBox).toFormat(0)\n\n return (\n \n
\n
Cash value in System \n {/*
\n \n Cash-in: \n \n {totalInCashBox} {currencyCode}\n \n
*/}\n
\n \n Cash-out: \n \n {totalInCassettes} {currencyCode}\n \n
\n {/*
\n Total: \n \n {total} {currencyCode}\n \n
*/}\n
\n
\n )\n}\n\nexport default CashCassettesFooter\n","import { useQuery, useMutation } from '@apollo/react-hooks'\nimport { makeStyles } from '@material-ui/core'\nimport gql from 'graphql-tag'\nimport * as R from 'ramda'\nimport React from 'react'\nimport * as Yup from 'yup'\n\nimport { Table as EditableTable } from 'src/components/editableTable'\nimport { CashOut, CashIn } from 'src/components/inputs/cashbox/Cashbox'\nimport { NumberInput, CashCassetteInput } from 'src/components/inputs/formik'\nimport TitleSection from 'src/components/layout/TitleSection'\nimport { EmptyTable } from 'src/components/table'\nimport { fromNamespace } from 'src/utils/config'\n\nimport styles from './CashCassettes.styles.js'\nimport CashCassettesFooter from './CashCassettesFooter'\n\nconst useStyles = makeStyles(styles)\n\nconst ValidationSchema = Yup.object().shape({\n name: Yup.string().required(),\n cashbox: Yup.number()\n .label('Cashbox')\n .required()\n .integer()\n .min(0)\n .max(1000),\n cassette1: Yup.number()\n .label('Cassette 1 (top)')\n .required()\n .integer()\n .min(0)\n .max(500),\n cassette2: Yup.number()\n .label('Cassette 2 (bottom)')\n .required()\n .integer()\n .min(0)\n .max(500)\n})\n\nconst GET_MACHINES_AND_CONFIG = gql`\n query getData {\n machines {\n name\n id: deviceId\n cashbox\n cassette1\n cassette2\n }\n config\n }\n`\n\n/* \n // for cash in total calculation\n bills {\n fiat\n deviceId\n created\n cashbox\n }\n*/\n\nconst SET_CASSETTE_BILLS = gql`\n mutation MachineAction(\n $deviceId: ID!\n $action: MachineAction!\n $cashbox: Int!\n $cassette1: Int!\n $cassette2: Int!\n ) {\n machineAction(\n deviceId: $deviceId\n action: $action\n cashbox: $cashbox\n cassette1: $cassette1\n cassette2: $cassette2\n ) {\n deviceId\n cashbox\n cassette1\n cassette2\n }\n }\n`\n\nconst CashCassettes = () => {\n const classes = useStyles()\n\n const { data } = useQuery(GET_MACHINES_AND_CONFIG)\n\n const machines = R.path(['machines'])(data) ?? []\n const config = R.path(['config'])(data) ?? {}\n const [setCassetteBills, { error }] = useMutation(SET_CASSETTE_BILLS, {\n refetchQueries: () => ['getData']\n })\n const bills = R.groupBy(bill => bill.deviceId)(R.path(['bills'])(data) ?? [])\n const deviceIds = R.uniq(\n R.map(R.prop('deviceId'))(R.path(['bills'])(data) ?? [])\n )\n const cashout = data?.config && fromNamespace('cashOut')(data.config)\n const locale = data?.config && fromNamespace('locale')(data.config)\n const fiatCurrency = locale?.fiatCurrency\n\n const onSave = (...[, { id, cashbox, cassette1, cassette2 }]) => {\n return setCassetteBills({\n variables: {\n action: 'setCassetteBills',\n deviceId: id,\n cashbox,\n cassette1,\n cassette2\n }\n })\n }\n const getCashoutSettings = id => fromNamespace(id)(cashout)\n const isCashOutDisabled = ({ id }) => !getCashoutSettings(id).active\n\n const elements = [\n {\n name: 'name',\n header: 'Machine',\n width: 254,\n view: name => <>{name}>,\n input: ({ field: { value: name } }) => <>{name}>\n },\n {\n name: 'cashbox',\n header: 'Cashbox',\n width: 240,\n view: value => (\n \n ),\n input: NumberInput,\n inputProps: {\n decimalPlaces: 0\n }\n },\n {\n name: 'cassette1',\n header: 'Cassette 1 (Top)',\n width: 265,\n stripe: true,\n view: (value, { id }) => (\n \n ),\n input: CashCassetteInput,\n inputProps: {\n decimalPlaces: 0\n }\n },\n {\n name: 'cassette2',\n header: 'Cassette 2 (Bottom)',\n width: 265,\n stripe: true,\n view: (value, { id }) => {\n return (\n \n )\n },\n input: CashCassetteInput,\n inputProps: {\n decimalPlaces: 0\n }\n }\n ]\n\n return (\n <>\n \n \n \n\n {data && R.isEmpty(machines) && (\n \n )}\n
\n \n >\n )\n}\n\nexport default CashCassettes\n","export default {\n cashbox: {\n width: 80,\n height: 36\n },\n tableContainer: {\n flex: 1,\n marginBottom: 100\n },\n tBody: {\n maxHeight: '65vh',\n overflow: 'auto'\n }\n}\n","function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport * as React from \"react\";\n\nvar _ref2 = /*#__PURE__*/React.createElement(\"rect\", {\n width: 12,\n height: 12,\n rx: 3,\n ry: 3,\n fill: \"#ff7311\"\n});\n\nfunction SvgPumpkin(_ref, svgRef) {\n var title = _ref.title,\n titleId = _ref.titleId,\n props = _objectWithoutProperties(_ref, [\"title\", \"titleId\"]);\n\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n width: 12,\n height: 12,\n viewBox: \"0 0 12 12\",\n xmlns: \"http://www.w3.org/2000/svg\",\n xmlnsXlink: \"http://www.w3.org/1999/xlink\",\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, _ref2);\n}\n\nvar ForwardRef = /*#__PURE__*/React.forwardRef(SvgPumpkin);\nexport default __webpack_public_path__ + \"static/media/pumpkin.877c3432.svg\";\nexport { ForwardRef as ReactComponent };","function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport * as React from \"react\";\n\nvar _ref2 = /*#__PURE__*/React.createElement(\"rect\", {\n width: 12,\n height: 12,\n rx: 3,\n ry: 3,\n fill: \"#ff584a\"\n});\n\nfunction SvgTomato(_ref, svgRef) {\n var title = _ref.title,\n titleId = _ref.titleId,\n props = _objectWithoutProperties(_ref, [\"title\", \"titleId\"]);\n\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n width: 12,\n height: 12,\n viewBox: \"0 0 12 12\",\n xmlns: \"http://www.w3.org/2000/svg\",\n xmlnsXlink: \"http://www.w3.org/1999/xlink\",\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, _ref2);\n}\n\nvar ForwardRef = /*#__PURE__*/React.forwardRef(SvgTomato);\nexport default __webpack_public_path__ + \"static/media/tomato.b3903800.svg\";\nexport { ForwardRef as ReactComponent };","import { fade } from '@material-ui/core/styles/colorManipulator'\n\nimport {\n detailsRowStyles,\n labelStyles\n} from 'src/pages/Transactions/Transactions.styles'\nimport { spacer, comet, primaryColor, fontSize4 } from 'src/styling/variables'\n\nconst machineDetailsStyles = {\n ...detailsRowStyles,\n wrapper: {\n display: 'flex',\n // marginTop: 24,\n // marginBottom: 32,\n marginTop: 12,\n marginBottom: 16,\n fontSize: fontSize4\n },\n row: {\n display: 'flex',\n flexDirection: 'row'\n // marginBottom: 36\n },\n list: {\n padding: 0,\n margin: 0,\n listStyle: 'none'\n },\n item: {\n height: spacer * 3,\n marginBottom: spacer * 1.5\n },\n link: {\n color: primaryColor,\n textDecoration: 'none'\n },\n separator: {\n width: 1,\n height: 170,\n zIndex: 1,\n marginRight: 60,\n marginLeft: 'auto',\n background: fade(comet, 0.5)\n }\n}\n\nexport { labelStyles, machineDetailsStyles }\n","import { Grid /*, Divider */ } from '@material-ui/core'\nimport { makeStyles } from '@material-ui/core/styles'\nimport BigNumber from 'bignumber.js'\nimport moment from 'moment'\nimport React from 'react'\n\nimport MachineActions from 'src/components/machineActions/MachineActions'\n\n// import { Status } from 'src/components/Status'\n// import { ReactComponent as LinkIcon } from 'src/styling/icons/button/link/zodiac.svg'\n\nimport { labelStyles, machineDetailsStyles } from './MachineDetailsCard.styles'\n\n// const supportArtices = [\n// {\n// // Default article for non-maped statuses\n// code: undefined,\n// label: 'Troubleshooting',\n// article:\n// 'https://support.lamassu.is/hc/en-us/categories/115000075249-Troubleshooting'\n// }\n// // TODO add Stuck and Fully Functional statuses articles for the new-admins\n// ]\n\n// const article = ({ code: status }) =>\n// supportArtices.find(({ code: article }) => article === status)\n\nconst useLStyles = makeStyles(labelStyles)\n\nconst Label = ({ children }) => {\n const classes = useLStyles()\n\n return {children}
\n}\n\nconst useMDStyles = makeStyles(machineDetailsStyles)\n\nconst Container = ({ children, ...props }) => (\n \n {children}\n \n)\n\nconst Item = ({ children, ...props }) => (\n \n {children}\n \n)\n\nconst MachineDetailsRow = ({ it: machine, onActionSuccess }) => {\n const classes = useMDStyles()\n\n return (\n \n {/* - \n
\n - \n
Statuses \n \n {machine.statuses.map((status, index) => (\n \n \n \n ))}\n \n \n - \n
Lamassu Support article \n \n {machine.statuses\n .map(article)\n .map(({ label, article }, index) => (\n \n \n '{label}' \n \n \n ))}\n \n \n \n \n */}\n - \n
\n - \n
Machine Model \n {machine.model} \n \n - \n
Paired at \n \n {moment(machine.pairedAt).format('YYYY-MM-DD HH:mm:ss')}\n \n \n - \n
\n \n - \n
Network speed \n \n {machine.downloadSpeed\n ? new BigNumber(machine.downloadSpeed).toFixed(4).toString() +\n ' MB/s'\n : 'unavailable'}\n \n \n - \n
Latency \n \n {machine.responseTime\n ? new BigNumber(machine.responseTime).toFixed(3).toString() +\n ' ms'\n : 'unavailable'}\n \n \n - \n
Packet Loss \n \n {machine.packetLoss\n ? new BigNumber(machine.packetLoss).toFixed(3).toString() +\n ' %'\n : 'unavailable'}\n \n \n \n \n \n )\n}\n\nexport default MachineDetailsRow\n","import { useQuery } from '@apollo/react-hooks'\nimport { makeStyles } from '@material-ui/core'\nimport gql from 'graphql-tag'\nimport moment from 'moment'\nimport * as R from 'ramda'\nimport React from 'react'\nimport { useLocation } from 'react-router-dom'\n\nimport { MainStatus } from 'src/components/Status'\nimport Title from 'src/components/Title'\nimport DataTable from 'src/components/tables/DataTable'\nimport { mainStyles } from 'src/pages/Transactions/Transactions.styles'\nimport { ReactComponent as WarningIcon } from 'src/styling/icons/status/pumpkin.svg'\nimport { ReactComponent as ErrorIcon } from 'src/styling/icons/status/tomato.svg'\n\nimport MachineDetailsRow from './MachineDetailsCard'\n\nconst GET_MACHINES = gql`\n {\n machines {\n name\n deviceId\n lastPing\n pairedAt\n version\n paired\n cashbox\n cassette1\n cassette2\n version\n model\n statuses {\n label\n type\n }\n downloadSpeed\n responseTime\n packetLoss\n }\n }\n`\n\nconst useStyles = makeStyles(mainStyles)\n\nconst MachineStatus = () => {\n const classes = useStyles()\n const { state } = useLocation()\n const addedMachineId = state?.id\n const { data: machinesResponse, refetch, loading } = useQuery(GET_MACHINES)\n\n const elements = [\n {\n header: 'Machine Name',\n width: 250,\n size: 'sm',\n textAlign: 'left',\n view: m => m.name\n },\n {\n header: 'Status',\n width: 350,\n size: 'sm',\n textAlign: 'left',\n view: m => \n },\n {\n header: 'Last ping',\n width: 200,\n size: 'sm',\n textAlign: 'left',\n view: m => (m.lastPing ? moment(m.lastPing).fromNow() : 'unknown')\n },\n {\n header: 'Software Version',\n width: 200,\n size: 'sm',\n textAlign: 'left',\n view: m => m.version || 'unknown'\n }\n ]\n\n const machines = R.path(['machines'])(machinesResponse) ?? []\n const expandedIndex = R.findIndex(R.propEq('deviceId', addedMachineId))(\n machines\n )\n\n const InnerMachineDetailsRow = ({ it }) => (\n \n )\n\n return (\n <>\n \n
\n
Machine Status \n \n
\n
\n \n Warning \n
\n
\n \n Error \n
\n
\n
\n \n >\n )\n}\n\nexport default MachineStatus\n","import React from 'react'\n\nexport default React.createContext()\n","import * as R from 'ramda'\n\nconst isValidNumber = R.both(R.is(Number), R.complement(R.equals(NaN)))\n\nconst transformNumber = value => (isValidNumber(value) ? value : null)\n\nexport { transformNumber }\n","import { makeStyles } from '@material-ui/core'\nimport React from 'react'\n\nimport { Link, IconButton } from 'src/components/buttons'\nimport { H4 } from 'src/components/typography'\nimport { ReactComponent as DisabledEditIcon } from 'src/styling/icons/action/edit/disabled.svg'\nimport { ReactComponent as EditIcon } from 'src/styling/icons/action/edit/enabled.svg'\n\nimport styles from './EditHeader.styles'\n\nconst useStyles = makeStyles(styles)\n\nconst Header = ({ title, editing, disabled, setEditing }) => {\n const classes = useStyles()\n\n return (\n \n
{title} \n {!editing && (\n
setEditing(true)}\n className={classes.button}\n disabled={disabled}>\n {disabled ? : }\n \n )}\n {editing && (\n
\n \n Save\n \n \n Cancel\n \n
\n )}\n
\n )\n}\n\nexport default Header\n","export default {\n header: {\n display: 'flex',\n alignItems: 'center',\n marginBottom: 16,\n height: 26,\n margin: 0\n },\n title: {\n flexShrink: 2,\n margin: 0,\n overflow: 'hidden',\n whiteSpace: 'nowrap',\n textOverflow: 'ellipsis'\n },\n button: {\n border: 'none',\n backgroundColor: 'transparent',\n cursor: 'pointer',\n marginLeft: 8\n },\n editingButtons: {\n display: 'flex',\n flexShrink: 0,\n marginLeft: 16,\n justifyContent: 'space-between',\n width: 110\n }\n}\n","import { makeStyles } from '@material-ui/core'\nimport classnames from 'classnames'\nimport { useFormikContext, Field as FormikField } from 'formik'\nimport React from 'react'\n\nimport { NumberInput } from 'src/components/inputs/formik'\nimport { Label1, Info1, TL2 } from 'src/components/typography'\n\nimport styles from './EditableNumber.styles'\n\nconst useStyles = makeStyles(styles)\n\nconst EditableNumber = ({\n label,\n name,\n editing,\n displayValue,\n decoration,\n className,\n decimalPlaces = 0,\n width = 80\n}) => {\n const classes = useStyles({ width, editing })\n const { values } = useFormikContext()\n\n const classNames = {\n [classes.fieldWrapper]: true,\n className\n }\n\n return (\n \n {label &&
{label} }\n
\n {!editing && (\n {displayValue(values[name])} \n )}\n {editing && (\n \n )}\n {decoration} \n
\n
\n )\n}\n\nexport default EditableNumber\n","export default {\n text: {\n margin: [[7, 0, 7, 1]]\n },\n fieldWrapper: {\n height: 53\n },\n valueWrapper: {\n display: 'flex',\n alignItems: 'baseline'\n },\n label: {\n margin: 0\n },\n decoration: {\n margin: [[0, 0, 0, 7]]\n }\n}\n","import { Form, Formik } from 'formik'\nimport React, { useContext, useState } from 'react'\nimport * as Yup from 'yup'\n\nimport PromptWhenDirty from 'src/components/PromptWhenDirty'\nimport { transformNumber } from 'src/utils/number'\n\nimport NotificationsCtx from '../NotificationsContext'\n\nimport Header from './EditHeader'\nimport EditableNumber from './EditableNumber'\n\nconst SingleFieldEditableNumber = ({\n title,\n label,\n width = 80,\n min = 0,\n max = 9999999,\n name,\n section,\n className\n}) => {\n const [saving, setSaving] = useState(false)\n\n const innerSave = async (section, value) => {\n if (saving) return\n\n setSaving(true)\n\n // no response means the save failed\n await save(section, value)\n\n setSaving(false)\n }\n\n const {\n save,\n data,\n currency,\n isEditing,\n isDisabled,\n setEditing\n } = useContext(NotificationsCtx)\n\n const schema = Yup.object().shape({\n [name]: Yup.number()\n .transform(transformNumber)\n .integer()\n .min(min)\n .max(max)\n .nullable()\n })\n\n return (\n innerSave(section, schema.cast(it))}\n onReset={() => {\n setEditing(name, false)\n }}>\n \n \n )\n}\n\nexport default SingleFieldEditableNumber\n","import { makeStyles } from '@material-ui/core'\nimport React, { useContext } from 'react'\n\nimport NotificationsCtx from '../NotificationsContext'\nimport SingleFieldEditableNumber from '../components/SingleFieldEditableNumber'\n\nimport styles from './CryptoBalanceAlerts.styles'\n\nconst LOW_BALANCE_KEY = 'cryptoLowBalance'\nconst HIGH_BALANCE_KEY = 'cryptoHighBalance'\n\nconst useStyles = makeStyles(styles)\n\nconst CryptoBalanceAlerts = ({ section, fieldWidth }) => {\n const classes = useStyles()\n\n const {\n data,\n save,\n currency,\n setEditing,\n isEditing,\n isDisabled\n } = useContext(NotificationsCtx)\n\n return (\n \n
setEditing(LOW_BALANCE_KEY, it)}\n width={fieldWidth}\n />\n\n
\n\n setEditing(HIGH_BALANCE_KEY, it)}\n width={fieldWidth}\n />\n \n )\n}\n\nexport default CryptoBalanceAlerts\n","export default {\n cryptoBalanceAlerts: {\n display: 'flex',\n marginBottom: 36,\n height: 135,\n alignItems: 'center'\n },\n cryptoBalanceAlertsForm: {\n width: 222,\n marginRight: 32\n },\n cryptoBalanceAlertsSecondForm: {\n marginLeft: 50\n },\n vertSeparator: {\n width: 1,\n height: '100%',\n borderRight: [[1, 'solid', 'black']]\n }\n}\n","import * as R from 'ramda'\nimport React, { useContext } from 'react'\nimport * as Yup from 'yup'\n\nimport { Table as EditableTable } from 'src/components/editableTable'\nimport { NumberInput } from 'src/components/inputs/formik'\nimport Autocomplete from 'src/components/inputs/formik/Autocomplete.js'\nimport { transformNumber } from 'src/utils/number'\n\nimport NotificationsCtx from '../NotificationsContext'\n\nconst HIGH_BALANCE_KEY = 'highBalance'\nconst LOW_BALANCE_KEY = 'lowBalance'\nconst CRYPTOCURRENCY_KEY = 'cryptoCurrency'\nconst NAME = 'cryptoBalanceOverrides'\n\nconst CryptoBalanceOverrides = ({ section }) => {\n const {\n cryptoCurrencies = [],\n data,\n save,\n error,\n currency,\n isDisabled,\n setEditing\n } = useContext(NotificationsCtx)\n const setupValues = data?.cryptoBalanceOverrides ?? []\n const innerSetEditing = it => setEditing(NAME, it)\n\n const onDelete = id => {\n const newOverrides = {\n cryptoBalanceOverrides: R.reject(it => it.id === id, setupValues)\n }\n return save(newOverrides)\n }\n\n const overridenCryptos = R.map(R.prop(CRYPTOCURRENCY_KEY))(setupValues)\n const suggestionFilter = R.filter(\n it => !R.contains(it.code, overridenCryptos)\n )\n const suggestions = suggestionFilter(cryptoCurrencies)\n\n const findSuggestion = it => {\n const coin = R.compose(R.find(R.propEq('code', it?.cryptoCurrency)))(\n cryptoCurrencies\n )\n return coin ? [coin] : []\n }\n\n const initialValues = {\n [CRYPTOCURRENCY_KEY]: null,\n [LOW_BALANCE_KEY]: '',\n [HIGH_BALANCE_KEY]: ''\n }\n\n const notesMin = 0\n const currencyMax = 9999999\n const validationSchema = Yup.object().shape(\n {\n [CRYPTOCURRENCY_KEY]: Yup.string()\n .label('Cryptocurrency')\n .nullable()\n .required(),\n [LOW_BALANCE_KEY]: Yup.number()\n .label('Low Balance')\n .when(HIGH_BALANCE_KEY, {\n is: HIGH_BALANCE_KEY => !HIGH_BALANCE_KEY,\n then: Yup.number().required()\n })\n .transform(transformNumber)\n .integer()\n .min(notesMin)\n .max(currencyMax)\n .nullable(),\n [HIGH_BALANCE_KEY]: Yup.number()\n .label('High Balance')\n .when(LOW_BALANCE_KEY, {\n is: LOW_BALANCE_KEY => !LOW_BALANCE_KEY,\n then: Yup.number().required()\n })\n .transform(transformNumber)\n .integer()\n .min(notesMin)\n .max(currencyMax)\n .nullable()\n },\n [LOW_BALANCE_KEY, HIGH_BALANCE_KEY]\n )\n\n const viewCrypto = it =>\n R.compose(\n R.path(['display']),\n R.find(R.propEq('code', it))\n )(cryptoCurrencies)\n\n const elements = [\n {\n name: CRYPTOCURRENCY_KEY,\n header: 'Cryptocurrency',\n width: 166,\n size: 'sm',\n view: viewCrypto,\n input: Autocomplete,\n inputProps: {\n options: it => R.concat(suggestions, findSuggestion(it)),\n optionsLimit: null,\n valueProp: 'code',\n labelProp: 'display'\n }\n },\n {\n name: LOW_BALANCE_KEY,\n width: 155,\n textAlign: 'right',\n bold: true,\n input: NumberInput,\n suffix: currency,\n inputProps: {\n decimalPlaces: 2\n }\n },\n {\n name: HIGH_BALANCE_KEY,\n width: 155,\n textAlign: 'right',\n bold: true,\n input: NumberInput,\n suffix: currency,\n inputProps: {\n decimalPlaces: 2\n }\n }\n ]\n\n return (\n save(section, it)}\n initialValues={initialValues}\n validationSchema={validationSchema}\n forceDisable={isDisabled(NAME) || !cryptoCurrencies}\n data={setupValues}\n elements={elements}\n disableAdd={!suggestions?.length}\n onDelete={onDelete}\n setEditing={innerSetEditing}\n />\n )\n}\n\nexport default CryptoBalanceOverrides\n","import { backgroundColor } from 'src/styling/variables'\n\nexport default {\n wrapper: {\n display: 'flex'\n },\n form: {\n marginBottom: 36\n },\n first: {\n width: 236\n },\n title: {\n marginTop: 0\n },\n row: {\n width: 183,\n display: 'grid',\n gridTemplateColumns: 'repeat(2,1fr)',\n gridTemplateRows: '1fr',\n gridColumnGap: 18,\n gridRowGap: 0\n },\n col2: {\n width: 136\n },\n cashboxLabel: {\n marginRight: 4,\n fontSize: 20\n },\n cashboxEmptyPart: {\n backgroundColor: `${backgroundColor}`\n }\n}\n","import { makeStyles } from '@material-ui/core'\nimport { Form, Formik } from 'formik'\nimport React, { useContext } from 'react'\nimport * as Yup from 'yup'\n\nimport PromptWhenDirty from 'src/components/PromptWhenDirty'\nimport { TL2 } from 'src/components/typography'\nimport { transformNumber } from 'src/utils/number'\n\nimport { Cashbox } from '../../../components/inputs/cashbox/Cashbox'\nimport NotificationsCtx from '../NotificationsContext'\nimport Header from '../components/EditHeader'\nimport EditableNumber from '../components/EditableNumber'\n\nimport styles from './FiatBalanceAlerts.styles.js'\n\nconst useStyles = makeStyles(styles)\n\nconst NAME = 'fiatBalanceAlerts'\n\nconst FiatBalance = ({\n section,\n min = 0,\n max = Number.MAX_SAFE_INTEGER,\n fieldWidth = 80\n}) => {\n const { isEditing, isDisabled, setEditing, data, save } = useContext(\n NotificationsCtx\n )\n const classes = useStyles()\n\n const editing = isEditing(NAME)\n\n const schema = Yup.object().shape({\n fiatBalanceCassette1: Yup.number()\n .transform(transformNumber)\n .integer()\n .min(min)\n .max(max)\n .nullable(),\n fiatBalanceCassette2: Yup.number()\n .transform(transformNumber)\n .integer()\n .min(min)\n .max(max)\n .nullable()\n })\n\n const fiatBalanceCassette1Percent =\n (100 * (data?.fiatBalanceCassette1 ?? 0)) / max\n const fiatBalanceCassette2Percent =\n (100 * (data?.fiatBalanceCassette2 ?? 0)) / max\n\n return (\n save(section, schema.cast(it))}\n onReset={() => {\n setEditing(NAME, false)\n }}>\n \n \n )\n}\n\nexport default FiatBalance\n","import * as R from 'ramda'\nimport React, { useContext } from 'react'\nimport * as Yup from 'yup'\n\nimport { Table as EditableTable } from 'src/components/editableTable'\nimport { NumberInput } from 'src/components/inputs/formik/'\nimport Autocomplete from 'src/components/inputs/formik/Autocomplete'\nimport { transformNumber } from 'src/utils/number'\n\nimport NotificationsCtx from '../NotificationsContext'\n\nconst CASSETTE_1_KEY = 'fiatBalanceCassette1'\nconst CASSETTE_2_KEY = 'fiatBalanceCassette2'\nconst MACHINE_KEY = 'machine'\nconst NAME = 'fiatBalanceOverrides'\n\nconst FiatBalanceOverrides = ({ section }) => {\n const {\n machines = [],\n data,\n save,\n isDisabled,\n setEditing,\n error\n } = useContext(NotificationsCtx)\n\n const setupValues = data?.fiatBalanceOverrides ?? []\n const innerSetEditing = it => setEditing(NAME, it)\n\n const overridenMachines = R.map(override => override.machine, setupValues)\n const suggestionFilter = R.filter(\n it => !R.contains(it.deviceId, overridenMachines)\n )\n const suggestions = suggestionFilter(machines)\n\n const findSuggestion = it => {\n const coin = R.compose(R.find(R.propEq('deviceId', it?.machine)))(machines)\n return coin ? [coin] : []\n }\n\n const initialValues = {\n [MACHINE_KEY]: null,\n [CASSETTE_1_KEY]: '',\n [CASSETTE_2_KEY]: ''\n }\n\n const notesMin = 0\n const notesMax = 9999999\n const validationSchema = Yup.object().shape(\n {\n [MACHINE_KEY]: Yup.string()\n .label('Machine')\n .nullable()\n .required(),\n [CASSETTE_1_KEY]: Yup.number()\n .label('Cassette 1 (top)')\n .when(CASSETTE_2_KEY, {\n is: CASSETTE_2_KEY => !CASSETTE_2_KEY,\n then: Yup.number().required()\n })\n .transform(transformNumber)\n .integer()\n .min(notesMin)\n .max(notesMax)\n .nullable(),\n [CASSETTE_2_KEY]: Yup.number()\n .label('Cassette 2 (bottom)')\n .when(CASSETTE_1_KEY, {\n is: CASSETTE_1_KEY => !CASSETTE_1_KEY,\n then: Yup.number().required()\n })\n .transform(transformNumber)\n .integer()\n .min(notesMin)\n .max(notesMax)\n .nullable()\n },\n [CASSETTE_1_KEY, CASSETTE_2_KEY]\n )\n\n const viewMachine = it =>\n R.compose(R.path(['name']), R.find(R.propEq('deviceId', it)))(machines)\n\n const elements = [\n {\n name: MACHINE_KEY,\n width: 238,\n size: 'sm',\n view: viewMachine,\n input: Autocomplete,\n inputProps: {\n options: it => R.concat(suggestions, findSuggestion(it)),\n valueProp: 'deviceId',\n labelProp: 'name'\n }\n },\n {\n name: CASSETTE_1_KEY,\n display: 'Cash-out 1',\n width: 155,\n textAlign: 'right',\n doubleHeader: 'Cash-out (Cassette Empty)',\n bold: true,\n input: NumberInput,\n suffix: 'notes',\n inputProps: {\n decimalPlaces: 0\n }\n },\n {\n name: CASSETTE_2_KEY,\n display: 'Cash-out 2',\n width: 155,\n textAlign: 'right',\n doubleHeader: 'Cash-out (Cassette Empty)',\n bold: true,\n input: NumberInput,\n suffix: 'notes',\n inputProps: {\n decimalPlaces: 0\n }\n }\n ]\n\n return (\n save(section, validationSchema.cast(it))}\n initialValues={initialValues}\n validationSchema={validationSchema}\n forceDisable={isDisabled(NAME) || !machines}\n data={setupValues}\n elements={elements}\n disableAdd={!suggestions?.length}\n setEditing={innerSetEditing}\n />\n )\n}\n\nexport default FiatBalanceOverrides\n","import { makeStyles } from '@material-ui/core'\nimport * as R from 'ramda'\nimport React, { useContext } from 'react'\n\nimport {\n Table,\n THead,\n TBody,\n Tr,\n Td,\n Th\n} from 'src/components/fake-table/Table'\nimport { Switch } from 'src/components/inputs'\nimport { fromNamespace, toNamespace } from 'src/utils/config'\nimport { startCase } from 'src/utils/string'\n\nimport NotificationsCtx from '../NotificationsContext'\n\nconst channelSize = 129\nconst sizes = {\n balance: 152,\n transactions: 184,\n compliance: 178,\n errors: 142,\n active: 263\n}\nconst width = R.sum(R.values(sizes)) + channelSize\n\nconst Row = ({ namespace, forceDisable }) => {\n const { data: rawData, save: rawSave } = useContext(NotificationsCtx)\n\n const save = R.compose(rawSave(null), toNamespace(namespace))\n const data = fromNamespace(namespace)(rawData)\n\n const disabled = forceDisable || !data || !data.active\n\n const Cell = ({ name, disabled }) => {\n const value = !!(data && data[name])\n\n return (\n \n {\n save({ [name]: event.target.checked })\n }}\n value={value}\n />\n \n )\n }\n\n return (\n \n {startCase(namespace)} \n | \n | \n | \n | \n | \n \n )\n}\n\nconst useStyles = makeStyles({\n mainTable: {\n width\n },\n wizardTable: {\n width: 930\n }\n})\nconst Setup = ({ wizard, forceDisable }) => {\n const widthAdjust = wizard ? 20 : 0\n const classes = useStyles()\n return (\n \n \n Channel \n {Object.keys(sizes).map(it => (\n \n {startCase(it)}\n \n ))}\n \n \n
\n
\n
\n \n
\n )\n}\n\nexport default Setup\n","import React from 'react'\n\nimport SingleFieldEditableNumber from '../components/SingleFieldEditableNumber'\n\nconst NAME = 'highValueTransaction'\n\nconst TransactionAlerts = ({ section, fieldWidth }) => {\n return (\n \n )\n}\n\nexport default TransactionAlerts\n","import { useQuery, useMutation } from '@apollo/react-hooks'\nimport gql from 'graphql-tag'\nimport * as R from 'ramda'\nimport React, { useState } from 'react'\n\nimport TitleSection from 'src/components/layout/TitleSection'\nimport { fromNamespace, toNamespace, namespaces } from 'src/utils/config'\n\nimport Section from '../../components/layout/Section'\n\nimport NotificationsCtx from './NotificationsContext'\nimport CryptoBalanceAlerts from './sections/CryptoBalanceAlerts'\nimport CryptoBalanceOverrides from './sections/CryptoBalanceOverrides'\nimport FiatBalanceAlerts from './sections/FiatBalanceAlerts'\nimport FiatBalanceOverrides from './sections/FiatBalanceOverrides'\nimport Setup from './sections/Setup'\nimport TransactionAlerts from './sections/TransactionAlerts'\n\nconst GET_INFO = gql`\n query getData {\n config\n machines {\n name\n deviceId\n }\n cryptoCurrencies {\n code\n display\n }\n }\n`\n\nconst SAVE_CONFIG = gql`\n mutation Save($config: JSONObject) {\n saveConfig(config: $config)\n }\n`\n\nconst FIELDS_WIDTH = 130\n\nconst Notifications = ({\n name: SCREEN_KEY,\n displaySetup = true,\n displayTransactionAlerts = true,\n displayFiatAlerts = true,\n displayCryptoAlerts = true,\n displayOverrides = true,\n displayTitle = true,\n wizard = false\n}) => {\n const [section, setSection] = useState(null)\n const [error, setError] = useState(null)\n const [editingKey, setEditingKey] = useState(null)\n\n const { data } = useQuery(GET_INFO)\n\n const [saveConfig] = useMutation(SAVE_CONFIG, {\n refetchQueries: ['getData'],\n onCompleted: () => setEditingKey(null),\n onError: error => setError(error)\n })\n\n const config = fromNamespace(SCREEN_KEY)(data?.config)\n const machines = data?.machines\n const cryptoCurrencies = data?.cryptoCurrencies\n\n const currency = R.path(['fiatCurrency'])(\n fromNamespace(namespaces.LOCALE)(data?.config)\n )\n\n const save = R.curry((section, rawConfig) => {\n const config = toNamespace(SCREEN_KEY)(rawConfig)\n setSection(section)\n setError(null)\n return saveConfig({ variables: { config } })\n })\n\n const setEditing = (key, state) => {\n if (!state) {\n setError(null)\n }\n setEditingKey(state ? key : null)\n }\n\n const isEditing = key => editingKey === key\n const isDisabled = key => editingKey && editingKey !== key\n\n const contextValue = {\n save,\n error,\n editingKey,\n data: config,\n currency,\n isEditing,\n isDisabled,\n setEditing,\n setSection,\n machines,\n cryptoCurrencies\n }\n\n return (\n \n {displayTitle && }\n {displaySetup && (\n \n )}\n {displayTransactionAlerts && (\n \n )}\n {displayFiatAlerts && (\n \n \n {displayOverrides && }\n \n )}\n {displayCryptoAlerts && (\n \n \n {displayOverrides && (\n \n )}\n \n )}\n \n )\n}\n\nexport default Notifications\n","import baseStyles from 'src/pages/Logs.styles'\n\nconst { button } = baseStyles\n\nconst mainStyles = {\n button,\n content: {\n display: 'flex'\n },\n transparentButton: {\n '& > *': {\n margin: 'auto 10px'\n },\n '& button': {\n border: 'none',\n backgroundColor: 'transparent',\n cursor: 'pointer'\n }\n },\n titleWrapper: {\n display: 'flex',\n alignItems: 'center',\n flex: 'wrap'\n },\n rowWrapper: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between'\n },\n rowTextAndSwitch: {\n display: 'flex',\n flex: 'wrap',\n alignItems: 'center',\n justifyContent: 'space-between',\n width: 285\n },\n popoverContent: {\n width: 272,\n padding: [[10, 15]]\n }\n}\n\nexport { mainStyles }\n","import { useQuery, useMutation } from '@apollo/react-hooks'\nimport { makeStyles } from '@material-ui/core/styles'\nimport gql from 'graphql-tag'\nimport React, { memo } from 'react'\n\nimport { Tooltip } from 'src/components/Tooltip'\nimport { Switch } from 'src/components/inputs'\nimport { H4, P, Label2 } from 'src/components/typography'\nimport { fromNamespace, toNamespace, namespaces } from 'src/utils/config'\n\nimport { mainStyles } from './CoinATMRadar.styles'\n\nconst useStyles = makeStyles(mainStyles)\n\nconst GET_CONFIG = gql`\n query getData {\n config\n }\n`\n\nconst SAVE_CONFIG = gql`\n mutation Save($config: JSONObject) {\n saveConfig(config: $config)\n }\n`\n\nconst Row = memo(({ title, disabled = false, checked, save, label }) => {\n const classes = useStyles()\n\n return (\n \n
\n
{title}
\n
save && save(event.target.checked)}\n />\n \n {label &&
{label} }\n
\n )\n})\n\nconst CoinATMRadar = memo(() => {\n const classes = useStyles()\n\n const { data } = useQuery(GET_CONFIG)\n\n const [saveConfig] = useMutation(SAVE_CONFIG, {\n refetchQueries: ['getData']\n })\n\n const save = it =>\n saveConfig({\n variables: { config: toNamespace(namespaces.COIN_ATM_RADAR, it) }\n })\n\n const coinAtmRadarConfig =\n data?.config && fromNamespace(namespaces.COIN_ATM_RADAR, data.config)\n if (!coinAtmRadarConfig) return null\n\n return (\n \n
\n
\n
Coin ATM Radar share settings \n
\n \n For details on configuring this panel, please read the relevant\n knowledgebase article{' '}\n \n here\n \n .\n
\n \n
\n
save({ active: value })}\n label={coinAtmRadarConfig.active ? 'Yes' : 'No'}\n />\n {'Machine info'} \n save({ commissions: value })}\n />\n save({ limitsAndVerification: value })}\n />\n
\n
\n )\n})\n\nexport default CoinATMRadar\n","import CoinATMRadar from './CoinATMRadar'\n\nexport default CoinATMRadar\n","import { createMuiTheme } from '@material-ui/core/styles'\n\nimport typographyStyles from 'src/components/typography/styles'\n\nimport {\n backgroundColor,\n inputFontFamily,\n secondaryColor,\n fontColor,\n offColor,\n subheaderColor,\n fontSize3,\n fontSize5\n} from './variables'\n\nconst { p } = typographyStyles\n\nexport default createMuiTheme({\n typography: {\n fontFamily: inputFontFamily,\n body1: { ...p }\n },\n MuiButtonBase: {\n disableRipple: true\n },\n palette: {\n primary: {\n light: secondaryColor,\n dark: secondaryColor,\n main: secondaryColor\n },\n secondary: {\n light: secondaryColor,\n dark: secondaryColor,\n main: secondaryColor\n },\n background: {\n default: backgroundColor\n }\n },\n overrides: {\n MuiRadio: {\n colorSecondary: {\n color: secondaryColor\n }\n },\n MuiAutocomplete: {\n root: {\n color: fontColor\n },\n noOptions: {\n padding: [[6, 16]]\n },\n option: {\n '&[data-focus=\"true\"]': {\n backgroundColor: subheaderColor\n }\n },\n paper: {\n color: fontColor,\n margin: 0\n },\n listbox: {\n padding: 0\n },\n tag: {\n '&[data-tag-index=\"0\"]': {\n marginLeft: 0\n },\n margin: 2,\n backgroundColor: subheaderColor,\n borderRadius: 4,\n height: 18\n }\n },\n MuiChip: {\n label: {\n paddingLeft: 4,\n paddingRight: 4,\n color: fontColor,\n fontSize: fontSize5\n }\n },\n MuiInput: {\n root: {\n color: fontColor\n },\n underline: {\n '&:before': {\n borderBottom: [[2, 'solid', fontColor]]\n }\n }\n },\n MuiInputLabel: {\n root: {\n font: 'inherit',\n fontSize: fontSize3,\n color: offColor\n },\n shrink: {\n color: fontColor,\n transform: 'translate(0, 1.7px) scale(0.83)'\n }\n },\n MuiFormLabel: {\n root: {\n '&$focused': {\n color: fontColor\n }\n }\n },\n MuiListItem: {\n root: {\n '&:nth-of-type(odd)': {\n backgroundColor: backgroundColor\n }\n }\n }\n }\n})\n","import typographyStyles from 'src/components/typography/styles'\nimport theme from 'src/styling/theme'\nimport { offColor } from 'src/styling/variables'\n\nconst { p } = typographyStyles\n\nconst styles = {\n header: {\n display: 'flex',\n alignItems: 'center',\n position: 'relative',\n flex: 'wrap'\n },\n transparentButton: {\n '& > *': {\n margin: 'auto 12px'\n },\n '& button': {\n border: 'none',\n backgroundColor: 'transparent',\n cursor: 'pointer'\n }\n },\n section: {\n marginBottom: 52\n },\n row: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n marginBottom: 28,\n width: 600,\n '&:last-child': {\n marginBottom: 0\n }\n },\n switchRow: {\n display: 'flex',\n alignItems: 'center',\n marginBottom: 28,\n width: 600\n },\n switch: {\n display: 'flex',\n alignItems: 'center',\n marginLeft: 120\n },\n submit: {\n justifyContent: 'flex-start',\n alignItems: 'center',\n height: 19,\n padding: [[0, 4, 4, 4]],\n '& > button': {\n marginRight: 40\n }\n },\n singleButton: {\n marginTop: 50,\n paddingLeft: 0\n }\n}\n\nconst contactInfoStyles = {\n infoMessage: {\n display: 'flex',\n marginBottom: 52,\n '& > p': {\n width: 330,\n color: offColor,\n marginTop: 4,\n marginLeft: 16\n }\n },\n radioButtonsRow: {\n height: 60,\n marginBottom: 14\n },\n radioButtons: {\n display: 'flex',\n flexDirection: 'row',\n paddingLeft: 4\n },\n rowWrapper: {\n display: 'flex',\n alignItems: 'center',\n position: 'relative',\n flex: 'wrap'\n },\n transparentButton: {\n '& > *': {\n margin: 'auto 12px'\n },\n '& button': {\n border: 'none',\n backgroundColor: 'transparent',\n cursor: 'pointer'\n }\n }\n}\n\nconst termsConditionsStyles = {\n enable: {\n display: 'flex',\n alignItems: 'center',\n marginBottom: 22 - theme.spacing(1),\n '& > span:first-child': {\n extend: p,\n marginRight: 116 - theme.spacing(1)\n },\n '& > span:last-child': {\n marginLeft: 4\n }\n }\n}\n\nconst fieldStyles = {\n field: {\n position: 'relative',\n width: 280,\n padding: [[0, 4, 4, 0]]\n },\n notEditing: {\n display: 'flex',\n flexDirection: 'column'\n },\n notEditingSingleLine: {\n '& > p:first-child': {\n height: 16,\n lineHeight: '16px',\n transform: 'scale(0.75)',\n transformOrigin: 'left',\n paddingLeft: 0,\n margin: [[1, 0, 6, 0]]\n },\n '& > p:last-child': {\n overflow: 'hidden',\n whiteSpace: 'nowrap',\n textOverflow: 'ellipsis',\n height: 25,\n margin: 0\n }\n },\n notEditingMultiline: {\n '& > p:first-child': {\n height: 16,\n lineHeight: '16px',\n transform: 'scale(0.75)',\n transformOrigin: 'left',\n paddingLeft: 0,\n margin: [[1, 0, 5, 0]]\n },\n '& > p:last-child': {\n width: 502,\n height: 121,\n overflowY: 'auto',\n lineHeight: '19px',\n wordWrap: 'anywhere',\n margin: 0\n }\n }\n}\n\nexport { styles, contactInfoStyles, termsConditionsStyles, fieldStyles }\n","import { useQuery, useMutation } from '@apollo/react-hooks'\nimport { makeStyles } from '@material-ui/core'\nimport classnames from 'classnames'\nimport { Form, Formik, Field as FormikField } from 'formik'\nimport gql from 'graphql-tag'\nimport * as R from 'ramda'\nimport React, { useState } from 'react'\nimport * as Yup from 'yup'\n\nimport ErrorMessage from 'src/components/ErrorMessage'\nimport PromptWhenDirty from 'src/components/PromptWhenDirty'\nimport { Link, IconButton } from 'src/components/buttons'\nimport Switch from 'src/components/inputs/base/Switch'\nimport { TextInput } from 'src/components/inputs/formik'\nimport { P, H4, Info3, Label1, Label2, Label3 } from 'src/components/typography'\nimport { ReactComponent as EditIcon } from 'src/styling/icons/action/edit/enabled.svg'\nimport { ReactComponent as WarningIcon } from 'src/styling/icons/warning-icon/comet.svg'\nimport { fontSize5 } from 'src/styling/variables'\nimport { fromNamespace, toNamespace, namespaces } from 'src/utils/config'\n\nimport {\n styles as globalStyles,\n contactInfoStyles\n} from './OperatorInfo.styles'\n\nconst FIELD_WIDTH = 280\n\nconst fieldStyles = {\n field: {\n position: 'relative',\n width: 280,\n height: 48,\n padding: [[0, 4, 4, 0]]\n },\n notEditing: {\n display: 'flex',\n flexDirection: 'column',\n '& > p:first-child': {\n height: 16,\n lineHeight: '16px',\n fontSize: fontSize5,\n transformOrigin: 'left',\n paddingLeft: 0,\n margin: [[3, 0, 3, 0]]\n },\n '& > p:last-child': {\n overflow: 'hidden',\n whiteSpace: 'nowrap',\n textOverflow: 'ellipsis',\n margin: 0\n }\n }\n}\n\nconst fieldUseStyles = makeStyles(fieldStyles)\n\nconst Field = ({ editing, field, displayValue, ...props }) => {\n const classes = fieldUseStyles()\n\n const classNames = {\n [classes.field]: true,\n [classes.notEditing]: !editing\n }\n\n return (\n \n {!editing && (\n <>\n {field.label} \n {displayValue(field.value)} \n >\n )}\n {editing && (\n \n )}\n
\n )\n}\n\nconst GET_CONFIG = gql`\n query getData {\n config\n }\n`\n\nconst SAVE_CONFIG = gql`\n mutation Save($config: JSONObject) {\n saveConfig(config: $config)\n }\n`\n\nconst styles = R.merge(globalStyles, contactInfoStyles)\n\nconst contactUseStyles = makeStyles(styles)\n\nconst ContactInfo = ({ wizard }) => {\n const classes = contactUseStyles()\n\n const [editing, setEditing] = useState(wizard || false)\n const [error, setError] = useState(null)\n\n const [saveConfig] = useMutation(SAVE_CONFIG, {\n onCompleted: () => setEditing(false),\n refetchQueries: () => ['getData'],\n onError: e => setError(e)\n })\n\n const { data } = useQuery(GET_CONFIG)\n\n const save = it => {\n return saveConfig({\n variables: { config: toNamespace(namespaces.OPERATOR_INFO, it) }\n })\n }\n\n const info =\n data?.config && fromNamespace(namespaces.OPERATOR_INFO, data.config)\n\n if (!info) return null\n\n const validationSchema = Yup.object().shape({\n active: Yup.boolean(),\n name: Yup.string(),\n phone: Yup.string(),\n email: Yup.string()\n .email('Please enter a valid email address')\n .required(),\n website: Yup.string(),\n companyNumber: Yup.string()\n })\n\n const fields = [\n {\n name: 'name',\n label: 'Full name',\n value: info.name ?? '',\n component: TextInput\n },\n {\n name: 'phone',\n label: 'Phone number',\n value: info.phone,\n component: TextInput\n },\n {\n name: 'email',\n label: 'Email',\n value: info.email ?? '',\n component: TextInput\n },\n {\n name: 'website',\n label: 'Website',\n value: info.website ?? '',\n component: TextInput\n },\n {\n name: 'companyNumber',\n label: 'Company number',\n value: info.companyNumber ?? '',\n component: TextInput\n }\n ]\n\n const findField = name => R.find(R.propEq('name', name))(fields)\n const findValue = name => findField(name).value\n\n const displayTextValue = value => value\n\n const form = {\n initialValues: {\n active: info.active,\n name: findValue('name'),\n phone: findValue('phone'),\n email: findValue('email'),\n website: findValue('website'),\n companyNumber: findValue('companyNumber')\n }\n }\n\n return (\n <>\n \n
Contact information \n \n \n
Info card enabled?
\n
\n \n save({\n active: event.target.checked\n })\n }\n />\n {info.active ? 'Yes' : 'No'} \n
\n
\n \n
\n
Info card \n {!editing && (\n setEditing(true)}>\n \n \n )}\n \n
save(validationSchema.cast(values))}\n onReset={() => {\n setEditing(false)\n setError(null)\n }}>\n \n \n
\n {!wizard && (\n \n \n \n Sharing your information with your customers through your machines\n allows them to contact you in case there's a problem with a machine\n in your network or a transaction.\n \n
\n )}\n >\n )\n}\n\nexport default ContactInfo\n","function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport * as React from \"react\";\n\nvar _ref2 = /*#__PURE__*/React.createElement(\"desc\", null, \"Created with Sketch.\");\n\nvar _ref3 = /*#__PURE__*/React.createElement(\"g\", {\n id: \"icon/table/false\",\n stroke: \"none\",\n strokeWidth: 1,\n fill: \"none\",\n fillRule: \"evenodd\"\n}, /*#__PURE__*/React.createElement(\"g\", {\n id: \"Group-4\",\n stroke: \"#FF584A\",\n strokeWidth: 4\n}, /*#__PURE__*/React.createElement(\"line\", {\n x1: 13.5,\n y1: 0.5,\n x2: 0.995667,\n y2: 13.004333,\n id: \"Line-7\"\n}), /*#__PURE__*/React.createElement(\"line\", {\n x1: 13.5,\n y1: 0.5,\n x2: 0.995667,\n y2: 13.004333,\n id: \"Line-7\",\n transform: \"translate(7.000000, 7.000000) scale(-1, 1) translate(-7.000000, -7.000000) \"\n})));\n\nfunction SvgFalse(_ref, svgRef) {\n var title = _ref.title,\n titleId = _ref.titleId,\n props = _objectWithoutProperties(_ref, [\"title\", \"titleId\"]);\n\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n width: \"14px\",\n height: \"14px\",\n viewBox: \"0 0 14 14\",\n xmlns: \"http://www.w3.org/2000/svg\",\n xmlnsXlink: \"http://www.w3.org/1999/xlink\",\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, _ref2, _ref3);\n}\n\nvar ForwardRef = /*#__PURE__*/React.forwardRef(SvgFalse);\nexport default __webpack_public_path__ + \"static/media/false.7f926859.svg\";\nexport { ForwardRef as ReactComponent };","function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport * as React from \"react\";\n\nvar _ref2 = /*#__PURE__*/React.createElement(\"desc\", null, \"Created with Sketch.\");\n\nvar _ref3 = /*#__PURE__*/React.createElement(\"g\", {\n id: \"icon/table/true\",\n stroke: \"none\",\n strokeWidth: 1,\n fill: \"none\",\n fillRule: \"evenodd\"\n}, /*#__PURE__*/React.createElement(\"path\", {\n d: \"M4.17451294,13.3251347 L0.599425104,9.29667256 C-0.199808368,8.3960844 -0.199808368,6.94040225 0.599425104,6.03981409 C1.39865858,5.13922593 2.69051421,5.13922593 3.48974768,6.03981409 L5.61967423,8.439847 L12.5102523,0.675441122 C13.3094858,-0.225147041 14.6033855,-0.225147041 15.4005749,0.675441122 C16.1998084,1.57372599 16.1998084,3.03171143 15.4005749,3.93229959 L7.06483552,13.3251347 C6.66624082,13.7742771 6.14295752,14 5.61967423,14 C5.09639093,14 4.57310763,13.7742771 4.17451294,13.3251347 Z\",\n id: \"Fill-1\",\n fill: \"#48F694\"\n}));\n\nfunction SvgTrue(_ref, svgRef) {\n var title = _ref.title,\n titleId = _ref.titleId,\n props = _objectWithoutProperties(_ref, [\"title\", \"titleId\"]);\n\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n width: \"16px\",\n height: \"14px\",\n viewBox: \"0 0 16 14\",\n xmlns: \"http://www.w3.org/2000/svg\",\n xmlnsXlink: \"http://www.w3.org/1999/xlink\",\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, _ref2, _ref3);\n}\n\nvar ForwardRef = /*#__PURE__*/React.forwardRef(SvgTrue);\nexport default __webpack_public_path__ + \"static/media/true.8e532da3.svg\";\nexport { ForwardRef as ReactComponent };","import baseStyles from 'src/pages/Logs.styles'\nimport { backgroundColor, zircon } from 'src/styling/variables'\n\nconst { fillColumn } = baseStyles\n\nconst booleanPropertiesTableStyles = {\n booleanPropertiesTableWrapper: {\n display: 'flex',\n flexDirection: 'column',\n width: 396\n },\n tableRow: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n '&:nth-child(even)': {\n backgroundColor: backgroundColor\n },\n '&:nth-child(odd)': {\n backgroundColor: zircon\n },\n minHeight: 32,\n height: 'auto',\n padding: [[8, 16, 8, 24]],\n boxShadow: '0 0 0 0 rgba(0, 0, 0, 0)'\n },\n leftTableCell: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'left',\n width: 200,\n padding: [0]\n },\n rightTableCell: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'right',\n padding: [0]\n },\n transparentButton: {\n '& > *': {\n margin: 'auto 12px'\n },\n '& button': {\n border: 'none',\n backgroundColor: 'transparent',\n cursor: 'pointer'\n }\n },\n rowWrapper: {\n display: 'flex',\n alignItems: 'center',\n position: 'relative',\n flex: 'wrap'\n },\n rightAligned: {\n marginLeft: 'auto'\n },\n radioButtons: {\n display: 'flex',\n flexDirection: 'row',\n margin: [-15]\n },\n rightLink: {\n marginLeft: '20px'\n },\n fillColumn,\n popoverContent: {\n width: 272,\n padding: [[10, 15]]\n }\n}\n\nexport { booleanPropertiesTableStyles }\n","import { makeStyles } from '@material-ui/core/styles'\nimport classnames from 'classnames'\nimport { useFormikContext, Form, Formik, Field as FormikField } from 'formik'\nimport * as R from 'ramda'\nimport React, { useState, memo } from 'react'\nimport * as Yup from 'yup'\n\nimport PromptWhenDirty from 'src/components/PromptWhenDirty'\nimport { Link, IconButton } from 'src/components/buttons'\nimport { RadioGroup } from 'src/components/inputs/formik'\nimport { Table, TableBody, TableRow, TableCell } from 'src/components/table'\nimport { H4 } from 'src/components/typography'\nimport { ReactComponent as EditIconDisabled } from 'src/styling/icons/action/edit/disabled.svg'\nimport { ReactComponent as EditIcon } from 'src/styling/icons/action/edit/enabled.svg'\nimport { ReactComponent as FalseIcon } from 'src/styling/icons/table/false.svg'\nimport { ReactComponent as TrueIcon } from 'src/styling/icons/table/true.svg'\n\nimport { booleanPropertiesTableStyles } from './BooleanPropertiesTable.styles'\n\nconst useStyles = makeStyles(booleanPropertiesTableStyles)\n\nconst BooleanCell = ({ name }) => {\n const { values } = useFormikContext()\n return values[name] === 'true' ? : \n}\n\nconst BooleanPropertiesTable = memo(\n ({ title, disabled, data, elements, save, forcedEditing = false }) => {\n const initialValues = R.fromPairs(\n elements.map(it => [it.name, data[it.name] ?? null])\n )\n\n const schemaValidation = R.fromPairs(\n elements.map(it => [it.name, Yup.boolean().required()])\n )\n\n const [editing, setEditing] = useState(forcedEditing)\n\n const classes = useStyles()\n\n const innerSave = async value => {\n save(R.filter(R.complement(R.isNil), value))\n setEditing(false)\n }\n\n const radioButtonOptions = [\n { display: 'Yes', code: 'true' },\n { display: 'No', code: 'false' }\n ]\n return (\n \n
\n {({ resetForm }) => {\n return (\n \n )\n }}\n \n
\n )\n }\n)\n\nexport default BooleanPropertiesTable\n","import { useQuery, useMutation } from '@apollo/react-hooks'\nimport { makeStyles } from '@material-ui/core/styles'\nimport gql from 'graphql-tag'\nimport * as R from 'ramda'\nimport React, { memo } from 'react'\n\nimport { BooleanPropertiesTable } from 'src/components/booleanPropertiesTable'\nimport { Switch } from 'src/components/inputs'\nimport { H4, P, Label2 } from 'src/components/typography'\nimport { fromNamespace, toNamespace, namespaces } from 'src/utils/config'\n\nimport { mainStyles } from './ReceiptPrinting.styles'\n\nconst useStyles = makeStyles(mainStyles)\n\nconst GET_CONFIG = gql`\n query getData {\n config\n }\n`\n\nconst SAVE_CONFIG = gql`\n mutation Save($config: JSONObject) {\n saveConfig(config: $config)\n }\n`\n\nconst ReceiptPrinting = memo(({ wizard }) => {\n const classes = useStyles()\n\n const { data } = useQuery(GET_CONFIG)\n\n const [saveConfig] = useMutation(SAVE_CONFIG, {\n refetchQueries: () => ['getData']\n })\n\n const save = it =>\n saveConfig({\n variables: { config: toNamespace(namespaces.RECEIPT, it) }\n })\n\n const receiptPrintingConfig =\n data?.config && fromNamespace(namespaces.RECEIPT, data.config)\n if (!receiptPrintingConfig) return null\n\n return (\n <>\n \n
Receipt options \n \n \n
Enable receipt printing?
\n
\n \n saveConfig({\n variables: {\n config: toNamespace(\n namespaces.RECEIPT,\n R.merge(receiptPrintingConfig, {\n active: event.target.checked\n })\n )\n }\n })\n }\n />\n
\n
{receiptPrintingConfig.active ? 'Yes' : 'No'} \n
\n \n >\n )\n})\n\nexport default ReceiptPrinting\n","const mainStyles = {\n rowWrapper: {\n display: 'flex',\n alignItems: 'center',\n position: 'relative',\n flex: 'wrap'\n },\n switchWrapper: {\n display: 'flex',\n marginLeft: 120\n }\n}\n\nexport { mainStyles }\n","import ReceiptPrinting from './ReceiptPrinting'\n\nexport default ReceiptPrinting\n","import { useQuery, useMutation } from '@apollo/react-hooks'\nimport { makeStyles } from '@material-ui/core'\nimport classnames from 'classnames'\nimport { Form, Formik, Field as FormikField } from 'formik'\nimport gql from 'graphql-tag'\nimport * as R from 'ramda'\nimport React, { useState } from 'react'\nimport * as Yup from 'yup'\n\nimport ErrorMessage from 'src/components/ErrorMessage'\nimport PromptWhenDirty from 'src/components/PromptWhenDirty'\nimport { Link, IconButton } from 'src/components/buttons'\nimport { Switch } from 'src/components/inputs'\nimport { TextInput } from 'src/components/inputs/formik'\nimport { H4, Info2, Info3, Label2, Label3 } from 'src/components/typography'\nimport { ReactComponent as EditIcon } from 'src/styling/icons/action/edit/enabled.svg'\nimport { fromNamespace, toNamespace, namespaces } from 'src/utils/config'\n\nimport {\n styles as globalStyles,\n termsConditionsStyles,\n fieldStyles\n} from './OperatorInfo.styles'\n\nconst useFieldStyles = makeStyles(fieldStyles)\n\nconst Field = ({\n editing,\n name,\n width,\n placeholder,\n label,\n value,\n multiline = false,\n rows,\n onFocus,\n ...props\n}) => {\n const classes = useFieldStyles()\n\n const classNames = {\n [classes.field]: true,\n [classes.notEditing]: !editing,\n [classes.notEditingSingleLine]: !editing && !multiline,\n [classes.notEditingMultiline]: !editing && multiline\n }\n\n return (\n \n {!editing && (\n <>\n {label} \n {value} \n >\n )}\n {editing && (\n \n )}\n
\n )\n}\n\nconst GET_CONFIG = gql`\n query getData {\n config\n }\n`\n\nconst SAVE_CONFIG = gql`\n mutation Save($config: JSONObject) {\n saveConfig(config: $config)\n }\n`\n\nconst styles = R.merge(globalStyles, termsConditionsStyles)\n\nconst useTermsConditionsStyles = makeStyles(styles)\n\nconst TermsConditions = () => {\n const [error, setError] = useState(null)\n const [editing, setEditing] = useState(false)\n const [saveConfig] = useMutation(SAVE_CONFIG, {\n onCompleted: () => {\n setError(null)\n setEditing(false)\n },\n refetchQueries: () => ['getData'],\n onError: e => setError(e)\n })\n\n const classes = useTermsConditionsStyles()\n\n const { data } = useQuery(GET_CONFIG)\n\n const termsAndConditions =\n data?.config && fromNamespace(namespaces.TERMS_CONDITIONS, data.config)\n const formData = termsAndConditions ?? {}\n const showOnScreen = termsAndConditions?.active ?? false\n\n const save = it =>\n saveConfig({\n variables: { config: toNamespace(namespaces.TERMS_CONDITIONS, it) }\n })\n\n const fields = [\n {\n name: 'title',\n label: 'Screen title',\n value: formData.title ?? '',\n width: 282\n },\n {\n name: 'text',\n label: 'Text content',\n value: formData.text ?? '',\n width: 502,\n multiline: true,\n rows: 6\n },\n {\n name: 'acceptButtonText',\n label: 'Accept button text',\n value: formData.acceptButtonText ?? '',\n placeholder: 'I accept',\n width: 282\n },\n {\n name: 'cancelButtonText',\n label: 'Cancel button text',\n value: formData.cancelButtonText ?? '',\n placeholder: 'Cancel',\n width: 282\n }\n ]\n\n const findField = name => R.find(R.propEq('name', name))(fields)\n const findValue = name => findField(name).value\n\n const initialValues = {\n title: findValue('title'),\n text: findValue('text'),\n acceptButtonText: findValue('acceptButtonText'),\n cancelButtonText: findValue('cancelButtonText')\n }\n\n const validationSchema = Yup.object().shape({\n title: Yup.string()\n .required()\n .max(50, 'Too long'),\n text: Yup.string().required(),\n acceptButtonText: Yup.string()\n .required()\n .max(50, 'Too long'),\n cancelButtonText: Yup.string()\n .required()\n .max(50, 'Too long')\n })\n\n return (\n <>\n \n
Terms & Conditions \n \n \n
\n Show on screen \n \n save({\n active: event.target.checked\n })\n }\n />\n {showOnScreen ? 'Yes' : 'No'} \n
\n
\n Info card \n {!editing && (\n setEditing(true)}>\n \n \n )}\n
\n
save(values)}\n onReset={() => {\n setEditing(false)\n setError(null)\n }}>\n \n \n
\n >\n )\n}\n\nexport default TermsConditions\n","import { makeStyles } from '@material-ui/core'\nimport Chip from '@material-ui/core/Chip'\nimport * as R from 'ramda'\nimport React from 'react'\n\nimport {\n secondaryColorLighter,\n secondaryColorDarker,\n offErrorColor,\n errorColor,\n offColor,\n inputFontWeight,\n smallestFontSize,\n inputFontFamily,\n spacer\n} from 'src/styling/variables'\nimport { onlyFirstToUpper } from 'src/utils/string'\n\nimport typographyStyles from './typography/styles'\nconst { label1 } = typographyStyles\n\nconst colors = {\n running: secondaryColorDarker,\n notRunning: offErrorColor\n}\n\nconst backgroundColors = {\n running: secondaryColorLighter,\n notRunning: errorColor\n}\n\nconst styles = {\n uptimeContainer: {\n display: 'inline-block',\n minWidth: 104,\n margin: [[0, 20]]\n },\n name: {\n extend: label1,\n paddingLeft: 4,\n color: offColor\n }\n}\n\nconst useStyles = makeStyles(styles)\n\nconst useChipStyles = makeStyles({\n root: {\n borderRadius: spacer / 2,\n marginTop: spacer / 2,\n marginRight: spacer / 4,\n marginBottom: spacer / 2,\n marginLeft: spacer / 4,\n height: spacer * 3,\n backgroundColor: ({ type }) => backgroundColors[type]\n },\n label: {\n fontSize: smallestFontSize,\n fontWeight: inputFontWeight,\n fontFamily: inputFontFamily,\n padding: [[spacer / 2, spacer]],\n color: ({ type }) => colors[type]\n }\n})\n\nconst Uptime = ({ process, ...props }) => {\n const classes = useStyles()\n\n const uptime = time => {\n if (time < 60) return `${time}s`\n if (time < 3600) return `${Math.floor(time / 60)}m`\n if (time < 86400) return `${Math.floor(time / 60 / 60)}h`\n return `${Math.floor(time / 60 / 60 / 24)}d`\n }\n\n return (\n \n
{R.toLower(process.name)}
\n
\n
\n )\n}\n\nexport default Uptime\n","import { useQuery } from '@apollo/react-hooks'\nimport { makeStyles } from '@material-ui/core'\nimport gql from 'graphql-tag'\nimport moment from 'moment'\nimport * as R from 'ramda'\nimport React, { useState, useRef } from 'react'\n\nimport LogsDowloaderPopover from 'src/components/LogsDownloaderPopper'\nimport Title from 'src/components/Title'\nimport Uptime from 'src/components/Uptime'\nimport { Select } from 'src/components/inputs'\nimport {\n Table,\n TableHead,\n TableRow,\n TableHeader,\n TableBody,\n TableCell\n} from 'src/components/table'\nimport { Info3, H4 } from 'src/components/typography'\nimport typographyStyles from 'src/components/typography/styles'\nimport { offColor } from 'src/styling/variables'\nimport { startCase } from 'src/utils/string'\n\nimport logsStyles from './Logs.styles'\n\nconst { p } = typographyStyles\nconst { tableWrapper } = logsStyles\n\nconst localStyles = {\n serverTableWrapper: {\n extend: tableWrapper,\n maxWidth: '100%',\n marginLeft: 0\n },\n serverVersion: {\n extend: p,\n color: offColor,\n margin: 'auto 0 auto 0'\n },\n headerLine2: {\n display: 'flex',\n justifyContent: 'space-between',\n marginBottom: 24\n },\n uptimeContainer: {\n margin: 'auto 0 auto 0'\n }\n}\n\nconst styles = R.merge(logsStyles, localStyles)\n\nconst useStyles = makeStyles(styles)\n\nconst SHOW_ALL = { code: 'SHOW_ALL', display: 'Show all' }\n\nconst formatDate = date => {\n return moment(date).format('YYYY-MM-DD HH:mm')\n}\n\nconst NUM_LOG_RESULTS = 500\n\nconst GET_CSV = gql`\n query ServerData($limit: Int, $from: Date, $until: Date) {\n serverLogsCsv(limit: $limit, from: $from, until: $until)\n }\n`\n\nconst GET_DATA = gql`\n query ServerData($limit: Int, $from: Date, $until: Date) {\n serverVersion\n uptime {\n name\n state\n uptime\n }\n serverLogs(limit: $limit, from: $from, until: $until) {\n logLevel\n id\n timestamp\n message\n }\n }\n`\n\nconst Logs = () => {\n const classes = useStyles()\n\n const tableEl = useRef()\n\n const [saveMessage, setSaveMessage] = useState(null)\n const [logLevel, setLogLevel] = useState(SHOW_ALL)\n\n const { data, loading } = useQuery(GET_DATA, {\n onCompleted: () => setSaveMessage(''),\n variables: {\n limit: NUM_LOG_RESULTS\n }\n })\n\n const defaultLogLevels = [\n { code: 'error', display: 'Error' },\n { code: 'info', display: 'Info' },\n { code: 'debug', display: 'Debug' }\n ]\n const serverVersion = data?.serverVersion\n const processStates = data?.uptime ?? []\n\n const getLogLevels = R.compose(\n R.prepend(SHOW_ALL),\n R.uniq,\n R.concat(defaultLogLevels),\n R.map(it => ({\n code: R.path(['logLevel'])(it),\n display: startCase(R.path(['logLevel'])(it))\n })),\n R.path(['serverLogs'])\n )\n\n const handleLogLevelChange = logLevel => {\n if (tableEl.current) tableEl.current.scrollTo(0, 0)\n\n setLogLevel(logLevel)\n }\n\n return (\n <>\n \n
\n
Server \n {data && (\n
\n R.path(['serverLogsCsv'])(logs)}\n />\n {saveMessage} \n
\n )}\n
\n
\n {serverVersion && Server version: v{serverVersion} }\n
\n
\n \n {data && (\n
\n )}\n
\n {processStates &&\n processStates.map((process, idx) => (\n \n ))}\n
\n
\n \n
\n
\n \n \n Date \n Level \n \n \n \n \n {data &&\n data.serverLogs\n .filter(\n log =>\n logLevel === SHOW_ALL || log.logLevel === logLevel.code\n )\n .map((log, idx) => (\n \n {formatDate(log.timestamp)} \n {log.logLevel} \n {log.message} \n \n ))}\n \n
\n {loading &&
{'Loading...'} }\n {!loading && !data?.serverLogs?.length && (\n
{'No activity so far'} \n )}\n
\n
\n >\n )\n}\n\nexport default Logs\n","function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport * as React from \"react\";\n\nvar _ref2 = /*#__PURE__*/React.createElement(\"desc\", null, \"Created with Sketch.\");\n\nvar _ref3 = /*#__PURE__*/React.createElement(\"g\", {\n id: \"icon/action/edit/white\",\n stroke: \"none\",\n strokeWidth: 1,\n fill: \"none\",\n fillRule: \"evenodd\",\n strokeLinecap: \"round\",\n strokeLinejoin: \"round\"\n}, /*#__PURE__*/React.createElement(\"path\", {\n d: \"M1,18 L1,18 C1,19.657 2.343,21 4,21 L18,21 C19.657,21 21,19.657 21,18\",\n id: \"Stroke-1\",\n stroke: \"#FFFFFF\",\n strokeWidth: 2\n}), /*#__PURE__*/React.createElement(\"polygon\", {\n id: \"Stroke-3\",\n stroke: \"#FFFFFF\",\n strokeWidth: 2,\n points: \"6 12 17 1 21 5 10 16 6 16\"\n}));\n\nfunction SvgWhite(_ref, svgRef) {\n var title = _ref.title,\n titleId = _ref.titleId,\n props = _objectWithoutProperties(_ref, [\"title\", \"titleId\"]);\n\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n width: \"22px\",\n height: \"22px\",\n viewBox: \"0 0 22 22\",\n xmlns: \"http://www.w3.org/2000/svg\",\n xmlnsXlink: \"http://www.w3.org/1999/xlink\",\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, _ref2, _ref3);\n}\n\nvar ForwardRef = /*#__PURE__*/React.forwardRef(SvgWhite);\nexport default __webpack_public_path__ + \"static/media/white.5f161f2c.svg\";\nexport { ForwardRef as ReactComponent };","import typographyStyles from 'src/components/typography/styles'\nimport { offColor } from 'src/styling/variables'\n\nconst { label1, p } = typographyStyles\n\nexport default {\n tr: ({ height }) => ({\n margin: 0,\n height\n }),\n table: ({ width }) => ({\n width\n }),\n head: {\n display: 'flex',\n flex: 1,\n justifyContent: 'space-between',\n alignItems: 'center',\n paddingRight: 12\n },\n button: {\n marginBottom: 1\n },\n itemWrapper: {\n display: 'flex',\n flexDirection: 'column',\n marginTop: 16,\n minHeight: 35\n },\n label: {\n extend: label1,\n color: offColor,\n marginBottom: 4\n },\n item: {\n extend: p,\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap'\n }\n}\n","import { makeStyles } from '@material-ui/core'\nimport classnames from 'classnames'\nimport React from 'react'\n\nimport { IconButton } from 'src/components/buttons'\nimport {\n Table,\n THead,\n TBody,\n Td,\n Th,\n Tr\n} from 'src/components/fake-table/Table'\nimport { ReactComponent as EditIcon } from 'src/styling/icons/action/edit/white.svg'\n\nimport styles from './SingleRowTable.styles'\n\nconst useStyles = makeStyles(styles)\n\nconst SingleRowTable = ({\n width = 378,\n height = 128,\n title,\n items,\n onEdit,\n className\n}) => {\n const classes = useStyles({ width, height })\n\n return (\n <>\n \n \n \n {title}\n \n \n \n \n \n \n \n \n {items && (\n <>\n {items[0] && (\n \n
{items[0].label}
\n
{items[0].value}
\n
\n )}\n {items[1] && (\n \n
{items[1].label}
\n
{items[1].value}
\n
\n )}\n >\n )}\n \n \n \n
\n >\n )\n}\n\nexport default SingleRowTable\n","import { useQuery, useMutation } from '@apollo/react-hooks'\nimport { makeStyles, Grid } from '@material-ui/core'\nimport gql from 'graphql-tag'\nimport * as R from 'ramda'\nimport React, { useState } from 'react'\n\nimport Modal from 'src/components/Modal'\nimport { SecretInput } from 'src/components/inputs/formik'\nimport TitleSection from 'src/components/layout/TitleSection'\nimport SingleRowTable from 'src/components/single-row-table/SingleRowTable'\nimport { formatLong } from 'src/utils/string'\n\nimport FormRenderer from './FormRenderer'\nimport schemas from './schemas'\n\nconst GET_INFO = gql`\n query getData {\n accounts\n }\n`\n\nconst SAVE_ACCOUNT = gql`\n mutation Save($accounts: JSONObject) {\n saveAccounts(accounts: $accounts)\n }\n`\n\nconst styles = {\n wrapper: {\n // widths + spacing is a little over 1200 on the design\n // this adjusts the margin after a small reduction on card size\n marginLeft: 1\n }\n}\n\nconst useStyles = makeStyles(styles)\n\nconst Services = () => {\n const [editingSchema, setEditingSchema] = useState(null)\n\n const { data } = useQuery(GET_INFO)\n const [saveAccount] = useMutation(SAVE_ACCOUNT, {\n onCompleted: () => setEditingSchema(null),\n refetchQueries: ['getData']\n })\n\n const classes = useStyles()\n\n const accounts = data?.accounts ?? {}\n\n const getItems = (code, elements) => {\n const faceElements = R.filter(R.prop('face'))(elements)\n const values = accounts[code] || {}\n return R.map(({ display, code, long }) => ({\n label: display,\n value: long ? formatLong(values[code]) : values[code]\n }))(faceElements)\n }\n\n const getElements = ({ code, elements }) => {\n return R.map(elem => {\n if (elem.component !== SecretInput) return elem\n return {\n ...elem,\n inputProps: {\n isPasswordFilled:\n !R.isNil(accounts[code]) &&\n !R.isNil(R.path([elem.code], accounts[code]))\n }\n }\n }, elements)\n }\n\n const getAccounts = ({ elements, code }) => {\n const account = accounts[code]\n const filterBySecretComponent = R.filter(R.propEq('component', SecretInput))\n const mapToCode = R.map(R.prop(['code']))\n const passwordFields = R.compose(\n mapToCode,\n filterBySecretComponent\n )(elements)\n return R.mapObjIndexed(\n (value, key) => (R.includes(key, passwordFields) ? '' : value),\n account\n )\n }\n\n const getValidationSchema = ({ code, getValidationSchema }) =>\n getValidationSchema(accounts[code])\n\n return (\n \n \n \n {R.values(schemas).map(schema => (\n \n setEditingSchema(schema)}\n items={getItems(schema.code, schema.elements)}\n />\n \n ))}\n \n {editingSchema && (\n setEditingSchema(null)}\n open={true}>\n \n saveAccount({\n variables: { accounts: { [editingSchema.code]: it } }\n })\n }\n elements={getElements(editingSchema)}\n validationSchema={getValidationSchema(editingSchema)}\n value={getAccounts(editingSchema)}\n />\n \n )}\n
\n )\n}\n\nexport default Services\n","import { useQuery } from '@apollo/react-hooks'\nimport { makeStyles } from '@material-ui/core'\nimport BigNumber from 'bignumber.js'\nimport gql from 'graphql-tag'\nimport moment from 'moment'\nimport * as R from 'ramda'\nimport React from 'react'\nimport { useHistory } from 'react-router-dom'\n\nimport LogsDowloaderPopover from 'src/components/LogsDownloaderPopper'\nimport Title from 'src/components/Title'\nimport DataTable from 'src/components/tables/DataTable'\nimport { ReactComponent as TxInIcon } from 'src/styling/icons/direction/cash-in.svg'\nimport { ReactComponent as TxOutIcon } from 'src/styling/icons/direction/cash-out.svg'\nimport { ReactComponent as CustomerLinkIcon } from 'src/styling/icons/month arrows/right.svg'\nimport { toUnit, formatCryptoAddress } from 'src/utils/coin'\n\nimport DetailsRow from './DetailsCard'\nimport { mainStyles } from './Transactions.styles'\nimport { getStatus } from './helper'\n\nconst useStyles = makeStyles(mainStyles)\n\nconst NUM_LOG_RESULTS = 1000\n\nconst GET_TRANSACTIONS_CSV = gql`\n query transactions(\n $simplified: Boolean\n $limit: Int\n $from: Date\n $until: Date\n ) {\n transactionsCsv(\n simplified: $simplified\n limit: $limit\n from: $from\n until: $until\n )\n }\n`\n\nconst GET_TRANSACTIONS = gql`\n query transactions($limit: Int, $from: Date, $until: Date) {\n transactions(limit: $limit, from: $from, until: $until) {\n id\n txClass\n txHash\n toAddress\n commissionPercentage\n expired\n machineName\n operatorCompleted\n sendConfirmed\n dispense\n hasError: error\n deviceId\n fiat\n cashInFee\n fiatCode\n cryptoAtoms\n cryptoCode\n toAddress\n created\n customerName\n customerIdCardData\n customerIdCardPhotoPath\n customerFrontCameraPath\n customerPhone\n discount\n customerId\n isAnonymous\n }\n }\n`\n\nconst Transactions = () => {\n const classes = useStyles()\n const history = useHistory()\n const { data: txResponse, loading } = useQuery(GET_TRANSACTIONS, {\n variables: {\n limit: NUM_LOG_RESULTS\n },\n pollInterval: 10000\n })\n\n const redirect = customerId => {\n return history.push(`/compliance/customer/${customerId}`)\n }\n\n const formatCustomerName = customer => {\n const { firstName, lastName } = customer\n\n return `${R.o(R.toUpper, R.head)(firstName)}. ${lastName}`\n }\n\n const getCustomerDisplayName = tx => {\n if (tx.customerName) return tx.customerName\n if (tx.customerIdCardData) return formatCustomerName(tx.customerIdCardData)\n return tx.customerPhone\n }\n const elements = [\n {\n header: '',\n width: 32,\n size: 'sm',\n view: it => (it.txClass === 'cashOut' ? : )\n },\n {\n header: 'Machine',\n name: 'machineName',\n width: 160,\n size: 'sm',\n view: R.path(['machineName'])\n },\n {\n header: 'Customer',\n width: 202,\n size: 'sm',\n view: it => (\n \n
{getCustomerDisplayName(it)}
\n {!it.isAnonymous && (\n
redirect(it.customerId)}>\n \n
\n )}\n
\n )\n },\n {\n header: 'Cash',\n width: 144,\n textAlign: 'right',\n size: 'sm',\n view: it => `${Number.parseFloat(it.fiat)} ${it.fiatCode}`\n },\n {\n header: 'Crypto',\n width: 150,\n textAlign: 'right',\n size: 'sm',\n view: it =>\n `${toUnit(new BigNumber(it.cryptoAtoms), it.cryptoCode)} ${\n it.cryptoCode\n }`\n },\n {\n header: 'Address',\n view: it => formatCryptoAddress(it.cryptoCode, it.toAddress),\n className: classes.overflowTd,\n size: 'sm',\n width: 140\n },\n {\n header: 'Date (UTC)',\n view: it => moment.utc(it.created).format('YYYY-MM-DD HH:mm:ss'),\n textAlign: 'right',\n size: 'sm',\n width: 195\n },\n {\n header: 'Status',\n view: it => getStatus(it),\n textAlign: 'left',\n size: 'sm',\n width: 80\n }\n ]\n\n return (\n <>\n \n
\n
Transactions \n {txResponse && (\n
\n R.path(['transactionsCsv'])(logs)}\n simplified\n />\n
\n )}\n
\n
\n
\n \n Cash-out \n
\n
\n \n Cash-in \n
\n
\n
\n \n >\n )\n}\n\nexport default Transactions\n","import { makeStyles, Box } from '@material-ui/core'\nimport classnames from 'classnames'\nimport { Field, useFormikContext } from 'formik'\nimport * as R from 'ramda'\nimport React, { memo } from 'react'\nimport * as Yup from 'yup'\n\nimport { NumberInput, RadioGroup } from 'src/components/inputs/formik'\nimport { H4, Label2, Label1, Info1, Info2 } from 'src/components/typography'\nimport { errorColor } from 'src/styling/variables'\nimport { transformNumber } from 'src/utils/number'\n// import { ReactComponent as TxInIcon } from 'src/styling/icons/direction/cash-in.svg'\n// import { ReactComponent as TxOutIcon } from 'src/styling/icons/direction/cash-out.svg'\n\nconst useStyles = makeStyles({\n radioLabel: {\n height: 40,\n padding: [[0, 10]]\n },\n radio: {\n padding: 4,\n margin: 4\n },\n radioGroup: {\n flexDirection: 'row'\n },\n error: {\n color: errorColor\n },\n specialLabel: {\n height: 40,\n padding: 0\n },\n specialGrid: {\n display: 'grid',\n gridTemplateColumns: [[182, 162, 141]]\n },\n directionIcon: {\n marginRight: 2\n },\n directionName: {\n marginLeft: 6\n },\n thresholdWrapper: {\n display: 'flex',\n flexDirection: 'column'\n },\n thresholdTitle: {\n marginTop: 50\n },\n thresholdContentWrapper: {\n display: 'flex',\n flexDirection: 'row'\n },\n thresholdField: {\n marginRight: 6,\n width: 75\n },\n description: {\n marginTop: 7\n },\n space: {\n marginLeft: 6,\n marginRight: 6\n },\n lastSpace: {\n marginLeft: 6\n },\n suspensionDays: {\n width: 34\n },\n input: {\n marginTop: -2\n },\n limitedInput: {\n width: 50\n },\n daysInput: {\n width: 60\n }\n})\n\n// const direction = Yup.string().required()\n\nconst triggerType = Yup.string().required()\nconst threshold = Yup.object().shape({\n threshold: Yup.number()\n .nullable()\n .transform(transformNumber)\n .label('Invalid threshold'),\n thresholdDays: Yup.number()\n .transform(transformNumber)\n .nullable()\n .label('Invalid threshold days')\n})\n\nconst requirement = Yup.object().shape({\n requirement: Yup.string().required(),\n suspensionDays: Yup.number()\n .transform(transformNumber)\n .nullable()\n})\n\nconst Schema = Yup.object()\n .shape({\n triggerType,\n requirement,\n threshold\n // direction\n })\n .test(({ threshold, triggerType }, context) => {\n const errorMessages = {\n txAmount: threshold => 'Amount must be greater than or equal to 0',\n txVolume: threshold => {\n const thresholdMessage = 'Volume must be greater than or equal to 0'\n const thresholdDaysMessage = 'Days must be greater than 0'\n const message = []\n if (threshold.threshold < 0) message.push(thresholdMessage)\n if (threshold.thresholdDays <= 0) message.push(thresholdDaysMessage)\n return message.join(', ')\n },\n txVelocity: threshold => {\n const thresholdMessage = 'Transactions must be greater than 0'\n const thresholdDaysMessage = 'Days must be greater than 0'\n const message = []\n if (threshold.threshold <= 0) message.push(thresholdMessage)\n if (threshold.thresholdDays <= 0) message.push(thresholdDaysMessage)\n return message.join(', ')\n },\n consecutiveDays: threshold => 'Days must be greater than 0'\n }\n const thresholdValidator = {\n txAmount: threshold => threshold.threshold >= 0,\n txVolume: threshold =>\n threshold.threshold >= 0 && threshold.thresholdDays > 0,\n txVelocity: threshold =>\n threshold.threshold > 0 && threshold.thresholdDays > 0,\n consecutiveDays: threshold => threshold.thresholdDays > 0\n }\n\n if (triggerType && thresholdValidator[triggerType](threshold)) return\n\n return context.createError({\n path: 'threshold',\n message: errorMessages[triggerType](threshold)\n })\n })\n .test(({ requirement }, context) => {\n const requirementValidator = requirement =>\n requirement.requirement === 'suspend'\n ? requirement.suspensionDays > 0\n : true\n\n if (requirement && requirementValidator(requirement)) return\n\n return context.createError({\n path: 'requirement',\n message: 'Suspension days must be greater than 0'\n })\n })\n\n// Direction V2 only\n// const directionSchema = Yup.object().shape({ direction })\n\n// const directionOptions = [\n// {\n// display: 'Both',\n// code: 'both'\n// },\n// {\n// display: 'Only cash-in',\n// code: 'cashIn'\n// },\n// {\n// display: 'Only cash-out',\n// code: 'cashOut'\n// }\n// ]\n\n// const directionOptions2 = [\n// {\n// display: (\n// <>\n// in\n// >\n// ),\n// code: 'cashIn'\n// },\n// {\n// display: (\n// <>\n// out\n// >\n// ),\n// code: 'cashOut'\n// },\n// {\n// display: (\n// <>\n// \n// \n// \n// \n// \n// \n// \n// \n// >\n// ),\n// code: 'both'\n// }\n// ]\n\n// const Direction = () => {\n// const classes = useStyles()\n// const { errors } = useFormikContext()\n\n// const titleClass = {\n// [classes.error]: errors.direction\n// }\n\n// return (\n// <>\n// \n// \n// In which type of transactions will it trigger?\n// \n// \n// \n// >\n// )\n// }\n\n// const txDirection = {\n// schema: directionSchema,\n// options: directionOptions,\n// Component: Direction,\n// initialValues: { direction: '' }\n// }\n\n// TYPE\nconst typeSchema = Yup.object()\n .shape({\n triggerType: Yup.string().required(),\n threshold: Yup.object({\n threshold: Yup.number()\n .transform(transformNumber)\n .nullable(),\n thresholdDays: Yup.number()\n .transform(transformNumber)\n .nullable()\n })\n })\n .test(({ threshold, triggerType }, context) => {\n const errorMessages = {\n txAmount: threshold => 'Amount must be greater than or equal to 0',\n txVolume: threshold => {\n const thresholdMessage = 'Volume must be greater than or equal to 0'\n const thresholdDaysMessage = 'Days must be greater than 0'\n const message = []\n if (!threshold.threshold || threshold.threshold < 0)\n message.push(thresholdMessage)\n if (!threshold.thresholdDays || threshold.thresholdDays <= 0)\n message.push(thresholdDaysMessage)\n return message.join(', ')\n },\n txVelocity: threshold => {\n const thresholdMessage = 'Transactions must be greater than 0'\n const thresholdDaysMessage = 'Days must be greater than 0'\n const message = []\n if (!threshold.threshold || threshold.threshold <= 0)\n message.push(thresholdMessage)\n if (!threshold.thresholdDays || threshold.thresholdDays <= 0)\n message.push(thresholdDaysMessage)\n return message.join(', ')\n },\n consecutiveDays: threshold => 'Days must be greater than 0'\n }\n const thresholdValidator = {\n txAmount: threshold => threshold.threshold >= 0,\n txVolume: threshold =>\n threshold.threshold >= 0 && threshold.thresholdDays > 0,\n txVelocity: threshold =>\n threshold.threshold > 0 && threshold.thresholdDays > 0,\n consecutiveDays: threshold => threshold.thresholdDays > 0\n }\n\n if (triggerType && thresholdValidator[triggerType](threshold)) return\n\n return context.createError({\n path: 'threshold',\n message: errorMessages[triggerType](threshold)\n })\n })\n\nconst typeOptions = [\n { display: 'Transaction amount', code: 'txAmount' },\n { display: 'Transaction volume', code: 'txVolume' },\n { display: 'Transaction velocity', code: 'txVelocity' },\n { display: 'Consecutive days', code: 'consecutiveDays' }\n]\n\nconst Type = ({ ...props }) => {\n const classes = useStyles()\n const {\n errors,\n touched,\n values,\n setTouched,\n handleChange\n } = useFormikContext()\n\n const typeClass = {\n [classes.error]: errors.triggerType && touched.triggerType\n }\n\n const containsType = R.contains(values?.triggerType)\n const isThresholdCurrencyEnabled = containsType(['txAmount', 'txVolume'])\n const isTransactionAmountEnabled = containsType(['txVelocity'])\n const isThresholdDaysEnabled = containsType(['txVolume', 'txVelocity'])\n const isConsecutiveDaysEnabled = containsType(['consecutiveDays'])\n\n const hasAmountError =\n !!errors.threshold &&\n !!touched.threshold?.threshold &&\n !isConsecutiveDaysEnabled &&\n (!values.threshold?.threshold || values.threshold?.threshold < 0)\n const hasDaysError =\n !!errors.threshold &&\n !!touched.threshold?.thresholdDays &&\n !containsType(['txAmount']) &&\n (!values.threshold?.thresholdDays || values.threshold?.thresholdDays < 0)\n\n const triggerTypeError = !!(hasDaysError || hasAmountError)\n\n const thresholdClass = {\n [classes.error]: triggerTypeError\n }\n\n const isRadioGroupActive = () => {\n return (\n isThresholdCurrencyEnabled ||\n isTransactionAmountEnabled ||\n isThresholdDaysEnabled ||\n isConsecutiveDaysEnabled\n )\n }\n\n return (\n <>\n \n Choose trigger type \n \n {\n handleChange(e)\n setTouched({\n threshold: false,\n thresholdDays: false\n })\n }}\n />\n\n \n {isRadioGroupActive() && (\n
\n Threshold\n \n )}\n
\n {isThresholdCurrencyEnabled && (\n <>\n \n \n {props.currency}\n \n >\n )}\n {isTransactionAmountEnabled && (\n <>\n \n \n transactions\n \n >\n )}\n {isThresholdDaysEnabled && (\n <>\n \n in\n \n \n days \n >\n )}\n {isConsecutiveDaysEnabled && (\n <>\n \n \n consecutive days\n \n >\n )}\n
\n
\n >\n )\n}\n\nconst type = currency => ({\n schema: typeSchema,\n options: typeOptions,\n Component: Type,\n props: { currency },\n initialValues: {\n triggerType: '',\n threshold: { threshold: '', thresholdDays: '' }\n }\n})\n\nconst requirementSchema = Yup.object()\n .shape({\n requirement: Yup.object({\n requirement: Yup.string().required(),\n suspensionDays: Yup.number().when('requirement', {\n is: value => value === 'suspend',\n then: Yup.number()\n .nullable()\n .transform(transformNumber),\n otherwise: Yup.number()\n .nullable()\n .transform(() => null)\n })\n }).required()\n })\n .test(({ requirement }, context) => {\n const requirementValidator = requirement =>\n requirement.requirement === 'suspend'\n ? requirement.suspensionDays > 0\n : true\n\n if (requirement && requirementValidator(requirement)) return\n\n return context.createError({\n path: 'requirement',\n message: 'Suspension days must be greater than 0'\n })\n })\n\nconst requirementOptions = [\n { display: 'SMS verification', code: 'sms' },\n { display: 'ID card image', code: 'idCardPhoto' },\n { display: 'ID data', code: 'idCardData' },\n { display: 'Customer camera', code: 'facephoto' },\n { display: 'Sanctions', code: 'sanctions' },\n { display: 'US SSN', code: 'usSsn' },\n // { display: 'Super user', code: 'superuser' },\n { display: 'Suspend', code: 'suspend' },\n { display: 'Block', code: 'block' }\n]\n\nconst Requirement = () => {\n const classes = useStyles()\n const {\n touched,\n errors,\n values,\n handleChange,\n setTouched\n } = useFormikContext()\n\n const hasRequirementError =\n !!errors.requirement &&\n !!touched.requirement?.suspensionDays &&\n (!values.requirement?.suspensionDays ||\n values.requirement?.suspensionDays < 0)\n\n const isSuspend = values?.requirement?.requirement === 'suspend'\n\n const titleClass = {\n [classes.error]:\n (!!errors.requirement && !isSuspend) || (isSuspend && hasRequirementError)\n }\n\n return (\n <>\n \n Choose a requirement \n \n {\n handleChange(e)\n setTouched({\n suspensionDays: false\n })\n }}\n />\n\n {isSuspend && (\n \n )}\n >\n )\n}\n\nconst requirements = {\n schema: requirementSchema,\n options: requirementOptions,\n Component: Requirement,\n initialValues: { requirement: { requirement: '', suspensionDays: '' } }\n}\n\nconst getView = (data, code, compare) => it => {\n if (!data) return ''\n\n return R.compose(R.prop(code), R.find(R.propEq(compare ?? 'code', it)))(data)\n}\n\n// const DirectionDisplay = ({ code }) => {\n// const classes = useStyles()\n// const displayName = getView(directionOptions, 'display')(code)\n// const showCashIn = code === 'cashIn' || code === 'both'\n// const showCashOut = code === 'cashOut' || code === 'both'\n\n// return (\n// \n// {showCashOut && }\n// {showCashIn && }\n// {displayName} \n//
\n// )\n// }\n\nconst RequirementInput = () => {\n const { values } = useFormikContext()\n const classes = useStyles()\n\n const requirement = values?.requirement?.requirement\n const isSuspend = requirement === 'suspend'\n\n const display = getView(requirementOptions, 'display')(requirement)\n\n return (\n \n {`${display} ${isSuspend ? 'for' : ''}`}\n {isSuspend && (\n \n )}\n {isSuspend && 'days'}\n \n )\n}\n\nconst RequirementView = ({ requirement, suspensionDays }) => {\n const classes = useStyles()\n const display = getView(requirementOptions, 'display')(requirement)\n const isSuspend = requirement === 'suspend'\n\n return (\n \n {`${display} ${isSuspend ? 'for' : ''}`}\n {isSuspend && (\n \n {suspensionDays}\n \n )}\n {isSuspend && 'days'}\n \n )\n}\n\nconst DisplayThreshold = ({ config, currency, isEdit }) => {\n const classes = useStyles()\n\n const inputClasses = {\n [classes.input]: true,\n [classes.limitedInput]: config?.triggerType === 'txVelocity',\n [classes.daysInput]: config?.triggerType === 'consecutiveDays'\n }\n\n const threshold = config?.threshold?.threshold\n const thresholdDays = config?.threshold?.thresholdDays\n\n const Threshold = isEdit ? (\n \n ) : (\n {threshold} \n )\n const ThresholdDays = isEdit ? (\n \n ) : (\n {thresholdDays} \n )\n\n switch (config?.triggerType) {\n case 'txAmount':\n return (\n \n {Threshold}\n \n {currency}\n \n \n )\n case 'txVolume':\n return (\n \n {Threshold}\n \n {currency}\n \n \n in\n \n {ThresholdDays}\n \n days\n \n \n )\n case 'txVelocity':\n return (\n \n {Threshold}\n \n transactions in\n \n {ThresholdDays}\n \n days\n \n \n )\n case 'consecutiveDays':\n return (\n \n {ThresholdDays}\n \n days\n \n \n )\n default:\n return ''\n }\n}\n\nconst ThresholdInput = memo(({ currency }) => {\n const { values } = useFormikContext()\n\n return \n})\n\nconst ThresholdView = ({ config, currency }) => {\n return \n}\n\nconst getElements = (currency, classes) => [\n {\n name: 'triggerType',\n size: 'sm',\n width: 230,\n input: ({ field: { value: name } }) => (\n <>{getView(typeOptions, 'display')(name)}>\n ),\n view: getView(typeOptions, 'display'),\n inputProps: {\n options: typeOptions,\n valueProp: 'code',\n labelProp: 'display',\n optionsLimit: null\n }\n },\n {\n name: 'requirement',\n size: 'sm',\n width: 230,\n bypassField: true,\n input: RequirementInput,\n view: it => \n },\n {\n name: 'threshold',\n size: 'sm',\n width: 284,\n textAlign: 'left',\n input: () => ,\n view: (it, config) => \n }\n // {\n // name: 'direction',\n // size: 'sm',\n // width: 282,\n // view: it => ,\n // input: RadioGroup,\n // inputProps: {\n // labelClassName: classes.tableRadioLabel,\n // className: classes.tableRadioGroup,\n // options: directionOptions2\n // }\n // }\n]\n\nconst triggerOrder = R.map(R.prop('code'))(typeOptions)\nconst sortBy = [\n R.comparator(\n (a, b) =>\n triggerOrder.indexOf(a.triggerType) < triggerOrder.indexOf(b.triggerType)\n )\n]\n\nconst fromServer = triggers =>\n R.map(\n ({ requirement, suspensionDays, threshold, thresholdDays, ...rest }) => ({\n requirement: {\n requirement,\n suspensionDays\n },\n threshold: {\n threshold,\n thresholdDays\n },\n ...rest\n })\n )(triggers)\n\nconst toServer = triggers =>\n R.map(({ requirement, threshold, ...rest }) => ({\n requirement: requirement.requirement,\n suspensionDays: requirement.suspensionDays,\n threshold: threshold.threshold,\n thresholdDays: threshold.thresholdDays,\n ...rest\n }))(triggers)\n\nexport {\n Schema,\n getElements,\n // txDirection,\n type,\n requirements,\n sortBy,\n fromServer,\n toServer\n}\n","import { makeStyles } from '@material-ui/core'\nimport { Form, Formik, useFormikContext } from 'formik'\nimport * as R from 'ramda'\nimport React, { useState, Fragment, useEffect } from 'react'\n\nimport ErrorMessage from 'src/components/ErrorMessage'\nimport Modal from 'src/components/Modal'\nimport Stepper from 'src/components/Stepper'\nimport { Button } from 'src/components/buttons'\nimport { H5, Info3 } from 'src/components/typography'\nimport { comet } from 'src/styling/variables'\nimport { singularOrPlural } from 'src/utils/string'\n\nimport { type, requirements } from './helper'\n\nconst LAST_STEP = 2\n\nconst styles = {\n stepper: {\n margin: [[16, 0, 14, 0]]\n },\n submit: {\n display: 'flex',\n flexDirection: 'row',\n margin: [['auto', 0, 24]]\n },\n button: {\n marginLeft: 'auto'\n },\n form: {\n height: '100%',\n display: 'flex',\n flexDirection: 'column'\n },\n infoTitle: {\n margin: [[18, 0, 20, 0]]\n },\n infoCurrentText: {\n color: comet\n },\n blankSpace: {\n padding: [[0, 30]],\n margin: [[0, 4, 0, 2]],\n borderBottom: `1px solid ${comet}`,\n display: 'inline-block'\n }\n}\n\nconst useStyles = makeStyles(styles)\n\nconst getStep = (step, currency) => {\n switch (step) {\n // case 1:\n // return txDirection\n case 1:\n return type(currency)\n case 2:\n return requirements\n default:\n return Fragment\n }\n}\n\nconst getText = (step, config, currency, classes) => {\n switch (step) {\n // case 1:\n // return `In ${getDirectionText(config)} transactions`\n case 1:\n return <>If the user {getTypeText(config, currency, classes)}>\n case 2:\n return <>the user will be {getRequirementText(config, classes)}.>\n default:\n return <>>\n }\n}\n\nconst orUnderline = (value, classes) => {\n const blankSpaceEl = \n return R.isEmpty(value) || R.isNil(value) ? blankSpaceEl : value\n}\n\n// const getDirectionText = config => {\n// switch (config.direction) {\n// case 'both':\n// return 'both cash-in and cash-out'\n// case 'cashIn':\n// return 'cash-in'\n// case 'cashOut':\n// return 'cash-out'\n// default:\n// return orUnderline(null)\n// }\n// }\n\nconst getTypeText = (config, currency, classes) => {\n switch (config.triggerType) {\n case 'txAmount':\n return (\n <>\n makes a single transaction over{' '}\n {orUnderline(config.threshold.threshold, classes)} {currency}\n >\n )\n case 'txVolume':\n return (\n <>\n makes {orUnderline(config.threshold.threshold, classes)} {currency}{' '}\n worth of transactions within{' '}\n {orUnderline(config.threshold.thresholdDays, classes)}{' '}\n {singularOrPlural(config.threshold.thresholdDays, 'day', 'days')}\n >\n )\n case 'txVelocity':\n return (\n <>\n makes {orUnderline(config.threshold.threshold, classes)}{' '}\n {singularOrPlural(\n config.threshold.threshold,\n 'transaction',\n 'transactions'\n )}{' '}\n in {orUnderline(config.threshold.thresholdDays, classes)}{' '}\n {singularOrPlural(config.threshold.thresholdDays, 'day', 'days')}\n >\n )\n case 'consecutiveDays':\n return (\n <>\n at least one transaction every day for{' '}\n {orUnderline(config.threshold.thresholdDays, classes)}{' '}\n {singularOrPlural(config.threshold.thresholdDays, 'day', 'days')}\n >\n )\n default:\n return <>>\n }\n}\n\nconst getRequirementText = (config, classes) => {\n switch (config.requirement?.requirement) {\n case 'sms':\n return <>asked to enter code provided through SMS verification>\n case 'idCardPhoto':\n return <>asked to scan a ID with photo>\n case 'idCardData':\n return <>asked to scan a ID>\n case 'facephoto':\n return <>asked to have a photo taken>\n case 'usSsn':\n return <>asked to input his social security number>\n case 'sanctions':\n return <>matched against the OFAC sanctions list>\n case 'superuser':\n return <>>\n case 'suspend':\n return (\n <>\n suspended for{' '}\n {orUnderline(config.requirement.suspensionDays, classes)}{' '}\n {singularOrPlural(config.requirement.suspensionDays, 'day', 'days')}\n >\n )\n case 'block':\n return <>blocked>\n default:\n return orUnderline(null, classes)\n }\n}\n\nconst InfoPanel = ({ step, config = {}, liveValues = {}, currency }) => {\n const classes = useStyles()\n\n const oldText = R.range(1, step).map(it =>\n getText(it, config, currency, classes)\n )\n const newText = getText(step, liveValues, currency, classes)\n const isLastStep = step === LAST_STEP\n\n return (\n <>\n Trigger overview so far \n \n {oldText}\n {step !== 1 && ', '}\n {newText}\n {!isLastStep && '...'}\n \n >\n )\n}\n\nconst GetValues = ({ setValues }) => {\n const { values } = useFormikContext()\n useEffect(() => {\n setValues && values && setValues(values)\n }, [setValues, values])\n\n return null\n}\n\nconst Wizard = ({ onClose, save, error, currency }) => {\n const classes = useStyles()\n\n const [liveValues, setLiveValues] = useState({})\n const [{ step, config }, setState] = useState({\n step: 1\n })\n\n const isLastStep = step === LAST_STEP\n const stepOptions = getStep(step, currency)\n\n const onContinue = async it => {\n const newConfig = R.merge(config, stepOptions.schema.cast(it))\n\n if (isLastStep) {\n return save(newConfig)\n }\n\n setState({\n step: step + 1,\n config: newConfig\n })\n }\n\n const createErrorMessage = (errors, touched, values) => {\n const triggerType = values?.triggerType\n const containsType = R.contains(triggerType)\n const isSuspend = values?.requirement?.requirement === 'suspend'\n\n const hasRequirementError =\n !!errors.requirement &&\n !!touched.requirement?.suspensionDays &&\n (!values.requirement?.suspensionDays ||\n values.requirement?.suspensionDays < 0)\n\n const hasAmountError =\n !!errors.threshold &&\n !!touched.threshold?.threshold &&\n !containsType(['consecutiveDays']) &&\n (!values.threshold?.threshold || values.threshold?.threshold < 0)\n\n const hasDaysError =\n !!errors.threshold &&\n !!touched.threshold?.thresholdDays &&\n !containsType(['txAmount']) &&\n (!values.threshold?.thresholdDays || values.threshold?.thresholdDays < 0)\n\n if (containsType(['txAmount', 'txVolume', 'txVelocity']) && hasAmountError)\n return errors.threshold\n\n if (\n containsType(['txVolume', 'txVelocity', 'consecutiveDays']) &&\n hasDaysError\n )\n return errors.threshold\n\n if (isSuspend && hasRequirementError) return errors.requirement\n }\n\n return (\n <>\n \n }\n infoPanelHeight={172}\n open={true}>\n \n \n {({ errors, touched, values }) => (\n \n )}\n \n \n >\n )\n}\n\nexport default Wizard\n","import { useQuery, useMutation } from '@apollo/react-hooks'\nimport { makeStyles, Box } from '@material-ui/core'\nimport gql from 'graphql-tag'\nimport * as R from 'ramda'\nimport React, { useState } from 'react'\nimport { v4 } from 'uuid'\n\nimport { Tooltip } from 'src/components/Tooltip'\nimport { Link, Button } from 'src/components/buttons'\nimport { Table as EditableTable } from 'src/components/editableTable'\nimport { Switch } from 'src/components/inputs'\nimport TitleSection from 'src/components/layout/TitleSection'\nimport { P, Label2, H2 } from 'src/components/typography'\nimport { fromNamespace, toNamespace, namespaces } from 'src/utils/config'\n\nimport styles from './Triggers.styles'\nimport Wizard from './Wizard'\nimport { Schema, getElements, sortBy, fromServer, toServer } from './helper'\n\nconst useStyles = makeStyles(styles)\n\nconst SAVE_CONFIG = gql`\n mutation Save($config: JSONObject) {\n saveConfig(config: $config)\n }\n`\n\nconst GET_INFO = gql`\n query getData {\n config\n }\n`\n\nconst Triggers = () => {\n const classes = useStyles()\n const [wizard, setWizard] = useState(false)\n\n const { data, loading } = useQuery(GET_INFO)\n const triggers = fromServer(data?.config?.triggers ?? [])\n\n const complianceConfig =\n data?.config && fromNamespace('compliance')(data.config)\n const rejectAddressReuse = complianceConfig?.rejectAddressReuse ?? false\n const [error, setError] = useState(null)\n\n const [saveConfig] = useMutation(SAVE_CONFIG, {\n onCompleted: () => setWizard(false),\n refetchQueries: () => ['getData'],\n onError: error => setError(error)\n })\n\n const add = rawConfig => {\n const toSave = R.concat([{ id: v4(), direction: 'both', ...rawConfig }])(\n triggers\n )\n return saveConfig({ variables: { config: { triggers: toServer(toSave) } } })\n }\n\n const addressReuseSave = rawConfig => {\n const config = toNamespace('compliance')(rawConfig)\n return saveConfig({ variables: { config } })\n }\n\n const save = config => {\n setError(null)\n return saveConfig({\n variables: { config: { triggers: toServer(config.triggers) } }\n })\n }\n\n const currency = R.path(['fiatCurrency'])(\n fromNamespace(namespaces.LOCALE)(data?.config)\n )\n\n return (\n <>\n \n \n \n Reject reused addresses
\n {\n addressReuseSave({ rejectAddressReuse: event.target.checked })\n }}\n value={rejectAddressReuse}\n />\n \n {rejectAddressReuse ? 'On' : 'Off'}\n \n \n \n This option requires a user to scan a different cryptocurrency\n address if they attempt to scan one that had been previously\n used for a transaction in your network\n
\n \n \n \n \n \n {!loading && !R.isEmpty(triggers) && (\n setWizard(true)}>\n + Add new trigger\n \n )}\n \n \n {wizard && (\n setWizard(null)}\n />\n )}\n {!loading && R.isEmpty(triggers) && (\n \n \n It seems there are no active compliance triggers on your network\n \n setWizard(true)}>Add first trigger \n \n )}\n >\n )\n}\n\nexport default Triggers\n","export default {\n switchLabel: {\n margin: 6,\n width: 24\n },\n tableRadioGroup: {\n flexDirection: 'row',\n justifyContent: 'space-between'\n },\n tableRadioLabel: {\n marginRight: 0\n },\n tableWidth: {\n width: 918\n }\n}\n","import Triggers from './Triggers'\n\nexport default Triggers\n","import { useQuery, useMutation } from '@apollo/react-hooks'\nimport gql from 'graphql-tag'\nimport * as R from 'ramda'\nimport React, { useState } from 'react'\n\nimport Modal from 'src/components/Modal'\nimport { NamespacedTable as EditableTable } from 'src/components/editableTable'\nimport TitleSection from 'src/components/layout/TitleSection'\nimport FormRenderer from 'src/pages/Services/FormRenderer'\nimport schemas from 'src/pages/Services/schemas'\nimport { fromNamespace, toNamespace } from 'src/utils/config'\n\nimport Wizard from './Wizard'\nimport { WalletSchema, getElements } from './helper'\n\nconst SAVE_CONFIG = gql`\n mutation Save($config: JSONObject, $accounts: JSONObject) {\n saveConfig(config: $config)\n saveAccounts(accounts: $accounts)\n }\n`\n\nconst SAVE_ACCOUNT = gql`\n mutation Save($accounts: JSONObject) {\n saveAccounts(accounts: $accounts)\n }\n`\n\nconst GET_INFO = gql`\n query getData {\n config\n accounts\n accountsConfig {\n code\n display\n class\n cryptos\n deprecated\n }\n cryptoCurrencies {\n code\n display\n }\n }\n`\n\nconst Wallet = ({ name: SCREEN_KEY }) => {\n const [editingSchema, setEditingSchema] = useState(null)\n const [onChangeFunction, setOnChangeFunction] = useState(null)\n const [wizard, setWizard] = useState(false)\n const { data } = useQuery(GET_INFO)\n\n const [saveConfig, { error }] = useMutation(SAVE_CONFIG, {\n onCompleted: () => setWizard(false),\n refetchQueries: () => ['getData']\n })\n\n const [saveAccount] = useMutation(SAVE_ACCOUNT, {\n onCompleted: () => setEditingSchema(null),\n refetchQueries: () => ['getData']\n })\n\n const save = (rawConfig, accounts) => {\n const config = toNamespace(SCREEN_KEY)(rawConfig)\n return saveConfig({ variables: { config, accounts } })\n }\n\n const config = data?.config && fromNamespace(SCREEN_KEY)(data.config)\n const accountsConfig = data?.accountsConfig\n const cryptoCurrencies = data?.cryptoCurrencies ?? []\n const accounts = data?.accounts ?? []\n\n const onChange = (previous, current, setValue) => {\n if (!current) return setValue(current)\n\n if (!accounts[current] && schemas[current]) {\n setEditingSchema(schemas[current])\n setOnChangeFunction(() => () => setValue(current))\n return\n }\n\n setValue(current)\n }\n\n const shouldOverrideEdit = it => {\n const namespaced = fromNamespace(it)(config)\n return !WalletSchema.isValidSync(namespaced)\n }\n\n const wizardSave = it =>\n saveAccount({\n variables: { accounts: { [editingSchema.code]: it } }\n }).then(it => {\n onChangeFunction()\n setOnChangeFunction(null)\n return it\n })\n\n return (\n <>\n \n !WalletSchema.isValidSync(it)}\n enableEdit\n shouldOverrideEdit={shouldOverrideEdit}\n editOverride={setWizard}\n editWidth={174}\n save={save}\n validationSchema={WalletSchema}\n elements={getElements(cryptoCurrencies, accountsConfig, onChange)}\n />\n {wizard && (\n setWizard(false)}\n save={save}\n error={error?.message}\n cryptoCurrencies={cryptoCurrencies}\n userAccounts={data?.config?.accounts}\n accounts={accounts}\n accountsConfig={accountsConfig}\n />\n )}\n {editingSchema && (\n setEditingSchema(null)}\n open={true}>\n \n \n )}\n >\n )\n}\n\nexport default Wallet\n","import { useQuery, useMutation } from '@apollo/react-hooks'\nimport { makeStyles } from '@material-ui/core'\nimport gql from 'graphql-tag'\nimport * as R from 'ramda'\nimport React from 'react'\n\nimport { Table as EditableTable } from 'src/components/editableTable'\nimport Section from 'src/components/layout/Section'\nimport TitleSection from 'src/components/layout/TitleSection'\nimport styles from 'src/pages/AddMachine/styles'\nimport { mainFields, defaults, schema } from 'src/pages/Commissions/helper'\nimport { fromNamespace, toNamespace, namespaces } from 'src/utils/config'\n\nconst useStyles = makeStyles(styles)\n\nconst GET_DATA = gql`\n query getData {\n config\n }\n`\nconst SAVE_CONFIG = gql`\n mutation Save($config: JSONObject) {\n saveConfig(config: $config)\n }\n`\n\nfunction Commissions({ isActive, doContinue }) {\n const classes = useStyles()\n const { data } = useQuery(GET_DATA)\n\n const [saveConfig] = useMutation(SAVE_CONFIG, {\n onCompleted: doContinue\n })\n\n const save = it => {\n const config = toNamespace('commissions')(it.commissions[0])\n return saveConfig({ variables: { config } })\n }\n\n const currency = R.path(['fiatCurrency'])(\n fromNamespace(namespaces.LOCALE)(data?.config)\n )\n\n return (\n \n \n \n
\n )\n}\n\nexport default Commissions\n","import { useQuery, useMutation } from '@apollo/react-hooks'\nimport { makeStyles } from '@material-ui/core'\nimport gql from 'graphql-tag'\nimport * as R from 'ramda'\nimport React from 'react'\n\nimport { Table as EditableTable } from 'src/components/editableTable'\nimport Section from 'src/components/layout/Section'\nimport TitleSection from 'src/components/layout/TitleSection'\nimport styles from 'src/pages/AddMachine/styles'\nimport {\n mainFields,\n localeDefaults as defaults,\n LocaleSchema as schema\n} from 'src/pages/Locales/helper'\nimport { toNamespace } from 'src/utils/config'\n\nimport { getConfiguredCoins } from '../helper'\n\nconst useStyles = makeStyles(styles)\n\nconst GET_DATA = gql`\n query getData {\n config\n accounts\n currencies {\n code\n display\n }\n countries {\n code\n display\n }\n cryptoCurrencies {\n code\n display\n }\n languages {\n code\n display\n }\n machines {\n name\n deviceId\n }\n }\n`\n\nconst SAVE_CONFIG = gql`\n mutation Save($config: JSONObject) {\n saveConfig(config: $config)\n }\n`\n\nfunction Locales({ isActive, doContinue }) {\n const classes = useStyles()\n const { data } = useQuery(GET_DATA)\n\n const [saveConfig] = useMutation(SAVE_CONFIG, {\n onCompleted: doContinue\n })\n\n const save = it => {\n const config = toNamespace('locale')(it.locale[0])\n return saveConfig({ variables: { config } })\n }\n\n const cryptoCurrencies = getConfiguredCoins(\n data?.config || {},\n data?.cryptoCurrencies || []\n )\n\n const onChangeCoin = (prev, curr, setValue) => setValue(curr)\n\n return (\n \n \n \n
\n )\n}\n\nexport default Locales\n","import { Box, makeStyles } from '@material-ui/core'\nimport React from 'react'\n\nimport { Label1 } from 'src/components/typography'\nimport { ReactComponent as WarningIcon } from 'src/styling/icons/warning-icon/comet.svg'\n\nconst useStyles = makeStyles({\n message: ({ width }) => ({\n width,\n marginTop: 4,\n marginLeft: 16\n })\n})\n\nconst InfoMessage = ({ children, width = 330, className }) => {\n const classes = useStyles({ width })\n\n return (\n \n \n {children} \n \n )\n}\n\nexport default InfoMessage\n","import { errorColor, spacer, primaryColor } from 'src/styling/variables'\n\nconst LABEL_WIDTH = 150\n\nexport default {\n radioGroup: {\n flexDirection: 'row',\n width: 600\n },\n radioLabel: {\n width: LABEL_WIDTH,\n height: 48\n },\n mdForm: {\n width: 385\n },\n infoMessage: {\n display: 'flex',\n marginBottom: 20,\n '& > p': {\n width: 330,\n marginTop: 4,\n marginLeft: 16\n }\n },\n actionButton: {\n marginBottom: spacer * 4\n },\n actionButtonLink: {\n textDecoration: 'none',\n color: primaryColor\n },\n error: {\n color: errorColor\n },\n button: {\n marginTop: spacer * 5\n },\n formButton: {\n margin: [[spacer * 3, 0, 0]]\n }\n}\n","import { useMutation, useQuery } from '@apollo/react-hooks'\nimport { makeStyles, Box } from '@material-ui/core'\nimport classnames from 'classnames'\nimport gql from 'graphql-tag'\nimport React, { useState } from 'react'\n\nimport InfoMessage from 'src/components/InfoMessage'\nimport { Tooltip } from 'src/components/Tooltip'\nimport { Button, SupportLinkButton } from 'src/components/buttons'\nimport { RadioGroup } from 'src/components/inputs'\nimport { H1, H4, P } from 'src/components/typography'\nimport FormRenderer from 'src/pages/Services/FormRenderer'\nimport twilio from 'src/pages/Services/schemas/twilio'\n\nimport styles from './Wallet/Shared.styles'\n\nconst GET_CONFIG = gql`\n {\n config\n accounts\n }\n`\n\nconst SAVE_ACCOUNTS = gql`\n mutation Save($accounts: JSONObject) {\n saveAccounts(accounts: $accounts)\n }\n`\n\nconst useStyles = makeStyles({\n ...styles,\n content: {\n width: 820\n },\n radioLabel: {\n ...styles.radioLabel,\n width: 280\n },\n wrapper: {\n width: 1200,\n height: 100,\n margin: [[0, 'auto']]\n },\n title: {\n marginLeft: 8,\n marginBottom: 5\n },\n info: {\n marginTop: 20,\n marginBottom: 20\n }\n})\n\nconst options = [\n {\n code: 'enable',\n display: 'Yes, I will'\n },\n {\n code: 'disable',\n display: 'No, not for now'\n }\n]\n\nfunction Twilio({ doContinue }) {\n const classes = useStyles()\n const [selected, setSelected] = useState(null)\n const [error, setError] = useState(false)\n\n const { data, refetch } = useQuery(GET_CONFIG)\n const [saveAccounts] = useMutation(SAVE_ACCOUNTS, {\n onCompleted: doContinue\n })\n\n const accounts = data?.accounts ?? []\n\n const onSelect = e => {\n setSelected(e.target.value)\n setError(false)\n }\n\n const clickContinue = () => {\n if (!selected) return setError(true)\n doContinue()\n }\n\n const save = twilio => {\n const accounts = { twilio }\n return saveAccounts({ variables: { accounts } }).then(() => refetch())\n }\n\n const titleClasses = {\n [classes.title]: true,\n [classes.error]: error\n }\n\n return (\n \n
\n
Twilio (SMS service) \n
\n \n Will you setup a two way machine or compliance?\n \n \n \n Two-way machines allow your customers not only to buy (cash-in)\n but also sell cryptocurrencies (cash-out).\n
\n \n You’ll need an SMS service for cash-out transactions and for any\n compliance triggers\n
\n \n \n\n
\n\n
\n To set up Twilio please read the instructions from our support portal.\n \n
\n\n {selected === 'enable' && (\n <>\n
Enter credentials \n
\n >\n )}\n {selected !== 'enable' && (\n
\n Continue\n \n )}\n
\n
\n )\n}\n\nexport default Twilio\n","import { useQuery, useMutation } from '@apollo/react-hooks'\nimport { makeStyles } from '@material-ui/core'\nimport gql from 'graphql-tag'\nimport * as R from 'ramda'\nimport React, { useState } from 'react'\n\nimport { Button } from 'src/components/buttons'\nimport { NamespacedTable as EditableTable } from 'src/components/editableTable'\nimport { P, H4 } from 'src/components/typography'\nimport { getElements, WalletSchema } from 'src/pages/Wallet/helper'\nimport { toNamespace, namespaces } from 'src/utils/config'\n\nimport styles from './Shared.styles'\n\nconst useStyles = makeStyles(styles)\nconst GET_INFO = gql`\n query getData {\n config\n accounts\n accountsConfig {\n code\n display\n class\n cryptos\n }\n cryptoCurrencies {\n code\n display\n }\n }\n`\n\nconst SAVE_CONFIG = gql`\n mutation Save($config: JSONObject, $accounts: JSONObject) {\n saveConfig(config: $config)\n saveAccounts(accounts: $accounts)\n }\n`\n\nconst AllSet = ({ data: currentData, doContinue }) => {\n const classes = useStyles()\n\n const { data } = useQuery(GET_INFO)\n const [saveConfig] = useMutation(SAVE_CONFIG, {\n onCompleted: doContinue\n })\n\n const [error, setError] = useState(false)\n\n const coin = currentData?.coin\n\n const accountsConfig = data?.accountsConfig\n const cryptoCurrencies = data?.cryptoCurrencies ?? []\n\n const save = () => {\n if (!WalletSchema.isValidSync(currentData)) return setError(true)\n\n const withCoin = toNamespace(coin, R.omit('coin', currentData))\n const config = toNamespace(namespaces.WALLETS)(withCoin)\n setError(false)\n return saveConfig({ variables: { config } })\n }\n\n return (\n <>\n All set \n \n These are your wallet settings. You can later edit these and add\n additional coins.\n
\n \n \n Continue\n \n >\n )\n}\n\nexport default AllSet\n","import { useMutation, useQuery } from '@apollo/react-hooks'\nimport { makeStyles } from '@material-ui/core'\nimport gql from 'graphql-tag'\nimport React, { useState } from 'react'\n\nimport { SupportLinkButton, Button } from 'src/components/buttons'\nimport { RadioGroup } from 'src/components/inputs'\nimport { P, H4 } from 'src/components/typography'\nimport FormRenderer from 'src/pages/Services/FormRenderer'\nimport schema from 'src/pages/Services/schemas'\n\nimport styles from './Shared.styles'\n\nconst useStyles = makeStyles({\n ...styles,\n radioGroup: styles.radioGroup,\n radioLabel: {\n ...styles.radioLabel,\n width: 200\n }\n})\n\nconst GET_CONFIG = gql`\n {\n accounts\n }\n`\nconst SAVE_ACCOUNTS = gql`\n mutation SaveAccountsBC($accounts: JSONObject) {\n saveAccounts(accounts: $accounts)\n }\n`\n\nconst options = [\n {\n code: 'enable',\n display: 'I will enable cash-out'\n },\n {\n code: 'disable',\n display: \"I won't enable cash-out\"\n }\n]\n\nconst Blockcypher = ({ addData }) => {\n const classes = useStyles()\n\n const { data } = useQuery(GET_CONFIG)\n const [saveConfig] = useMutation(SAVE_ACCOUNTS, {\n onCompleted: () => addData({ zeroConf: 'blockcypher' })\n })\n\n const [selected, setSelected] = useState(null)\n const [error, setError] = useState(false)\n\n const accounts = data?.accounts ?? []\n\n const onSelect = e => {\n setSelected(e.target.value)\n setError(false)\n }\n\n const save = blockcypher => {\n const accounts = { blockcypher }\n return saveConfig({ variables: { accounts } })\n }\n\n return (\n <>\n Blockcypher \n \n If you are enabling cash-out services, create a Blockcypher account.\n
\n \n \n \n {selected === 'disable' && (\n addData({ zeroConf: 'all-zero-conf' })}\n className={classes.button}>\n Continue\n \n )}\n {selected === 'enable' && (\n \n )}\n
\n >\n )\n}\n\nexport default Blockcypher\n","import { useQuery } from '@apollo/react-hooks'\nimport { makeStyles } from '@material-ui/core'\nimport { Formik, Form, Field } from 'formik'\nimport gql from 'graphql-tag'\nimport React, { useState } from 'react'\nimport * as Yup from 'yup'\n\nimport PromptWhenDirty from 'src/components/PromptWhenDirty'\nimport { Button } from 'src/components/buttons'\nimport { RadioGroup } from 'src/components/inputs/formik'\nimport { H4 } from 'src/components/typography'\n\nimport styles from './Shared.styles'\n\nconst useStyles = makeStyles(styles)\n\nconst GET_CONFIG = gql`\n {\n cryptoCurrencies {\n code\n display\n }\n }\n`\n\nconst schema = Yup.object().shape({\n coin: Yup.string().required()\n})\n\nconst ChooseCoin = ({ addData }) => {\n const classes = useStyles()\n const [error, setError] = useState(false)\n\n const { data } = useQuery(GET_CONFIG)\n const cryptoCurrencies = data?.cryptoCurrencies ?? []\n\n const onSubmit = it => {\n if (!schema.isValidSync(it)) return setError(true)\n\n if (it.coin !== 'BTC') {\n return addData({ coin: it.coin, zeroConf: 'all-zero-conf' })\n }\n\n addData(it)\n }\n\n return (\n <>\n \n Choose your first cryptocurrency\n \n\n \n \n \n >\n )\n}\n\nexport default ChooseCoin\n","import * as R from 'ramda'\n\nimport schema from 'src/pages/Services/schemas'\nconst contains = crypto => R.compose(R.contains(crypto), R.prop('cryptos'))\nconst sameClass = type => R.propEq('class', type)\nconst filterConfig = (crypto, type) =>\n R.filter(it => sameClass(type)(it) && contains(crypto)(it))\nexport const getItems = (accountsConfig, accounts, type, crypto) => {\n const fConfig = filterConfig(crypto, type)(accountsConfig)\n const find = code => accounts && accounts[code]\n\n const [filled, unfilled] = R.partition(({ code }) => {\n const account = find(code)\n if (!schema[code]) return true\n\n const { getValidationSchema } = schema[code]\n return getValidationSchema(account).isValidSync(account)\n })(fConfig)\n\n return { filled, unfilled }\n}\n","import { useQuery, useMutation } from '@apollo/react-hooks'\nimport { makeStyles } from '@material-ui/core'\nimport gql from 'graphql-tag'\nimport * as R from 'ramda'\nimport React, { useState } from 'react'\n\nimport { Button, SupportLinkButton } from 'src/components/buttons'\nimport { RadioGroup } from 'src/components/inputs'\nimport { H4, Info3 } from 'src/components/typography'\nimport FormRenderer from 'src/pages/Services/FormRenderer'\nimport schema from 'src/pages/Services/schemas'\nimport { ReactComponent as WarningIcon } from 'src/styling/icons/warning-icon/comet.svg'\n\nimport styles from './Shared.styles'\nimport { getItems } from './getItems'\n\nconst useStyles = makeStyles(styles)\n\nconst GET_CONFIG = gql`\n {\n accounts\n accountsConfig {\n code\n display\n class\n cryptos\n }\n cryptoCurrencies {\n code\n display\n }\n }\n`\n\nconst SAVE_ACCOUNTS = gql`\n mutation Save($accounts: JSONObject) {\n saveAccounts(accounts: $accounts)\n }\n`\n\nconst isConfigurable = it => R.contains(it)(['kraken', 'itbit', 'bitstamp'])\n\nconst ChooseExchange = ({ data: currentData, addData }) => {\n const classes = useStyles()\n const { data } = useQuery(GET_CONFIG)\n const [saveAccounts] = useMutation(SAVE_ACCOUNTS, {\n onCompleted: () => submit()\n })\n\n const [selected, setSelected] = useState(null)\n const [error, setError] = useState(false)\n\n const accounts = data?.accounts ?? []\n const accountsConfig = data?.accountsConfig ?? []\n\n const coin = currentData.coin\n const exchanges = getItems(accountsConfig, accounts, 'exchange', coin)\n\n const submit = () => {\n if (!selected) return setError(true)\n addData({ exchange: selected })\n }\n\n const saveExchange = name => exchange => {\n const accounts = { [name]: exchange }\n return saveAccounts({ variables: { accounts } })\n }\n\n const onSelect = e => {\n setSelected(e.target.value)\n setError(false)\n }\n\n const supportArticles = {\n kraken:\n 'https://support.lamassu.is/hc/en-us/articles/115001206891-Kraken-trading',\n itbit:\n 'https://support.lamassu.is/hc/en-us/articles/360026195032-itBit-trading',\n bitstamp:\n 'https://support.lamassu.is/hc/en-us/articles/115001206911-Bitstamp-trading'\n }\n\n return (\n \n
Choose your exchange \n
\n {!isConfigurable(selected) && (\n
\n Continue\n \n )}\n {isConfigurable(selected) && (\n <>\n
\n \n \n Make sure you set up {schema[selected].name} to enter the\n necessary information below. Please follow the instructions on our\n support page if you haven’t.\n \n
\n
\n\n
Enter exchange information \n
\n >\n )}\n
\n )\n}\n\nexport default ChooseExchange\n","import { useQuery } from '@apollo/react-hooks'\nimport { makeStyles } from '@material-ui/core'\nimport gql from 'graphql-tag'\nimport * as R from 'ramda'\nimport React, { useState } from 'react'\n\nimport { Button } from 'src/components/buttons'\nimport { RadioGroup } from 'src/components/inputs'\nimport { H4 } from 'src/components/typography'\n\nimport styles from './Shared.styles'\nimport { getItems } from './getItems'\n\nconst useStyles = makeStyles(styles)\n\nconst GET_CONFIG = gql`\n {\n accountsConfig {\n code\n display\n class\n cryptos\n }\n }\n`\n\nconst ChooseTicker = ({ data: currentData, addData }) => {\n const classes = useStyles()\n const { data } = useQuery(GET_CONFIG)\n\n const [selected, setSelected] = useState(null)\n const [error, setError] = useState(false)\n\n const accounts = data?.accounts ?? []\n const accountsConfig = data?.accountsConfig ?? []\n\n const coin = currentData.coin\n const tickers = getItems(accountsConfig, accounts, 'ticker', coin)\n\n const submit = () => {\n if (!selected) return setError(true)\n addData({ ticker: selected })\n }\n\n const onSelect = e => {\n setSelected(e.target.value)\n setError(false)\n }\n\n return (\n \n
Choose your ticker \n \n \n Continue\n \n \n )\n}\n\nexport default ChooseTicker\n","import * as Yup from 'yup'\n\nimport {\n TextInput,\n SecretInput,\n Autocomplete\n} from 'src/components/inputs/formik'\n\nconst singleBitgo = code => ({\n code: 'bitgo',\n name: 'BitGo',\n title: 'BitGo (Wallet)',\n elements: [\n {\n code: 'token',\n display: 'API Token',\n component: TextInput,\n face: true,\n long: true\n },\n {\n code: 'environment',\n display: 'Environment',\n component: Autocomplete,\n inputProps: {\n options: [\n { code: 'prod', display: 'prod' },\n { code: 'test', display: 'test' }\n ],\n labelProp: 'display',\n valueProp: 'code'\n },\n face: true\n },\n {\n code: `${code}WalletId`,\n display: `${code} Wallet ID`,\n component: TextInput\n },\n {\n code: `${code}WalletPassphrase`,\n display: `${code} Wallet Passphrase`,\n component: SecretInput\n }\n ],\n validationSchema: Yup.object().shape({\n token: Yup.string()\n .max(100, 'Too long')\n .required(),\n environment: Yup.string()\n .matches(/(prod|test)/)\n .required(),\n [`${code}WalletId`]: Yup.string()\n .max(100, 'Too long')\n .required(),\n [`${code}WalletPassphrase`]: Yup.string()\n .max(100, 'Too long')\n .required()\n })\n})\n\nexport default singleBitgo\n","import { useQuery, useMutation } from '@apollo/react-hooks'\nimport { makeStyles } from '@material-ui/core'\nimport gql from 'graphql-tag'\nimport * as R from 'ramda'\nimport React, { useState } from 'react'\n\nimport { Button, SupportLinkButton } from 'src/components/buttons'\nimport { RadioGroup } from 'src/components/inputs'\nimport { H4, Info3 } from 'src/components/typography'\nimport FormRenderer from 'src/pages/Services/FormRenderer'\nimport schema from 'src/pages/Services/schemas'\nimport bitgo from 'src/pages/Services/schemas/singlebitgo'\nimport { ReactComponent as WarningIcon } from 'src/styling/icons/warning-icon/comet.svg'\n\nimport styles from './Shared.styles'\nimport { getItems } from './getItems'\n\nconst useStyles = makeStyles(styles)\n\nconst GET_CONFIG = gql`\n {\n accounts\n accountsConfig {\n code\n display\n class\n cryptos\n }\n cryptoCurrencies {\n code\n display\n }\n }\n`\n\nconst SAVE_ACCOUNTS = gql`\n mutation Save($accounts: JSONObject) {\n saveAccounts(accounts: $accounts)\n }\n`\n\nconst isConfigurable = it => R.contains(it)(['infura', 'bitgo'])\n\nconst isLocalHosted = it =>\n R.contains(it)([\n 'bitcoind',\n 'geth',\n 'litecoind',\n 'dashd',\n 'zcashd',\n 'bitcoincashd'\n ])\n\nconst ChooseWallet = ({ data: currentData, addData }) => {\n const classes = useStyles()\n const { data } = useQuery(GET_CONFIG)\n const [saveAccounts] = useMutation(SAVE_ACCOUNTS, {\n onCompleted: () => submit()\n })\n\n const [selected, setSelected] = useState(null)\n const [error, setError] = useState(false)\n\n const accounts = data?.accounts ?? []\n const accountsConfig = data?.accountsConfig ?? []\n\n const coin = currentData.coin\n const wallets = getItems(accountsConfig, accounts, 'wallet', coin)\n\n const saveWallet = name => wallet => {\n const accounts = { [name]: wallet }\n return saveAccounts({ variables: { accounts } })\n }\n\n const submit = () => {\n if (!selected) return setError(true)\n addData({ wallet: selected })\n }\n\n const onSelect = e => {\n setSelected(e.target.value)\n setError(false)\n }\n\n return (\n \n
Choose your wallet \n
\n {isLocalHosted(selected) && (\n <>\n
\n \n \n To set up {selected} please read the node wallet instructions from\n our support portal.\n \n
\n
\n >\n )}\n {!isConfigurable(selected) && (\n
\n Continue\n \n )}\n {selected === 'bitgo' && (\n <>\n
\n \n \n Make sure you set up a BitGo wallet to enter the necessary\n information below. Please follow the instructions on our support\n page if you haven’t.\n \n
\n
\n
Enter wallet information \n
\n >\n )}\n {selected === 'infura' && (\n <>\n
Enter wallet information \n
\n >\n )}\n
\n )\n}\n\nexport default ChooseWallet\n","import { makeStyles } from '@material-ui/core'\nimport * as R from 'ramda'\nimport React, { useState } from 'react'\n\nimport Sidebar, { Stepper } from 'src/components/layout/Sidebar'\nimport TitleSection from 'src/components/layout/TitleSection'\nimport styles from 'src/pages/AddMachine/styles'\n\nimport AllSet from './AllSet'\nimport Blockcypher from './Blockcypher'\nimport ChooseCoin from './ChooseCoin'\nimport ChooseExchange from './ChooseExchange'\nimport ChooseTicker from './ChooseTicker'\nimport ChooseWallet from './ChooseWallet'\n\nconst useStyles = makeStyles(styles)\n\nconst steps = [\n {\n label: 'Choose cryptocurrency',\n component: ChooseCoin\n },\n {\n label: 'Choose wallet',\n component: ChooseWallet\n },\n {\n label: 'Choose ticker',\n component: ChooseTicker\n },\n {\n label: 'Exchange',\n component: ChooseExchange\n },\n {\n label: 'Blockcypher',\n component: Blockcypher\n },\n {\n label: 'All set',\n component: AllSet\n }\n]\n\nconst Wallet = ({ doContinue }) => {\n const [step, setStep] = useState(0)\n const [data, setData] = useState({})\n\n const classes = useStyles()\n const mySteps = data?.coin === 'BTC' ? steps : R.remove(4, 1, steps)\n\n const Component = mySteps[step].component\n\n const addData = it => {\n setData(R.merge(data, it))\n setStep(step + 1)\n }\n\n return (\n \n
\n \n
\n
\n
\n {mySteps.map((it, idx) => (\n \n ))}\n \n
\n \n
\n
\n
\n )\n}\n\nexport default Wallet\n","import { makeStyles } from '@material-ui/core'\nimport React from 'react'\n\nimport { Button } from 'src/components/buttons'\nimport { H1, P } from 'src/components/typography'\nimport { comet } from 'src/styling/variables'\n\nconst styles = {\n welcome: {\n textAlign: 'center',\n paddingTop: 256\n },\n title: {\n lineHeight: 1,\n fontSize: 48\n },\n getStarted: {\n fontSize: 24,\n fontWeight: 500,\n marginBottom: 54,\n color: comet\n }\n}\n\nconst useStyles = makeStyles(styles)\n\nfunction Welcome({ doContinue }) {\n const classes = useStyles()\n\n return (\n \n
Welcome to the Lamassu Admin \n
\n To get you started, we’ve put together a wizard that will\n \n help set up what you need before pairing your machines.\n
\n
\n Get started\n \n
\n )\n}\n\nexport default Welcome\n","import * as R from 'ramda'\nimport React from 'react'\n\nimport { schema as CommissionsSchema } from 'src/pages/Commissions/helper'\nimport { LocaleSchema } from 'src/pages/Locales/helper'\nimport { WalletSchema } from 'src/pages/Wallet/helper'\nimport { fromNamespace, namespaces } from 'src/utils/config'\n\nimport Commissions from './components/Commissions'\nimport Locale from './components/Locales'\n// import Notifications from './components/Notifications'\n// import WizardOperatorInfo from './components/OperatorInfo'\nimport Twilio from './components/Twilio'\nimport Wallet from './components/Wallet/Wallet'\nimport Welcome from './components/Welcome'\n\nconst getConfiguredCoins = (config, crypto) => {\n const wallet = fromNamespace(namespaces.WALLETS, config)\n return R.filter(it =>\n WalletSchema.isValidSync(fromNamespace(it.code, wallet))\n )(crypto)\n}\n\nconst hasValidWallet = (config, crypto) => {\n const wallet = fromNamespace(namespaces.WALLETS, config)\n const coins = R.map(it => fromNamespace(it.code, wallet))(crypto)\n\n const hasValidConfig = R.compose(\n R.any(R.identity),\n R.map(it => WalletSchema.isValidSync(it))\n )(coins)\n\n return hasValidConfig\n}\n\nconst hasValidLocale = config => {\n const locale = fromNamespace(namespaces.LOCALE, config)\n return LocaleSchema.isValidSync(locale)\n}\n\nconst hasValidCommissions = config => {\n const commission = fromNamespace(namespaces.COMMISSIONS, config)\n return CommissionsSchema.isValidSync(commission)\n}\n\nconst getWizardStep = (config, crypto) => {\n if (!config) return 0\n\n const validWallet = hasValidWallet(config, crypto)\n if (!validWallet) return 1\n\n const validLocale = hasValidLocale(config)\n if (!validLocale) return 2\n\n const validCommission = hasValidCommissions(config)\n if (!validCommission) return 3\n\n return 0\n}\n\nconst STEPS = [\n {\n id: 'welcome',\n Component: Welcome\n },\n {\n id: 'wallet',\n Component: Wallet,\n exImage: '/assets/wizard/fullexample.wallet.png',\n subtitle: 'Wallet settings',\n text: `Your wallet settings are the first step for this wizard. \n We'll start by setting up one of cryptocurrencies to get you up and running,\n but you can later set up as many as you want.`\n },\n {\n id: 'locale',\n Component: Locale,\n exImage: '/assets/wizard/fullexample.locale.png',\n subtitle: 'Locales',\n text: `From the Locales panel, you can define default settings\n that will be applied to all machines you add to your network later on.\n These settings may be overridden for specific machines in the Overrides section.`\n },\n {\n id: 'twilio',\n Component: Twilio,\n exImage: '/assets/wizard/fullexample.twilio.png',\n subtitle: 'Twilio (SMS service)',\n text: (\n <>\n Twilio is used for SMS operator notifications, phone number collection\n for compliance, and 1-confirmation redemptions on cash-out transactions.\n \n You'll need to configure Twilio if you're offering cash-out or any\n compliance options\n >\n )\n },\n {\n id: 'commissions',\n Component: Commissions,\n exImage: '/assets/wizard/fullexample.commissions.png',\n subtitle: 'Commissions',\n text: `From the Commissions page, you can define all the commissions of your\n machines. The values set here will be default values of all machines\n you'll later add to your network. Default settings keep you from\n having to enter the same values everytime you add a new machine. Once\n a machine is added, you may override these values per machine and per\n cryptocurrency in the overrides section.`\n }\n // {\n // id: 'notifications',\n // Component: Notifications,\n // exImage: '/assets/wizard/fullexample.notifications.png',\n // subtitle: 'Notifications',\n // text: `Your notification settings will allow customize what notifications you\n // get and where. You can later override all default balance alerts setup\n // here.`\n // },\n // {\n // id: 'operatorInfo',\n // Component: WizardOperatorInfo,\n // exImage: '/assets/wizard/fullexample.operatorinfo.png',\n // subtitle: 'Operator info',\n // text: `Your contact information is important for your customer to be able\n // to contact you in case there’s a problem with one of your machines.\n // In this page, you also be able to set up what you want to share with\n // Coin ATM Radar and add the Terms & Services text that is displayed by your machines.`\n // }\n]\n\nexport { getWizardStep, STEPS, getConfiguredCoins }\n","import { makeStyles, Drawer, Grid } from '@material-ui/core'\nimport classnames from 'classnames'\nimport React, { useState } from 'react'\n\nimport Modal from 'src/components/Modal'\nimport Stepper from 'src/components/Stepper'\nimport { Button, Link } from 'src/components/buttons'\nimport { P, H2, Info2 } from 'src/components/typography'\nimport { spacer } from 'src/styling/variables'\n\nconst useStyles = makeStyles(() => ({\n drawer: {\n borderTop: 'none',\n boxShadow: '0 0 4px 0 rgba(0, 0, 0, 0.08)'\n },\n wrapper: {\n padding: '32px 0',\n flexGrow: 1,\n height: 264\n },\n smallWrapper: {\n height: 84\n },\n title: {\n margin: [[0, spacer * 4, 0, 0]]\n },\n subtitle: {\n marginTop: spacer,\n marginBottom: 6,\n lineHeight: 1.25,\n display: 'inline'\n },\n modal: {\n background: 'none',\n boxShadow: 'none'\n }\n}))\n\nfunction Footer({ currentStep, steps, subtitle, text, exImage, open, start }) {\n const classes = useStyles()\n const [fullExample, setFullExample] = useState(false)\n\n const wrapperClassNames = {\n [classes.wrapper]: true,\n [classes.smallWrapper]: !open\n }\n\n return (\n \n \n
\n \n Setup Lamassu Admin \n {subtitle} \n {open && {text}
}\n \n \n \n {steps && currentStep && (\n \n )}\n \n \n \n {open && (\n
\n \n {\n setFullExample(true)\n }}>\n See full example\n \n \n \n \n \n Get Started\n \n \n \n \n )}\n
\n {\n setFullExample(false)\n }}\n open={fullExample}>\n \n \n \n )\n}\n\nexport default Footer\n","import { useQuery } from '@apollo/react-hooks'\nimport { makeStyles, Dialog, DialogContent } from '@material-ui/core'\nimport classnames from 'classnames'\nimport gql from 'graphql-tag'\nimport React, { useState, useContext } from 'react'\nimport { useHistory } from 'react-router-dom'\n\nimport { AppContext } from 'src/App'\nimport { getWizardStep, STEPS } from 'src/pages/Wizard/helper'\nimport { backgroundColor } from 'src/styling/variables'\n\nimport Footer from './components/Footer'\n\nconst useStyles = makeStyles({\n wrapper: {\n display: 'flex',\n padding: [[16, 0]],\n flexDirection: 'column',\n justifyContent: 'space-between',\n backgroundColor: backgroundColor\n },\n welcomeBackground: {\n background: 'url(/wizard-background.svg) no-repeat center center fixed',\n backgroundColor: backgroundColor,\n backgroundSize: 'cover'\n },\n blurred: {\n filter: 'blur(4px)',\n pointerEvents: 'none'\n }\n})\n\nconst GET_DATA = gql`\n query getData {\n config\n accounts\n cryptoCurrencies {\n code\n display\n }\n }\n`\n\nconst Wizard = ({ fromAuthRegister }) => {\n const classes = useStyles()\n const { data, loading } = useQuery(GET_DATA)\n const history = useHistory()\n const { setWizardTested } = useContext(AppContext)\n\n const [step, setStep] = useState(0)\n const [open, setOpen] = useState(true)\n\n const [footerExp, setFooterExp] = useState(false)\n\n if (loading) {\n return <>>\n }\n\n const wizardStep = getWizardStep(data?.config, data?.cryptoCurrencies)\n\n const shouldGoBack =\n history.length && !history.location.state?.fromAuthRegister\n\n if (wizardStep === 0) {\n setWizardTested(true)\n shouldGoBack ? history.goBack() : history.push('/')\n }\n\n const isWelcome = step === 0\n const classNames = {\n [classes.blurred]: footerExp,\n [classes.wrapper]: true,\n [classes.welcomeBackground]: isWelcome\n }\n\n const start = () => {\n setFooterExp(false)\n }\n\n const doContinue = () => {\n if (step >= STEPS.length - 1) {\n setOpen(false)\n history.push('/')\n }\n\n const nextStep = step === 0 && wizardStep ? wizardStep : step + 1\n\n setFooterExp(true)\n setStep(nextStep)\n }\n\n const current = STEPS[step]\n\n return (\n \n \n \n \n {!isWelcome && (\n \n )}\n \n )\n}\n\nexport default Wizard\n","import Wizard from './Wizard'\n\nexport default Wizard\n","import Fade from '@material-ui/core/Fade'\nimport Slide from '@material-ui/core/Slide'\nimport { makeStyles } from '@material-ui/core/styles'\nimport * as R from 'ramda'\nimport React, { useContext } from 'react'\nimport {\n matchPath,\n Route,\n Redirect,\n Switch,\n useHistory,\n useLocation\n} from 'react-router-dom'\n\nimport { AppContext } from 'src/App'\nimport AuthRegister from 'src/pages/AuthRegister'\nimport Blacklist from 'src/pages/Blacklist'\nimport Cashout from 'src/pages/Cashout'\nimport Commissions from 'src/pages/Commissions'\n// import ConfigMigration from 'src/pages/ConfigMigration'\nimport { Customers, CustomerProfile } from 'src/pages/Customers'\nimport Dashboard from 'src/pages/Dashboard'\nimport Funding from 'src/pages/Funding'\nimport Locales from 'src/pages/Locales'\nimport PromoCodes from 'src/pages/LoyaltyPanel/PromoCodes'\nimport MachineLogs from 'src/pages/MachineLogs'\nimport Machines from 'src/pages/Machines'\nimport CashCassettes from 'src/pages/Maintenance/CashCassettes'\nimport MachineStatus from 'src/pages/Maintenance/MachineStatus'\nimport Notifications from 'src/pages/Notifications/Notifications'\nimport CoinAtmRadar from 'src/pages/OperatorInfo/CoinATMRadar'\nimport ContactInfo from 'src/pages/OperatorInfo/ContactInfo'\nimport ReceiptPrinting from 'src/pages/OperatorInfo/ReceiptPrinting'\nimport TermsConditions from 'src/pages/OperatorInfo/TermsConditions'\nimport ServerLogs from 'src/pages/ServerLogs'\nimport Services from 'src/pages/Services/Services'\n// import TokenManagement from 'src/pages/TokenManagement/TokenManagement'\nimport Transactions from 'src/pages/Transactions/Transactions'\nimport Triggers from 'src/pages/Triggers'\nimport WalletSettings from 'src/pages/Wallet/Wallet'\nimport Wizard from 'src/pages/Wizard'\nimport { namespaces } from 'src/utils/config'\n\nconst useStyles = makeStyles({\n wrapper: {\n flex: 1,\n display: 'flex',\n flexDirection: 'column',\n height: '100%'\n }\n})\n\nconst tree = [\n {\n key: 'transactions',\n label: 'Transactions',\n route: '/transactions',\n component: Transactions\n },\n {\n key: 'maintenance',\n label: 'Maintenance',\n route: '/maintenance',\n get component() {\n return () => \n },\n children: [\n {\n key: 'cash_cassettes',\n label: 'Cash Cassettes',\n route: '/maintenance/cash-cassettes',\n component: CashCassettes\n },\n {\n key: 'funding',\n label: 'Funding',\n route: '/maintenance/funding',\n component: Funding\n },\n {\n key: 'logs',\n label: 'Machine Logs',\n route: '/maintenance/logs',\n component: MachineLogs\n },\n {\n key: 'machine-status',\n label: 'Machine Status',\n route: '/maintenance/machine-status',\n component: MachineStatus\n },\n {\n key: 'server-logs',\n label: 'Server',\n route: '/maintenance/server-logs',\n component: ServerLogs\n }\n ]\n },\n {\n key: 'settings',\n label: 'Settings',\n route: '/settings',\n get component() {\n return () => \n },\n children: [\n {\n key: namespaces.COMMISSIONS,\n label: 'Commissions',\n route: '/settings/commissions',\n component: Commissions\n },\n {\n key: namespaces.LOCALE,\n label: 'Locales',\n route: '/settings/locale',\n component: Locales\n },\n {\n key: namespaces.CASH_OUT,\n label: 'Cash-out',\n route: '/settings/cash-out',\n component: Cashout\n },\n {\n key: namespaces.NOTIFICATIONS,\n label: 'Notifications',\n route: '/settings/notifications',\n component: Notifications\n },\n {\n key: 'services',\n label: '3rd party services',\n route: '/settings/3rd-party-services',\n component: Services\n },\n {\n key: namespaces.WALLETS,\n label: 'Wallet',\n route: '/settings/wallet-settings',\n component: WalletSettings\n },\n {\n key: namespaces.OPERATOR_INFO,\n label: 'Operator Info',\n route: '/settings/operator-info',\n title: 'Operator Information',\n get component() {\n return () => (\n \n )\n },\n children: [\n {\n key: 'contact-info',\n label: 'Contact information',\n route: '/settings/operator-info/contact-info',\n component: ContactInfo\n },\n {\n key: 'receipt-printing',\n label: 'Receipt',\n route: '/settings/operator-info/receipt-printing',\n component: ReceiptPrinting\n },\n {\n key: 'coin-atm-radar',\n label: 'Coin ATM Radar',\n route: '/settings/operator-info/coin-atm-radar',\n component: CoinAtmRadar\n },\n {\n key: 'terms-conditions',\n label: 'Terms & Conditions',\n route: '/settings/operator-info/terms-conditions',\n component: TermsConditions\n }\n ]\n }\n ]\n },\n {\n key: 'compliance',\n label: 'Compliance',\n route: '/compliance',\n get component() {\n return () => \n },\n children: [\n {\n key: 'triggers',\n label: 'Triggers',\n route: '/compliance/triggers',\n component: Triggers\n },\n {\n key: 'customers',\n label: 'Customers',\n route: '/compliance/customers',\n component: Customers\n },\n {\n key: 'blacklist',\n label: 'Blacklist',\n route: '/compliance/blacklist',\n component: Blacklist\n },\n {\n key: 'promo-codes',\n label: 'Promo Codes',\n route: '/compliance/loyalty/codes',\n component: PromoCodes\n },\n {\n key: 'customer',\n route: '/compliance/customer/:id',\n component: CustomerProfile\n }\n ]\n }\n // {\n // key: 'system',\n // label: 'System',\n // route: '/system',\n // get component() {\n // return () => \n // },\n // children: [\n // {\n // key: 'token-management',\n // label: 'Token Management',\n // route: '/system/token-management',\n // component: TokenManagement\n // }\n // ]\n // }\n]\n\nconst map = R.map(R.when(R.has('children'), R.prop('children')))\nconst mappedRoutes = R.compose(R.flatten, map)(tree)\nconst parentRoutes = R.filter(R.has('children'))(mappedRoutes).concat(\n R.filter(R.has('children'))(tree)\n)\nconst leafRoutes = R.compose(R.flatten, map)(mappedRoutes)\n\nconst flattened = R.concat(leafRoutes, parentRoutes)\n\nconst hasSidebar = route =>\n R.any(r => r.route === route)(\n R.compose(\n R.flatten,\n R.map(R.prop('children')),\n R.filter(R.has('children'))\n )(mappedRoutes)\n )\n\nconst getParent = route =>\n R.find(\n R.propEq(\n 'route',\n R.dropLast(\n 1,\n R.dropLastWhile(x => x !== '/', route)\n )\n )\n )(flattened)\n\nconst Routes = () => {\n const classes = useStyles()\n\n const history = useHistory()\n const location = useLocation()\n\n const { wizardTested } = useContext(AppContext)\n\n const dontTriggerPages = ['/404', '/register', '/wizard']\n\n if (!wizardTested && !R.contains(location.pathname)(dontTriggerPages)) {\n history.push('/wizard')\n }\n\n const Transition = location.state ? Slide : Fade\n\n const transitionProps =\n Transition === Slide\n ? {\n direction:\n R.findIndex(R.propEq('route', location.state.prev))(leafRoutes) >\n R.findIndex(R.propEq('route', location.pathname))(leafRoutes)\n ? 'right'\n : 'left'\n }\n : { timeout: 400 }\n\n return (\n \n \n \n \n \n \n \n \n }\n />\n \n