Merge pull request #1017 from chaotixkilla/fix-ui-ux-tweaks
Improve UI/UX on multiple screens
This commit is contained in:
commit
412f3ac2b5
25 changed files with 246 additions and 153 deletions
|
|
@ -1,7 +1,7 @@
|
|||
import { useLazyQuery } from '@apollo/react-hooks'
|
||||
import { makeStyles, ClickAwayListener } from '@material-ui/core'
|
||||
import classnames from 'classnames'
|
||||
import { format, isSameDay } from 'date-fns/fp'
|
||||
import { format } from 'date-fns/fp'
|
||||
import FileSaver from 'file-saver'
|
||||
import * as R from 'ramda'
|
||||
import React, { useState, useCallback } from 'react'
|
||||
|
|
@ -189,7 +189,6 @@ const LogsDownloaderPopover = ({
|
|||
|
||||
if (!range || !range.from) return
|
||||
if (range.from && !range.until) range.until = new Date()
|
||||
if (isSameDay(range.until, range.from)) range.until = new Date()
|
||||
|
||||
if (selectedRadio === RANGE) {
|
||||
fetchLogs({
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import { makeStyles, ClickAwayListener } from '@material-ui/core'
|
||||
import * as R from 'ramda'
|
||||
import React, { useState, memo } from 'react'
|
||||
|
||||
import Popper from 'src/components/Popper'
|
||||
|
|
@ -8,9 +9,9 @@ const useStyles = makeStyles({
|
|||
transparentButton: {
|
||||
border: 'none',
|
||||
backgroundColor: 'transparent',
|
||||
marginTop: 4,
|
||||
outline: 'none',
|
||||
cursor: 'pointer'
|
||||
cursor: 'pointer',
|
||||
marginTop: 4
|
||||
},
|
||||
popoverContent: ({ width }) => ({
|
||||
width,
|
||||
|
|
@ -69,11 +70,22 @@ const HoverableTooltip = memo(({ parentElements, children, width }) => {
|
|||
|
||||
return (
|
||||
<div>
|
||||
<div
|
||||
onMouseEnter={handler.handleOpenHelpPopper}
|
||||
onMouseLeave={handler.handleCloseHelpPopper}>
|
||||
{parentElements}
|
||||
</div>
|
||||
{!R.isNil(parentElements) && (
|
||||
<div
|
||||
onMouseEnter={handler.handleOpenHelpPopper}
|
||||
onMouseLeave={handler.handleCloseHelpPopper}>
|
||||
{parentElements}
|
||||
</div>
|
||||
)}
|
||||
{R.isNil(parentElements) && (
|
||||
<button
|
||||
type="button"
|
||||
onMouseEnter={handler.handleOpenHelpPopper}
|
||||
onMouseLeave={handler.handleCloseHelpPopper}
|
||||
className={handler.classes.transparentButton}>
|
||||
<HelpIcon />
|
||||
</button>
|
||||
)}
|
||||
<Popper
|
||||
open={handler.helpPopperOpen}
|
||||
anchorEl={handler.helpPopperAnchorEl}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
import { makeStyles } from '@material-ui/core'
|
||||
import classnames from 'classnames'
|
||||
import * as R from 'ramda'
|
||||
import React, { useContext } from 'react'
|
||||
|
||||
|
|
@ -11,6 +13,14 @@ import { startCase } from 'src/utils/string'
|
|||
|
||||
import TableCtx from './Context'
|
||||
|
||||
const styles = {
|
||||
orderedBySpan: {
|
||||
whiteSpace: 'nowrap'
|
||||
}
|
||||
}
|
||||
|
||||
const useStyles = makeStyles(styles)
|
||||
|
||||
const groupSecondHeader = elements => {
|
||||
const [toSHeader, noSHeader] = R.partition(R.has('doubleHeader'))(elements)
|
||||
|
||||
|
|
@ -31,6 +41,7 @@ const groupSecondHeader = elements => {
|
|||
}
|
||||
|
||||
const Header = () => {
|
||||
const classes = useStyles()
|
||||
const {
|
||||
elements,
|
||||
enableEdit,
|
||||
|
|
@ -40,6 +51,7 @@ const Header = () => {
|
|||
deleteWidth,
|
||||
enableToggle,
|
||||
toggleWidth,
|
||||
orderedBy,
|
||||
DEFAULT_COL_SIZE
|
||||
} = useContext(TableCtx)
|
||||
|
||||
|
|
@ -60,11 +72,40 @@ const Header = () => {
|
|||
const mapElement = (
|
||||
{ name, width = DEFAULT_COL_SIZE, header, textAlign },
|
||||
idx
|
||||
) => (
|
||||
<Td header key={idx} width={width} textAlign={textAlign}>
|
||||
{header || startCase(name)}
|
||||
</Td>
|
||||
)
|
||||
) => {
|
||||
const orderClasses = classnames({
|
||||
[classes.orderedBySpan]:
|
||||
R.isNil(header) && !R.isNil(orderedBy) && R.equals(name, orderedBy.code)
|
||||
})
|
||||
|
||||
const attachOrderedByToComplexHeader = header => {
|
||||
if (!R.isNil(orderedBy) && R.equals(name, orderedBy.code)) {
|
||||
try {
|
||||
const cloneHeader = R.clone(header)
|
||||
const children = R.path(['props', 'children'], cloneHeader)
|
||||
const spanChild = R.find(it => R.equals(it.type, 'span'), children)
|
||||
spanChild.props.children = R.append(' -', spanChild.props.children)
|
||||
return cloneHeader
|
||||
} catch (e) {
|
||||
return header
|
||||
}
|
||||
}
|
||||
return header
|
||||
}
|
||||
|
||||
return (
|
||||
<Td header key={idx} width={width} textAlign={textAlign}>
|
||||
{!R.isNil(header) ? (
|
||||
<>{attachOrderedByToComplexHeader(header) ?? header}</>
|
||||
) : (
|
||||
<span className={orderClasses}>
|
||||
{startCase(name)}{' '}
|
||||
{!R.isNil(orderedBy) && R.equals(name, orderedBy.code) && '-'}
|
||||
</span>
|
||||
)}
|
||||
</Td>
|
||||
)
|
||||
}
|
||||
|
||||
const [innerElements, HeaderElement] = groupSecondHeader(elements)
|
||||
|
||||
|
|
|
|||
|
|
@ -56,7 +56,8 @@ const ETable = ({
|
|||
sortBy,
|
||||
createText = 'Add override',
|
||||
forceAdd = false,
|
||||
tbodyWrapperClass
|
||||
tbodyWrapperClass,
|
||||
orderedBy = null
|
||||
}) => {
|
||||
const [editingId, setEditingId] = useState(null)
|
||||
const [adding, setAdding] = useState(false)
|
||||
|
|
@ -155,6 +156,7 @@ const ETable = ({
|
|||
actionColSize,
|
||||
stripeWhen,
|
||||
forceAdd,
|
||||
orderedBy,
|
||||
DEFAULT_COL_SIZE
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import { makeStyles } from '@material-ui/core'
|
||||
import classnames from 'classnames'
|
||||
import { useSelect } from 'downshift'
|
||||
import * as R from 'ramda'
|
||||
import React from 'react'
|
||||
|
||||
import { ReactComponent as Arrowdown } from 'src/styling/icons/action/arrow/regular.svg'
|
||||
|
|
@ -29,7 +30,9 @@ function Select({ className, label, items, ...props }) {
|
|||
|
||||
const selectClassNames = {
|
||||
[classes.select]: true,
|
||||
[classes.selectFiltered]: selectedItem !== props.default,
|
||||
[classes.selectFiltered]: props.defaultAsFilter
|
||||
? true
|
||||
: !R.equals(selectedItem, props.default),
|
||||
[classes.open]: isOpen
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -27,16 +27,17 @@ const Sidebar = ({
|
|||
{loading && <P>Loading...</P>}
|
||||
{!loading &&
|
||||
data?.map((it, idx) => (
|
||||
<div
|
||||
key={idx}
|
||||
className={classnames({
|
||||
[classes.activeLink]: isSelected(it),
|
||||
[classes.customRenderActiveLink]: itemRender && isSelected(it),
|
||||
[classes.customRenderLink]: itemRender,
|
||||
[classes.link]: true
|
||||
})}
|
||||
onClick={() => onClick(it)}>
|
||||
{itemRender ? itemRender(it, isSelected(it)) : displayName(it)}
|
||||
<div className={classes.linkWrapper} onClick={() => onClick(it)}>
|
||||
<div
|
||||
key={idx}
|
||||
className={classnames({
|
||||
[classes.activeLink]: isSelected(it),
|
||||
[classes.customRenderActiveLink]: itemRender && isSelected(it),
|
||||
[classes.customRenderLink]: itemRender,
|
||||
[classes.link]: true
|
||||
})}>
|
||||
{itemRender ? itemRender(it, isSelected(it)) : displayName(it)}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
{!loading && children}
|
||||
|
|
|
|||
|
|
@ -30,7 +30,9 @@ export default {
|
|||
boxShadow: `-200px 0px 0px 0px ${sidebarColor}`
|
||||
}
|
||||
},
|
||||
|
||||
linkWrapper: {
|
||||
cursor: 'pointer'
|
||||
},
|
||||
link: {
|
||||
extend: p,
|
||||
position: 'relative',
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ export default {
|
|||
},
|
||||
buttonText: {
|
||||
color: backgroundColor,
|
||||
fontFamily: 'Mont',
|
||||
fontSize: 15
|
||||
},
|
||||
icon: {
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import * as R from 'ramda'
|
|||
import React, { useContext } from 'react'
|
||||
|
||||
import AppContext from 'src/AppContext'
|
||||
import { Tooltip } from 'src/components/Tooltip'
|
||||
import { HoverableTooltip } from 'src/components/Tooltip'
|
||||
import TitleSection from 'src/components/layout/TitleSection'
|
||||
import DataTable from 'src/components/tables/DataTable'
|
||||
import { H4, Info2, P } from 'src/components/typography'
|
||||
|
|
@ -127,9 +127,9 @@ const Accounting = () => {
|
|||
<span className={classes.operation}>
|
||||
{it.description}
|
||||
{!!it.extraInfo && (
|
||||
<Tooltip width={175}>
|
||||
<HoverableTooltip width={175}>
|
||||
<P>{it.extraInfo}</P>
|
||||
</Tooltip>
|
||||
</HoverableTooltip>
|
||||
)}
|
||||
</span>
|
||||
)
|
||||
|
|
|
|||
|
|
@ -300,6 +300,7 @@ const Analytics = () => {
|
|||
items={REPRESENTING_OPTIONS}
|
||||
default={REPRESENTING_OPTIONS[0]}
|
||||
selectedItem={representing}
|
||||
defaultAsFilter
|
||||
/>
|
||||
<Select
|
||||
label="Time period"
|
||||
|
|
@ -307,6 +308,7 @@ const Analytics = () => {
|
|||
items={PERIOD_OPTIONS}
|
||||
default={PERIOD_OPTIONS[0]}
|
||||
selectedItem={period}
|
||||
defaultAsFilter
|
||||
/>
|
||||
</div>
|
||||
<div className={classes.overview}>
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import { utils as coinUtils } from 'lamassu-coins'
|
|||
import * as R from 'ramda'
|
||||
import React, { useState } from 'react'
|
||||
|
||||
import { Tooltip } from 'src/components/Tooltip'
|
||||
import { HoverableTooltip } from 'src/components/Tooltip'
|
||||
import { Link } from 'src/components/buttons'
|
||||
import { Switch } from 'src/components/inputs'
|
||||
import Sidebar from 'src/components/layout/Sidebar'
|
||||
|
|
@ -186,13 +186,13 @@ const Blacklist = () => {
|
|||
value={rejectAddressReuse}
|
||||
/>
|
||||
<Label2>{rejectAddressReuse ? 'On' : 'Off'}</Label2>
|
||||
<Tooltip width={304}>
|
||||
<HoverableTooltip width={304}>
|
||||
<P>
|
||||
The "Reject reused addresses" option means that all addresses
|
||||
that are used once will be automatically rejected if there's
|
||||
an attempt to use them again on a new transaction.
|
||||
</P>
|
||||
</Tooltip>
|
||||
</HoverableTooltip>
|
||||
</Box>
|
||||
</Box>
|
||||
<BlacklistTable
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import gql from 'graphql-tag'
|
|||
import * as R from 'ramda'
|
||||
import React, { useState } from 'react'
|
||||
|
||||
import { Tooltip } from 'src/components/Tooltip'
|
||||
import { HoverableTooltip } from 'src/components/Tooltip'
|
||||
import { NamespacedTable as EditableTable } from 'src/components/editableTable'
|
||||
import { Switch } from 'src/components/inputs'
|
||||
import TitleSection from 'src/components/layout/TitleSection'
|
||||
|
|
@ -54,7 +54,7 @@ const GET_INFO = gql`
|
|||
const CashOut = ({ name: SCREEN_KEY }) => {
|
||||
const classes = useStyles()
|
||||
const [wizard, setWizard] = useState(false)
|
||||
const { data } = useQuery(GET_INFO)
|
||||
const { data, loading } = useQuery(GET_INFO)
|
||||
|
||||
const [saveConfig, { error }] = useMutation(SAVE_CONFIG, {
|
||||
onCompleted: () => setWizard(false),
|
||||
|
|
@ -81,58 +81,60 @@ const CashOut = ({ name: SCREEN_KEY }) => {
|
|||
const wasNeverEnabled = it => R.compose(R.length, R.keys)(it) === 1
|
||||
|
||||
return (
|
||||
<>
|
||||
<TitleSection title="Cash-out">
|
||||
<div className={classes.fudgeFactor}>
|
||||
<P>Transaction fudge factor</P>
|
||||
<Switch
|
||||
checked={fudgeFactorActive}
|
||||
onChange={event => {
|
||||
save({ fudgeFactorActive: event.target.checked })
|
||||
}}
|
||||
value={fudgeFactorActive}
|
||||
/>
|
||||
<Label2 className={classes.switchLabel}>
|
||||
{fudgeFactorActive ? 'On' : 'Off'}
|
||||
</Label2>
|
||||
<Tooltip width={304}>
|
||||
<P>
|
||||
Automatically accept customer deposits as complete if their
|
||||
received amount is 100 crypto atoms or less.
|
||||
</P>
|
||||
<P>
|
||||
(Crypto atoms are the smallest unit in each cryptocurrency. E.g.,
|
||||
satoshis in Bitcoin, or wei in Ethereum.)
|
||||
</P>
|
||||
</Tooltip>
|
||||
</div>
|
||||
</TitleSection>
|
||||
<EditableTable
|
||||
namespaces={R.map(R.path(['deviceId']))(machines)}
|
||||
data={config}
|
||||
stripeWhen={wasNeverEnabled}
|
||||
enableEdit
|
||||
editWidth={134}
|
||||
enableToggle
|
||||
toggleWidth={109}
|
||||
onToggle={onToggle}
|
||||
save={save}
|
||||
error={error?.message}
|
||||
validationSchema={DenominationsSchema}
|
||||
disableRowEdit={R.compose(R.not, R.path(['active']))}
|
||||
elements={getElements(machines, locale, classes)}
|
||||
/>
|
||||
{R.isEmpty(machines) && <EmptyTable message="No machines so far" />}
|
||||
{wizard && (
|
||||
<Wizard
|
||||
machine={R.find(R.propEq('deviceId', wizard))(machines)}
|
||||
onClose={() => setWizard(false)}
|
||||
!loading && (
|
||||
<>
|
||||
<TitleSection title="Cash-out">
|
||||
<div className={classes.fudgeFactor}>
|
||||
<P>Transaction fudge factor</P>
|
||||
<Switch
|
||||
checked={fudgeFactorActive}
|
||||
onChange={event => {
|
||||
save({ fudgeFactorActive: event.target.checked })
|
||||
}}
|
||||
value={fudgeFactorActive}
|
||||
/>
|
||||
<Label2 className={classes.switchLabel}>
|
||||
{fudgeFactorActive ? 'On' : 'Off'}
|
||||
</Label2>
|
||||
<HoverableTooltip width={304}>
|
||||
<P>
|
||||
Automatically accept customer deposits as complete if their
|
||||
received amount is 100 crypto atoms or less.
|
||||
</P>
|
||||
<P>
|
||||
(Crypto atoms are the smallest unit in each cryptocurrency.
|
||||
E.g., satoshis in Bitcoin, or wei in Ethereum.)
|
||||
</P>
|
||||
</HoverableTooltip>
|
||||
</div>
|
||||
</TitleSection>
|
||||
<EditableTable
|
||||
namespaces={R.map(R.path(['deviceId']))(machines)}
|
||||
data={config}
|
||||
stripeWhen={wasNeverEnabled}
|
||||
enableEdit
|
||||
editWidth={134}
|
||||
enableToggle
|
||||
toggleWidth={109}
|
||||
onToggle={onToggle}
|
||||
save={save}
|
||||
error={error?.message}
|
||||
locale={locale}
|
||||
validationSchema={DenominationsSchema}
|
||||
disableRowEdit={R.compose(R.not, R.path(['active']))}
|
||||
elements={getElements(machines, locale, classes)}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
{R.isEmpty(machines) && <EmptyTable message="No machines so far" />}
|
||||
{wizard && (
|
||||
<Wizard
|
||||
machine={R.find(R.propEq('deviceId', wizard))(machines)}
|
||||
onClose={() => setWizard(false)}
|
||||
save={save}
|
||||
error={error?.message}
|
||||
locale={locale}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,6 +8,12 @@ import { getBillOptions } from 'src/utils/bill-options'
|
|||
import { CURRENCY_MAX } from 'src/utils/constants'
|
||||
import { transformNumber } from 'src/utils/number'
|
||||
|
||||
const widthsByNumberOfCassettes = {
|
||||
2: { machine: 300, cassette: 225, zeroConf: 200 },
|
||||
3: { machine: 210, cassette: 180, zeroConf: 200 },
|
||||
4: { machine: 200, cassette: 150, zeroConf: 150 }
|
||||
}
|
||||
|
||||
const DenominationsSchema = Yup.object().shape({
|
||||
cassette1: Yup.number()
|
||||
.label('Cassette 1')
|
||||
|
|
@ -60,7 +66,7 @@ const getElements = (machines, locale = {}, classes) => {
|
|||
{
|
||||
name: 'id',
|
||||
header: 'Machine',
|
||||
width: 300,
|
||||
width: widthsByNumberOfCassettes[maxNumberOfCassettes].machine,
|
||||
view: it => machines.find(({ deviceId }) => deviceId === it).name,
|
||||
size: 'sm',
|
||||
editable: false
|
||||
|
|
@ -76,7 +82,7 @@ const getElements = (machines, locale = {}, classes) => {
|
|||
size: 'sm',
|
||||
stripe: true,
|
||||
textAlign: 'right',
|
||||
width: (maxNumberOfCassettes > 2 ? 600 : 460) / maxNumberOfCassettes,
|
||||
width: widthsByNumberOfCassettes[maxNumberOfCassettes].cassette,
|
||||
suffix: fiatCurrency,
|
||||
bold: bold,
|
||||
view: it => it,
|
||||
|
|
@ -99,7 +105,7 @@ const getElements = (machines, locale = {}, classes) => {
|
|||
size: 'sm',
|
||||
stripe: true,
|
||||
textAlign: 'right',
|
||||
width: maxNumberOfCassettes > 2 ? 150 : 290,
|
||||
width: widthsByNumberOfCassettes[maxNumberOfCassettes].zeroConf,
|
||||
input: NumberInput,
|
||||
inputProps: {
|
||||
decimalPlaces: 0
|
||||
|
|
|
|||
|
|
@ -160,6 +160,7 @@ const CommissionsList = memo(
|
|||
default={ORDER_OPTIONS[0]}
|
||||
items={ORDER_OPTIONS}
|
||||
selectedItem={orderProp}
|
||||
defaultAsFilter
|
||||
/>
|
||||
</div>
|
||||
<div className={classes.tableWrapper}>
|
||||
|
|
@ -172,6 +173,7 @@ const CommissionsList = memo(
|
|||
validationSchema={getListCommissionsSchema(localeConfig)}
|
||||
data={tableData}
|
||||
elements={commissionsList(data, currency)}
|
||||
orderedBy={orderProp}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ const ALL_COINS = {
|
|||
code: 'ALL_COINS'
|
||||
}
|
||||
|
||||
const cashInAndOutHeaderStyle = { marginLeft: 6 }
|
||||
const cashInAndOutHeaderStyle = { marginLeft: 6, whiteSpace: 'nowrap' }
|
||||
|
||||
const cashInHeader = (
|
||||
<div>
|
||||
|
|
@ -488,7 +488,7 @@ const getListCommissionsFields = (getData, currency, defaults) => {
|
|||
{
|
||||
name: 'cryptoCurrencies',
|
||||
display: 'Crypto Currency',
|
||||
width: 265,
|
||||
width: 255,
|
||||
view: R.prop(0),
|
||||
size: 'sm',
|
||||
editable: false
|
||||
|
|
@ -510,7 +510,7 @@ const getListCommissionsFields = (getData, currency, defaults) => {
|
|||
header: cashOutHeader,
|
||||
name: 'cashOut',
|
||||
display: 'Cash-out',
|
||||
width: 130,
|
||||
width: 140,
|
||||
input: NumberInput,
|
||||
textAlign: 'right',
|
||||
greenText: true,
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import { useState, React } from 'react'
|
|||
import ErrorMessage from 'src/components/ErrorMessage'
|
||||
import PromptWhenDirty from 'src/components/PromptWhenDirty'
|
||||
import { MainStatus } from 'src/components/Status'
|
||||
import { Tooltip } from 'src/components/Tooltip'
|
||||
import { HoverableTooltip } from 'src/components/Tooltip'
|
||||
import { ActionButton } from 'src/components/buttons'
|
||||
import { Label1, P, H3 } from 'src/components/typography'
|
||||
import {
|
||||
|
|
@ -148,7 +148,7 @@ const EditableCard = ({
|
|||
<div className={classes.cardHeader}>
|
||||
{titleIcon}
|
||||
<H3 className={classes.cardTitle}>{title}</H3>
|
||||
<Tooltip width={304}></Tooltip>
|
||||
<HoverableTooltip width={304}></HoverableTooltip>
|
||||
</div>
|
||||
{state && authorize && (
|
||||
<div className={classnames(label1ClassNames)}>
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import * as Yup from 'yup'
|
|||
|
||||
import ErrorMessage from 'src/components/ErrorMessage'
|
||||
import Modal from 'src/components/Modal'
|
||||
import { Tooltip } from 'src/components/Tooltip'
|
||||
import { HoverableTooltip } from 'src/components/Tooltip'
|
||||
import { Button } from 'src/components/buttons'
|
||||
import { NumberInput, Autocomplete } from 'src/components/inputs/formik'
|
||||
import { H3, TL1, P } from 'src/components/typography'
|
||||
|
|
@ -99,7 +99,7 @@ const IndividualDiscountModal = ({
|
|||
<div>
|
||||
<div className={classes.discountRateWrapper}>
|
||||
<H3>Define discount rate</H3>
|
||||
<Tooltip width={304}>
|
||||
<HoverableTooltip width={304}>
|
||||
<P>
|
||||
This is a percentage discount off of your existing
|
||||
commission rates for a customer entering this code at
|
||||
|
|
@ -110,7 +110,7 @@ const IndividualDiscountModal = ({
|
|||
code is set for 50%, then you'll instead be charging 4%
|
||||
on transactions using the code.
|
||||
</P>
|
||||
</Tooltip>
|
||||
</HoverableTooltip>
|
||||
</div>
|
||||
<div className={classes.discountInput}>
|
||||
<Field
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import * as Yup from 'yup'
|
|||
|
||||
import ErrorMessage from 'src/components/ErrorMessage'
|
||||
import Modal from 'src/components/Modal'
|
||||
import { Tooltip } from 'src/components/Tooltip'
|
||||
import { HoverableTooltip } from 'src/components/Tooltip'
|
||||
import { Button } from 'src/components/buttons'
|
||||
import { TextInput, NumberInput } from 'src/components/inputs/formik'
|
||||
import { H3, TL1, P } from 'src/components/typography'
|
||||
|
|
@ -69,7 +69,7 @@ const PromoCodesModal = ({ showModal, onClose, errorMsg, addCode }) => {
|
|||
/>
|
||||
<div className={classes.modalLabel2Wrapper}>
|
||||
<H3 className={classes.modalLabel2}>Define discount rate</H3>
|
||||
<Tooltip width={304}>
|
||||
<HoverableTooltip width={304}>
|
||||
<P>
|
||||
This is a percentage discount off of your existing
|
||||
commission rates for a customer entering this code at the
|
||||
|
|
@ -80,7 +80,7 @@ const PromoCodesModal = ({ showModal, onClose, errorMsg, addCode }) => {
|
|||
set for 50%, then you'll instead be charging 4% on
|
||||
transactions using the code.
|
||||
</P>
|
||||
</Tooltip>
|
||||
</HoverableTooltip>
|
||||
</div>
|
||||
<div className={classes.discountInput}>
|
||||
<Field
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import * as R from 'ramda'
|
|||
import React from 'react'
|
||||
|
||||
import Stepper from 'src/components/Stepper'
|
||||
import { Tooltip } from 'src/components/Tooltip'
|
||||
import { HoverableTooltip } from 'src/components/Tooltip'
|
||||
import { Button } from 'src/components/buttons'
|
||||
import { Cashbox } from 'src/components/inputs/cashbox/Cashbox'
|
||||
import { NumberInput, RadioGroup } from 'src/components/inputs/formik'
|
||||
|
|
@ -188,12 +188,12 @@ const WizardStep = ({
|
|||
classes.centerAlignment
|
||||
)}>
|
||||
<P>Since previous update</P>
|
||||
<Tooltip width={215}>
|
||||
<HoverableTooltip width={215}>
|
||||
<P>
|
||||
Number of bills inside the cash box, since the last
|
||||
cash box changes.
|
||||
</P>
|
||||
</Tooltip>
|
||||
</HoverableTooltip>
|
||||
</div>
|
||||
<div
|
||||
className={classnames(
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ const Notifications = ({
|
|||
const [error, setError] = useState(null)
|
||||
const [editingKey, setEditingKey] = useState(null)
|
||||
|
||||
const { data } = useQuery(GET_INFO)
|
||||
const { data, loading } = useQuery(GET_INFO)
|
||||
|
||||
const [saveConfig] = useMutation(SAVE_CONFIG, {
|
||||
refetchQueries: ['getData'],
|
||||
|
|
@ -101,40 +101,47 @@ const Notifications = ({
|
|||
}
|
||||
|
||||
return (
|
||||
<NotificationsCtx.Provider value={contextValue}>
|
||||
{displayTitle && <TitleSection title="Notifications" />}
|
||||
{displaySetup && (
|
||||
<Section title="Setup" error={error && !section}>
|
||||
<Setup forceDisable={!!editingKey} wizard={wizard} />
|
||||
</Section>
|
||||
)}
|
||||
{displayTransactionAlerts && (
|
||||
<Section title="Transaction alerts" error={error && section === 'tx'}>
|
||||
<TransactionAlerts section="tx" fieldWidth={FIELDS_WIDTH} />
|
||||
</Section>
|
||||
)}
|
||||
{displayFiatAlerts && (
|
||||
<Section
|
||||
title="Fiat balance alerts"
|
||||
error={error && section === 'fiat'}>
|
||||
<FiatBalanceAlerts section="fiat" max={100} fieldWidth={50} />
|
||||
{displayOverrides && <FiatBalanceOverrides section="fiat" />}
|
||||
</Section>
|
||||
)}
|
||||
{displayCryptoAlerts && (
|
||||
<Section
|
||||
title="Crypto balance alerts"
|
||||
error={error && section === 'crypto'}>
|
||||
<CryptoBalanceAlerts section="crypto" fieldWidth={FIELDS_WIDTH} />
|
||||
{displayOverrides && (
|
||||
<CryptoBalanceOverrides
|
||||
section="crypto"
|
||||
fieldWidth={FIELDS_WIDTH}
|
||||
/>
|
||||
)}
|
||||
</Section>
|
||||
)}
|
||||
</NotificationsCtx.Provider>
|
||||
!loading && (
|
||||
<NotificationsCtx.Provider value={contextValue}>
|
||||
{displayTitle && <TitleSection title="Notifications" />}
|
||||
{displaySetup && (
|
||||
<Section title="Setup" error={error && !section}>
|
||||
<Setup forceDisable={!!editingKey} wizard={wizard} />
|
||||
</Section>
|
||||
)}
|
||||
{displayTransactionAlerts && (
|
||||
<Section title="Transaction alerts" error={error && section === 'tx'}>
|
||||
<TransactionAlerts section="tx" fieldWidth={FIELDS_WIDTH} />
|
||||
</Section>
|
||||
)}
|
||||
{displayFiatAlerts && (
|
||||
<Section
|
||||
title="Fiat balance alerts"
|
||||
error={error && section === 'fiat'}>
|
||||
<FiatBalanceAlerts section="fiat" max={100} fieldWidth={50} />
|
||||
{displayOverrides && (
|
||||
<FiatBalanceOverrides
|
||||
config={fromNamespace(namespaces.CASH_OUT)(data?.config)}
|
||||
section="fiat"
|
||||
/>
|
||||
)}
|
||||
</Section>
|
||||
)}
|
||||
{displayCryptoAlerts && (
|
||||
<Section
|
||||
title="Crypto balance alerts"
|
||||
error={error && section === 'crypto'}>
|
||||
<CryptoBalanceAlerts section="crypto" fieldWidth={FIELDS_WIDTH} />
|
||||
{displayOverrides && (
|
||||
<CryptoBalanceOverrides
|
||||
section="crypto"
|
||||
fieldWidth={FIELDS_WIDTH}
|
||||
/>
|
||||
)}
|
||||
</Section>
|
||||
)}
|
||||
</NotificationsCtx.Provider>
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import * as Yup from 'yup'
|
|||
import { Table as EditableTable } from 'src/components/editableTable'
|
||||
import { NumberInput } from 'src/components/inputs/formik/'
|
||||
import Autocomplete from 'src/components/inputs/formik/Autocomplete'
|
||||
import { fromNamespace } from 'src/utils/config'
|
||||
import { transformNumber } from 'src/utils/number'
|
||||
|
||||
import NotificationsCtx from '../NotificationsContext'
|
||||
|
|
@ -23,7 +24,13 @@ const CASSETTE_LIST = [
|
|||
CASSETTE_4_KEY
|
||||
]
|
||||
|
||||
const FiatBalanceOverrides = ({ section }) => {
|
||||
const widthsByNumberOfCassettes = {
|
||||
2: { machine: 230, cassette: 250 },
|
||||
3: { machine: 216, cassette: 270 },
|
||||
4: { machine: 210, cassette: 204 }
|
||||
}
|
||||
|
||||
const FiatBalanceOverrides = ({ config, section }) => {
|
||||
const {
|
||||
machines = [],
|
||||
data,
|
||||
|
|
@ -36,9 +43,13 @@ const FiatBalanceOverrides = ({ section }) => {
|
|||
const setupValues = data?.fiatBalanceOverrides ?? []
|
||||
const innerSetEditing = it => setEditing(NAME, it)
|
||||
|
||||
const cashoutConfig = it => fromNamespace(it)(config)
|
||||
|
||||
const overridenMachines = R.map(override => override.machine, setupValues)
|
||||
const suggestionFilter = R.filter(
|
||||
it => !R.contains(it.deviceId, overridenMachines)
|
||||
it =>
|
||||
!R.includes(it.deviceId, overridenMachines) &&
|
||||
cashoutConfig(it.deviceId).active
|
||||
)
|
||||
const suggestions = suggestionFilter(machines)
|
||||
|
||||
|
|
@ -114,7 +125,7 @@ const FiatBalanceOverrides = ({ section }) => {
|
|||
const elements = [
|
||||
{
|
||||
name: MACHINE_KEY,
|
||||
width: 238,
|
||||
width: widthsByNumberOfCassettes[maxNumberOfCassettes].machine,
|
||||
size: 'sm',
|
||||
view: viewMachine,
|
||||
input: Autocomplete,
|
||||
|
|
@ -132,7 +143,7 @@ const FiatBalanceOverrides = ({ section }) => {
|
|||
elements.push({
|
||||
name: `fillingPercentageCassette${it}`,
|
||||
display: `Cash cassette ${it}`,
|
||||
width: 155,
|
||||
width: widthsByNumberOfCassettes[maxNumberOfCassettes].cassette,
|
||||
textAlign: 'right',
|
||||
doubleHeader: 'Cash Cassette Empty',
|
||||
bold: true,
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ import { startCase } from 'src/utils/string'
|
|||
|
||||
import NotificationsCtx from '../NotificationsContext'
|
||||
|
||||
const channelSize = 129
|
||||
const channelSize = 229
|
||||
const sizes = {
|
||||
balance: 152,
|
||||
transactions: 184,
|
||||
|
|
@ -26,7 +26,7 @@ const sizes = {
|
|||
active: 263
|
||||
}
|
||||
|
||||
const Row = ({ namespace, forceDisable }) => {
|
||||
const Row = ({ namespace, forceDisable, shouldUpperCase }) => {
|
||||
const { data: rawData, save: rawSave } = useContext(NotificationsCtx)
|
||||
|
||||
const save = R.compose(rawSave(null), toNamespace(namespace))
|
||||
|
|
@ -53,7 +53,9 @@ const Row = ({ namespace, forceDisable }) => {
|
|||
|
||||
return (
|
||||
<Tr>
|
||||
<Td width={channelSize}>{startCase(namespace)}</Td>
|
||||
<Td width={channelSize}>
|
||||
{shouldUpperCase ? R.toUpper(namespace) : startCase(namespace)}
|
||||
</Td>
|
||||
<Cell name="balance" disabled={disabled} />
|
||||
<Cell name="transactions" disabled={disabled} />
|
||||
<Cell name="compliance" disabled={disabled} />
|
||||
|
|
@ -84,7 +86,7 @@ const Setup = ({ wizard, forceDisable }) => {
|
|||
</THead>
|
||||
<TBody>
|
||||
<Row namespace="email" forceDisable={forceDisable} />
|
||||
<Row namespace="sms" forceDisable={forceDisable} />
|
||||
<Row namespace="sms" shouldUpperCase forceDisable={forceDisable} />
|
||||
<Row namespace="notificationCenter" forceDisable={forceDisable} />
|
||||
</TBody>
|
||||
</Table>
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import { makeStyles } from '@material-ui/core/styles'
|
|||
import gql from 'graphql-tag'
|
||||
import React, { memo } from 'react'
|
||||
|
||||
import { Tooltip } from 'src/components/Tooltip'
|
||||
import { HoverableTooltip } from 'src/components/Tooltip'
|
||||
import { BooleanPropertiesTable } from 'src/components/booleanPropertiesTable'
|
||||
import { Switch } from 'src/components/inputs'
|
||||
import { H4, P, Label2 } from 'src/components/typography'
|
||||
|
|
@ -66,7 +66,7 @@ const CoinATMRadar = memo(({ wizard }) => {
|
|||
<div>
|
||||
<div className={classes.header}>
|
||||
<H4>Coin ATM Radar share settings</H4>
|
||||
<Tooltip width={304}>
|
||||
<HoverableTooltip width={304}>
|
||||
<P>
|
||||
For details on configuring this panel, please read the relevant
|
||||
knowledgebase article{' '}
|
||||
|
|
@ -78,7 +78,7 @@ const CoinATMRadar = memo(({ wizard }) => {
|
|||
</a>
|
||||
.
|
||||
</P>
|
||||
</Tooltip>
|
||||
</HoverableTooltip>
|
||||
</div>
|
||||
<Row
|
||||
title={'Share information?'}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import gql from 'graphql-tag'
|
|||
import * as R from 'ramda'
|
||||
import React, { useState } from 'react'
|
||||
|
||||
import { Tooltip } from 'src/components/Tooltip'
|
||||
import { HoverableTooltip } from 'src/components/Tooltip'
|
||||
import { Link } from 'src/components/buttons'
|
||||
import { Switch } from 'src/components/inputs'
|
||||
import TitleSection from 'src/components/layout/TitleSection'
|
||||
|
|
@ -141,13 +141,13 @@ const Triggers = () => {
|
|||
<Label2 className={classes.switchLabel}>
|
||||
{rejectAddressReuse ? 'On' : 'Off'}
|
||||
</Label2>
|
||||
<Tooltip width={304}>
|
||||
<HoverableTooltip width={304}>
|
||||
<P>
|
||||
This option requires a user to scan a different cryptocurrency
|
||||
address if they attempt to scan one that had been previously
|
||||
used for a transaction in your network
|
||||
</P>
|
||||
</Tooltip>
|
||||
</HoverableTooltip>
|
||||
</Box>
|
||||
</Box>
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import gql from 'graphql-tag'
|
|||
import React, { useState } from 'react'
|
||||
|
||||
import InfoMessage from 'src/components/InfoMessage'
|
||||
import { Tooltip } from 'src/components/Tooltip'
|
||||
import { HoverableTooltip } from 'src/components/Tooltip'
|
||||
import { Button, SupportLinkButton } from 'src/components/buttons'
|
||||
import { RadioGroup } from 'src/components/inputs'
|
||||
import { H1, H4, P } from 'src/components/typography'
|
||||
|
|
@ -102,7 +102,7 @@ function Twilio({ doContinue }) {
|
|||
<H4 noMargin className={classnames(titleClasses)}>
|
||||
Will you setup a two way machine or compliance?
|
||||
</H4>
|
||||
<Tooltip width={304}>
|
||||
<HoverableTooltip width={304}>
|
||||
<P>
|
||||
Two-way machines allow your customers not only to buy (cash-in)
|
||||
but also sell cryptocurrencies (cash-out).
|
||||
|
|
@ -111,7 +111,7 @@ function Twilio({ doContinue }) {
|
|||
You’ll need an SMS service for cash-out transactions and for any
|
||||
compliance triggers
|
||||
</P>
|
||||
</Tooltip>
|
||||
</HoverableTooltip>
|
||||
</Box>
|
||||
|
||||
<RadioGroup
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue