partial: notifications, op info, services
This commit is contained in:
parent
a90833726e
commit
6d6edf578c
22 changed files with 290 additions and 795 deletions
|
|
@ -35,7 +35,7 @@ const cashboxStyles = {
|
|||
border: '4px solid'
|
||||
},
|
||||
emptyPart: {
|
||||
backgroundColor: 'white',
|
||||
backgroundColor: 'var(--ghost)',
|
||||
height: ({ percent }) => `${100 - percent}%`,
|
||||
position: 'relative',
|
||||
'& > p': {
|
||||
|
|
|
|||
|
|
@ -1,20 +0,0 @@
|
|||
export default {
|
||||
cryptoBalanceAlerts: {
|
||||
display: 'flex',
|
||||
marginBottom: 36,
|
||||
height: 135,
|
||||
alignItems: 'center'
|
||||
},
|
||||
cryptoBalanceAlertsForm: {
|
||||
width: 222,
|
||||
marginRight: 32
|
||||
},
|
||||
cryptoBalanceAlertsSecondForm: {
|
||||
marginLeft: 50
|
||||
},
|
||||
vertSeparator: {
|
||||
width: 1,
|
||||
height: '100%',
|
||||
borderRight: [[1, 'solid', 'black']]
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,3 @@
|
|||
import { makeStyles } from '@mui/styles'
|
||||
import React from 'react'
|
||||
import { H4 } from 'src/components/typography'
|
||||
import DisabledEditIcon from 'src/styling/icons/action/edit/disabled.svg?react'
|
||||
|
|
@ -6,27 +5,23 @@ import EditIcon from 'src/styling/icons/action/edit/enabled.svg?react'
|
|||
|
||||
import { Link, IconButton } from 'src/components/buttons'
|
||||
|
||||
import styles from './EditHeader.styles'
|
||||
|
||||
const useStyles = makeStyles(styles)
|
||||
|
||||
const Header = ({ title, editing, disabled, setEditing }) => {
|
||||
const classes = useStyles()
|
||||
|
||||
return (
|
||||
<div className={classes.header}>
|
||||
<H4 className={classes.title}>{title}</H4>
|
||||
<div className="flex items-center m-0 mb-4 h-7">
|
||||
<H4 noMargin className="overflow-hidden whitespace-nowrap text-ellipsis">
|
||||
{title}
|
||||
</H4>
|
||||
{!editing && (
|
||||
<IconButton
|
||||
onClick={() => setEditing(true)}
|
||||
className={classes.button}
|
||||
className="border-0 bg-transparent shrink-0 cursor-pointer ml-2"
|
||||
disabled={disabled}
|
||||
size="large">
|
||||
{disabled ? <DisabledEditIcon /> : <EditIcon />}
|
||||
</IconButton>
|
||||
)}
|
||||
{editing && (
|
||||
<div className={classes.editingButtons}>
|
||||
<div className="flex ml-4 justify-between shrink-0 w-27">
|
||||
<Link color="primary" type="submit">
|
||||
Save
|
||||
</Link>
|
||||
|
|
@ -36,7 +31,7 @@ const Header = ({ title, editing, disabled, setEditing }) => {
|
|||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
)
|
||||
}
|
||||
|
||||
export default Header
|
||||
|
|
|
|||
|
|
@ -1,29 +0,0 @@
|
|||
export default {
|
||||
header: {
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
marginBottom: 16,
|
||||
height: 26,
|
||||
margin: 0
|
||||
},
|
||||
title: {
|
||||
flexShrink: 2,
|
||||
margin: 0,
|
||||
overflow: 'hidden',
|
||||
whiteSpace: 'nowrap',
|
||||
textOverflow: 'ellipsis'
|
||||
},
|
||||
button: {
|
||||
border: 'none',
|
||||
backgroundColor: 'transparent',
|
||||
cursor: 'pointer',
|
||||
marginLeft: 8
|
||||
},
|
||||
editingButtons: {
|
||||
display: 'flex',
|
||||
flexShrink: 0,
|
||||
marginLeft: 16,
|
||||
justifyContent: 'space-between',
|
||||
width: 110
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,3 @@
|
|||
import { makeStyles } from '@mui/styles'
|
||||
import classnames from 'classnames'
|
||||
import { useFormikContext, Field as FormikField } from 'formik'
|
||||
import React from 'react'
|
||||
|
|
@ -6,10 +5,6 @@ import { Label1, Info1, TL2 } from 'src/components/typography'
|
|||
|
||||
import { NumberInput } from 'src/components/inputs/formik'
|
||||
|
||||
import styles from './EditableNumber.styles'
|
||||
|
||||
const useStyles = makeStyles(styles)
|
||||
|
||||
const EditableNumber = ({
|
||||
label,
|
||||
name,
|
||||
|
|
@ -20,20 +15,21 @@ const EditableNumber = ({
|
|||
decimalPlaces = 0,
|
||||
width = 80
|
||||
}) => {
|
||||
const classes = useStyles({ width, editing })
|
||||
const { values } = useFormikContext()
|
||||
|
||||
const classNames = {
|
||||
[classes.fieldWrapper]: true,
|
||||
'h-13': true,
|
||||
className
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={classnames(classNames)}>
|
||||
{label && <Label1 className={classes.label}>{label}</Label1>}
|
||||
<div className={classes.valueWrapper}>
|
||||
{label && <Label1 noMargin>{label}</Label1>}
|
||||
<div className="flex items-baseline">
|
||||
{!editing && (
|
||||
<Info1 className={classes.text}>{displayValue(values[name])}</Info1>
|
||||
<Info1 noMargin className="my-2">
|
||||
{displayValue(values[name])}
|
||||
</Info1>
|
||||
)}
|
||||
{editing && (
|
||||
<FormikField
|
||||
|
|
@ -47,7 +43,9 @@ const EditableNumber = ({
|
|||
decimalPlaces={decimalPlaces}
|
||||
/>
|
||||
)}
|
||||
<TL2 className={classes.decoration}>{decoration}</TL2>
|
||||
<TL2 noMargin className="ml-2">
|
||||
{decoration}
|
||||
</TL2>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,18 +0,0 @@
|
|||
export default {
|
||||
text: {
|
||||
margin: [[7, 0, 7, 1]]
|
||||
},
|
||||
fieldWrapper: {
|
||||
height: 53
|
||||
},
|
||||
valueWrapper: {
|
||||
display: 'flex',
|
||||
alignItems: 'baseline'
|
||||
},
|
||||
label: {
|
||||
margin: 0
|
||||
},
|
||||
decoration: {
|
||||
margin: [[0, 0, 0, 7]]
|
||||
}
|
||||
}
|
||||
|
|
@ -1,31 +1,24 @@
|
|||
import { makeStyles } from '@mui/styles'
|
||||
import React, { useContext } from 'react'
|
||||
|
||||
import NotificationsCtx from '../NotificationsContext'
|
||||
import SingleFieldEditableNumber from '../components/SingleFieldEditableNumber'
|
||||
|
||||
import styles from './CryptoBalanceAlerts.styles'
|
||||
|
||||
const LOW_BALANCE_KEY = 'cryptoLowBalance'
|
||||
const HIGH_BALANCE_KEY = 'cryptoHighBalance'
|
||||
|
||||
const useStyles = makeStyles(styles)
|
||||
|
||||
const CryptoBalanceAlerts = ({ section, fieldWidth }) => {
|
||||
const classes = useStyles()
|
||||
|
||||
const { data, save, currency, setEditing, isEditing, isDisabled } =
|
||||
useContext(NotificationsCtx)
|
||||
|
||||
return (
|
||||
<div className={classes.cryptoBalanceAlerts}>
|
||||
<div className="flex mb-9 h-34 items-center gap-12">
|
||||
<SingleFieldEditableNumber
|
||||
name={LOW_BALANCE_KEY}
|
||||
data={data}
|
||||
save={save}
|
||||
section={section}
|
||||
decoration={currency}
|
||||
className={classes.cryptoBalanceAlertsForm}
|
||||
className="w-50"
|
||||
title="Default (Low balance)"
|
||||
label="Alert me under"
|
||||
editing={isEditing(LOW_BALANCE_KEY)}
|
||||
|
|
@ -34,7 +27,7 @@ const CryptoBalanceAlerts = ({ section, fieldWidth }) => {
|
|||
width={fieldWidth}
|
||||
/>
|
||||
|
||||
<div className={classes.vertSeparator} />
|
||||
<div className="w-[1px] h-full border-r border-r-comet" />
|
||||
|
||||
<SingleFieldEditableNumber
|
||||
name={HIGH_BALANCE_KEY}
|
||||
|
|
@ -42,7 +35,6 @@ const CryptoBalanceAlerts = ({ section, fieldWidth }) => {
|
|||
section={section}
|
||||
save={save}
|
||||
decoration={currency}
|
||||
className={classes.cryptoBalanceAlertsSecondForm}
|
||||
title="Default (High balance)"
|
||||
label="Alert me over"
|
||||
editing={isEditing(HIGH_BALANCE_KEY)}
|
||||
|
|
|
|||
|
|
@ -1,20 +0,0 @@
|
|||
export default {
|
||||
cryptoBalanceAlerts: {
|
||||
display: 'flex',
|
||||
marginBottom: 36,
|
||||
height: 135,
|
||||
alignItems: 'center'
|
||||
},
|
||||
cryptoBalanceAlertsForm: {
|
||||
width: 222,
|
||||
marginRight: 32
|
||||
},
|
||||
cryptoBalanceAlertsSecondForm: {
|
||||
marginLeft: 50
|
||||
},
|
||||
vertSeparator: {
|
||||
width: 1,
|
||||
height: '100%',
|
||||
borderRight: [[1, 'solid', 'black']]
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,3 @@
|
|||
import { makeStyles } from '@mui/styles'
|
||||
import { Form, Formik } from 'formik'
|
||||
import * as R from 'ramda'
|
||||
import React, { useContext } from 'react'
|
||||
|
|
@ -13,10 +12,6 @@ import NotificationsCtx from '../NotificationsContext'
|
|||
import Header from '../components/EditHeader'
|
||||
import EditableNumber from '../components/EditableNumber'
|
||||
|
||||
import styles from './FiatBalanceAlerts.styles'
|
||||
|
||||
const useStyles = makeStyles(styles)
|
||||
|
||||
const CASH_IN_KEY = 'fiatBalanceAlertsCashIn'
|
||||
const CASH_OUT_KEY = 'fiatBalanceAlertsCashOut'
|
||||
const RECYCLER_STACKER_KEY = 'fiatBalanceAlertsRecyclerStacker'
|
||||
|
|
@ -34,8 +29,6 @@ const FiatBalance = ({ section, min = 0, max = 100, fieldWidth = 80 }) => {
|
|||
save,
|
||||
machines = []
|
||||
} = useContext(NotificationsCtx)
|
||||
const classes = useStyles()
|
||||
|
||||
const maxNumberOfCassettes = Math.max(
|
||||
...R.map(it => it.numberOfCassettes, machines),
|
||||
DEFAULT_NUMBER_OF_CASSETTES
|
||||
|
|
@ -97,8 +90,8 @@ const FiatBalance = ({ section, min = 0, max = 100, fieldWidth = 80 }) => {
|
|||
setEditing(CASH_OUT_KEY, false)
|
||||
}}>
|
||||
{({ values }) => (
|
||||
<>
|
||||
<Form className={classes.form}>
|
||||
<div className="flex flex-col gap-9">
|
||||
<Form>
|
||||
<PromptWhenDirty />
|
||||
<Header
|
||||
title="Cash box"
|
||||
|
|
@ -106,24 +99,16 @@ const FiatBalance = ({ section, min = 0, max = 100, fieldWidth = 80 }) => {
|
|||
disabled={isDisabled(CASH_IN_KEY)}
|
||||
setEditing={it => setEditing(CASH_IN_KEY, it)}
|
||||
/>
|
||||
<div className={classes.wrapper}>
|
||||
<div className={classes.first}>
|
||||
<div className={classes.row}>
|
||||
<div className={classes.col2}>
|
||||
<EditableNumber
|
||||
label="Alert me over"
|
||||
name="cashInAlertThreshold"
|
||||
editing={isEditing(CASH_IN_KEY)}
|
||||
displayValue={x => (x === '' ? '-' : x)}
|
||||
decoration="notes"
|
||||
width={fieldWidth}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<EditableNumber
|
||||
label="Alert me over"
|
||||
name="cashInAlertThreshold"
|
||||
editing={isEditing(CASH_IN_KEY)}
|
||||
displayValue={x => (x === '' ? '-' : x)}
|
||||
decoration="notes"
|
||||
width={fieldWidth}
|
||||
/>
|
||||
</Form>
|
||||
<Form className={classes.form}>
|
||||
<Form>
|
||||
<PromptWhenDirty />
|
||||
<Header
|
||||
title="Cash out (Empty)"
|
||||
|
|
@ -131,14 +116,12 @@ const FiatBalance = ({ section, min = 0, max = 100, fieldWidth = 80 }) => {
|
|||
disabled={isDisabled(CASH_OUT_KEY)}
|
||||
setEditing={it => setEditing(CASH_OUT_KEY, it)}
|
||||
/>
|
||||
<div className={classes.wrapper}>
|
||||
<div className="flex flex-wrap gap-8">
|
||||
{R.map(
|
||||
it => (
|
||||
<>
|
||||
<div className={classes.row}>
|
||||
<div className="flex w-50 gap-4">
|
||||
<Cashbox
|
||||
labelClassName={classes.cashboxLabel}
|
||||
emptyPartClassName={classes.cashboxEmptyPart}
|
||||
percent={
|
||||
values[`fillingPercentageCassette${it + 1}`] ??
|
||||
data[`cassette${it + 1}`]
|
||||
|
|
@ -148,8 +131,8 @@ const FiatBalance = ({ section, min = 0, max = 100, fieldWidth = 80 }) => {
|
|||
omitInnerPercentage
|
||||
cashOut
|
||||
/>
|
||||
<div className={classes.col2}>
|
||||
<TL2 className={classes.title}>Cassette {it + 1}</TL2>
|
||||
<div className="w-30">
|
||||
<TL2 className="mt-0">Cassette {it + 1}</TL2>
|
||||
<EditableNumber
|
||||
label="Alert me under"
|
||||
name={`fillingPercentageCassette${it + 1}`}
|
||||
|
|
@ -166,7 +149,7 @@ const FiatBalance = ({ section, min = 0, max = 100, fieldWidth = 80 }) => {
|
|||
)}
|
||||
</div>
|
||||
</Form>
|
||||
<Form className={classes.form}>
|
||||
<Form>
|
||||
<PromptWhenDirty />
|
||||
<Header
|
||||
title="Cash recycling"
|
||||
|
|
@ -174,14 +157,12 @@ const FiatBalance = ({ section, min = 0, max = 100, fieldWidth = 80 }) => {
|
|||
disabled={isDisabled(RECYCLER_STACKER_KEY)}
|
||||
setEditing={it => setEditing(RECYCLER_STACKER_KEY, it)}
|
||||
/>
|
||||
<div className={classes.wrapper}>
|
||||
<div className="flex flex-wrap gap-8">
|
||||
{R.chain(
|
||||
it => [
|
||||
<>
|
||||
<div className={classes.row}>
|
||||
<div className="flex w-50 gap-4">
|
||||
<Cashbox
|
||||
labelClassName={classes.cashboxLabel}
|
||||
emptyPartClassName={classes.cashboxEmptyPart}
|
||||
percent={
|
||||
values[
|
||||
`fillingPercentageRecycler${(it + 1) * 2 - 1}`
|
||||
|
|
@ -192,10 +173,8 @@ const FiatBalance = ({ section, min = 0, max = 100, fieldWidth = 80 }) => {
|
|||
omitInnerPercentage
|
||||
cashOut
|
||||
/>
|
||||
<div className={classes.col2}>
|
||||
<TL2 className={classes.title}>
|
||||
Recycler {(it + 1) * 2 - 1}
|
||||
</TL2>
|
||||
<div className="w-30">
|
||||
<TL2 className="mt-0">Recycler {(it + 1) * 2 - 1}</TL2>
|
||||
<EditableNumber
|
||||
label="Alert me under"
|
||||
name={`fillingPercentageRecycler${(it + 1) * 2 - 1}`}
|
||||
|
|
@ -208,10 +187,8 @@ const FiatBalance = ({ section, min = 0, max = 100, fieldWidth = 80 }) => {
|
|||
</div>
|
||||
</>,
|
||||
<>
|
||||
<div className={classes.row}>
|
||||
<div className="flex w-50 gap-4">
|
||||
<Cashbox
|
||||
labelClassName={classes.cashboxLabel}
|
||||
emptyPartClassName={classes.cashboxEmptyPart}
|
||||
percent={
|
||||
values[`fillingPercentageRecycler${(it + 1) * 2}`] ??
|
||||
data[`recycler${(it + 1) * 2}`]
|
||||
|
|
@ -221,10 +198,8 @@ const FiatBalance = ({ section, min = 0, max = 100, fieldWidth = 80 }) => {
|
|||
omitInnerPercentage
|
||||
cashOut
|
||||
/>
|
||||
<div className={classes.col2}>
|
||||
<TL2 className={classes.title}>
|
||||
Recycler {(it + 1) * 2}
|
||||
</TL2>
|
||||
<div className="w-30">
|
||||
<TL2 className="mt-0">Recycler {(it + 1) * 2}</TL2>
|
||||
<EditableNumber
|
||||
label="Alert me under"
|
||||
name={`fillingPercentageRecycler${(it + 1) * 2}`}
|
||||
|
|
@ -241,7 +216,7 @@ const FiatBalance = ({ section, min = 0, max = 100, fieldWidth = 80 }) => {
|
|||
)}
|
||||
</div>
|
||||
</Form>
|
||||
</>
|
||||
</div>
|
||||
)}
|
||||
</Formik>
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,31 +0,0 @@
|
|||
import { backgroundColor } from 'src/styling/variables'
|
||||
|
||||
export default {
|
||||
wrapper: {
|
||||
display: 'flex'
|
||||
},
|
||||
form: {
|
||||
marginBottom: 36
|
||||
},
|
||||
title: {
|
||||
marginTop: 0
|
||||
},
|
||||
row: {
|
||||
width: 236,
|
||||
display: 'grid',
|
||||
gridTemplateColumns: 'repeat(2,1fr)',
|
||||
gridTemplateRows: '1fr',
|
||||
gridColumnGap: 18,
|
||||
gridRowGap: 0
|
||||
},
|
||||
col2: {
|
||||
width: 136
|
||||
},
|
||||
cashboxLabel: {
|
||||
marginRight: 4,
|
||||
fontSize: 20
|
||||
},
|
||||
cashboxEmptyPart: {
|
||||
backgroundColor: `${backgroundColor}`
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,3 @@
|
|||
import { makeStyles } from '@mui/styles'
|
||||
import Switch from '@mui/material/Switch'
|
||||
import * as R from 'ramda'
|
||||
import React, { useContext } from 'react'
|
||||
|
|
@ -74,12 +73,6 @@ const Row = ({
|
|||
)
|
||||
}
|
||||
|
||||
const useStyles = makeStyles({
|
||||
wizardTable: {
|
||||
width: 930
|
||||
}
|
||||
})
|
||||
|
||||
const Setup = ({ wizard, forceDisable }) => {
|
||||
const {
|
||||
data: rawData,
|
||||
|
|
@ -120,9 +113,8 @@ const Setup = ({ wizard, forceDisable }) => {
|
|||
]
|
||||
|
||||
const widthAdjust = wizard ? 20 : 0
|
||||
const classes = useStyles()
|
||||
return (
|
||||
<Table className={wizard ? classes.wizardTable : null}>
|
||||
<Table className={wizard ? 'w-233' : null}>
|
||||
<THead>
|
||||
<Th width={channelSize - widthAdjust}>Channel</Th>
|
||||
{Object.keys(sizes).map(it => (
|
||||
|
|
|
|||
|
|
@ -1,18 +1,11 @@
|
|||
import { useQuery, useMutation, gql } from "@apollo/client";
|
||||
import { makeStyles } from '@mui/styles'
|
||||
import Switch from '@mui/material/Switch'
|
||||
import { useQuery, useMutation, gql } from '@apollo/client'
|
||||
import React, { memo } from 'react'
|
||||
import { HelpTooltip } from 'src/components/Tooltip'
|
||||
import { H4, P, Label2 } from 'src/components/typography'
|
||||
|
||||
import { BooleanPropertiesTable } from 'src/components/booleanPropertiesTable'
|
||||
import { fromNamespace, toNamespace, namespaces } from 'src/utils/config'
|
||||
|
||||
import { SupportLinkButton } from '../../components/buttons'
|
||||
|
||||
import { global } from './OperatorInfo.styles'
|
||||
|
||||
const useStyles = makeStyles(global)
|
||||
import SwitchRow from './components/SwitchRow.jsx'
|
||||
import Header from './components/Header.jsx'
|
||||
|
||||
const GET_CONFIG = gql`
|
||||
query getData {
|
||||
|
|
@ -26,27 +19,7 @@ const SAVE_CONFIG = gql`
|
|||
}
|
||||
`
|
||||
|
||||
const Row = memo(({ title, disabled = false, checked, save, label }) => {
|
||||
const classes = useStyles()
|
||||
|
||||
return (
|
||||
<div className={classes.switchRow}>
|
||||
<P>{title}</P>
|
||||
<div className={classes.switch}>
|
||||
<Switch
|
||||
disabled={disabled}
|
||||
checked={checked}
|
||||
onChange={event => save && save(event.target.checked)}
|
||||
/>
|
||||
{label && <Label2>{label}</Label2>}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
})
|
||||
|
||||
const CoinATMRadar = memo(({ wizard }) => {
|
||||
const classes = useStyles()
|
||||
|
||||
const { data } = useQuery(GET_CONFIG)
|
||||
|
||||
const [saveConfig] = useMutation(SAVE_CONFIG, {
|
||||
|
|
@ -63,53 +36,34 @@ const CoinATMRadar = memo(({ wizard }) => {
|
|||
if (!coinAtmRadarConfig) return null
|
||||
|
||||
return (
|
||||
<div className={classes.content}>
|
||||
<div>
|
||||
<div className={classes.header}>
|
||||
<H4>Coin ATM Radar share settings</H4>
|
||||
<HelpTooltip width={320}>
|
||||
<P>
|
||||
For details on configuring this panel, please read the relevant
|
||||
knowledgebase article{' '}
|
||||
<a
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
href="https://support.lamassu.is/hc/en-us/articles/360023720472-Coin-ATM-Radar">
|
||||
here
|
||||
</a>
|
||||
.
|
||||
</P>
|
||||
<SupportLinkButton
|
||||
link="https://support.lamassu.is/hc/en-us/articles/360023720472-Coin-ATM-Radar"
|
||||
label="Lamassu Support Article"
|
||||
bottomSpace="1"
|
||||
/>
|
||||
</HelpTooltip>
|
||||
</div>
|
||||
<Row
|
||||
title={'Share information?'}
|
||||
checked={coinAtmRadarConfig.active}
|
||||
save={value => save({ active: value })}
|
||||
label={coinAtmRadarConfig.active ? 'Yes' : 'No'}
|
||||
/>
|
||||
<BooleanPropertiesTable
|
||||
editing={wizard}
|
||||
title="Machine info"
|
||||
data={coinAtmRadarConfig}
|
||||
elements={[
|
||||
{
|
||||
name: 'commissions',
|
||||
display: 'Commissions'
|
||||
},
|
||||
{
|
||||
name: 'limitsAndVerification',
|
||||
display: 'Limits and verification'
|
||||
}
|
||||
]}
|
||||
save={save}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<>
|
||||
<Header
|
||||
title="Coin ATM Radar share settings"
|
||||
articleUrl="https://support.lamassu.is/hc/en-us/articles/360023720472-Coin-ATM-Radar"
|
||||
tooltipText="For details on configuring this panel, please read the relevant knowledgebase article."
|
||||
/>
|
||||
<SwitchRow
|
||||
title={'Share information?'}
|
||||
checked={coinAtmRadarConfig.active}
|
||||
save={value => save({ active: value })}
|
||||
/>
|
||||
<BooleanPropertiesTable
|
||||
editing={wizard}
|
||||
title="Machine info"
|
||||
data={coinAtmRadarConfig}
|
||||
elements={[
|
||||
{
|
||||
name: 'commissions',
|
||||
display: 'Commissions'
|
||||
},
|
||||
{
|
||||
name: 'limitsAndVerification',
|
||||
display: 'Limits and verification'
|
||||
}
|
||||
]}
|
||||
save={save}
|
||||
/>
|
||||
</>
|
||||
)
|
||||
})
|
||||
|
||||
|
|
|
|||
|
|
@ -1,70 +1,37 @@
|
|||
import { useQuery, useMutation, gql } from "@apollo/client";
|
||||
import { makeStyles } from '@mui/styles'
|
||||
import Switch from '@mui/material/Switch'
|
||||
import classnames from 'classnames'
|
||||
import { useQuery, useMutation, gql } from '@apollo/client'
|
||||
import { Form, Formik, Field as FormikField } from 'formik'
|
||||
import * as R from 'ramda'
|
||||
import React, { useState } from 'react'
|
||||
import ErrorMessage from 'src/components/ErrorMessage'
|
||||
import PromptWhenDirty from 'src/components/PromptWhenDirty'
|
||||
import { HelpTooltip } from 'src/components/Tooltip'
|
||||
import { P, H4, Info3, Label1, Label2, Label3 } from 'src/components/typography'
|
||||
import { H4, Info3, Label3 } from 'src/components/typography'
|
||||
import EditIcon from 'src/styling/icons/action/edit/enabled.svg?react'
|
||||
import WarningIcon from 'src/styling/icons/warning-icon/comet.svg?react'
|
||||
import * as Yup from 'yup'
|
||||
|
||||
import { Link, IconButton, SupportLinkButton } from 'src/components/buttons'
|
||||
import { Link, IconButton } from 'src/components/buttons'
|
||||
import { TextInput } from 'src/components/inputs/formik'
|
||||
import { fontSize5 } from 'src/styling/variables'
|
||||
import { fromNamespace, toNamespace, namespaces } from 'src/utils/config'
|
||||
|
||||
import { global } from './OperatorInfo.styles'
|
||||
import SwitchRow from './components/SwitchRow.jsx'
|
||||
import InfoMessage from './components/InfoMessage.jsx'
|
||||
import Header from './components/Header.jsx'
|
||||
|
||||
const FIELD_WIDTH = 280
|
||||
|
||||
const fieldStyles = {
|
||||
field: {
|
||||
position: 'relative',
|
||||
width: 280,
|
||||
height: 48,
|
||||
padding: [[0, 4, 4, 0]]
|
||||
},
|
||||
notEditing: {
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
'& > p:first-child': {
|
||||
height: 16,
|
||||
lineHeight: '16px',
|
||||
fontSize: fontSize5,
|
||||
transformOrigin: 'left',
|
||||
paddingLeft: 0,
|
||||
margin: [[3, 0, 3, 0]]
|
||||
},
|
||||
'& > p:last-child': {
|
||||
overflow: 'hidden',
|
||||
whiteSpace: 'nowrap',
|
||||
textOverflow: 'ellipsis',
|
||||
margin: 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const fieldUseStyles = makeStyles(fieldStyles)
|
||||
|
||||
const Field = ({ editing, field, displayValue, ...props }) => {
|
||||
const classes = fieldUseStyles()
|
||||
|
||||
const classNames = {
|
||||
[classes.field]: true,
|
||||
[classes.notEditing]: !editing
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={classnames(classNames)}>
|
||||
<div className="w-70 h-12 p-0 pl-1 pb-1">
|
||||
{!editing && (
|
||||
<>
|
||||
<Label3>{field.label}</Label3>
|
||||
<Info3>{displayValue(field.value)}</Info3>
|
||||
<Label3 noMargin className="h-4 text-[13px] my-[3px]">
|
||||
{field.label}
|
||||
</Label3>
|
||||
<Info3
|
||||
noMargin
|
||||
className="overflow-hidden whitespace-nowrap text-ellipsis">
|
||||
{displayValue(field.value)}
|
||||
</Info3>
|
||||
</>
|
||||
)}
|
||||
{editing && (
|
||||
|
|
@ -95,11 +62,7 @@ const SAVE_CONFIG = gql`
|
|||
}
|
||||
`
|
||||
|
||||
const contactUseStyles = makeStyles(global)
|
||||
|
||||
const ContactInfo = ({ wizard }) => {
|
||||
const classes = contactUseStyles()
|
||||
|
||||
const [editing, setEditing] = useState(wizard || false)
|
||||
const [error, setError] = useState(null)
|
||||
|
||||
|
|
@ -187,42 +150,17 @@ const ContactInfo = ({ wizard }) => {
|
|||
|
||||
return (
|
||||
<>
|
||||
<div className={classes.header}>
|
||||
<H4>Contact information</H4>
|
||||
<HelpTooltip width={320}>
|
||||
<P>
|
||||
For details on configuring this panel, please read the relevant
|
||||
knowledgebase article:
|
||||
</P>
|
||||
<SupportLinkButton
|
||||
link="https://support.lamassu.is/hc/en-us/articles/360033051732-Enabling-Operator-Info"
|
||||
label="Lamassu Support Article"
|
||||
bottomSpace="1"
|
||||
/>
|
||||
</HelpTooltip>
|
||||
</div>
|
||||
<div className={classes.switchRow}>
|
||||
<P>Info card enabled?</P>
|
||||
<div className={classes.switch}>
|
||||
<Switch
|
||||
checked={info.active}
|
||||
onChange={event =>
|
||||
save({
|
||||
active: event.target.checked
|
||||
})
|
||||
}
|
||||
/>
|
||||
<Label2>{info.active ? 'Yes' : 'No'}</Label2>
|
||||
</div>
|
||||
</div>
|
||||
<div className={classes.section}>
|
||||
<div className={classes.header}>
|
||||
<Header
|
||||
title="Contact information"
|
||||
articleUrl="https://support.lamassu.is/hc/en-us/articles/360033051732-Enabling-Operator-Info"
|
||||
tooltipText="For details on configuring this panel, please read the relevant knowledgebase article:"
|
||||
/>
|
||||
<SwitchRow checked={info.active} save={save} title="Info card enabled?" />
|
||||
<div>
|
||||
<div className="flex items-center gap-4">
|
||||
<H4>Info card</H4>
|
||||
{!editing && (
|
||||
<IconButton
|
||||
className={classes.transparentButton}
|
||||
onClick={() => setEditing(true)}
|
||||
size="large">
|
||||
<IconButton onClick={() => setEditing(true)} size="large">
|
||||
<EditIcon />
|
||||
</IconButton>
|
||||
)}
|
||||
|
|
@ -239,9 +177,9 @@ const ContactInfo = ({ wizard }) => {
|
|||
setError(null)
|
||||
}}>
|
||||
{({ errors }) => (
|
||||
<Form>
|
||||
<Form className="flex flex-col gap-7 w-147">
|
||||
<PromptWhenDirty />
|
||||
<div className={classes.row}>
|
||||
<div className="flex gap-6 justify-between">
|
||||
<Field
|
||||
field={findField('name')}
|
||||
editing={editing}
|
||||
|
|
@ -255,7 +193,7 @@ const ContactInfo = ({ wizard }) => {
|
|||
onFocus={() => setError(null)}
|
||||
/>
|
||||
</div>
|
||||
<div className={classes.row}>
|
||||
<div className="flex gap-6">
|
||||
<Field
|
||||
field={findField('email')}
|
||||
editing={editing}
|
||||
|
|
@ -269,7 +207,7 @@ const ContactInfo = ({ wizard }) => {
|
|||
onFocus={() => setError(null)}
|
||||
/>
|
||||
</div>
|
||||
<div className={classes.row}>
|
||||
<div className="flex gap-6">
|
||||
<Field
|
||||
field={findField('companyNumber')}
|
||||
editing={editing}
|
||||
|
|
@ -278,41 +216,34 @@ const ContactInfo = ({ wizard }) => {
|
|||
/>
|
||||
</div>
|
||||
{editing && !!getErrorMsg(errors) && (
|
||||
<ErrorMessage className={classes.formErrorMsg}>
|
||||
{getErrorMsg(errors)}
|
||||
</ErrorMessage>
|
||||
<ErrorMessage>{getErrorMsg(errors)}</ErrorMessage>
|
||||
)}
|
||||
{editing && (
|
||||
<div className="flex gap-10">
|
||||
<Link color="primary" type="submit">
|
||||
Save
|
||||
</Link>
|
||||
<Link color="secondary" type="reset">
|
||||
Cancel
|
||||
</Link>
|
||||
{error && <ErrorMessage>Failed to save changes</ErrorMessage>}
|
||||
</div>
|
||||
)}
|
||||
<div className={classnames(classes.row, classes.submit)}>
|
||||
{editing && (
|
||||
<>
|
||||
<Link color="primary" type="submit">
|
||||
Save
|
||||
</Link>
|
||||
<Link color="secondary" type="reset">
|
||||
Cancel
|
||||
</Link>
|
||||
{error && (
|
||||
<ErrorMessage>Failed to save changes</ErrorMessage>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</Form>
|
||||
)}
|
||||
</Formik>
|
||||
</div>
|
||||
{!wizard && (
|
||||
<div className={classnames(classes.section, classes.infoMessage)}>
|
||||
<WarningIcon />
|
||||
<Label1>
|
||||
<>
|
||||
<InfoMessage Icon={WarningIcon}>
|
||||
Sharing your information with your customers through your machines
|
||||
allows them to contact you in case there's a problem with a machine
|
||||
in your network or a transaction.
|
||||
</Label1>
|
||||
</div>
|
||||
</InfoMessage>
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
)
|
||||
}
|
||||
|
||||
export default ContactInfo
|
||||
|
|
|
|||
|
|
@ -1,15 +1,11 @@
|
|||
import { useQuery, useMutation, gql } from "@apollo/client";
|
||||
import { makeStyles } from '@mui/styles'
|
||||
import Switch from '@mui/material/Switch'
|
||||
import { useQuery, useMutation, gql } from '@apollo/client'
|
||||
import * as R from 'ramda'
|
||||
import React, { memo } from 'react'
|
||||
import { H4, P, Label2 } from 'src/components/typography'
|
||||
import { H4 } from 'src/components/typography'
|
||||
|
||||
import { fromNamespace, toNamespace, namespaces } from 'src/utils/config'
|
||||
|
||||
import { global } from './OperatorInfo.styles'
|
||||
|
||||
const useStyles = makeStyles(global)
|
||||
import SwitchRow from './components/SwitchRow.jsx'
|
||||
|
||||
const GET_CONFIG = gql`
|
||||
query getData {
|
||||
|
|
@ -24,14 +20,26 @@ const SAVE_CONFIG = gql`
|
|||
`
|
||||
|
||||
const MachineScreens = memo(({ wizard }) => {
|
||||
const classes = useStyles()
|
||||
|
||||
const { data } = useQuery(GET_CONFIG)
|
||||
|
||||
const [saveConfig] = useMutation(SAVE_CONFIG, {
|
||||
refetchQueries: () => ['getData']
|
||||
})
|
||||
|
||||
const save = it => {
|
||||
const formatConfig = R.compose(
|
||||
toNamespace(namespaces.MACHINE_SCREENS),
|
||||
toNamespace('rates'),
|
||||
R.mergeRight(ratesScreenConfig)
|
||||
)
|
||||
|
||||
return saveConfig({
|
||||
variables: {
|
||||
config: formatConfig({ active: it })
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const machineScreensConfig =
|
||||
data?.config && fromNamespace(namespaces.MACHINE_SCREENS, data.config)
|
||||
|
||||
|
|
@ -46,32 +54,12 @@ const MachineScreens = memo(({ wizard }) => {
|
|||
|
||||
return (
|
||||
<>
|
||||
<div className={classes.header}>
|
||||
<H4>Rates screen</H4>
|
||||
</div>
|
||||
<div className={classes.switchRow}>
|
||||
<P>Enable rates screen</P>
|
||||
<div className={classes.switch}>
|
||||
<Switch
|
||||
checked={ratesScreenConfig.active}
|
||||
onChange={event =>
|
||||
saveConfig({
|
||||
variables: {
|
||||
config: R.compose(
|
||||
toNamespace(namespaces.MACHINE_SCREENS),
|
||||
toNamespace('rates')
|
||||
)(
|
||||
R.merge(ratesScreenConfig, {
|
||||
active: event.target.checked
|
||||
})
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
/>
|
||||
<Label2>{ratesScreenConfig.active ? 'Yes' : 'No'}</Label2>
|
||||
</div>
|
||||
</div>
|
||||
<H4>Rates screen</H4>
|
||||
<SwitchRow
|
||||
save={save}
|
||||
title="Enable rates screen"
|
||||
checked={ratesScreenConfig.active}
|
||||
/>
|
||||
</>
|
||||
)
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,118 +0,0 @@
|
|||
import { offColor } from 'src/styling/variables'
|
||||
|
||||
const global = {
|
||||
content: {
|
||||
display: 'flex'
|
||||
},
|
||||
header: {
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
position: 'relative',
|
||||
flex: 'wrap'
|
||||
},
|
||||
section: {
|
||||
marginBottom: 52
|
||||
},
|
||||
row: {
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'space-between',
|
||||
marginBottom: 28,
|
||||
width: 600,
|
||||
'&:last-child': {
|
||||
marginBottom: 0
|
||||
}
|
||||
},
|
||||
switchRow: {
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
position: 'relative',
|
||||
flex: 'wrap',
|
||||
justifyContent: 'space-between',
|
||||
width: 396
|
||||
},
|
||||
switch: {
|
||||
display: 'flex',
|
||||
alignItems: 'center'
|
||||
},
|
||||
submit: {
|
||||
justifyContent: 'flex-start',
|
||||
alignItems: 'center',
|
||||
padding: [[0, 4, 4, 4]],
|
||||
'& > button': {
|
||||
marginRight: 40
|
||||
}
|
||||
},
|
||||
transparentButton: {
|
||||
'& > *': {
|
||||
margin: 'auto 12px'
|
||||
},
|
||||
'& button': {
|
||||
border: 'none',
|
||||
backgroundColor: 'transparent',
|
||||
cursor: 'pointer'
|
||||
}
|
||||
},
|
||||
infoMessage: {
|
||||
display: 'flex',
|
||||
marginBottom: 52,
|
||||
'& > p': {
|
||||
width: 330,
|
||||
color: offColor,
|
||||
marginTop: 4,
|
||||
marginLeft: 16
|
||||
}
|
||||
},
|
||||
formErrorMsg: {
|
||||
margin: [[0, 0, 20, 0]]
|
||||
}
|
||||
}
|
||||
|
||||
const fieldStyles = {
|
||||
field: {
|
||||
position: 'relative',
|
||||
width: 280,
|
||||
padding: [[0, 4, 4, 0]]
|
||||
},
|
||||
notEditing: {
|
||||
display: 'flex',
|
||||
flexDirection: 'column'
|
||||
},
|
||||
notEditingSingleLine: {
|
||||
'& > p:first-child': {
|
||||
height: 16,
|
||||
lineHeight: '16px',
|
||||
transform: 'scale(0.75)',
|
||||
transformOrigin: 'left',
|
||||
paddingLeft: 0,
|
||||
margin: [[1, 0, 6, 0]]
|
||||
},
|
||||
'& > p:last-child': {
|
||||
overflow: 'hidden',
|
||||
whiteSpace: 'nowrap',
|
||||
textOverflow: 'ellipsis',
|
||||
height: 25,
|
||||
margin: 0
|
||||
}
|
||||
},
|
||||
notEditingMultiline: {
|
||||
'& > p:first-child': {
|
||||
height: 16,
|
||||
lineHeight: '16px',
|
||||
transform: 'scale(0.75)',
|
||||
transformOrigin: 'left',
|
||||
paddingLeft: 0,
|
||||
margin: [[1, 0, 5, 0]]
|
||||
},
|
||||
'& > p:last-child': {
|
||||
width: 502,
|
||||
height: 121,
|
||||
overflowY: 'auto',
|
||||
lineHeight: '19px',
|
||||
wordWrap: 'anywhere',
|
||||
margin: 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export { global, fieldStyles }
|
||||
|
|
@ -1,19 +1,12 @@
|
|||
import { useQuery, useMutation, gql } from "@apollo/client";
|
||||
import { makeStyles } from '@mui/styles'
|
||||
import Switch from '@mui/material/Switch'
|
||||
import { useQuery, useMutation, gql } from '@apollo/client'
|
||||
import * as R from 'ramda'
|
||||
import React, { memo } from 'react'
|
||||
import { HelpTooltip } from 'src/components/Tooltip'
|
||||
import { H4, P, Label2 } from 'src/components/typography'
|
||||
|
||||
import { BooleanPropertiesTable } from 'src/components/booleanPropertiesTable'
|
||||
import { fromNamespace, toNamespace, namespaces } from 'src/utils/config'
|
||||
|
||||
import { SupportLinkButton } from '../../components/buttons'
|
||||
|
||||
import { global } from './OperatorInfo.styles'
|
||||
|
||||
const useStyles = makeStyles(global)
|
||||
import Header from './components/Header.jsx'
|
||||
import SwitchRow from './components/SwitchRow.jsx'
|
||||
|
||||
const GET_CONFIG = gql`
|
||||
query getData {
|
||||
|
|
@ -28,14 +21,23 @@ const SAVE_CONFIG = gql`
|
|||
`
|
||||
|
||||
const ReceiptPrinting = memo(({ wizard }) => {
|
||||
const classes = useStyles()
|
||||
|
||||
const { data } = useQuery(GET_CONFIG)
|
||||
|
||||
const [saveConfig] = useMutation(SAVE_CONFIG, {
|
||||
refetchQueries: () => ['getData']
|
||||
})
|
||||
|
||||
const saveSwitch = object => {
|
||||
return saveConfig({
|
||||
variables: {
|
||||
config: toNamespace(
|
||||
namespaces.RECEIPT,
|
||||
R.mergeRight(receiptPrintingConfig, object)
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const save = it =>
|
||||
saveConfig({
|
||||
variables: { config: toNamespace(namespaces.RECEIPT, it) }
|
||||
|
|
@ -47,84 +49,26 @@ const ReceiptPrinting = memo(({ wizard }) => {
|
|||
|
||||
return (
|
||||
<>
|
||||
<div className={classes.header}>
|
||||
<H4>Receipt options</H4>
|
||||
<HelpTooltip width={320}>
|
||||
<P>
|
||||
For details on configuring this panel, please read the relevant
|
||||
knowledgebase article:
|
||||
</P>
|
||||
<SupportLinkButton
|
||||
link="https://support.lamassu.is/hc/en-us/articles/360058513951-Receipt-options-printers"
|
||||
label="Lamassu Support Article"
|
||||
bottomSpace="1"
|
||||
/>
|
||||
</HelpTooltip>
|
||||
</div>
|
||||
<div className={classes.switchRow}>
|
||||
<P>Enable receipt printing</P>
|
||||
<div className={classes.switch}>
|
||||
<Switch
|
||||
checked={receiptPrintingConfig.active}
|
||||
onChange={event =>
|
||||
saveConfig({
|
||||
variables: {
|
||||
config: toNamespace(
|
||||
namespaces.RECEIPT,
|
||||
R.merge(receiptPrintingConfig, {
|
||||
active: event.target.checked
|
||||
})
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
/>
|
||||
<Label2>{receiptPrintingConfig.active ? 'Yes' : 'No'}</Label2>
|
||||
</div>
|
||||
</div>
|
||||
<div className={classes.switchRow}>
|
||||
<P>Automatic receipt printing</P>
|
||||
<div className={classes.switch}>
|
||||
<Switch
|
||||
disabled={!receiptPrintingConfig.active}
|
||||
checked={receiptPrintingConfig.automaticPrint}
|
||||
onChange={event =>
|
||||
saveConfig({
|
||||
variables: {
|
||||
config: toNamespace(
|
||||
namespaces.RECEIPT,
|
||||
R.merge(receiptPrintingConfig, {
|
||||
automaticPrint: event.target.checked
|
||||
})
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
/>
|
||||
<Label2>{receiptPrintingConfig.automaticPrint ? 'Yes' : 'No'}</Label2>
|
||||
</div>
|
||||
</div>
|
||||
<div className={classes.switchRow}>
|
||||
<P>Offer SMS receipt</P>
|
||||
<div className={classes.switch}>
|
||||
<Switch
|
||||
checked={receiptPrintingConfig.sms}
|
||||
onChange={event =>
|
||||
saveConfig({
|
||||
variables: {
|
||||
config: toNamespace(
|
||||
namespaces.RECEIPT,
|
||||
R.merge(receiptPrintingConfig, {
|
||||
sms: event.target.checked
|
||||
})
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
/>
|
||||
<Label2>{receiptPrintingConfig.sms ? 'Yes' : 'No'}</Label2>
|
||||
</div>
|
||||
</div>
|
||||
<Header
|
||||
title="Receipt printing"
|
||||
tooltipText="For details on configuring this panel, please read the relevant knowledgebase article."
|
||||
articleUrl="https://support.lamassu.is/hc/en-us/articles/360058513951-Receipt-options-printers"
|
||||
/>
|
||||
<SwitchRow
|
||||
title="Enable receipt printing"
|
||||
checked={receiptPrintingConfig.active}
|
||||
save={it => saveSwitch({ active: it })}
|
||||
/>
|
||||
<SwitchRow
|
||||
title="Automatic receipt printing"
|
||||
checked={receiptPrintingConfig.automaticPrint}
|
||||
save={it => saveSwitch({ automaticPrint: it })}
|
||||
/>
|
||||
<SwitchRow
|
||||
title="Offer SMS receipt"
|
||||
checked={receiptPrintingConfig.sms}
|
||||
save={it => saveSwitch({ sms: it })}
|
||||
/>
|
||||
<BooleanPropertiesTable
|
||||
editing={wizard}
|
||||
title={'Visible on the receipt (options)'}
|
||||
|
|
|
|||
|
|
@ -1,24 +1,20 @@
|
|||
import { useQuery, useMutation, gql } from "@apollo/client";
|
||||
import { makeStyles } from '@mui/styles'
|
||||
import Switch from '@mui/material/Switch'
|
||||
import { useQuery, useMutation, gql } from '@apollo/client'
|
||||
import classnames from 'classnames'
|
||||
import { Form, Formik, Field as FormikField } from 'formik'
|
||||
import * as R from 'ramda'
|
||||
import React, { useState } from 'react'
|
||||
import ErrorMessage from 'src/components/ErrorMessage'
|
||||
import PromptWhenDirty from 'src/components/PromptWhenDirty'
|
||||
import { HelpTooltip } from 'src/components/Tooltip'
|
||||
import { H4, Info2, Info3, Label2, Label3, P } from 'src/components/typography'
|
||||
import { Info2, Info3, Label3 } from 'src/components/typography'
|
||||
import EditIcon from 'src/styling/icons/action/edit/enabled.svg?react'
|
||||
import * as Yup from 'yup'
|
||||
|
||||
import { Link, IconButton, SupportLinkButton } from 'src/components/buttons'
|
||||
import { Link, IconButton } from 'src/components/buttons'
|
||||
import { TextInput } from 'src/components/inputs/formik'
|
||||
import { fromNamespace, toNamespace, namespaces } from 'src/utils/config'
|
||||
|
||||
import { global, fieldStyles } from './OperatorInfo.styles'
|
||||
|
||||
const useFieldStyles = makeStyles(fieldStyles)
|
||||
import Header from './components/Header.jsx'
|
||||
import SwitchRow from './components/SwitchRow.jsx'
|
||||
|
||||
const Field = ({
|
||||
editing,
|
||||
|
|
@ -32,21 +28,21 @@ const Field = ({
|
|||
onFocus,
|
||||
...props
|
||||
}) => {
|
||||
const classes = useFieldStyles()
|
||||
|
||||
const classNames = {
|
||||
[classes.field]: true,
|
||||
[classes.notEditing]: !editing,
|
||||
[classes.notEditingSingleLine]: !editing && !multiline,
|
||||
[classes.notEditingMultiline]: !editing && multiline
|
||||
const info3ClassNames = {
|
||||
'overflow-hidden whitespace-nowrap text-ellipsis h-6': !multiline,
|
||||
'wrap-anywhere overflow-y-auto h-32 mt-4 leading-[23px]': multiline
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={classnames(classNames)}>
|
||||
<div className={`w-125 p-0 pl-1 pb-1`}>
|
||||
{!editing && (
|
||||
<>
|
||||
<Label3>{label}</Label3>
|
||||
<Info3>{value}</Info3>
|
||||
<Label3 noMargin className="h-4 text-[13px] my-[3px] mb-1">
|
||||
{label}
|
||||
</Label3>
|
||||
<Info3 noMargin className={classnames(info3ClassNames)}>
|
||||
{value}
|
||||
</Info3>
|
||||
</>
|
||||
)}
|
||||
{editing && (
|
||||
|
|
@ -81,8 +77,6 @@ const SAVE_CONFIG = gql`
|
|||
}
|
||||
`
|
||||
|
||||
const useTermsConditionsStyles = makeStyles(global)
|
||||
|
||||
const TermsConditions = () => {
|
||||
const [error, setError] = useState(null)
|
||||
const [editing, setEditing] = useState(false)
|
||||
|
|
@ -95,8 +89,6 @@ const TermsConditions = () => {
|
|||
onError: e => setError(e)
|
||||
})
|
||||
|
||||
const classes = useTermsConditionsStyles()
|
||||
|
||||
const { data } = useQuery(GET_CONFIG)
|
||||
|
||||
const termsAndConditions =
|
||||
|
|
@ -169,72 +161,30 @@ const TermsConditions = () => {
|
|||
|
||||
return (
|
||||
<>
|
||||
<div className={classes.header}>
|
||||
<H4>Terms & Conditions</H4>
|
||||
<HelpTooltip width={320}>
|
||||
<P>
|
||||
For details on configuring this panel, please read the relevant
|
||||
knowledgebase article:
|
||||
</P>
|
||||
<SupportLinkButton
|
||||
link="https://support.lamassu.is/hc/en-us/articles/360015982211-Terms-and-Conditions"
|
||||
label="Lamassu Support Article"
|
||||
bottomSpace="1"
|
||||
/>
|
||||
</HelpTooltip>
|
||||
</div>
|
||||
<div className={classes.switchRow}>
|
||||
<P>Show on screen</P>
|
||||
<div className={classes.switch}>
|
||||
<Switch
|
||||
checked={showOnScreen}
|
||||
onChange={event =>
|
||||
save({
|
||||
active: event.target.checked
|
||||
})
|
||||
}
|
||||
/>
|
||||
<Label2>{showOnScreen ? 'Yes' : 'No'}</Label2>
|
||||
</div>
|
||||
</div>
|
||||
<div className={classes.switchRow}>
|
||||
<P>
|
||||
Capture customer photo on acceptance <br /> of Terms & Conditions
|
||||
screen
|
||||
</P>
|
||||
<div className={classes.switch}>
|
||||
<Switch
|
||||
checked={tcPhoto}
|
||||
onChange={event =>
|
||||
save({
|
||||
tcPhoto: event.target.checked
|
||||
})
|
||||
}
|
||||
/>
|
||||
<Label2>{tcPhoto ? 'Yes' : 'No'}</Label2>
|
||||
</div>
|
||||
</div>
|
||||
<div className={classes.switchRow}>
|
||||
<P>Add 7 seconds delay on screen</P>
|
||||
<div className={classes.switch}>
|
||||
<Switch
|
||||
checked={addDelayOnScreen}
|
||||
onChange={event =>
|
||||
save({
|
||||
delay: event.target.checked
|
||||
})
|
||||
}
|
||||
/>
|
||||
<Label2>{addDelayOnScreen ? 'Yes' : 'No'}</Label2>
|
||||
</div>
|
||||
</div>
|
||||
<div className={classes.header}>
|
||||
<Header
|
||||
title="Terms & Conditions"
|
||||
tooltipText="For details on configuring this panel, please read the relevant knowledgebase article:"
|
||||
articleUrl="https://support.lamassu.is/hc/en-us/articles/360015982211-Terms-and-Conditions"
|
||||
/>
|
||||
<SwitchRow
|
||||
title="Show on screen"
|
||||
checked={showOnScreen}
|
||||
save={it => save({ active: it })}
|
||||
/>
|
||||
<SwitchRow
|
||||
title="Capture customer photo on acceptance of Terms & Conditions"
|
||||
checked={tcPhoto}
|
||||
save={it => save({ tcPhoto: it })}
|
||||
/>
|
||||
<SwitchRow
|
||||
title="Add 7 seconds delay on screen"
|
||||
checked={addDelayOnScreen}
|
||||
save={it => save({ delay: it })}
|
||||
/>
|
||||
<div className="flex gap-3">
|
||||
<Info2>Info card</Info2>
|
||||
{!editing && (
|
||||
<IconButton
|
||||
className={classes.transparentButton}
|
||||
onClick={() => setEditing(true)}
|
||||
size="large">
|
||||
<IconButton onClick={() => setEditing(true)} size="large">
|
||||
<EditIcon />
|
||||
</IconButton>
|
||||
)}
|
||||
|
|
@ -251,10 +201,10 @@ const TermsConditions = () => {
|
|||
setError(null)
|
||||
}}>
|
||||
{({ errors }) => (
|
||||
<Form>
|
||||
<Form className="flex flex-col gap-6">
|
||||
<PromptWhenDirty />
|
||||
{fields.map((f, idx) => (
|
||||
<div className={classes.row} key={idx}>
|
||||
<div className="flex gap-7" key={idx}>
|
||||
<Field
|
||||
editing={editing}
|
||||
name={f.name}
|
||||
|
|
@ -268,7 +218,7 @@ const TermsConditions = () => {
|
|||
/>
|
||||
</div>
|
||||
))}
|
||||
<div className={classnames(classes.row, classes.submit)}>
|
||||
<div className="flex gap-10">
|
||||
{editing && (
|
||||
<>
|
||||
<Link color="primary" type="submit">
|
||||
|
|
@ -288,7 +238,7 @@ const TermsConditions = () => {
|
|||
)}
|
||||
</Formik>
|
||||
</>
|
||||
);
|
||||
)
|
||||
}
|
||||
|
||||
export default TermsConditions
|
||||
|
|
|
|||
|
|
@ -0,0 +1,20 @@
|
|||
import React from 'react'
|
||||
import { H4, P } from 'src/components/typography/index.jsx'
|
||||
import { HelpTooltip } from 'src/components/Tooltip.jsx'
|
||||
import { SupportLinkButton } from 'src/components/buttons/index.js'
|
||||
|
||||
const Header = ({ title, tooltipText, articleUrl }) => (
|
||||
<div className="flex items-center">
|
||||
<H4>{title}</H4>
|
||||
<HelpTooltip width={320}>
|
||||
<P>{tooltipText}</P>
|
||||
<SupportLinkButton
|
||||
link={articleUrl}
|
||||
label="Lamassu Support Article"
|
||||
bottomSpace="1"
|
||||
/>
|
||||
</HelpTooltip>
|
||||
</div>
|
||||
)
|
||||
|
||||
export default Header
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
import React from 'react'
|
||||
|
||||
import { Label1 } from 'src/components/typography'
|
||||
|
||||
const InfoMessage = ({ Icon, children }) => (
|
||||
<div className="flex my-13 gap-4">
|
||||
<Icon />
|
||||
<Label1 className="w-83 text-comet mt-1">{children}</Label1>
|
||||
</div>
|
||||
)
|
||||
|
||||
export default InfoMessage
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
import React, { memo } from 'react'
|
||||
import { Label2, P } from 'src/components/typography/index.jsx'
|
||||
import Switch from '@mui/material/Switch'
|
||||
|
||||
const SwitchRow = memo(({ title, disabled = false, checked, save }) => {
|
||||
return (
|
||||
<div className="flex justify-between w-99">
|
||||
<P>{title}</P>
|
||||
<div className="flex items-center">
|
||||
<Switch
|
||||
disabled={disabled}
|
||||
checked={checked}
|
||||
onChange={event => save && save(event.target.checked)}
|
||||
/>
|
||||
<Label2>{checked ? 'Yes' : 'No'}</Label2>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
})
|
||||
|
||||
export default SwitchRow
|
||||
|
|
@ -1,5 +1,3 @@
|
|||
import Grid from '@mui/material/Grid'
|
||||
import { makeStyles } from '@mui/styles'
|
||||
import classnames from 'classnames'
|
||||
import { Formik, Form, FastField } from 'formik'
|
||||
import * as R from 'ramda'
|
||||
|
|
@ -8,29 +6,7 @@ import ErrorMessage from 'src/components/ErrorMessage'
|
|||
|
||||
import { Button } from 'src/components/buttons'
|
||||
import { SecretInput } from 'src/components/inputs/formik'
|
||||
import { spacer } from 'src/styling/variables'
|
||||
|
||||
const styles = {
|
||||
footer: {
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
margin: [['auto', 0, spacer * 4, 0]]
|
||||
},
|
||||
button: {
|
||||
margin: [['auto', 0, 0, 'auto']]
|
||||
},
|
||||
form: {
|
||||
flex: 1,
|
||||
display: 'flex',
|
||||
flexDirection: 'column'
|
||||
},
|
||||
grid: {
|
||||
marginBottom: 24,
|
||||
marginTop: 12
|
||||
}
|
||||
}
|
||||
|
||||
const useStyles = makeStyles(styles)
|
||||
const FormRenderer = ({
|
||||
validationSchema,
|
||||
elements,
|
||||
|
|
@ -40,8 +16,6 @@ const FormRenderer = ({
|
|||
buttonClass,
|
||||
xs = 12
|
||||
}) => {
|
||||
const classes = useStyles()
|
||||
|
||||
const initialValues = R.compose(
|
||||
R.mergeAll,
|
||||
R.map(({ code }) => ({ [code]: (value && value[code]) ?? '' }))
|
||||
|
|
@ -74,11 +48,11 @@ const FormRenderer = ({
|
|||
validationSchema={validationSchema}
|
||||
onSubmit={saveNonEmptySecret}>
|
||||
{({ errors }) => (
|
||||
<Form className={classes.form}>
|
||||
<Grid container spacing={3} className={classes.grid}>
|
||||
<Form className="flex flex-col flex-1">
|
||||
<div className="flex flex-col gap-3 mb-6 mt-3">
|
||||
{elements.map(
|
||||
({ component, code, display, settings, inputProps }) => (
|
||||
<Grid item xs={xs} key={code}>
|
||||
<div key={code}>
|
||||
<FastField
|
||||
component={component}
|
||||
{...inputProps}
|
||||
|
|
@ -87,18 +61,18 @@ const FormRenderer = ({
|
|||
settings={settings}
|
||||
fullWidth={true}
|
||||
/>
|
||||
</Grid>
|
||||
</div>
|
||||
)
|
||||
)}
|
||||
</Grid>
|
||||
<div className={classes.footer}>
|
||||
</div>
|
||||
<div className="flex flex-row mt-auto mb-8">
|
||||
{!R.isEmpty(R.mergeRight(errors, saveError)) && (
|
||||
<ErrorMessage>
|
||||
{R.head(R.values(R.mergeRight(errors, saveError)))}
|
||||
</ErrorMessage>
|
||||
)}
|
||||
<Button
|
||||
className={classnames(classes.button, buttonClass)}
|
||||
className={classnames('mt-auto ml-auto', buttonClass)}
|
||||
type="submit">
|
||||
{buttonLabel}
|
||||
</Button>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,4 @@
|
|||
import { useQuery, useMutation, gql } from "@apollo/client";
|
||||
import Grid from '@mui/material/Grid'
|
||||
import { makeStyles } from '@mui/styles'
|
||||
import { useQuery, useMutation, gql } from '@apollo/client'
|
||||
import * as R from 'ramda'
|
||||
import React, { useState } from 'react'
|
||||
import Modal from 'src/components/Modal'
|
||||
|
|
@ -33,16 +31,6 @@ const SAVE_ACCOUNT = gql`
|
|||
}
|
||||
`
|
||||
|
||||
const styles = {
|
||||
wrapper: {
|
||||
// widths + spacing is a little over 1200 on the design
|
||||
// this adjusts the margin after a small reduction on card size
|
||||
marginLeft: 1
|
||||
}
|
||||
}
|
||||
|
||||
const useStyles = makeStyles(styles)
|
||||
|
||||
const Services = () => {
|
||||
const [editingSchema, setEditingSchema] = useState(null)
|
||||
|
||||
|
|
@ -57,8 +45,6 @@ const Services = () => {
|
|||
|
||||
const schemas = _schemas(markets)
|
||||
|
||||
const classes = useStyles()
|
||||
|
||||
const accounts = data?.accounts ?? {}
|
||||
|
||||
const getItems = (code, elements) => {
|
||||
|
|
@ -116,20 +102,19 @@ const Services = () => {
|
|||
|
||||
return (
|
||||
!loading && (
|
||||
<div className={classes.wrapper}>
|
||||
<div>
|
||||
<TitleSection title="Third-Party services" />
|
||||
<Grid container spacing={4}>
|
||||
<div className="grid grid-cols-3 gap-5">
|
||||
{R.values(schemas).map(schema => (
|
||||
<Grid item key={schema.code}>
|
||||
<SingleRowTable
|
||||
editMessage={'Configure ' + schema.title}
|
||||
title={schema.title}
|
||||
onEdit={() => setEditingSchema(schema)}
|
||||
items={getItems(schema.code, schema.elements)}
|
||||
/>
|
||||
</Grid>
|
||||
<SingleRowTable
|
||||
key={schema.code}
|
||||
editMessage={'Configure ' + schema.title}
|
||||
title={schema.title}
|
||||
onEdit={() => setEditingSchema(schema)}
|
||||
items={getItems(schema.code, schema.elements)}
|
||||
/>
|
||||
))}
|
||||
</Grid>
|
||||
</div>
|
||||
{editingSchema && (
|
||||
<Modal
|
||||
title={`Edit ${editingSchema.name}`}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue