chore: reformat code

This commit is contained in:
Rafael Taranto 2025-05-12 14:49:39 +01:00
parent 3d930aa73b
commit aedabcbdee
509 changed files with 6030 additions and 4266 deletions

View file

@ -1,5 +1,5 @@
{
"trailingComma": "none",
"trailingComma": "all",
"tabWidth": 2,
"semi": false,
"singleQuote": true,

View file

@ -2,7 +2,6 @@ import js from '@eslint/js'
import globals from 'globals'
import pluginReact from 'eslint-plugin-react'
import json from '@eslint/json'
import css from '@eslint/css'
import { defineConfig, globalIgnores } from 'eslint/config'
import reactCompiler from 'eslint-plugin-react-compiler'
import eslintConfigPrettier from 'eslint-config-prettier/flat'
@ -16,7 +15,13 @@ export default defineConfig([
},
{
files: ['packages/admin-ui/**/*.{js,mjs,jsx}'],
languageOptions: { sourceType: 'module', globals: globals.browser }
languageOptions: {
sourceType: 'module',
globals: {
...globals.browser,
process: 'readonly'
}
}
},
{
files: ['packages/server/**/*.{js,cjs}'],
@ -35,15 +40,8 @@ export default defineConfig([
language: 'json/json',
extends: ['json/recommended']
},
{
files: ['**/*.css'],
plugins: { css },
language: 'css/css',
extends: ['css/recommended']
},
{
rules: {
// 'no-unused-vars': 'on',
'react/prop-types': 'off',
'react/display-name': 'off',
'react/no-unescaped-entities': 'off',

View file

@ -34,7 +34,7 @@ const Main = () => {
onCompleted: userResponse => {
if (!userData && userResponse?.userData)
setUserData(userResponse.userData)
}
},
})
const route = location.pathname

View file

@ -42,4 +42,4 @@
.navButton:hover {
background-color: rgba(0, 0, 0, 0.04);
}
}

View file

@ -7,7 +7,7 @@ import classnames from 'classnames'
const cardState = Object.freeze({
DEFAULT: 'default',
SHRUNK: 'shrunk',
EXPANDED: 'expanded'
EXPANDED: 'expanded',
})
const CollapsibleCard = ({ className, state, shrunkComponent, children }) => {
@ -19,7 +19,7 @@ const CollapsibleCard = ({ className, state, shrunkComponent, children }) => {
}
CollapsibleCard.propTypes = {
shrunkComponent: PropTypes.node.isRequired
shrunkComponent: PropTypes.node.isRequired,
}
export default CollapsibleCard

View file

@ -101,5 +101,5 @@ export const ConfirmDialog = memo(
</DialogActions>
</Dialog>
)
}
},
)

View file

@ -14,7 +14,7 @@ const CopyToClipboard = ({
buttonClassname,
children,
wrapperClassname,
removeSpace = true
removeSpace = true,
}) => {
const [anchorEl, setAnchorEl] = useState(null)
@ -68,7 +68,7 @@ const CopyToClipboard = ({
</>
)}
</div>
);
)
}
export default CopyToClipboard

View file

@ -34,7 +34,7 @@ export const DeleteDialog = ({
item = 'item',
confirmationMessage = `Are you sure you want to delete this ${item}?`,
extraMessage,
errorMessage = ''
errorMessage = '',
}) => {
return (
<Dialog open={open} aria-labelledby="form-dialog-title">

View file

@ -50,7 +50,7 @@ const ImagePopper = memo(
</div>
</ClickAwayListener>
)
}
},
)
export default ImagePopper

View file

@ -7,7 +7,7 @@ import { H1 } from 'src/components/typography'
import CloseIcon from 'src/styling/icons/action/close/zodiac.svg?react'
export const InformativeDialog = memo(
({ title = '', open, onDissmised, disabled = false, data, ...props }) => {
({ title = '', open, onDissmised, data, ...props }) => {
const innerOnClose = () => {
onDissmised()
}
@ -16,8 +16,8 @@ export const InformativeDialog = memo(
<Dialog
PaperProps={{
style: {
borderRadius: 8
}
borderRadius: 8,
},
}}
fullWidth
open={open}
@ -35,5 +35,5 @@ export const InformativeDialog = memo(
<DialogContent>{data}</DialogContent>
</Dialog>
)
}
},
)

View file

@ -15,7 +15,6 @@ import { formatDate } from 'src/utils/timezones'
import Popper from './Popper'
import DateRangePicker from './date-range-picker/DateRangePicker'
import { RadioGroup } from './inputs'
import typographyStyles from './typography/styles'
import { H4, Info1, Label1, Label2 } from './typography/index.jsx'
const DateContainer = ({ date, children }) => {
@ -31,7 +30,7 @@ const DateContainer = ({ date, children }) => {
<div className="flex flex-col">
<Label2 noMargin>{`${format(
'MMM',
date
date,
)} ${format('yyyy', date)}`}</Label2>
<Label1 noMargin className="text-comet">
{format('EEEE', date)}
@ -57,7 +56,7 @@ const LogsDownloaderPopover = ({
getLogs,
timezone,
simplified,
className
className,
}) => {
const [selectedRadio, setSelectedRadio] = useState(ALL)
const [selectedAdvancedRadio, setSelectedAdvancedRadio] = useState(ADVANCED)
@ -65,12 +64,12 @@ const LogsDownloaderPopover = ({
const [range, setRange] = useState({ from: null, until: null })
const [anchorEl, setAnchorEl] = useState(null)
const [fetchLogs] = useLazyQuery(query, {
onCompleted: data => createLogsFile(getLogs(data), range)
onCompleted: data => createLogsFile(getLogs(data), range),
})
const dateRangePickerClasses = {
'block h-full': selectedRadio === RANGE,
hidden: selectedRadio === ALL
hidden: selectedRadio === ALL,
}
const handleRadioButtons = evt => {
@ -88,7 +87,7 @@ const LogsDownloaderPopover = ({
(from, until) => {
setRange({ from, until })
},
[setRange]
[setRange],
)
const downloadLogs = (range, args) => {
@ -97,8 +96,8 @@ const LogsDownloaderPopover = ({
variables: {
...args,
simplified: selectedAdvancedRadio === SIMPLIFIED,
excludeTestingCustomers: true
}
excludeTestingCustomers: true,
},
})
}
@ -112,8 +111,8 @@ const LogsDownloaderPopover = ({
from: range.from,
until: range.until,
simplified: selectedAdvancedRadio === SIMPLIFIED,
excludeTestingCustomers: true
}
excludeTestingCustomers: true,
},
})
}
}
@ -124,7 +123,7 @@ const LogsDownloaderPopover = ({
}
const blob = new window.Blob([logs], {
type: 'text/plain;charset=utf-8'
type: 'text/plain;charset=utf-8',
})
FileSaver.saveAs(
@ -132,8 +131,8 @@ const LogsDownloaderPopover = ({
selectedRadio === ALL
? `${formatDateFile(new Date())}_${name}.csv`
: `${formatDateFile(range.from)}_${formatDateFile(
range.until
)}_${name}.csv`
range.until,
)}_${name}.csv`,
)
}
@ -147,12 +146,12 @@ const LogsDownloaderPopover = ({
const radioButtonOptions = [
{ display: 'All logs', code: ALL },
{ display: 'Date range', code: RANGE }
{ display: 'Date range', code: RANGE },
]
const advancedRadioButtonOptions = [
{ display: 'Advanced logs', code: ADVANCED },
{ display: 'Simplified logs', code: SIMPLIFIED }
{ display: 'Simplified logs', code: SIMPLIFIED },
]
const open = Boolean(anchorEl)
@ -201,9 +200,9 @@ const LogsDownloaderPopover = ({
hours: 23,
minutes: 59,
seconds: 59,
milliseconds: 999
milliseconds: 999,
},
new Date()
new Date(),
)}
onRangeChange={handleRangeChange}
/>

View file

@ -17,14 +17,12 @@ const Modal = ({
infoPanel,
handleClose,
children,
secondaryModal,
className,
closeOnEscape,
closeOnBackdropClick,
...props
}) => {
const TitleCase = small ? H4 : H1
const closeSize = xl ? 28 : small ? 16 : 20
const innerClose = (evt, reason) => {
if (!closeOnBackdropClick && reason === 'backdropClick') return
@ -44,7 +42,7 @@ const Modal = ({
style={{ width, height, minHeight: height ?? 400 }}
className={classnames(
'flex flex-col max-h-[90vh] rounded-lg outline-0',
className
className,
)}>
<div className="flex">
{title && (
@ -78,11 +76,11 @@ const Modal = ({
style={{
width,
height: infoPanelHeight,
minHeight: infoPanelHeight ?? 200
minHeight: infoPanelHeight ?? 200,
}}
className={classnames(
'mt-4 flex flex-col max-h-[90vh] overflow-y-auto rounded-lg outline-0',
className
className,
)}>
<div className="w-full flex flex-col flex-1 py-0 px-6">
{infoPanel}

View file

@ -52,28 +52,28 @@ const NotificationCenter = ({
hasUnreadProp,
buttonCoords,
popperRef,
refetchHasUnreadHeader
refetchHasUnreadHeader,
}) => {
const { data, loading } = useQuery(GET_NOTIFICATIONS, {
pollInterval: 60000
pollInterval: 60000,
})
const [xOffset, setXoffset] = useState(300)
const [showingUnread, setShowingUnread] = useState(false)
const machines = R.compose(
R.map(R.prop('name')),
R.indexBy(R.prop('deviceId'))
R.indexBy(R.prop('deviceId')),
)(R.path(['machines'])(data) ?? [])
const notifications = R.path(['notifications'])(data) ?? []
const [hasUnread, setHasUnread] = useState(hasUnreadProp)
const [toggleClearNotification] = useMutation(TOGGLE_CLEAR_NOTIFICATION, {
onError: () => console.error('Error while clearing notification'),
refetchQueries: () => ['getNotifications']
refetchQueries: () => ['getNotifications'],
})
const [clearAllNotifications] = useMutation(CLEAR_ALL_NOTIFICATIONS, {
onError: () => console.error('Error while clearing all notifications'),
refetchQueries: () => ['getNotifications']
refetchQueries: () => ['getNotifications'],
})
useEffect(() => {
@ -103,7 +103,7 @@ const NotificationCenter = ({
valid={n.valid}
toggleClear={() =>
toggleClearNotification({
variables: { id: n.id, read: !n.read }
variables: { id: n.id, read: !n.read },
})
}
/>
@ -121,7 +121,7 @@ const NotificationCenter = ({
className={classes.notificationIcon}
style={{
top: buttonCoords?.y ?? 0,
left: buttonCoords?.x ? buttonCoords.x - xOffset : 0
left: buttonCoords?.x ? buttonCoords.x - xOffset : 0,
}}>
<NotificationIconZodiac />
{hasUnread && <div className={classes.hasUnread} />}

View file

@ -6,8 +6,10 @@
box-shadow: 0 0 14px 0 rgba(0, 0, 0, 0.24);
}
.container @media only screen and (max-width: 1920px) {
width: 30vw;
@media only screen and (max-width: 1920px) {
.container {
width: 30vw;
}
}
.header {
@ -75,7 +77,7 @@
}
.unread {
background-color: var(--spring3)
background-color: var(--spring3);
}
.notificationRowIcon {
@ -83,11 +85,11 @@
}
.notificationRowIcon > * {
margin-left: 24px
margin-left: 24px;
}
.readIconWrapper {
flex-grow: 1
flex-grow: 1;
}
.unreadIcon {
@ -118,7 +120,7 @@
}
.notificationBody {
margin: 0
margin: 0;
}
.notificationSubtitle {
@ -142,4 +144,4 @@
height: 9px;
background-color: var(--spring);
border-radius: 50%;
}
}

View file

@ -12,37 +12,36 @@ import classes from './NotificationCenter.module.css'
const types = {
transaction: {
display: 'Transactions',
icon: <Transaction height={16} width={16} />
icon: <Transaction height={16} width={16} />,
},
highValueTransaction: {
display: 'Transactions',
icon: <Transaction height={16} width={16} />
icon: <Transaction height={16} width={16} />,
},
fiatBalance: {
display: 'Maintenance',
icon: <Wrench height={16} width={16} />
icon: <Wrench height={16} width={16} />,
},
cryptoBalance: {
display: 'Maintenance',
icon: <Wrench height={16} width={16} />
icon: <Wrench height={16} width={16} />,
},
compliance: {
display: 'Compliance',
icon: <WarningIcon height={16} width={16} />
icon: <WarningIcon height={16} width={16} />,
},
error: { display: 'Error', icon: <WarningIcon height={16} width={16} /> }
error: { display: 'Error', icon: <WarningIcon height={16} width={16} /> },
}
const NotificationRow = ({
id,
type,
detail,
message,
deviceName,
created,
read,
valid,
toggleClear
toggleClear,
}) => {
const typeDisplay = R.path([type, 'display'])(types) ?? null
const icon = R.path([type, 'icon'])(types) ?? (
@ -50,7 +49,7 @@ const NotificationRow = ({
)
const age = prettyMs(new Date().getTime() - new Date(created).getTime(), {
compact: true,
verbose: true
verbose: true,
})
const notificationTitle =
typeDisplay && deviceName
@ -61,13 +60,13 @@ const NotificationRow = ({
const iconClass = {
[classes.readIcon]: read,
[classes.unreadIcon]: !read
[classes.unreadIcon]: !read,
}
return (
<div
className={classnames(
classes.notificationRow,
!read && valid ? classes.unread : ''
!read && valid ? classes.unread : '',
)}>
<div className={classes.notificationRowIcon}>
<div>{icon}</div>

View file

@ -1,2 +1,3 @@
import NotificationCenter from './NotificationCenter'
export default NotificationCenter

View file

@ -14,7 +14,7 @@ const Popover = ({ children, bgColor = white, className, ...props }) => {
top: ['bottom'],
bottom: ['top'],
left: ['right'],
right: ['left']
right: ['left'],
}
const modifiers = [
@ -22,36 +22,36 @@ const Popover = ({ children, bgColor = white, className, ...props }) => {
name: 'flip',
enabled: R.defaultTo(false, props.flip),
options: {
allowedAutoPlacements: flipPlacements[props.placement]
}
allowedAutoPlacements: flipPlacements[props.placement],
},
},
{
name: 'preventOverflow',
enabled: true,
options: {
rootBoundary: 'scrollParent'
}
rootBoundary: 'scrollParent',
},
},
{
name: 'offset',
enabled: true,
options: {
offset: [0, 10]
}
offset: [0, 10],
},
},
{
name: 'arrow',
enabled: R.defaultTo(true, props.showArrow),
options: {
element: arrowRef
}
element: arrowRef,
},
},
{
name: 'computeStyles',
options: {
gpuAcceleration: false
}
}
gpuAcceleration: false,
},
},
]
return (

View file

@ -30,4 +30,4 @@
.tooltip[data-popper-placement^='right'] > div > span {
left: -4px;
}
}

View file

@ -12,7 +12,6 @@ const SearchBox = memo(
filters = [],
options = [],
inputPlaceholder = '',
size,
onChange,
...props
}) => {
@ -20,7 +19,7 @@ const SearchBox = memo(
const inputClasses = {
'flex flex-1 h-8 px-2 py-2 font-md items-center rounded-2xl bg-zircon text-comet': true,
'rounded-b-none': popupOpen
'rounded-b-none': popupOpen,
}
const innerOnChange = filters => onChange(filters)
@ -57,7 +56,7 @@ const SearchBox = memo(
placeholder={inputPlaceholder}
inputProps={{
className: 'font-bold',
...params.inputProps
...params.inputProps,
}}
/>
)
@ -74,10 +73,11 @@ const SearchBox = memo(
<div className="w-[88%] h-[1px] my-p mx-auto border-1 border-comet" />
{children}
</Paper>
)
}} />
);
}
),
}}
/>
)
},
)
export default SearchBox

View file

@ -12,7 +12,7 @@ const SearchFilter = ({
filters,
onFilterDelete,
deleteAllFilters,
entries = 0
entries = 0,
}) => {
return (
<>
@ -33,7 +33,7 @@ const SearchFilter = ({
<Label3 className="text-comet m-auto mr-3">{`${entries} ${singularOrPlural(
entries,
`entry`,
`entries`
`entries`,
)}`}</Label3>
}
<ActionButton

View file

@ -18,13 +18,13 @@ const Stepper = memo(({ steps, currentStep, color = 'spring', className }) => {
const separatorClasses = {
'w-7 h-[2px] border-2 z-1': true,
'border-spring': color === 'spring',
'border-zodiac': color === 'zodiac'
'border-zodiac': color === 'zodiac',
}
const separatorEmptyClasses = {
'w-7 h-[2px] border-2 z-1': true,
'border-dust': color === 'spring',
'border-comet': color === 'zodiac'
'border-comet': color === 'zodiac',
}
return (

View file

@ -9,4 +9,4 @@
height: 100%;
width: 100%;
overflow: visible;
}
}

View file

@ -6,7 +6,7 @@ import { TL1 } from './typography'
const Subtitle = memo(({ children, className, extraMarginTop }) => {
const classNames = {
'text-comet my-4': true,
'mt-18': extraMarginTop
'mt-18': extraMarginTop,
}
return <TL1 className={classnames(classNames, className)}>{children}</TL1>

View file

@ -4,30 +4,6 @@ import React, { useState, memo } from 'react'
import Popper from 'src/components/Popper'
import HelpIcon from 'src/styling/icons/action/help/zodiac.svg?react'
const useStyles = {
transparentButton: {
border: 'none',
backgroundColor: 'transparent',
outline: 'none',
cursor: 'pointer',
marginTop: 4
},
relativelyPositioned: {
position: 'relative'
},
safeSpace: {
position: 'absolute',
backgroundColor: '#0000',
height: 40,
left: '-50%',
width: '200%'
},
popoverContent: ({ width }) => ({
width,
padding: [[10, 15]]
})
}
const usePopperHandler = () => {
const [helpPopperAnchorEl, setHelpPopperAnchorEl] = useState(null)
@ -50,7 +26,7 @@ const usePopperHandler = () => {
helpPopperOpen,
handleOpenHelpPopper,
openHelpPopper,
handleCloseHelpPopper
handleCloseHelpPopper,
}
}

View file

@ -25,27 +25,27 @@ const BooleanPropertiesTable = memo(
const [editing, setEditing] = useState(forcedEditing)
const initialValues = R.fromPairs(
elements.map(it => [it.name, data[it.name]?.toString() ?? 'false'])
elements.map(it => [it.name, data[it.name]?.toString() ?? 'false']),
)
const validationSchema = Yup.object().shape(
R.fromPairs(
elements.map(it => [
it.name,
Yup.mixed().oneOf(['true', 'false', true, false]).required()
])
)
Yup.mixed().oneOf(['true', 'false', true, false]).required(),
]),
),
)
const innerSave = async values => {
const toBoolean = (num, _) => R.equals(num, 'true')
const toBoolean = num => R.equals(num, 'true')
save(R.mapObjIndexed(toBoolean, R.filter(R.complement(R.isNil))(values)))
setEditing(false)
}
const radioButtonOptions = [
{ display: 'Yes', code: 'true' },
{ display: 'No', code: 'false' }
{ display: 'No', code: 'false' },
]
return (
<div className="flex w-sm flex-col ">
@ -117,7 +117,7 @@ const BooleanPropertiesTable = memo(
</Formik>
</div>
)
}
},
)
export default BooleanPropertiesTable

View file

@ -21,7 +21,7 @@ const ActionButton = memo(
[moduleStyles.secondary]: color === 'secondary',
[moduleStyles.spring]: color === 'spring',
[moduleStyles.tomato]: color === 'tomato',
[moduleStyles.center]: center
[moduleStyles.center]: center,
}
return (
@ -35,7 +35,7 @@ const ActionButton = memo(
<div
className={classnames(
moduleStyles.actionButtonIcon,
moduleStyles.actionButtonIconActive
moduleStyles.actionButtonIconActive,
)}>
<InverseIcon />
</div>
@ -43,7 +43,7 @@ const ActionButton = memo(
{children && <div>{children}</div>}
</button>
)
}
},
)
export default ActionButton

View file

@ -4,18 +4,18 @@ import {
subheaderColor,
subheaderDarkColor,
offColor,
offDarkColor
offDarkColor,
} from 'src/styling/variables'
const colors = (color1, color2, color3) => {
return {
backgroundColor: color1,
'&:hover': {
backgroundColor: color2
backgroundColor: color2,
},
'&:active': {
backgroundColor: color3
}
backgroundColor: color3,
},
}
}
@ -30,23 +30,23 @@ export default {
height: buttonHeight,
color: fontColor,
'&:active': {
color: white
}
color: white,
},
},
primary: {
extend: colors(subheaderColor, subheaderDarkColor, offColor),
'&:active': {
color: white,
'& $buttonIcon': {
display: 'none'
display: 'none',
},
'& $buttonIconActive': {
display: 'block'
}
display: 'block',
},
},
'& $buttonIconActive': {
display: 'none'
}
display: 'none',
},
},
secondary: {
extend: colors(offColor, offDarkColor, white),
@ -54,17 +54,17 @@ export default {
'&:active': {
color: fontColor,
'& $buttonIcon': {
display: 'flex'
display: 'flex',
},
'& $buttonIconActive': {
display: 'none'
}
display: 'none',
},
},
'& $buttonIcon': {
display: 'none'
display: 'none',
},
'& $buttonIconActive': {
display: 'flex'
}
}
display: 'flex',
},
},
}

View file

@ -29,15 +29,15 @@ const ActionButton = memo(
'text-white',
{
[moduleStyles.buttonSm]: size === 'sm',
[moduleStyles.buttonXl]: size === 'xl'
}
[moduleStyles.buttonXl]: size === 'xl',
},
)}
{...props}>
{children}
</button>
</div>
)
}
},
)
export default ActionButton

View file

@ -14,13 +14,13 @@
.buttonXl {
composes: h1 from '../typography/typography.module.css';
height: 61px;
border-radius: 15px
border-radius: 15px;
}
.buttonSm {
height: 32px;
padding: 0 16px;
border-radius: 8px
border-radius: 8px;
}
.button:disabled {
@ -46,4 +46,4 @@
margin-top: 2px;
background-color: var(--spring2);
box-shadow: 0 2px var(--spring4);
}
}

View file

@ -11,7 +11,7 @@ const FeatureButton = memo(
classes.baseButton,
classes.roundButton,
classes.primary,
className
className,
)}
{...props}>
{Icon && (
@ -23,7 +23,7 @@ const FeatureButton = memo(
<div
className={classnames(
classes.buttonIcon,
classes.buttonIconActive
classes.buttonIconActive,
)}>
<InverseIcon />
</div>
@ -31,7 +31,7 @@ const FeatureButton = memo(
{children}
</button>
)
}
},
)
export default FeatureButton

View file

@ -11,7 +11,6 @@ const IDButton = memo(
className,
Icon,
InverseIcon,
popoverWidth = 152,
children,
popoverClassname,
...props
@ -25,11 +24,11 @@ const IDButton = memo(
[classes.idButton]: true,
[classes.primary]: true,
[classes.open]: open,
[classes.closed]: !open
[classes.closed]: !open,
}
const iconClassNames = {
[classes.buttonIcon]: true
[classes.buttonIcon]: true,
}
const handleClick = event => {
@ -74,7 +73,7 @@ const IDButton = memo(
</Popover>
</>
)
}
},
)
export default IDButton

View file

@ -10,7 +10,7 @@ const Link = memo(
[classes.primary]: color === 'primary',
[classes.secondary]: color === 'secondary',
[classes.noColor]: color === 'noColor',
[classes.action]: color === 'action'
[classes.action]: color === 'action',
}
return (
@ -21,7 +21,7 @@ const Link = memo(
{children}
</button>
)
}
},
)
export default Link

View file

@ -44,4 +44,4 @@
.action:hover {
box-shadow: none;
background-color: rgba(72, 246, 148, 0.8);
}
}

View file

@ -12,14 +12,14 @@ const SubpageButton = memo(
InverseIcon,
toggle,
forceDisable = false,
children
children,
}) => {
const [active, setActive] = useState(false)
const isActive = forceDisable ? false : active
const classNames = {
[classes.button]: true,
[classes.normal]: !isActive,
[classes.active]: isActive
[classes.active]: isActive,
}
const normalButton = <Icon className={classes.buttonIcon} />
@ -29,14 +29,14 @@ const SubpageButton = memo(
<InverseIcon
className={classnames(
classes.buttonIcon,
classes.buttonIconActiveLeft
classes.buttonIconActiveLeft,
)}
/>
<H4 className="text-white">{children}</H4>
<CancelIconInverse
className={classnames(
classes.buttonIcon,
classes.buttonIconActiveRight
classes.buttonIconActiveRight,
)}
/>
</>
@ -56,7 +56,7 @@ const SubpageButton = memo(
{isActive ? activeButton : normalButton}
</button>
)
}
},
)
export default SubpageButton

View file

@ -27,7 +27,7 @@
}
.active:hover {
background-color: var(--comet);
background-color: var(--comet);
}
.buttonIcon {

View file

@ -8,10 +8,10 @@ export default {
extend: baseButton,
padding: 0,
color: white,
borderRadius: baseButton.height / 2
borderRadius: baseButton.height / 2,
},
normalButton: {
width: baseButton.height
width: baseButton.height,
},
activeButton: {
display: 'flex',
@ -21,26 +21,26 @@ export default {
fontWeight: 'bold',
padding: '0 5px',
'&:hover': {
backgroundColor: offColor
}
backgroundColor: offColor,
},
},
buttonIcon: {
width: 16,
height: 16,
overflow: 'visible',
'& g': {
strokeWidth: 1.8
}
strokeWidth: 1.8,
},
},
buttonIconActiveLeft: {
marginRight: 12,
marginLeft: 4
marginLeft: 4,
},
buttonIconActiveRight: {
marginRight: 5,
marginLeft: 20
marginLeft: 20,
},
white: {
color: white
}
color: white,
},
}

View file

@ -15,5 +15,5 @@ export {
IDButton,
AddButton,
SupportLinkButton,
SubpageButton
SubpageButton,
}

View file

@ -10,7 +10,7 @@ import {
lastDayOfMonth,
startOfMonth,
startOfWeek,
sub
sub,
} from 'date-fns/fp'
import * as R from 'ramda'
import React, { useState } from 'react'
@ -24,7 +24,7 @@ const Calendar = ({ minDate, maxDate, handleSelect, ...props }) => {
const [currentDisplayedMonth, setCurrentDisplayedMonth] = useState(new Date())
const weekdays = Array.from(Array(7)).map((_, i) =>
format('EEEEE', add({ days: i }, startOfWeek(new Date())))
format('EEEEE', add({ days: i }, startOfWeek(new Date()))),
)
const monthLength = month => getDaysInMonth(month)
@ -33,21 +33,21 @@ const Calendar = ({ minDate, maxDate, handleSelect, ...props }) => {
const lastMonth = sub({ months: 1 }, month)
const lastMonthRange = R.range(0, getDay(startOfMonth(month))).reverse()
const lastMonthDays = R.map(i =>
sub({ days: i }, lastDayOfMonth(lastMonth))
sub({ days: i }, lastDayOfMonth(lastMonth)),
)(lastMonthRange)
const thisMonthRange = R.range(0, monthLength(month))
const thisMonthDays = R.map(i => add({ days: i }, startOfMonth(month)))(
thisMonthRange
thisMonthRange,
)
const nextMonth = add({ months: 1 }, month)
const nextMonthRange = R.range(
0,
42 - lastMonthDays.length - thisMonthDays.length
42 - lastMonthDays.length - thisMonthDays.length,
)
const nextMonthDays = R.map(i => add({ days: i }, startOfMonth(nextMonth)))(
nextMonthRange
nextMonthRange,
)
return R.concat(R.concat(lastMonthDays, thisMonthDays), nextMonthDays)
@ -63,7 +63,7 @@ const Calendar = ({ minDate, maxDate, handleSelect, ...props }) => {
isSameMonth(minDate, prevMonth) ||
differenceInMonths(minDate, prevMonth) > 0
? prevMonth
: currentDisplayedMonth
: currentDisplayedMonth,
)
}
}
@ -75,7 +75,7 @@ const Calendar = ({ minDate, maxDate, handleSelect, ...props }) => {
isSameMonth(maxDate, nextMonth) ||
differenceInMonths(nextMonth, maxDate) > 0
? nextMonth
: currentDisplayedMonth
: currentDisplayedMonth,
)
}
}
@ -91,7 +91,7 @@ const Calendar = ({ minDate, maxDate, handleSelect, ...props }) => {
<span>
{`${format('MMMM', currentDisplayedMonth)} ${format(
'yyyy',
currentDisplayedMonth
currentDisplayedMonth,
)}`}
</span>
<button

View file

@ -53,7 +53,7 @@
padding-right: 5px;
}
.table th,
.table th,
.table td {
margin: 0;
padding: 3px 0 3px 0;
@ -63,4 +63,4 @@
font-size: 13px;
font-family: var(--museo);
font-weight: 700;
}
}

View file

@ -23,14 +23,14 @@ const DateRangePicker = ({ minDate, maxDate, className, onRangeChange }) => {
if (from && !to) {
if (differenceInDays(from, day) >= 0) {
setTo(
set({ hours: 23, minutes: 59, seconds: 59, milliseconds: 999 }, day)
set({ hours: 23, minutes: 59, seconds: 59, milliseconds: 999 }, day),
)
} else {
setTo(
set(
{ hours: 23, minutes: 59, seconds: 59, milliseconds: 999 },
R.clone(from)
)
R.clone(from),
),
)
setFrom(day)
}

View file

@ -8,24 +8,24 @@ const Tile = ({
isUpperBound,
isBetween,
isDisabled,
children
children,
}) => {
const selected = isLowerBound || isUpperBound
const rangeClasses = {
[classes.between]: isBetween && !(isLowerBound && isUpperBound),
[classes.lowerBound]: isLowerBound && !isUpperBound,
[classes.upperBound]: isUpperBound && !isLowerBound
[classes.upperBound]: isUpperBound && !isLowerBound,
}
const buttonWrapperClasses = {
[classes.wrapper]: true,
[classes.selected]: selected
[classes.selected]: selected,
}
const buttonClasses = {
[classes.button]: true,
[classes.disabled]: isDisabled
[classes.disabled]: isDisabled,
}
return (

View file

@ -5,7 +5,7 @@ import {
Td,
THead,
TDoubleLevelHead,
ThDoubleLevel
ThDoubleLevel,
} from 'src/components/fake-table/Table'
import { sentenceCase } from 'src/utils/string'
@ -24,11 +24,11 @@ const groupSecondHeader = elements => {
{
width: R.sum(R.map(R.prop('width'), group)),
elements: group,
name: doubleHeader(group[0])
}
]
name: doubleHeader(group[0]),
},
],
),
R.reduce(R.concat, [])
R.reduce(R.concat, []),
)
return R.all(R.pipe(doubleHeader, R.isNil), elements)
@ -47,7 +47,7 @@ const Header = () => {
enableToggle,
toggleWidth,
orderedBy,
DEFAULT_COL_SIZE
DEFAULT_COL_SIZE,
} = useContext(TableCtx)
const mapElement2 = (it, idx) => {
@ -66,11 +66,13 @@ const Header = () => {
const mapElement = (
{ name, display, width = DEFAULT_COL_SIZE, header, textAlign },
idx
idx,
) => {
const orderClasses = classnames({
'whitespace-nowrap':
R.isNil(header) && !R.isNil(orderedBy) && R.equals(name, orderedBy.code)
R.isNil(header) &&
!R.isNil(orderedBy) &&
R.equals(name, orderedBy.code),
})
const attachOrderedByToComplexHeader = header => {
@ -82,6 +84,7 @@ const Header = () => {
spanChild.props.children = R.append(' -', spanChild.props.children)
return cloneHeader
} catch (e) {
console.error(e)
return header
}
}

View file

@ -18,7 +18,7 @@ const NamespacedTable = ({
const innerData = R.map(it => ({
id: it,
...fromNamespace(it)(data)
...fromNamespace(it)(data),
}))(namespaces)
return (

View file

@ -35,7 +35,7 @@ const ActionCol = ({ disabled, editing }) => {
forceAdd,
clearError,
actionColSize,
error
error,
} = useContext(TableCtx)
const disableEdit = disabled || (disableRowEdit && disableRowEdit(values))
@ -136,10 +136,10 @@ const ECol = ({ editing, focus, config, extraPaddingRight, extraPadding }) => {
PrefixComponent = Label2,
suffix,
SuffixComponent = Label2,
textStyle = it => {},
isHidden = it => false,
textStyle = () => {},
isHidden = () => false,
view = it => it?.toString(),
inputProps = {}
inputProps = {},
} = config
const fields = names ?? [name]
@ -158,7 +158,7 @@ const ECol = ({ editing, focus, config, extraPaddingRight, extraPadding }) => {
size,
bold,
textAlign: isEditing ? editingAlign : textAlign,
...inputProps
...inputProps,
}
const newAlign = isEditing ? editingAlign : textAlign
@ -174,7 +174,7 @@ const ECol = ({ editing, focus, config, extraPaddingRight, extraPadding }) => {
className={{
[moduleStyles.extraPaddingRight]: extraPaddingRight,
[moduleStyles.extraPadding]: extraPadding,
'flex items-center': suffix || prefix
'flex items-center': suffix || prefix,
}}
width={width}
size={size}
@ -225,7 +225,7 @@ const groupStriped = elements => {
return R.insert(
index,
{ width, editable: false, view: () => <StripesSvg /> },
noStripe
noStripe,
)
}
@ -238,7 +238,7 @@ const ERow = ({ editing, disabled, lastOfGroup, newRow }) => {
error,
enableToggle,
rowSize,
stripeWhen
stripeWhen,
} = useContext(TableCtx)
const shouldStripe = !editing && stripeWhen && stripeWhen(values)
@ -255,11 +255,11 @@ const ERow = ({ editing, disabled, lastOfGroup, newRow }) => {
: -1
const elementToFocusIndex = innerElements.findIndex(
it => it.editable === undefined || it.editable
it => it.editable === undefined || it.editable,
)
const classNames = {
[moduleStyles.lastOfGroup]: lastOfGroup
[moduleStyles.lastOfGroup]: lastOfGroup,
}
const touchedErrors = R.pick(R.keys(touched), errors)

View file

@ -26,4 +26,4 @@
.fields {
display: flex;
flex-direction: column;
}
}

View file

@ -19,7 +19,7 @@ const DEFAULT_COL_SIZE = 100
const getWidth = R.compose(
R.reduce(R.add)(0),
R.map(it => it.width ?? DEFAULT_COL_SIZE)
R.map(it => it.width ?? DEFAULT_COL_SIZE),
)
const ETable = ({
@ -54,7 +54,7 @@ const ETable = ({
createText = 'Add override',
forceAdd = false,
tbodyWrapperClass,
orderedBy = null
orderedBy = null,
}) => {
const [editingId, setEditingId] = useState(null)
const [adding, setAdding] = useState(false)
@ -80,6 +80,7 @@ const ETable = ({
try {
await save({ [name]: list }, it)
} catch (err) {
console.error(err)
setSaving(false)
return
}
@ -152,7 +153,7 @@ const ETable = ({
stripeWhen,
forceAdd,
orderedBy,
DEFAULT_COL_SIZE
DEFAULT_COL_SIZE,
}
return (

View file

@ -35,20 +35,20 @@ const Td = ({
size,
bold,
textAlign,
action
action,
}) => {
const inlineStyle = {
...style,
width,
textAlign,
fontSize: size === 'sm' ? '14px' : size === 'lg' ? '24px' : ''
fontSize: size === 'sm' ? '14px' : size === 'lg' ? '24px' : '',
}
const cssClasses = {
[styles.td]: !header,
[styles.tdHeader]: header,
'font-bold': !header && (bold || size === 'lg'),
[styles.actionCol]: action
[styles.actionCol]: action,
}
return (
@ -88,21 +88,21 @@ const Tr = ({
children,
className,
size,
newRow
newRow,
}) => {
const inlineStyle = {
minHeight: size === 'sm' ? '34px' : size === 'lg' ? '68px' : '48px'
minHeight: size === 'sm' ? '34px' : size === 'lg' ? '68px' : '48px',
}
const cardClasses = {
[styles.card]: true,
[styles.trError]: error,
[styles.trAdding]: newRow
[styles.trAdding]: newRow,
}
const mainContentClasses = {
[styles.mainContent]: true,
[styles.sizeSm]: size === 'sm',
[styles.sizeLg]: size === 'lg'
[styles.sizeLg]: size === 'lg',
}
return (
@ -141,5 +141,5 @@ export {
Td,
Th,
ThDoubleLevel,
EditCell
EditCell,
}

View file

@ -9,7 +9,6 @@ import { P } from 'src/components/typography'
import TextInput from './TextInput'
const Autocomplete = ({
optionsLimit = 5, // set limit = null for no limit
limit,
options,
label,
@ -17,7 +16,6 @@ const Autocomplete = ({
multiple,
onChange,
labelProp,
shouldStayOpen,
value: outsideValue,
error,
fullWidth,
@ -61,11 +59,11 @@ const Autocomplete = ({
const filterOptions = (array, { inputValue }) =>
R.union(
R.isEmpty(inputValue) ? valueArray() : [],
filter(array, inputValue)
filter(array, inputValue),
).slice(
0,
R.defaultTo(undefined)(limit) &&
Math.max(limit, R.isEmpty(inputValue) ? valueArray().length : 0)
Math.max(limit, R.isEmpty(inputValue) ? valueArray().length : 0),
)
return (
@ -105,7 +103,7 @@ const Autocomplete = ({
'flex w-4 h-4 rounded-md': true,
'bg-spring4': props.warning === 'clean',
'bg-orange-yellow': props.warning === 'partial',
'bg-tomato': props.warning === 'important'
'bg-tomato': props.warning === 'important',
}
const hoverableElement = <div className={classnames(className)} />
@ -122,9 +120,10 @@ const Autocomplete = ({
)
}}
slotProps={{
chip: { onDelete: null }
}} />
);
chip: { onDelete: null },
}}
/>
)
}
export default Autocomplete

View file

@ -11,7 +11,7 @@ const CodeInput = ({
numInputs,
error,
inputStyle,
containerStyle
containerStyle,
}) => {
return (
<OtpInput
@ -26,7 +26,7 @@ const CodeInput = ({
inputStyle,
classes.input,
'font-museo font-black text-4xl',
error && 'border-tomato'
error && 'border-tomato',
)}
inputType={'tel'}
renderInput={props => <input {...props} />}

View file

@ -23,7 +23,7 @@ const Dropdown = ({ label, name, options, onChange, value, className }) => {
))}
</Select>
</FormControl>
);
)
}
export default Dropdown

View file

@ -18,7 +18,6 @@ const NumberInput = memo(
bold,
className,
decimalPlaces,
InputProps,
...props
}) => {
return (
@ -41,14 +40,14 @@ const NumberInput = memo(
onChange({
target: {
id: name,
value: values.floatValue
}
value: values.floatValue,
},
})
}}
{...props}
/>
)
}
},
)
export default NumberInput

View file

@ -13,7 +13,7 @@ const RadioGroup = ({
onChange,
className,
labelClassName,
radioClassName
radioClassName,
}) => {
return (
<>

View file

@ -29,7 +29,7 @@ const SecretInput = memo(
placeholder={isPasswordFilled ? placeholder : ''}
/>
)
}
},
)
export default SecretInput

View file

@ -7,20 +7,19 @@ import Arrowdown from 'src/styling/icons/action/arrow/regular.svg?react'
import styles from './Select.module.css'
function Select({ className, label, items, ...props }) {
const {
isOpen,
selectedItem,
getToggleButtonProps,
getLabelProps,
getMenuProps,
getItemProps
getItemProps,
} = useSelect({
items,
selectedItem: props.selectedItem,
onSelectedItemChange: item => {
props.onSelectedItemChange(item.selectedItem)
}
},
})
const selectClassNames = {
@ -28,7 +27,7 @@ function Select({ className, label, items, ...props }) {
[styles.selectFiltered]: props.defaultAsFilter
? true
: !R.equals(selectedItem, props.default),
[styles.open]: isOpen
[styles.open]: isOpen,
}
return (

View file

@ -97,4 +97,4 @@
.open button {
border-radius: 8px 8px 0 0;
}
}

View file

@ -13,7 +13,6 @@ const TextInput = memo(
onBlur,
value,
error,
suffix,
textAlign,
width,
inputClasses,
@ -29,7 +28,7 @@ const TextInput = memo(
const style = {
width: width,
textAlign: textAlign
textAlign: textAlign,
}
const sizeClass =
@ -40,7 +39,7 @@ const TextInput = memo(
: styles.size
const divClass = {
[styles.bold]: bold
[styles.bold]: bold,
}
return (
@ -60,15 +59,16 @@ const TextInput = memo(
classes: {
root: sizeClass,
underline: filled ? styles.underline : null,
input: inputClasses
input: inputClasses,
},
...InputProps
...InputProps,
},
htmlInput: { style: { textAlign } }
}} />
);
}
htmlInput: { style: { textAlign } },
}}
/>
)
},
)
export default TextInput

View file

@ -21,4 +21,4 @@
.underline:hover:not(.Mui-disabled)::before {
border-bottom-color: var(--spring);
}
}

View file

@ -7,6 +7,7 @@ import RadioGroup from './RadioGroup'
import SecretInput from './SecretInput'
import TextInput from './TextInput'
import ToggleButtonGroup from './ToggleButtonGroup'
export {
Checkbox,
CodeInput,
@ -16,5 +17,5 @@ export {
RadioGroup,
Autocomplete,
ToggleButtonGroup,
Dropdown
Dropdown,
}

View file

@ -11,12 +11,12 @@ import { primaryColor as zodiac, tomato } from '../../../styling/variables.js'
const colors = {
cashOut: {
empty: tomato,
full: zodiac
full: zodiac,
},
cashIn: {
empty: zodiac,
full: tomato
}
full: tomato,
},
}
const Cashbox = ({
@ -28,7 +28,7 @@ const Cashbox = ({
emptyPartClassName,
labelClassName,
omitInnerPercentage,
isLow
isLow,
}) => {
const ltHalf = percent <= 51
const color =
@ -72,7 +72,7 @@ const CashIn = ({
width,
height,
total,
omitInnerPercentage
omitInnerPercentage,
}) => {
const percent = (100 * notes) / capacity
const isLow = percent < threshold
@ -117,7 +117,7 @@ const CashOut = ({
threshold,
width,
height,
omitInnerPercentage
omitInnerPercentage,
}) => {
const percent = (100 * notes) / capacity
const isLow = percent < threshold
@ -159,7 +159,7 @@ const CashOutLite = ({
currency,
notes,
threshold,
width
width,
}) => {
const percent = (100 * notes) / capacity
const isLow = percent < threshold

View file

@ -49,4 +49,4 @@
border: 2px solid;
text-align: end;
display: inline-block;
}
}

View file

@ -33,7 +33,7 @@ const CashCassetteInput = memo(
/>
</div>
)
}
},
)
export default CashCassetteInput

View file

@ -3,20 +3,13 @@ import React, { memo } from 'react'
import { Checkbox } from '../base'
const CheckboxInput = memo(
({
label,
textAlign,
fullWidth,
enabled = true,
disabledMessage = '',
...props
}) => {
({ label, enabled = true, disabledMessage = '', ...props }) => {
const { name, onChange, value } = props.field
const settings = {
enabled: enabled,
label: label,
disabledMessage: disabledMessage
disabledMessage: disabledMessage,
}
return (
@ -28,7 +21,7 @@ const CheckboxInput = memo(
{...props}
/>
)
}
},
)
export default CheckboxInput

View file

@ -15,5 +15,5 @@ export {
SecretInput,
RadioGroup,
CashCassetteInput,
Dropdown
Dropdown,
}

View file

@ -14,5 +14,5 @@ export {
Select,
RadioGroup,
CashIn,
CashOut
CashOut,
}

View file

@ -177,16 +177,16 @@ const Header = memo(({ tree, user }) => {
name: 'offset',
enabled: true,
options: {
offset: ['100vw', '100vw']
}
offset: ['100vw', '100vw'],
},
},
{
name: 'preventOverflow',
enabled: true,
options: {
rootBoundary: 'viewport'
}
}
rootBoundary: 'viewport',
},
},
]}>
<NotificationCenter
popperRef={popperRef}

View file

@ -49,7 +49,7 @@
}
.li::after {
content: "";
content: '';
display: block;
background: white;
width: 0;

View file

@ -14,7 +14,7 @@ const Sidebar = ({
onClick,
children,
itemRender,
loading = false
loading = false,
}) => {
return (
<div className={styles.sidebar}>
@ -30,7 +30,7 @@ const Sidebar = ({
[styles.activeLink]: isSelected(it),
[styles.customRenderActiveLink]: itemRender && isSelected(it),
[styles.customRenderLink]: itemRender,
[styles.link]: true
[styles.link]: true,
})}>
{itemRender ? itemRender(it, isSelected(it)) : displayName(it)}
</div>
@ -54,7 +54,7 @@ const Stepper = ({ step, it, idx, steps }) => {
className={classnames({
[styles.itemText]: true,
[styles.itemTextActive]: active,
[styles.itemTextPast]: past
[styles.itemTextPast]: past,
})}>
{it.label}
</span>
@ -65,7 +65,7 @@ const Stepper = ({ step, it, idx, steps }) => {
<div
className={classnames({
[styles.stepperPath]: true,
[styles.stepperPast]: past
[styles.stepperPast]: past,
})}></div>
)}
</div>

View file

@ -39,7 +39,7 @@
}
.link::after {
content: "";
content: '';
display: block;
background: var(--zodiac);
width: 4px;
@ -103,4 +103,4 @@
.stepperPast {
border: 1px solid var(--zodiac);
}
}

View file

@ -15,13 +15,13 @@ const TitleSection = ({
buttons = [],
children,
appendix,
appendixRight
appendixRight,
}) => {
return (
<div
className={classnames(
'flex justify-between items-center flex-row',
className
className,
)}>
<div className="flex items-center">
<Title>{title}</Title>
@ -44,7 +44,7 @@ const TitleSection = ({
{button.text}
</Info1>
</SubpageButton>
)
),
)}
</>
)}

View file

@ -12,7 +12,7 @@ const STATES = {
EMPTY: 'EMPTY',
RUNNING: 'RUNNING',
FAILURE: 'FAILURE',
FILLED: 'FILLED'
FILLED: 'FILLED',
}
const MACHINE = gql`
@ -47,7 +47,7 @@ const MACHINE_LOGS = gql`
const createCsv = async ({ machineLogsCsv }) => {
const machineLogs = new Blob([machineLogsCsv], {
type: 'text/plain;charset=utf-8'
type: 'text/plain;charset=utf-8',
})
FileSaver.saveAs(machineLogs, 'machineLogs.csv')
@ -59,11 +59,11 @@ const DiagnosticsModal = ({ onClose, deviceId, sendAction }) => {
let timeout = null
const [fetchSummary, { loading }] = useLazyQuery(MACHINE_LOGS, {
onCompleted: data => createCsv(data)
onCompleted: data => createCsv(data),
})
const { data, stopPolling, startPolling } = useQuery(MACHINE, {
variables: { deviceId }
variables: { deviceId },
})
useEffect(() => {
@ -168,8 +168,8 @@ const DiagnosticsModal = ({ onClose, deviceId, sendAction }) => {
variables: {
from: subMinutes(new Date(timestamp), 5),
deviceId,
limit: 500
}
limit: 500,
},
})
}}
className="mt-auto ml-auto mr-2 mb-0">

View file

@ -49,7 +49,7 @@ const isStaticState = machineState => {
'unpaired',
'maintenance',
'virgin',
'wifiList'
'wifiList',
]
return staticStates.includes(machineState)
}
@ -73,7 +73,7 @@ const MachineActions = memo(({ machine, onActionSuccess }) => {
const [fetchMachineEvents, { loading: loadingEvents }] = useLazyQuery(
MACHINE,
preflightOptions
preflightOptions,
)
const [simpleMachineAction] = useMutation(MACHINE_ACTION)
@ -86,7 +86,7 @@ const MachineActions = memo(({ machine, onActionSuccess }) => {
onCompleted: () => {
onActionSuccess && onActionSuccess()
setAction({ display: action.display, command: null })
}
},
})
const confirmDialogOpen = Boolean(action.command)
@ -100,7 +100,7 @@ const MachineActions = memo(({ machine, onActionSuccess }) => {
? warningMessage
: null
setAction({ ...actionToDo, message })
}
},
})
fetchMachineEvents()
}
@ -118,7 +118,7 @@ const MachineActions = memo(({ machine, onActionSuccess }) => {
setAction({
command: 'rename',
display: 'Rename',
confirmationMessage: 'Write the new name for this machine'
confirmationMessage: 'Write the new name for this machine',
})
}>
Rename
@ -131,7 +131,7 @@ const MachineActions = memo(({ machine, onActionSuccess }) => {
onClick={() =>
setAction({
command: 'unpair',
display: 'Unpair'
display: 'Unpair',
})
}>
Unpair
@ -144,7 +144,7 @@ const MachineActions = memo(({ machine, onActionSuccess }) => {
onClick={() =>
setAction({
command: 'reboot',
display: 'Reboot'
display: 'Reboot',
})
}>
Reboot
@ -159,7 +159,7 @@ const MachineActions = memo(({ machine, onActionSuccess }) => {
command: 'shutdown',
display: 'Shutdown',
message:
'In order to bring it back online, the machine will need to be visited and its power reset.'
'In order to bring it back online, the machine will need to be visited and its power reset.',
})
}>
Shutdown
@ -172,7 +172,7 @@ const MachineActions = memo(({ machine, onActionSuccess }) => {
onClick={() => {
machineStatusPreflight({
command: 'restartServices',
display: 'Restart services for'
display: 'Restart services for',
})
}}>
Restart services
@ -188,7 +188,7 @@ const MachineActions = memo(({ machine, onActionSuccess }) => {
command: 'emptyUnit',
display: 'Empty',
message:
"Triggering this action will move all cash inside the machine towards its cashbox (if possible), allowing for the collection of cash from the machine via only its cashbox. Depending on how full the cash units are, it's possible that this action will need to be used more than once to ensure that the unit is left completely empty."
"Triggering this action will move all cash inside the machine towards its cashbox (if possible), allowing for the collection of cash from the machine via only its cashbox. Depending on how full the cash units are, it's possible that this action will need to be used more than once to ensure that the unit is left completely empty.",
})
}}>
Empty Unit
@ -205,7 +205,7 @@ const MachineActions = memo(({ machine, onActionSuccess }) => {
command: 'refillUnit',
display: 'Refill',
message:
'Triggering this action will refill the recyclers in this machine, by using bills present in its cassettes. This action may require manual operation of the cassettes and close attention to make sure that the denominations in the cassettes match the denominations in the recyclers.'
'Triggering this action will refill the recyclers in this machine, by using bills present in its cassettes. This action may require manual operation of the cassettes and close attention to make sure that the denominations in the cassettes match the denominations in the recyclers.',
})
}}>
Refill Unit
@ -228,8 +228,8 @@ const MachineActions = memo(({ machine, onActionSuccess }) => {
simpleMachineAction({
variables: {
deviceId: machine.deviceId,
action: 'diagnostics'
}
action: 'diagnostics',
},
})
}
deviceId={machine.deviceId}
@ -253,8 +253,8 @@ const MachineActions = memo(({ machine, onActionSuccess }) => {
variables: {
deviceId: machine.deviceId,
action: `${action?.command}`,
...(action?.command === 'rename' && { newName: value })
}
...(action?.command === 'rename' && { newName: value }),
},
})
}}
onDismissed={() => {

View file

@ -7,7 +7,7 @@ import {
TBody,
Td,
Th,
Tr
Tr,
} from 'src/components/fake-table/Table'
import EditIcon from 'src/styling/icons/action/edit/white.svg?react'
@ -19,7 +19,7 @@ const SingleRowTable = ({
title,
items,
onEdit,
className
className,
}) => {
return (
<>

View file

@ -8,7 +8,7 @@ const EmptyTable = memo(({ message, className }) => {
<div
className={classNames(
className,
'flex flex-col items-center w-full mt-13 text-sm font-bold font-museo'
'flex flex-col items-center w-full mt-13 text-sm font-bold font-museo',
)}>
<EmptyTableIcon />
<H4>{message}</H4>

View file

@ -7,7 +7,7 @@ const Table = memo(({ className, children, ...props }) => {
{...props}
className={classnames(
'table-fixed border-separate border-spacing-0',
className
className,
)}>
{children}
</table>

View file

@ -7,7 +7,7 @@ const TableCell = memo(
({ colspan, rightAlign, className, children, ...props }) => {
const styles = {
[classes.tableCell]: true,
'text-right': rightAlign
'text-right': rightAlign,
}
return (
@ -18,7 +18,7 @@ const TableCell = memo(
{children}
</td>
)
}
},
)
export default TableCell

View file

@ -5,7 +5,7 @@ const TableHeaderCell = memo(
({ rightAlign, children, className, ...props }) => {
const styles = {
'bg-zodiac text-white py-0 px-6 h-8 text-sm text-left': true,
'text-right': rightAlign
'text-right': rightAlign,
}
return (
@ -13,7 +13,7 @@ const TableHeaderCell = memo(
{children}
</th>
)
}
},
)
export default TableHeaderCell

View file

@ -8,7 +8,7 @@ const TableRow = memo(
'h-8': !header && size === 'sm',
'h-9 font-bold text-base ': !header && size === 'lg',
'bg-misty-rose': error,
'bg-spring3': success
'bg-spring3': success,
}
return (
@ -16,7 +16,7 @@ const TableRow = memo(
{children}
</tr>
)
}
},
)
export default TableRow

View file

@ -15,5 +15,5 @@ export {
TableHead,
TableHeader,
TableRow,
TableBody
TableBody,
}

View file

@ -5,7 +5,7 @@ import {
AutoSizer,
List,
CellMeasurer,
CellMeasurerCache
CellMeasurerCache,
} from 'react-virtualized'
import {
Table,
@ -13,7 +13,7 @@ import {
THead,
Tr,
Td,
Th
Th,
} from 'src/components/fake-table/Table'
import { H4 } from 'src/components/typography'
import ExpandClosedIcon from 'src/styling/icons/action/expand/closed.svg?react'
@ -40,7 +40,7 @@ const Row = ({
const trClasses = {
'cursor-pointer': hasPointer,
'border-2 border-transparent': true,
'border-2 border-zircon shadow-md': expanded
'border-2 border-zircon shadow-md': expanded,
}
return (
@ -79,7 +79,7 @@ const Row = ({
<div className="pb-3">
<Tr
className={classnames({
'border-2 border-zircon shadow-md': expanded
'border-2 border-zircon shadow-md': expanded,
})}>
<Td width={width}>
<Details it={data} timezone={props.timezone} />
@ -126,7 +126,7 @@ const DataTable = ({
const cache = new CellMeasurerCache({
defaultHeight: 58,
fixedWidth: true
fixedWidth: true,
})
function rowRenderer({ index, key, parent, style }) {
@ -168,12 +168,12 @@ const DataTable = ({
<div
className={classnames({
'flex flex-1 flex-col': true,
[className]: !!className
[className]: !!className,
})}>
<Table
className={classnames(
'mb-12 min-h-50 flex-1 flex flex-col',
tableClassName
tableClassName,
)}
style={{ width }}>
<THead>

View file

@ -7,7 +7,7 @@ function H1({ children, noMargin, className, ...props }) {
const classNames = {
[styles.h1]: true,
[styles.noMargin]: noMargin,
[className]: !!className
[className]: !!className,
}
return (
@ -21,7 +21,7 @@ function H2({ children, noMargin, className, ...props }) {
const classNames = {
[styles.h2]: true,
[styles.noMargin]: noMargin,
[className]: !!className
[className]: !!className,
}
return (
@ -35,7 +35,7 @@ function H3({ children, noMargin, className, ...props }) {
const classNames = {
[styles.h3]: true,
[styles.noMargin]: noMargin,
[className]: !!className
[className]: !!className,
}
return (
@ -49,7 +49,7 @@ function H4({ children, noMargin, className, ...props }) {
const classNames = {
[styles.h4]: true,
[styles.noMargin]: noMargin,
[className]: !!className
[className]: !!className,
}
return (
@ -63,7 +63,7 @@ function H5({ children, noMargin, className, ...props }) {
const classNames = {
[styles.h5]: true,
[styles.noMargin]: noMargin,
[className]: !!className
[className]: !!className,
}
return (
@ -90,7 +90,7 @@ function pBuilder(elementClass) {
[className]: !!className,
[styles[elementClass]]: elementClass,
[styles.inline]: inline,
[styles.noMargin]: noMargin
[styles.noMargin]: noMargin,
}
return (
<p className={classnames(classNames)} {...props}>
@ -115,5 +115,5 @@ export {
Mono,
Label1,
Label2,
Label3
Label3,
}

View file

@ -7,132 +7,132 @@ import {
fontSize5,
fontPrimary,
fontSecondary,
fontMonospaced
fontMonospaced,
} from 'src/styling/variables'
const base = {
lineHeight: '120%',
color: fontColor
color: fontColor,
}
export default {
base: {
lineHeight: '120%',
color: fontColor
color: fontColor,
},
h1: {
extend: base,
fontSize: fontSize1,
fontFamily: fontPrimary,
fontWeight: 900
fontWeight: 900,
},
h2: {
extend: base,
fontSize: fontSize2,
fontFamily: fontPrimary,
fontWeight: 900
fontWeight: 900,
},
h3: {
extend: base,
fontSize: fontSize4,
fontFamily: fontPrimary,
fontWeight: 900
fontWeight: 900,
},
h4: {
extend: base,
fontSize: fontSize4,
fontFamily: fontPrimary,
fontWeight: 700
fontWeight: 700,
},
h5: {
extend: base,
fontSize: fontSize3,
fontFamily: fontPrimary,
fontWeight: 700
fontWeight: 700,
},
p: {
...base,
fontSize: fontSize4,
fontFamily: fontSecondary,
fontWeight: 500
fontWeight: 500,
},
tl1: {
extend: base,
fontSize: fontSize2,
fontFamily: fontSecondary,
fontWeight: 700
fontWeight: 700,
},
tl2: {
extend: base,
fontSize: fontSize4,
fontFamily: fontSecondary,
fontWeight: 700
fontWeight: 700,
},
info1: {
extend: base,
fontSize: fontSize1,
fontFamily: fontSecondary,
fontWeight: 700
fontWeight: 700,
},
info2: {
extend: base,
fontSize: fontSize3,
fontFamily: fontSecondary,
fontWeight: 700
fontWeight: 700,
},
info3: {
extend: base,
fontSize: fontSize3,
fontFamily: fontSecondary,
fontWeight: 500
fontWeight: 500,
},
mono: {
extend: base,
fontSize: fontSize4,
fontFamily: fontMonospaced,
fontWeight: 500
fontWeight: 500,
},
monoBold: {
fontWeight: 700
fontWeight: 700,
},
monoSmall: {
fontSize: fontSize5
fontSize: fontSize5,
},
inputFont: {
fontSize: fontSize2,
fontFamily: fontSecondary,
fontWeight: 500,
lineHeight: '110%',
color: fontColor
color: fontColor,
},
regularLabel: {
fontSize: fontSize4,
fontFamily: fontSecondary,
fontWeight: 500,
lineHeight: '110%'
lineHeight: '110%',
},
label1: {
fontSize: fontSize5,
fontFamily: fontSecondary,
fontWeight: 500,
color: fontColor
color: fontColor,
},
label2: {
fontSize: fontSize5,
fontFamily: fontSecondary,
fontWeight: 700,
color: fontColor
color: fontColor,
},
label3: {
fontSize: fontSize4,
fontFamily: fontSecondary,
fontWeight: 500,
color: fontColor
color: fontColor,
},
inline: {
display: 'inline'
display: 'inline',
},
noMargin: {
margin: 0
}
margin: 0,
},
}

View file

@ -7,5 +7,5 @@ ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
document.getElementById('root'),
)

View file

@ -58,7 +58,7 @@ const QrCodeComponent = ({ qrCode, name, count, onPaired }) => {
if (hasNewMachine) {
timeout.current = setTimeout(
() => onPaired(addedMachine),
CLOSE_SCREEN_TIMEOUT
CLOSE_SCREEN_TIMEOUT,
)
}
@ -111,7 +111,7 @@ const QrCodeComponent = ({ qrCode, name, count, onPaired }) => {
}
const initialValues = {
name: ''
name: '',
}
const validationSchema = Yup.object().shape({
@ -124,9 +124,9 @@ const validationSchema = Yup.object().shape({
(value, context) =>
!R.includes(
R.toLower(value),
R.map(R.toLower, context.options.context.machineNames)
)
)
R.map(R.toLower, context.options.context.machineNames),
),
),
})
const MachineNameComponent = ({ nextStep, setQrCode, setName }) => {
@ -138,7 +138,7 @@ const MachineNameComponent = ({ nextStep, setQrCode, setName }) => {
setQrCode(createPairingTotem)
nextStep()
},
onError: e => console.log(e)
onError: e => console.log(e),
})
const { data } = useQuery(GET_MACHINES)
@ -147,7 +147,7 @@ const MachineNameComponent = ({ nextStep, setQrCode, setName }) => {
const uniqueNameValidator = value => {
try {
validationSchema.validateSync(value, {
context: { machineNames: machineNames }
context: { machineNames: machineNames },
})
} catch (error) {
return error
@ -189,12 +189,12 @@ const MachineNameComponent = ({ nextStep, setQrCode, setName }) => {
const steps = [
{
label: 'Machine name',
component: MachineNameComponent
component: MachineNameComponent,
},
{
label: 'Scan QR code',
component: QrCodeComponent
}
component: QrCodeComponent,
},
]
const renderStepper = (step, it, idx) => {
@ -208,7 +208,7 @@ const renderStepper = (step, it, idx) => {
className={classnames({
'mr-6 text-comet': true,
'text-zodiac font-bold': active,
'text-zodiac': past
'text-zodiac': past,
})}>
{it.label}
</span>
@ -219,7 +219,7 @@ const renderStepper = (step, it, idx) => {
<div
className={classnames({
'absolute h-7 w-px border border-comet border-solid right-2 top-[18px]': true,
'border-zodiac': past
'border-zodiac': past,
})}></div>
)}
</div>

View file

@ -26,29 +26,29 @@ const REPRESENTING_OPTIONS = [
{ code: 'overTime', display: 'Over time' },
{ code: 'volumeOverTime', display: 'Volume' },
{ code: 'topMachines', display: 'Top machines' },
{ code: 'hourOfTheDay', display: 'Hour of the day' }
{ code: 'hourOfTheDay', display: 'Hour of the day' },
]
const PERIOD_OPTIONS = [
{ code: 'day', display: 'Last 24 hours' },
{ code: 'threeDays', display: 'Last 3 days' },
{ code: 'week', display: 'Last 7 days' },
{ code: 'month', display: 'Last 30 days' }
{ code: 'month', display: 'Last 30 days' },
]
const TIME_OPTIONS = {
day: DAY,
threeDays: 3 * DAY,
week: WEEK,
month: MONTH
month: MONTH,
}
const DAY_OPTIONS = R.map(
it => ({
code: R.toLower(it),
display: it
display: it,
}),
Array.from(Array(7)).map((_, i) =>
format('EEEE', add({ days: i }, startOfWeek(new Date())))
)
format('EEEE', add({ days: i }, startOfWeek(new Date()))),
),
)
const GET_TRANSACTIONS = gql`
@ -112,7 +112,7 @@ const OverviewEntry = ({ label, value, oldValue, currency }) => {
const growthClasses = {
'font-bold': true,
'text-malachite': R.gt(value, oldValue),
'text-tomato': R.gt(oldValue, value)
'text-tomato': R.gt(oldValue, value),
}
return (
@ -139,8 +139,8 @@ const Analytics = () => {
variables: {
from: subDays(65, endOfToday()),
until: endOfToday(),
excludeTestingCustomers: true
}
excludeTestingCustomers: true,
},
})
const { data: configResponse, loading: configLoading } = useQuery(GET_DATA)
@ -148,7 +148,7 @@ const Analytics = () => {
const [period, setPeriod] = useState(PERIOD_OPTIONS[0])
const [machine, setMachine] = useState(MACHINE_OPTIONS[0])
const [selectedDay, setSelectedDay] = useState(
R.equals(representing.code, 'hourOfTheDay') ? DAY_OPTIONS[0] : null
R.equals(representing.code, 'hourOfTheDay') ? DAY_OPTIONS[0] : null,
)
const loading = txLoading || configLoading
@ -175,20 +175,20 @@ const Analytics = () => {
tx =>
(!tx.dispensed || !tx.expired) &&
(tx.sendConfirmed || tx.dispense) &&
!tx.hasError
)
!tx.hasError,
),
) ?? []
const machineOptions = R.clone(MACHINE_OPTIONS)
R.forEach(
m => machineOptions.push({ code: m.deviceId, display: m.name }),
machines
machines,
)
const machineTxs = R.filter(
tx => (machine.code === 'all' ? true : tx.deviceId === machine.code),
data
data,
)
const filteredData = timeInterval => ({
@ -213,35 +213,35 @@ const Analytics = () => {
txDay < Date.now() - TIME_OPTIONS[timeInterval] &&
txDay >= Date.now() - 2 * TIME_OPTIONS[timeInterval]
)
}) ?? []
}) ?? [],
})
const txs = {
current: filteredData(period.code).current.length,
previous: filteredData(period.code).previous.length
previous: filteredData(period.code).previous.length,
}
const median = values => (values.length === 0 ? 0 : R.median(values))
const medianAmount = {
current: median(R.map(d => d.fiat, filteredData(period.code).current)),
previous: median(R.map(d => d.fiat, filteredData(period.code).previous))
previous: median(R.map(d => d.fiat, filteredData(period.code).previous)),
}
const txVolume = {
current: R.sum(R.map(d => d.fiat, filteredData(period.code).current)),
previous: R.sum(R.map(d => d.fiat, filteredData(period.code).previous))
previous: R.sum(R.map(d => d.fiat, filteredData(period.code).previous)),
}
const commissions = {
current: R.sum(R.map(d => d.profit, filteredData(period.code).current)),
previous: R.sum(R.map(d => d.profit, filteredData(period.code).previous))
previous: R.sum(R.map(d => d.profit, filteredData(period.code).previous)),
}
const handleRepresentationChange = newRepresentation => {
setRepresenting(newRepresentation)
setSelectedDay(
R.equals(newRepresentation.code, 'hourOfTheDay') ? DAY_OPTIONS[0] : null
R.equals(newRepresentation.code, 'hourOfTheDay') ? DAY_OPTIONS[0] : null,
)
}

View file

@ -13,20 +13,19 @@ const GraphTooltip = ({
coords,
data,
dateInterval,
period,
currency,
representing
representing,
}) => {
const formattedDateInterval = !R.includes('hourOfDay', representing.code)
? [
formatDate(dateInterval[1], null, 'MMM d'),
formatDate(dateInterval[1], null, 'HH:mm'),
formatDate(dateInterval[0], null, 'HH:mm')
formatDate(dateInterval[0], null, 'HH:mm'),
]
: [
formatDate(dateInterval[1], null, 'MMM d'),
formatDateNonUtc(dateInterval[1], 'HH:mm'),
formatDateNonUtc(dateInterval[0], 'HH:mm')
formatDateNonUtc(dateInterval[0], 'HH:mm'),
]
const transactions = R.reduce(
@ -37,7 +36,7 @@ const GraphTooltip = ({
return acc
},
{ volume: 0, cashIn: 0, cashOut: 0 },
data
data,
)
return (

View file

@ -12,7 +12,7 @@ import classes from './wrappers.module.css'
const options = [
{ code: 'hourOfDayTransactions', display: 'Transactions' },
{ code: 'hourOfDayVolume', display: 'Volume' }
{ code: 'hourOfDayVolume', display: 'Volume' },
]
const HourOfDayBarGraphHeader = ({
@ -26,13 +26,13 @@ const HourOfDayBarGraphHeader = ({
dayOptions,
handleDayChange,
timezone,
currency
currency,
}) => {
const [graphType /*, setGraphType */] = useState(options[0].code)
const legend = {
cashIn: <div className={classes.cashInIcon}></div>,
cashOut: <div className={classes.cashOutIcon}></div>
cashOut: <div className={classes.cashOutIcon}></div>,
}
const offset = getTimezoneOffset(timezone)
@ -41,7 +41,7 @@ const HourOfDayBarGraphHeader = ({
(acc, value) => {
const created = new Date(value.created)
created.setTime(
created.getTime() + created.getTimezoneOffset() * MINUTE + offset
created.getTime() + created.getTimezoneOffset() * MINUTE + offset,
)
switch (created.getDay()) {
case 0:
@ -71,7 +71,7 @@ const HourOfDayBarGraphHeader = ({
return acc
},
R.fromPairs(R.map(it => [it.code, []], dayOptions)),
data
data,
)
return (

View file

@ -18,7 +18,7 @@ const OverTimeDotGraphHeader = ({
selectedMachine,
handleMachineChange,
timezone,
currency
currency,
}) => {
const [logarithmic, setLogarithmic] = useState()
@ -35,7 +35,7 @@ const OverTimeDotGraphHeader = ({
d="M 5 6 l 20 0"
/>
</svg>
)
),
}
return (

View file

@ -8,7 +8,7 @@ import classes from './wrappers.module.css'
const options = [
{ code: 'topMachinesTransactions', display: 'Transactions' },
{ code: 'topMachinesVolume', display: 'Volume' }
{ code: 'topMachinesVolume', display: 'Volume' },
]
const TopMachinesBarGraphHeader = ({
@ -18,13 +18,13 @@ const TopMachinesBarGraphHeader = ({
machines,
selectedMachine,
timezone,
currency
currency,
}) => {
const [graphType /*, setGraphType */] = useState(options[0].code)
const legend = {
cashIn: <div className={classes.cashInIcon}></div>,
cashOut: <div className={classes.cashOutIcon}></div>
cashOut: <div className={classes.cashOutIcon}></div>,
}
return (

View file

@ -18,7 +18,7 @@ const VolumeOverTimeGraphHeader = ({
selectedMachine,
handleMachineChange,
timezone,
currency
currency,
}) => {
const [logarithmic, setLogarithmic] = useState()
@ -42,7 +42,7 @@ const VolumeOverTimeGraphHeader = ({
strokeLinecap="round"
/>
</svg>
)
),
}
return (

View file

@ -12,7 +12,7 @@
.graphHeaderRight {
margin-top: 15px;
display: flex;
gap: 30px
gap: 30px;
}
.cashInIcon {
@ -45,12 +45,12 @@
.graphHeaderSwitchBox {
display: flex;
flex-direction: column;
/*'& > *': {*/
/* margin: 0*/
/*},*/
/*'& > :first-child': {*/
/* marginBottom: 2,*/
/* extend: label1,*/
/* color: offColor*/
/*}*/
/*'& > *': {*/
/* margin: 0*/
/*},*/
/*'& > :first-child': {*/
/* marginBottom: 2,*/
/* extend: label1,*/
/* color: offColor*/
/*}*/
}

View file

@ -17,7 +17,7 @@ const GraphWrapper = ({
selectedMachine,
machines,
selectedDay,
log
log,
}) => {
const [selectionCoords, setSelectionCoords] = useState(null)
const [selectionDateInterval, setSelectionDateInterval] = useState(null)

View file

@ -11,7 +11,7 @@ import {
subheaderDarkColor,
fontColor,
fontSecondary,
subheaderColor
subheaderColor,
} from 'src/styling/variables'
import { MINUTE } from 'src/utils/time'
import { toUtc } from 'src/utils/timezones'
@ -22,7 +22,6 @@ const Graph = ({
setSelectionCoords,
setSelectionData,
setSelectionDateInterval,
selectedMachine
}) => {
const ref = useRef(null)
@ -36,9 +35,9 @@ const Graph = ({
top: 25,
right: 0.5,
bottom: 27,
left: 36.5
left: 36.5,
}),
[]
[],
)
const offset = getTimezoneOffset(timezone)
@ -64,7 +63,7 @@ const Graph = ({
const tzCreated = new Date(it.created).setTime(
new Date(it.created).getTime() +
new Date(it.created).getTimezoneOffset() * MINUTE +
offset
offset,
)
const created = new Date(tzCreated)
@ -77,7 +76,7 @@ const Graph = ({
created.getUTCHours() < new Date(upperBound).getUTCHours())
)
}, data),
[data, offset]
[data, offset],
)
const txClassByHourInterval = useCallback(
@ -91,16 +90,16 @@ const Graph = ({
return acc
},
{ cashIn: 0, cashOut: 0 },
filterByHourInterval(lowerBound, upperBound)
filterByHourInterval(lowerBound, upperBound),
),
[filterByHourInterval]
[filterByHourInterval],
)
const x = d3
.scaleUtc()
.domain([
toUtc(startOfDay(new Date())),
toUtc(add({ days: 1 }, startOfDay(new Date())))
toUtc(add({ days: 1 }, startOfDay(new Date()))),
])
.rangeRound([GRAPH_MARGIN.left, GRAPH_WIDTH - GRAPH_MARGIN.right])
@ -111,7 +110,7 @@ const Graph = ({
const upperBound = R.clone(it)
return [lowerBound, filterByHourInterval(lowerBound, upperBound)]
},
R.init(getTickIntervals(x.domain(), 2))
R.init(getTickIntervals(x.domain(), 2)),
)
const groupedByTxClass = R.map(
@ -121,7 +120,7 @@ const Graph = ({
const upperBound = R.clone(it)
return [lowerBound, txClassByHourInterval(lowerBound, upperBound)]
},
R.init(getTickIntervals(x.domain(), 2))
R.init(getTickIntervals(x.domain(), 2)),
)
const y = d3
@ -130,13 +129,13 @@ const Graph = ({
0,
d3.max(
groupedByTxClass.map(it => it[1]),
d => d.cashIn + d.cashOut
d => d.cashIn + d.cashOut,
) !== 0
? d3.max(
groupedByTxClass.map(it => it[1]),
d => d.cashIn + d.cashOut
d => d.cashIn + d.cashOut,
)
: 50
: 50,
])
.range([GRAPH_HEIGHT - GRAPH_MARGIN.bottom, GRAPH_MARGIN.top])
@ -145,15 +144,15 @@ const Graph = ({
g
.attr(
'transform',
`translate(0, ${GRAPH_HEIGHT - GRAPH_MARGIN.bottom})`
`translate(0, ${GRAPH_HEIGHT - GRAPH_MARGIN.bottom})`,
)
.call(
d3
.axisBottom(x)
.ticks(d3.timeHour.every(2))
.tickFormat(d3.timeFormat('%H:%M'))
.tickFormat(d3.timeFormat('%H:%M')),
),
[GRAPH_MARGIN, x]
[GRAPH_MARGIN, x],
)
const buildYAxis = useCallback(
@ -165,10 +164,10 @@ const Graph = ({
.axisLeft(y)
.ticks(GRAPH_HEIGHT / 100)
.tickSize(0)
.tickFormat(``)
.tickFormat(``),
)
.call(g => g.select('.domain').remove()),
[GRAPH_MARGIN, y]
[GRAPH_MARGIN, y],
)
const buildVerticalLines = useCallback(
@ -195,7 +194,7 @@ const Graph = ({
})
.attr('y1', GRAPH_MARGIN.top)
.attr('y2', GRAPH_HEIGHT - GRAPH_MARGIN.bottom),
[GRAPH_MARGIN, x]
[GRAPH_MARGIN, x],
)
const buildHoverableEventRects = useCallback(
@ -227,15 +226,15 @@ const Graph = ({
const endDate = R.clone(date)
const filteredData = groupedByDateInterval.find(it =>
R.equals(startDate, it[0])
R.equals(startDate, it[0]),
)[1]
const rectXCoords = {
left: R.clone(d.target.getBoundingClientRect().x),
right: R.clone(
d.target.getBoundingClientRect().x +
d.target.getBoundingClientRect().width
)
d.target.getBoundingClientRect().width,
),
}
const xCoord =
@ -248,18 +247,18 @@ const Graph = ({
setSelectionData(filteredData)
setSelectionCoords({
x: Math.round(xCoord),
y: Math.round(yCoord)
y: Math.round(yCoord),
})
d3.select(`#event-rect-${x(d.target.__data__)}`).attr(
'fill',
subheaderColor
subheaderColor,
)
})
.on('mouseleave', d => {
d3.select(`#event-rect-${x(d.target.__data__)}`).attr(
'fill',
'transparent'
'transparent',
)
setSelectionDateInterval(null)
setSelectionData(null)
@ -271,8 +270,8 @@ const Graph = ({
setSelectionCoords,
setSelectionData,
setSelectionDateInterval,
x
]
x,
],
)
const buildEventRects = useCallback(
@ -298,7 +297,7 @@ const Graph = ({
.attr('height', GRAPH_HEIGHT - GRAPH_MARGIN.bottom - GRAPH_MARGIN.top)
.attr('stroke', 'transparent')
.attr('fill', 'transparent'),
[GRAPH_MARGIN, x]
[GRAPH_MARGIN, x],
)
const formatTicksText = useCallback(
@ -309,7 +308,7 @@ const Graph = ({
.style('fill', fontColor)
.style('stroke-width', 0.5)
.style('font-family', fontSecondary),
[]
[],
)
const drawCashIn = useCallback(
@ -334,7 +333,7 @@ const Graph = ({
GRAPH_HEIGHT -
y(interval[1].cashIn) -
GRAPH_MARGIN.bottom -
BAR_MARGIN / 2
BAR_MARGIN / 2,
)
})
.attr('width', d => {
@ -348,7 +347,7 @@ const Graph = ({
})
.attr('rx', 2.5)
},
[x, y, GRAPH_MARGIN, groupedByTxClass]
[x, y, GRAPH_MARGIN, groupedByTxClass],
)
const drawCashOut = useCallback(
@ -377,7 +376,7 @@ const Graph = ({
GRAPH_HEIGHT -
y(interval[1].cashOut) -
GRAPH_MARGIN.bottom -
BAR_MARGIN / 2
BAR_MARGIN / 2,
)
})
.attr('width', d => {
@ -391,7 +390,7 @@ const Graph = ({
})
.attr('rx', 2.5)
},
[x, y, GRAPH_MARGIN, groupedByTxClass]
[x, y, GRAPH_MARGIN, groupedByTxClass],
)
const drawChart = useCallback(() => {
@ -417,7 +416,7 @@ const Graph = ({
buildVerticalLines,
drawCashIn,
formatTicksText,
drawCashOut
drawCashOut,
])
useEffect(() => {
@ -433,5 +432,5 @@ export default memo(
(prev, next) =>
R.equals(prev.period, next.period) &&
R.equals(prev.selectedDay, next.selectedDay) &&
R.equals(prev.selectedMachine, next.selectedMachine)
R.equals(prev.selectedMachine, next.selectedMachine),
)

View file

@ -13,7 +13,7 @@ import {
fontColor,
primaryColor,
fontSecondary,
subheaderColor
subheaderColor,
} from 'src/styling/variables'
import { numberToFiatAmount } from 'src/utils/number'
import { MINUTE, DAY, WEEK, MONTH } from 'src/utils/time'
@ -25,7 +25,7 @@ const Graph = ({
setSelectionCoords,
setSelectionData,
setSelectionDateInterval,
log = false
log = false,
}) => {
const ref = useRef(null)
@ -38,9 +38,9 @@ const Graph = ({
top: 25,
right: 3.5,
bottom: 27,
left: 38
left: 38,
}),
[]
[],
)
const offset = getTimezoneOffset(timezone)
@ -50,7 +50,7 @@ const Graph = ({
day: [NOW - DAY, NOW],
threeDays: [NOW - 3 * DAY, NOW],
week: [NOW - WEEK, NOW],
month: [NOW - MONTH, NOW]
month: [NOW - MONTH, NOW],
}
const dataPoints = useMemo(
@ -59,28 +59,28 @@ const Graph = ({
freq: 24,
step: 60 * 60 * 1000,
tick: d3.utcHour.every(1),
labelFormat: '%H:%M'
labelFormat: '%H:%M',
},
threeDays: {
freq: 12,
step: 6 * 60 * 60 * 1000,
tick: d3.utcDay.every(1),
labelFormat: '%a %d'
labelFormat: '%a %d',
},
week: {
freq: 7,
step: 24 * 60 * 60 * 1000,
tick: d3.utcDay.every(1),
labelFormat: '%a %d'
labelFormat: '%a %d',
},
month: {
freq: 30,
step: 24 * 60 * 60 * 1000,
tick: d3.utcDay.every(1),
labelFormat: '%d'
}
labelFormat: '%d',
},
}),
[]
[],
)
const getPastAndCurrentDayLabels = useCallback(d => {
@ -97,11 +97,11 @@ const Graph = ({
const previousDateMonth = previousDate.getUTCMonth()
const daysOfWeek = Array.from(Array(7)).map((_, i) =>
format('EEE', add({ days: i }, startOfWeek(new Date())))
format('EEE', add({ days: i }, startOfWeek(new Date()))),
)
const months = Array.from(Array(12)).map((_, i) =>
format('LLL', add({ months: i }, startOfYear(new Date())))
format('LLL', add({ months: i }, startOfYear(new Date()))),
)
return {
@ -112,7 +112,7 @@ const Graph = ({
current:
currentDateMonth !== previousDateMonth
? months[currentDateMonth]
: `${daysOfWeek[currentDateWeekday]} ${currentDateDay}`
: `${daysOfWeek[currentDateWeekday]} ${currentDateDay}`,
}
}, [])
@ -134,7 +134,7 @@ const Graph = ({
return points
},
[NOW, dataPoints, period.code]
[NOW, dataPoints, period.code],
)
const buildAreas = useCallback(
@ -159,7 +159,7 @@ const Graph = ({
return points
},
[NOW, dataPoints, period.code]
[NOW, dataPoints, period.code],
)
const x = d3
@ -177,7 +177,7 @@ const Graph = ({
.scaleLinear()
.domain([
0,
(d3.max(data, d => new BigNumber(d.fiat).toNumber()) ?? 1000) * 1.03
(d3.max(data, d => new BigNumber(d.fiat).toNumber()) ?? 1000) * 1.03,
])
.nice()
.range([GRAPH_HEIGHT - GRAPH_MARGIN.bottom, GRAPH_MARGIN.top])
@ -186,7 +186,7 @@ const Graph = ({
.scaleLog()
.domain([
(d3.min(data, d => new BigNumber(d.fiat).toNumber()) ?? 1) * 0.9,
(d3.max(data, d => new BigNumber(d.fiat).toNumber()) ?? 1000) * 1.1
(d3.max(data, d => new BigNumber(d.fiat).toNumber()) ?? 1000) * 1.1,
])
.range([GRAPH_HEIGHT - GRAPH_MARGIN.bottom, GRAPH_MARGIN.top])
@ -196,7 +196,7 @@ const Graph = ({
const fullBreakpoints = [
graphLimits[1],
...R.filter(it => it > dataLimits[0] && it < dataLimits[1], breakpoints),
dataLimits[0]
dataLimits[0],
]
const intervals = []
@ -227,7 +227,7 @@ const Graph = ({
g
.attr(
'transform',
`translate(0, ${GRAPH_HEIGHT - GRAPH_MARGIN.bottom})`
`translate(0, ${GRAPH_HEIGHT - GRAPH_MARGIN.bottom})`,
)
.call(
d3
@ -235,18 +235,18 @@ const Graph = ({
.ticks(dataPoints[period.code].tick)
.tickFormat(d => {
return d3.timeFormat(dataPoints[period.code].labelFormat)(
d.getTime() + d.getTimezoneOffset() * MINUTE
d.getTime() + d.getTimezoneOffset() * MINUTE,
)
})
.tickSizeOuter(0)
.tickSizeOuter(0),
)
.call(g =>
g
.select('.domain')
.attr('stroke', primaryColor)
.attr('stroke-width', 1)
.attr('stroke-width', 1),
),
[GRAPH_MARGIN, dataPoints, period.code, x]
[GRAPH_MARGIN, dataPoints, period.code, x],
)
const buildYAxis = useCallback(
@ -264,12 +264,12 @@ const Graph = ({
if (d >= 1000) return numberToFiatAmount(d / 1000) + 'k'
return numberToFiatAmount(d)
})
}),
)
.select('.domain')
.attr('stroke', primaryColor)
.attr('stroke-width', 1),
[GRAPH_MARGIN, y, log]
[GRAPH_MARGIN, y, log],
)
const buildGrid = useCallback(
@ -286,7 +286,7 @@ const Graph = ({
.attr('x1', d => 0.5 + x(d))
.attr('x2', d => 0.5 + x(d))
.attr('y1', GRAPH_MARGIN.top)
.attr('y2', GRAPH_HEIGHT - GRAPH_MARGIN.bottom)
.attr('y2', GRAPH_HEIGHT - GRAPH_MARGIN.bottom),
)
// Horizontal lines
.call(g =>
@ -297,13 +297,13 @@ const Graph = ({
d3
.axisLeft(y)
.scale()
.ticks(GRAPH_HEIGHT / 100)
.ticks(GRAPH_HEIGHT / 100),
)
.join('line')
.attr('y1', d => 0.5 + y(d))
.attr('y2', d => 0.5 + y(d))
.attr('x1', GRAPH_MARGIN.left)
.attr('x2', GRAPH_WIDTH)
.attr('x2', GRAPH_WIDTH),
)
// Vertical transparent rectangles for events
.call(g =>
@ -319,14 +319,14 @@ const Graph = ({
const intervals = getAreaInterval(
buildAreas(x.domain()).map(it => Math.round(x(it) * 100) / 100),
x.range(),
x2.range()
x2.range(),
)
const interval = getAreaIntervalByX(intervals, xValue)
return Math.round((interval[0] - interval[1]) * 100) / 100
})
.attr(
'height',
GRAPH_HEIGHT - GRAPH_MARGIN.bottom - GRAPH_MARGIN.top
GRAPH_HEIGHT - GRAPH_MARGIN.bottom - GRAPH_MARGIN.top,
)
.attr('stroke', 'transparent')
.attr('fill', 'transparent')
@ -336,7 +336,7 @@ const Graph = ({
const intervals = getAreaInterval(
buildAreas(x.domain()).map(it => Math.round(x(it) * 100) / 100),
x.range(),
x2.range()
x2.range(),
)
const dateInterval = getDateIntervalByX(areas, intervals, xValue)
@ -354,8 +354,8 @@ const Graph = ({
left: R.clone(d.target.getBoundingClientRect().x),
right: R.clone(
d.target.getBoundingClientRect().x +
d.target.getBoundingClientRect().width
)
d.target.getBoundingClientRect().width,
),
}
const xCoord =
@ -370,7 +370,7 @@ const Graph = ({
setSelectionData(filteredData)
setSelectionCoords({
x: Math.round(xCoord),
y: Math.round(yCoord)
y: Math.round(yCoord),
})
d3.select(d.target).attr('fill', subheaderColor)
@ -380,7 +380,7 @@ const Graph = ({
setSelectionDateInterval(null)
setSelectionData(null)
setSelectionCoords(null)
})
}),
)
// Thick vertical lines
.call(g =>
@ -391,7 +391,7 @@ const Graph = ({
buildTicks(x.domain()).filter(x => {
if (period.code === 'day') return x.getUTCHours() === 0
return x.getUTCDate() === 1
})
}),
)
.join('line')
.attr('class', 'dateSeparator')
@ -400,7 +400,7 @@ const Graph = ({
.attr('y1', GRAPH_MARGIN.top - 50)
.attr('y2', GRAPH_HEIGHT - GRAPH_MARGIN.bottom)
.attr('stroke-width', 5)
.join('text')
.join('text'),
)
// Left side breakpoint label
.call(g => {
@ -458,8 +458,8 @@ const Graph = ({
offset,
setSelectionCoords,
setSelectionData,
setSelectionDateInterval
]
setSelectionDateInterval,
],
)
const formatTicksText = useCallback(
@ -470,7 +470,7 @@ const Graph = ({
.style('fill', fontColor)
.style('stroke-width', 0.5)
.style('font-family', fontSecondary),
[]
[],
)
const formatText = useCallback(
@ -481,7 +481,7 @@ const Graph = ({
.style('fill', offColor)
.style('stroke-width', 0.5)
.style('font-family', fontSecondary),
[]
[],
)
const formatTicks = useCallback(() => {
@ -505,10 +505,10 @@ const Graph = ({
.attr('y1', 0.5 + y(median))
.attr('y2', 0.5 + y(median))
.attr('x1', GRAPH_MARGIN.left)
.attr('x2', GRAPH_WIDTH)
.attr('x2', GRAPH_WIDTH),
)
},
[GRAPH_MARGIN, y, data, log]
[GRAPH_MARGIN, y, data, log],
)
const drawData = useCallback(
@ -524,7 +524,7 @@ const Graph = ({
.attr('fill', d => (d.txClass === 'cashIn' ? java : neon))
.attr('r', 3.5)
},
[data, offset, x, y]
[data, offset, x, y],
)
const drawChart = useCallback(() => {
@ -550,7 +550,7 @@ const Graph = ({
drawData,
formatText,
formatTicks,
formatTicksText
formatTicksText,
])
useEffect(() => {
@ -566,5 +566,5 @@ export default memo(
(prev, next) =>
R.equals(prev.period, next.period) &&
R.equals(prev.selectedMachine, next.selectedMachine) &&
R.equals(prev.log, next.log)
R.equals(prev.log, next.log),
)

View file

@ -8,7 +8,7 @@ import {
differenceInMilliseconds,
format,
startOfWeek,
startOfYear
startOfYear,
} from 'date-fns/fp'
import * as R from 'ramda'
import React, { memo, useCallback, useEffect, useMemo, useRef } from 'react'
@ -21,7 +21,7 @@ import {
fontColor,
primaryColor,
fontSecondary,
subheaderColor
subheaderColor,
} from 'src/styling/variables'
import { numberToFiatAmount } from 'src/utils/number'
import { MINUTE, DAY, WEEK, MONTH } from 'src/utils/time'
@ -33,7 +33,7 @@ const Graph = ({
setSelectionCoords,
setSelectionData,
setSelectionDateInterval,
log = false
log = false,
}) => {
const ref = useRef(null)
@ -46,9 +46,9 @@ const Graph = ({
top: 25,
right: 3.5,
bottom: 27,
left: 38
left: 38,
}),
[]
[],
)
const offset = getTimezoneOffset(timezone)
@ -58,7 +58,7 @@ const Graph = ({
day: [NOW - DAY, NOW],
threeDays: [NOW - 3 * DAY, NOW],
week: [NOW - WEEK, NOW],
month: [NOW - MONTH, NOW]
month: [NOW - MONTH, NOW],
}
const dataPoints = useMemo(
@ -67,28 +67,28 @@ const Graph = ({
freq: 24,
step: 60 * 60 * 1000,
tick: d3.utcHour.every(1),
labelFormat: '%H:%M'
labelFormat: '%H:%M',
},
threeDays: {
freq: 12,
step: 6 * 60 * 60 * 1000,
tick: d3.utcDay.every(1),
labelFormat: '%a %d'
labelFormat: '%a %d',
},
week: {
freq: 7,
step: 24 * 60 * 60 * 1000,
tick: d3.utcDay.every(1),
labelFormat: '%a %d'
labelFormat: '%a %d',
},
month: {
freq: 30,
step: 24 * 60 * 60 * 1000,
tick: d3.utcDay.every(1),
labelFormat: '%d'
}
labelFormat: '%d',
},
}),
[]
[],
)
const getPastAndCurrentDayLabels = useCallback(d => {
@ -105,11 +105,11 @@ const Graph = ({
const previousDateMonth = previousDate.getUTCMonth()
const daysOfWeek = Array.from(Array(7)).map((_, i) =>
format('EEE', add({ days: i }, startOfWeek(new Date())))
format('EEE', add({ days: i }, startOfWeek(new Date()))),
)
const months = Array.from(Array(12)).map((_, i) =>
format('LLL', add({ months: i }, startOfYear(new Date())))
format('LLL', add({ months: i }, startOfYear(new Date()))),
)
return {
@ -120,7 +120,7 @@ const Graph = ({
current:
currentDateMonth !== previousDateMonth
? months[currentDateMonth]
: `${daysOfWeek[currentDateWeekday]} ${currentDateDay}`
: `${daysOfWeek[currentDateWeekday]} ${currentDateDay}`,
}
}, [])
@ -142,7 +142,7 @@ const Graph = ({
return points
},
[NOW, dataPoints, period.code]
[NOW, dataPoints, period.code],
)
const buildAreas = useCallback(
@ -167,7 +167,7 @@ const Graph = ({
return points
},
[NOW, dataPoints, period.code]
[NOW, dataPoints, period.code],
)
const x = d3
@ -192,14 +192,14 @@ const Graph = ({
else if (i === dates.length - 1)
return addMilliseconds(
-dataPoints[period.code].step,
dates[dates.length - 2]
dates[dates.length - 2],
)
else return date
})
.map(date => {
const middleOfBin = addMilliseconds(
dataPoints[period.code].step / 2,
date
date,
)
const txs = data.filter(tx => {
@ -236,7 +236,7 @@ const Graph = ({
.scaleLog()
.domain([
min === 0 ? 0.9 : min * 0.9,
(max === min ? min + Math.pow(10, 2 * min + 1) : max) * 2
(max === min ? min + Math.pow(10, 2 * min + 1) : max) * 2,
])
.clamp(true)
.range([GRAPH_HEIGHT - GRAPH_MARGIN.bottom, GRAPH_MARGIN.top])
@ -247,7 +247,7 @@ const Graph = ({
const fullBreakpoints = [
graphLimits[1],
...R.filter(it => it > dataLimits[0] && it < dataLimits[1], breakpoints),
dataLimits[0]
dataLimits[0],
]
const intervals = []
@ -278,7 +278,7 @@ const Graph = ({
g
.attr(
'transform',
`translate(0, ${GRAPH_HEIGHT - GRAPH_MARGIN.bottom})`
`translate(0, ${GRAPH_HEIGHT - GRAPH_MARGIN.bottom})`,
)
.call(
d3
@ -286,18 +286,18 @@ const Graph = ({
.ticks(dataPoints[period.code].tick)
.tickFormat(d => {
return d3.timeFormat(dataPoints[period.code].labelFormat)(
d.getTime() + d.getTimezoneOffset() * MINUTE
d.getTime() + d.getTimezoneOffset() * MINUTE,
)
})
.tickSizeOuter(0)
.tickSizeOuter(0),
)
.call(g =>
g
.select('.domain')
.attr('stroke', primaryColor)
.attr('stroke-width', 1)
.attr('stroke-width', 1),
),
[GRAPH_MARGIN, dataPoints, period.code, x]
[GRAPH_MARGIN, dataPoints, period.code, x],
)
const buildYAxis = useCallback(
@ -315,12 +315,12 @@ const Graph = ({
if (d >= 1000) return numberToFiatAmount(d / 1000) + 'k'
return numberToFiatAmount(d)
})
}),
)
.select('.domain')
.attr('stroke', primaryColor)
.attr('stroke-width', 1),
[GRAPH_MARGIN, y, log]
[GRAPH_MARGIN, y, log],
)
const buildGrid = useCallback(
@ -337,7 +337,7 @@ const Graph = ({
.attr('x1', d => 0.5 + x(d))
.attr('x2', d => 0.5 + x(d))
.attr('y1', GRAPH_MARGIN.top)
.attr('y2', GRAPH_HEIGHT - GRAPH_MARGIN.bottom)
.attr('y2', GRAPH_HEIGHT - GRAPH_MARGIN.bottom),
)
// Horizontal lines
.call(g =>
@ -348,13 +348,13 @@ const Graph = ({
d3
.axisLeft(y)
.scale()
.ticks(GRAPH_HEIGHT / 100)
.ticks(GRAPH_HEIGHT / 100),
)
.join('line')
.attr('y1', d => 0.5 + y(d))
.attr('y2', d => 0.5 + y(d))
.attr('x1', GRAPH_MARGIN.left)
.attr('x2', GRAPH_WIDTH)
.attr('x2', GRAPH_WIDTH),
)
// Vertical transparent rectangles for events
.call(g =>
@ -370,14 +370,14 @@ const Graph = ({
const intervals = getAreaInterval(
buildAreas(x.domain()).map(it => Math.round(x(it) * 100) / 100),
x.range(),
x2.range()
x2.range(),
)
const interval = getAreaIntervalByX(intervals, xValue)
return Math.round((interval[0] - interval[1]) * 100) / 100
})
.attr(
'height',
GRAPH_HEIGHT - GRAPH_MARGIN.bottom - GRAPH_MARGIN.top
GRAPH_HEIGHT - GRAPH_MARGIN.bottom - GRAPH_MARGIN.top,
)
.attr('stroke', 'transparent')
.attr('fill', 'transparent')
@ -387,7 +387,7 @@ const Graph = ({
const intervals = getAreaInterval(
buildAreas(x.domain()).map(it => Math.round(x(it) * 100) / 100),
x.range(),
x2.range()
x2.range(),
)
const dateInterval = getDateIntervalByX(areas, intervals, xValue)
@ -405,8 +405,8 @@ const Graph = ({
left: R.clone(d.target.getBoundingClientRect().x),
right: R.clone(
d.target.getBoundingClientRect().x +
d.target.getBoundingClientRect().width
)
d.target.getBoundingClientRect().width,
),
}
const xCoord =
@ -421,7 +421,7 @@ const Graph = ({
setSelectionData(filteredData)
setSelectionCoords({
x: Math.round(xCoord),
y: Math.round(yCoord)
y: Math.round(yCoord),
})
d3.select(d.target).attr('fill', subheaderColor)
@ -431,7 +431,7 @@ const Graph = ({
setSelectionDateInterval(null)
setSelectionData(null)
setSelectionCoords(null)
})
}),
)
// Thick vertical lines
.call(g =>
@ -442,7 +442,7 @@ const Graph = ({
buildTicks(x.domain()).filter(x => {
if (period.code === 'day') return x.getUTCHours() === 0
return x.getUTCDate() === 1
})
}),
)
.join('line')
.attr('class', 'dateSeparator')
@ -451,7 +451,7 @@ const Graph = ({
.attr('y1', GRAPH_MARGIN.top - 50)
.attr('y2', GRAPH_HEIGHT - GRAPH_MARGIN.bottom)
.attr('stroke-width', 5)
.join('text')
.join('text'),
)
// Left side breakpoint label
.call(g => {
@ -509,8 +509,8 @@ const Graph = ({
offset,
setSelectionCoords,
setSelectionData,
setSelectionDateInterval
]
setSelectionDateInterval,
],
)
const formatTicksText = useCallback(
@ -521,7 +521,7 @@ const Graph = ({
.style('fill', fontColor)
.style('stroke-width', 0.5)
.style('font-family', fontSecondary),
[]
[],
)
const formatText = useCallback(
@ -532,7 +532,7 @@ const Graph = ({
.style('fill', offColor)
.style('stroke-width', 0.5)
.style('font-family', fontSecondary),
[]
[],
)
const formatTicks = useCallback(() => {
@ -574,7 +574,7 @@ const Graph = ({
.line()
.curve(d3.curveMonotoneX)
.x(d => x(d.date))
.y(d => y(d.cashIn))
.y(d => y(d.cashIn)),
)
g.append('g')
@ -599,10 +599,10 @@ const Graph = ({
.line()
.curve(d3.curveMonotoneX)
.x(d => x(d.date))
.y(d => y(d.cashOut))
.y(d => y(d.cashOut)),
)
},
[x, y, bins, GRAPH_MARGIN]
[x, y, bins, GRAPH_MARGIN],
)
const drawChart = useCallback(() => {
@ -626,7 +626,7 @@ const Graph = ({
drawData,
formatText,
formatTicks,
formatTicksText
formatTicksText,
])
useEffect(() => {
@ -642,5 +642,5 @@ export default memo(
(prev, next) =>
R.equals(prev.period, next.period) &&
R.equals(prev.selectedMachine, next.selectedMachine) &&
R.equals(prev.log, next.log)
R.equals(prev.log, next.log),
)

View file

@ -8,10 +8,10 @@ import {
neon,
subheaderDarkColor,
fontColor,
fontSecondary
fontSecondary,
} from 'src/styling/variables'
const Graph = ({ data, machines, currency, selectedMachine }) => {
const Graph = ({ data, machines, currency }) => {
const ref = useRef(null)
const AMOUNT_OF_MACHINES = 5
@ -24,9 +24,9 @@ const Graph = ({ data, machines, currency, selectedMachine }) => {
top: 25,
right: 0.5,
bottom: 27,
left: 36.5
left: 36.5,
}),
[]
[],
)
const machinesClone = R.clone(machines)
@ -41,7 +41,7 @@ const Graph = ({ data, machines, currency, selectedMachine }) => {
if (!R.isNil(machinesClone[it])) return machinesClone[it]
return { code: `ghostMachine${it}`, display: `` }
},
R.times(R.identity, AMOUNT_OF_MACHINES)
R.times(R.identity, AMOUNT_OF_MACHINES),
)
const txByDevice = R.reduce(
@ -50,14 +50,14 @@ const Graph = ({ data, machines, currency, selectedMachine }) => {
return acc
},
{},
filledMachines
filledMachines,
)
const getDeviceVolume = deviceId =>
R.reduce(
(acc, value) => acc + BigNumber(value.fiat).toNumber(),
0,
txByDevice[deviceId]
txByDevice[deviceId],
)
const getDeviceVolumeByTxClass = deviceId =>
@ -70,18 +70,18 @@ const Graph = ({ data, machines, currency, selectedMachine }) => {
return acc
},
{ cashIn: 0, cashOut: 0 },
txByDevice[deviceId]
txByDevice[deviceId],
)
const devicesByVolume = R.sort(
(a, b) => b[1] - a[1],
R.map(m => [m.code, getDeviceVolume(m.code)], filledMachines)
R.map(m => [m.code, getDeviceVolume(m.code)], filledMachines),
)
const topMachines = R.take(AMOUNT_OF_MACHINES, devicesByVolume)
const txClassVolumeByDevice = R.fromPairs(
R.map(v => [v[0], getDeviceVolumeByTxClass(v[0])], topMachines)
R.map(v => [v[0], getDeviceVolumeByTxClass(v[0])], topMachines),
)
const x = d3
@ -94,7 +94,9 @@ const Graph = ({ data, machines, currency, selectedMachine }) => {
.scaleLinear()
.domain([
0,
d3.max(topMachines, d => d[1]) !== 0 ? d3.max(topMachines, d => d[1]) : 50
d3.max(topMachines, d => d[1]) !== 0
? d3.max(topMachines, d => d[1])
: 50,
])
.range([GRAPH_HEIGHT - GRAPH_MARGIN.bottom, GRAPH_MARGIN.top])
@ -104,7 +106,7 @@ const Graph = ({ data, machines, currency, selectedMachine }) => {
.attr('class', 'x-axis-1')
.attr(
'transform',
`translate(0, ${GRAPH_HEIGHT - GRAPH_MARGIN.bottom})`
`translate(0, ${GRAPH_HEIGHT - GRAPH_MARGIN.bottom})`,
)
.call(
d3
@ -113,12 +115,12 @@ const Graph = ({ data, machines, currency, selectedMachine }) => {
d =>
`${
R.find(it => it.code === d[0], filledMachines).display ?? ''
}`
}`,
)
.tickSize(0)
.tickPadding(10)
.tickPadding(10),
),
[GRAPH_MARGIN, x, filledMachines]
[GRAPH_MARGIN, x, filledMachines],
)
const buildXAxis2 = useCallback(
@ -126,7 +128,7 @@ const Graph = ({ data, machines, currency, selectedMachine }) => {
g.attr('class', 'x-axis-2')
.attr(
'transform',
`translate(0, ${GRAPH_HEIGHT - GRAPH_MARGIN.bottom})`
`translate(0, ${GRAPH_HEIGHT - GRAPH_MARGIN.bottom})`,
)
.call(
d3
@ -134,24 +136,24 @@ const Graph = ({ data, machines, currency, selectedMachine }) => {
.tickFormat(d =>
R.includes(`ghostMachine`, d[0])
? ``
: `${d[1].toFixed(2)} ${currency}`
: `${d[1].toFixed(2)} ${currency}`,
)
.tickSize(0)
.tickPadding(10)
.tickPadding(10),
)
},
[GRAPH_MARGIN, x, currency]
[GRAPH_MARGIN, x, currency],
)
const positionXAxisLabels = useCallback(() => {
d3.selectAll('.x-axis-1 .tick text').attr('transform', function (d) {
d3.selectAll('.x-axis-1 .tick text').attr('transform', function () {
const widthPerEntry = (x.range()[1] - x.range()[0]) / AMOUNT_OF_MACHINES
return `translate(${-widthPerEntry / 2.25 + this.getBBox().width / 2}, 0)`
})
}, [x])
const positionXAxis2Labels = useCallback(() => {
d3.selectAll('.x-axis-2 .tick text').attr('transform', function (d) {
d3.selectAll('.x-axis-2 .tick text').attr('transform', function () {
const widthPerEntry = (x.range()[1] - x.range()[0]) / AMOUNT_OF_MACHINES
return `translate(${widthPerEntry / 2.25 - this.getBBox().width / 2}, 0)`
})
@ -166,10 +168,10 @@ const Graph = ({ data, machines, currency, selectedMachine }) => {
.axisLeft(y)
.ticks(GRAPH_HEIGHT / 100)
.tickSize(0)
.tickFormat(``)
.tickFormat(``),
)
.call(g => g.select('.domain').remove()),
[GRAPH_MARGIN, y]
[GRAPH_MARGIN, y],
)
const formatTicksText = useCallback(
@ -180,7 +182,7 @@ const Graph = ({ data, machines, currency, selectedMachine }) => {
.style('fill', fontColor)
.style('stroke-width', 0.5)
.style('font-family', fontSecondary),
[]
[],
)
const buildGrid = useCallback(
@ -213,10 +215,10 @@ const Graph = ({ data, machines, currency, selectedMachine }) => {
return 0.5 + x(d) - paddedXValue
})
.attr('y1', GRAPH_MARGIN.top)
.attr('y2', GRAPH_HEIGHT - GRAPH_MARGIN.bottom)
.attr('y2', GRAPH_HEIGHT - GRAPH_MARGIN.bottom),
)
},
[GRAPH_MARGIN, x]
[GRAPH_MARGIN, x],
)
const drawCashIn = useCallback(
@ -231,13 +233,13 @@ const Graph = ({ data, machines, currency, selectedMachine }) => {
R.clamp(
0,
GRAPH_HEIGHT,
GRAPH_HEIGHT - y(d[1].cashIn) - GRAPH_MARGIN.bottom - BAR_MARGIN
)
GRAPH_HEIGHT - y(d[1].cashIn) - GRAPH_MARGIN.bottom - BAR_MARGIN,
),
)
.attr('width', x.bandwidth())
.attr('rx', 2.5)
},
[txClassVolumeByDevice, x, y, GRAPH_MARGIN]
[txClassVolumeByDevice, x, y, GRAPH_MARGIN],
)
const drawCashOut = useCallback(
@ -252,7 +254,7 @@ const Graph = ({ data, machines, currency, selectedMachine }) => {
d =>
y(d[1].cashIn + d[1].cashOut) -
GRAPH_MARGIN.top +
GRAPH_MARGIN.bottom
GRAPH_MARGIN.bottom,
)
.attr('height', d => {
return R.clamp(
@ -261,13 +263,13 @@ const Graph = ({ data, machines, currency, selectedMachine }) => {
GRAPH_HEIGHT -
y(d[1].cashOut) -
GRAPH_MARGIN.bottom -
BAR_MARGIN / 2
BAR_MARGIN / 2,
)
})
.attr('width', x.bandwidth())
.attr('rx', 2.5)
},
[txClassVolumeByDevice, x, y, GRAPH_MARGIN]
[txClassVolumeByDevice, x, y, GRAPH_MARGIN],
)
const drawChart = useCallback(() => {
@ -295,7 +297,7 @@ const Graph = ({ data, machines, currency, selectedMachine }) => {
formatTicksText,
buildGrid,
drawCashIn,
drawCashOut
drawCashOut,
])
useEffect(() => {
@ -310,5 +312,5 @@ export default memo(
Graph,
(prev, next) =>
R.equals(prev.period, next.period) &&
R.equals(prev.selectedMachine, next.selectedMachine)
R.equals(prev.selectedMachine, next.selectedMachine),
)

View file

@ -1,5 +1,6 @@
.welcomeBackground {
background: var(--ghost) url(/wizard-background.svg) no-repeat fixed center center;
background: var(--ghost) url(/wizard-background.svg) no-repeat fixed center
center;
background-size: cover;
height: 100vh;
width: 100vw;
@ -22,7 +23,7 @@
display: flex;
flex-direction: row;
align-items: center;
margin-bottom: 30px
margin-bottom: 30px;
}
.icon {
@ -70,4 +71,3 @@
.confirm2FAInput {
margin-top: 25px;
}

View file

@ -46,7 +46,7 @@ const Input2FAState = ({ state, dispatch }) => {
onCompleted: ({ userData }) => {
setUserData(userData)
history.push('/')
}
},
})
const [input2FA, { error: mutationError }] = useMutation(INPUT_2FA, {
@ -55,15 +55,15 @@ const Input2FAState = ({ state, dispatch }) => {
return getUserData()
}
return setInvalidToken(true)
}
},
})
const handle2FAChange = value => {
dispatch({
type: STATES.INPUT_2FA,
payload: {
twoFAField: value
}
twoFAField: value,
},
})
setInvalidToken(false)
}
@ -79,8 +79,8 @@ const Input2FAState = ({ state, dispatch }) => {
username: state.clientField,
password: state.passwordField,
code: state.twoFAField,
rememberMe: state.rememberMeField
}
rememberMe: state.rememberMeField,
},
}
input2FA(options)

View file

@ -24,12 +24,12 @@ const validationSchema = Yup.object().shape({
localClient: Yup.string()
.required('Client field is required!')
.email('Username field should be in an email format!'),
localRememberMe: Yup.boolean()
localRememberMe: Yup.boolean(),
})
const initialValues = {
localClient: '',
localRememberMe: false
localRememberMe: false,
}
const InputFIDOState = ({ state, strategy }) => {
@ -74,8 +74,8 @@ const InputFIDOState = ({ state, strategy }) => {
{
onCompleted: ({ validateAssertion: success }) => {
success ? getUserData() : setInvalidToken(true)
}
}
},
},
)
const [assertionOptions, { error: assertionQueryError }] = useLazyQuery(
@ -86,11 +86,11 @@ const InputFIDOState = ({ state, strategy }) => {
? {
username: state.clientField,
password: state.passwordField,
domain: window.location.hostname
domain: window.location.hostname,
}
: {
username: localClientField,
domain: window.location.hostname
domain: window.location.hostname,
},
onCompleted: ({ generateAssertionOptions: options }) => {
startAssertion(options)
@ -102,31 +102,31 @@ const InputFIDOState = ({ state, strategy }) => {
password: state.passwordField,
rememberMe: state.rememberMeField,
assertionResponse: res,
domain: window.location.hostname
domain: window.location.hostname,
}
: {
username: localClientField,
rememberMe: localRememberMeField,
assertionResponse: res,
domain: window.location.hostname
domain: window.location.hostname,
}
validateAssertion({
variables
variables,
})
})
.catch(err => {
console.error(err)
setInvalidToken(true)
})
}
}
},
},
)
const [getUserData, { error: queryError }] = useLazyQuery(GET_USER_DATA, {
onCompleted: ({ userData }) => {
setUserData(userData)
history.push('/')
}
},
})
const getErrorMsg = (formikErrors, formikTouched) => {

View file

@ -1,6 +1,5 @@
import Paper from '@mui/material/Paper'
import React, { useReducer } from 'react'
import { H5 } from 'src/components/typography'
import Logo from 'src/styling/icons/menu/logo.svg?react'
import Input2FAState from './Input2FAState'
@ -18,7 +17,7 @@ const initialState = {
clientField: '',
passwordField: '',
rememberMeField: false,
loginState: STATES.LOGIN
loginState: STATES.LOGIN,
}
const reducer = (state, action) => {

View file

@ -44,13 +44,13 @@ const GET_USER_DATA = gql`
const validationSchema = Yup.object().shape({
email: Yup.string().label('Email').required().email(),
password: Yup.string().required('Password field is required'),
rememberMe: Yup.boolean()
rememberMe: Yup.boolean(),
})
const initialValues = {
email: '',
password: '',
rememberMe: false
rememberMe: false,
}
const getErrorMsg = (formikErrors, formikTouched, mutationError) => {
@ -62,7 +62,7 @@ const getErrorMsg = (formikErrors, formikTouched, mutationError) => {
return null
}
const LoginState = ({ state, dispatch, strategy }) => {
const LoginState = ({ dispatch, strategy }) => {
const history = useHistory()
const { setUserData } = useContext(AppContext)
@ -72,8 +72,8 @@ const LoginState = ({ state, dispatch, strategy }) => {
const options = {
variables: {
username,
password
}
password,
},
}
const { data: loginResponse } = await login(options)
@ -84,16 +84,16 @@ const LoginState = ({ state, dispatch, strategy }) => {
payload: {
clientField: username,
passwordField: password,
rememberMeField: rememberMe
}
rememberMeField: rememberMe,
},
})
}
const [validateAssertion, { error: FIDOMutationError }] = useMutation(
VALIDATE_ASSERTION,
{
onCompleted: ({ validateAssertion: success }) => success && getUserData()
}
onCompleted: ({ validateAssertion: success }) => success && getUserData(),
},
)
const [assertionOptions, { error: assertionQueryError }] = useLazyQuery(
@ -105,15 +105,15 @@ const LoginState = ({ state, dispatch, strategy }) => {
validateAssertion({
variables: {
assertionResponse: res,
domain: window.location.hostname
}
domain: window.location.hostname,
},
})
})
.catch(err => {
console.error(err)
})
}
}
},
},
)
const [getUserData, { error: userDataQueryError }] = useLazyQuery(
@ -122,8 +122,8 @@ const LoginState = ({ state, dispatch, strategy }) => {
onCompleted: ({ userData }) => {
setUserData(userData)
history.push('/')
}
}
},
},
)
return (
@ -149,7 +149,7 @@ const LoginState = ({ state, dispatch, strategy }) => {
loginMutationError ||
FIDOMutationError ||
assertionQueryError ||
userDataQueryError
userDataQueryError,
)}
/>
<Field
@ -164,7 +164,7 @@ const LoginState = ({ state, dispatch, strategy }) => {
loginMutationError ||
FIDOMutationError ||
assertionQueryError ||
userDataQueryError
userDataQueryError,
)}
/>
<div className="mt-9 flex">
@ -183,7 +183,7 @@ const LoginState = ({ state, dispatch, strategy }) => {
loginMutationError ||
FIDOMutationError ||
assertionQueryError ||
userDataQueryError
userDataQueryError,
) && (
<P className="text-tomato">
{getErrorMsg(
@ -192,7 +192,7 @@ const LoginState = ({ state, dispatch, strategy }) => {
loginMutationError ||
FIDOMutationError ||
assertionQueryError ||
userDataQueryError
userDataQueryError,
)}
</P>
)}
@ -202,11 +202,11 @@ const LoginState = ({ state, dispatch, strategy }) => {
onClick={() => {
return strategy === 'FIDOUsernameless'
? assertionOptions({
variables: { domain: window.location.hostname }
variables: { domain: window.location.hostname },
})
: dispatch({
type: 'FIDO',
payload: {}
payload: {},
})
}}
buttonClassName="w-full"

Some files were not shown because too many files have changed in this diff Show more