partial: second batch of components
This commit is contained in:
parent
8cd7374ee8
commit
9f4bf1de7b
35 changed files with 616 additions and 1044 deletions
|
|
@ -1,5 +1,4 @@
|
|||
import { useQuery, useMutation, gql } from "@apollo/client";
|
||||
import { makeStyles } from '@mui/styles'
|
||||
import { useQuery, useMutation, gql } from '@apollo/client'
|
||||
import * as R from 'ramda'
|
||||
import React, { useState, useEffect } from 'react'
|
||||
import ActionButton from 'src/components/buttons/ActionButton'
|
||||
|
|
@ -9,10 +8,8 @@ import ClearAllIconInverse from 'src/styling/icons/stage/spring/empty.svg?react'
|
|||
import ClearAllIcon from 'src/styling/icons/stage/zodiac/empty.svg?react'
|
||||
import ShowUnreadIcon from 'src/styling/icons/stage/zodiac/full.svg?react'
|
||||
|
||||
import styles from './NotificationCenter.styles'
|
||||
import NotificationRow from './NotificationRow'
|
||||
|
||||
const useStyles = makeStyles(styles)
|
||||
import classes from './NotificationCenter.module.css'
|
||||
|
||||
const GET_NOTIFICATIONS = gql`
|
||||
query getNotifications {
|
||||
|
|
@ -63,7 +60,6 @@ const NotificationCenter = ({
|
|||
const [xOffset, setXoffset] = useState(300)
|
||||
|
||||
const [showingUnread, setShowingUnread] = useState(false)
|
||||
const classes = useStyles({ buttonCoords, xOffset })
|
||||
const machines = R.compose(
|
||||
R.map(R.prop('name')),
|
||||
R.indexBy(R.prop('deviceId'))
|
||||
|
|
@ -120,7 +116,13 @@ const NotificationCenter = ({
|
|||
<div className={classes.container}>
|
||||
<div className={classes.header}>
|
||||
<H5 className={classes.headerText}>Notifications</H5>
|
||||
<button onClick={close} className={classes.notificationIcon}>
|
||||
<button
|
||||
onClick={close}
|
||||
className={classes.notificationIcon}
|
||||
style={{
|
||||
top: buttonCoords?.y ?? 0,
|
||||
left: buttonCoords?.x ? buttonCoords.x - xOffset : 0
|
||||
}}>
|
||||
<NotificationIconZodiac />
|
||||
{hasUnread && <div className={classes.hasUnread} />}
|
||||
</button>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,145 @@
|
|||
.container {
|
||||
width: 40vw;
|
||||
height: 110vh;
|
||||
right: 0;
|
||||
background-color: white;
|
||||
box-shadow: 0 0 14px 0 rgba(0, 0, 0, 0.24);
|
||||
}
|
||||
|
||||
.container @media only screen and (max-width: 1920px) {
|
||||
width: 30vw;
|
||||
}
|
||||
|
||||
.header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.headerText {
|
||||
margin-top: 20px;
|
||||
margin-left: 12px;
|
||||
}
|
||||
|
||||
.actionButtons {
|
||||
display: flex;
|
||||
margin-left: 16px;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
.notificationIcon {
|
||||
position: absolute;
|
||||
cursor: pointer;
|
||||
background: transparent;
|
||||
box-shadow: 0 0 0 transparent;
|
||||
border: 0 solid transparent;
|
||||
text-shadow: 0 0 0 transparent;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.clearAllButton {
|
||||
margin-top: -16px;
|
||||
margin-left: 8px;
|
||||
background-color: var(--zircon);
|
||||
}
|
||||
|
||||
.notificationsList {
|
||||
height: 90vh;
|
||||
max-height: 100vh;
|
||||
margin-top: 24px;
|
||||
margin-left: 0;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
background-color: white;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.notificationRow {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: flex-start;
|
||||
position: relative;
|
||||
margin-bottom: 16px;
|
||||
padding-top: 12px;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.notificationRow > *:first-child {
|
||||
margin-right: 24px;
|
||||
}
|
||||
|
||||
.notificationContent {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
width: 300px;
|
||||
}
|
||||
|
||||
.unread {
|
||||
background-color: var(--spring3)
|
||||
}
|
||||
|
||||
.notificationRowIcon {
|
||||
align-self: center;
|
||||
}
|
||||
|
||||
.notificationRowIcon > * {
|
||||
margin-left: 24px
|
||||
}
|
||||
|
||||
.readIconWrapper {
|
||||
flex-grow: 1
|
||||
}
|
||||
|
||||
.unreadIcon {
|
||||
margin-top: 5px;
|
||||
margin-left: 8px;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
background-color: var(--spring);
|
||||
border-radius: 50%;
|
||||
cursor: pointer;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.readIcon {
|
||||
margin-left: 8px;
|
||||
margin-top: 5px;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
border: 1px solid var(--comet);
|
||||
border-radius: 50%;
|
||||
cursor: pointer;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.notificationTitle {
|
||||
margin: 0;
|
||||
color: var(--comet);
|
||||
}
|
||||
|
||||
.notificationBody {
|
||||
margin: 0
|
||||
}
|
||||
|
||||
.notificationSubtitle {
|
||||
margin: 0;
|
||||
margin-bottom: 8px;
|
||||
color: var(--comet);
|
||||
}
|
||||
|
||||
.stripes {
|
||||
position: absolute;
|
||||
height: 100%;
|
||||
top: 0;
|
||||
opacity: 60%;
|
||||
}
|
||||
|
||||
.hasUnread {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 16px;
|
||||
width: 9px;
|
||||
height: 9px;
|
||||
background-color: var(--spring);
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
|
@ -1,144 +0,0 @@
|
|||
import {
|
||||
spacer,
|
||||
white,
|
||||
zircon,
|
||||
secondaryColor,
|
||||
spring3,
|
||||
comet
|
||||
} from 'src/styling/variables'
|
||||
|
||||
const styles = {
|
||||
container: {
|
||||
'@media only screen and (max-width: 1920px)': {
|
||||
width: '30vw'
|
||||
},
|
||||
width: '40vw',
|
||||
height: '110vh',
|
||||
right: 0,
|
||||
backgroundColor: white,
|
||||
boxShadow: '0 0 14px 0 rgba(0, 0, 0, 0.24)'
|
||||
},
|
||||
header: {
|
||||
display: 'flex',
|
||||
justifyContent: 'space-between'
|
||||
},
|
||||
headerText: {
|
||||
marginTop: spacer * 2.5,
|
||||
marginLeft: spacer * 3
|
||||
},
|
||||
actionButtons: {
|
||||
display: 'flex',
|
||||
marginLeft: spacer * 2,
|
||||
height: 0
|
||||
},
|
||||
notificationIcon: ({ buttonCoords, xOffset }) => ({
|
||||
position: 'absolute',
|
||||
top: buttonCoords ? buttonCoords.y : 0,
|
||||
left: buttonCoords ? buttonCoords.x - xOffset : 0,
|
||||
cursor: 'pointer',
|
||||
background: 'transparent',
|
||||
boxShadow: '0px 0px 0px transparent',
|
||||
border: '0px solid transparent',
|
||||
textShadow: '0px 0px 0px transparent',
|
||||
outline: 'none'
|
||||
}),
|
||||
clearAllButton: {
|
||||
marginTop: -spacer * 2,
|
||||
marginLeft: spacer,
|
||||
backgroundColor: zircon
|
||||
},
|
||||
notificationsList: {
|
||||
height: '90vh',
|
||||
maxHeight: '100vh',
|
||||
marginTop: spacer * 3,
|
||||
marginLeft: 0,
|
||||
overflowY: 'auto',
|
||||
overflowX: 'hidden',
|
||||
backgroundColor: white,
|
||||
zIndex: 10
|
||||
},
|
||||
notificationRow: {
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'flex-start',
|
||||
position: 'relative',
|
||||
marginBottom: spacer / 2,
|
||||
paddingTop: spacer * 1.5,
|
||||
'& > *:first-child': {
|
||||
marginRight: 24
|
||||
},
|
||||
'& > *': {
|
||||
marginRight: 10
|
||||
},
|
||||
'& > *:last-child': {
|
||||
marginRight: 0
|
||||
}
|
||||
},
|
||||
notificationContent: {
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
justifyContent: 'center',
|
||||
width: 300
|
||||
},
|
||||
unread: {
|
||||
backgroundColor: spring3
|
||||
},
|
||||
notificationRowIcon: {
|
||||
alignSelf: 'center',
|
||||
'& > *': {
|
||||
marginLeft: spacer * 3
|
||||
}
|
||||
},
|
||||
readIconWrapper: {
|
||||
flexGrow: 1
|
||||
},
|
||||
unreadIcon: {
|
||||
marginTop: 5,
|
||||
marginLeft: spacer,
|
||||
width: '12px',
|
||||
height: '12px',
|
||||
backgroundColor: secondaryColor,
|
||||
borderRadius: '50%',
|
||||
cursor: 'pointer',
|
||||
zIndex: 1
|
||||
},
|
||||
readIcon: {
|
||||
marginLeft: spacer,
|
||||
marginTop: 5,
|
||||
width: '12px',
|
||||
height: '12px',
|
||||
border: [[1, 'solid', comet]],
|
||||
borderRadius: '50%',
|
||||
cursor: 'pointer',
|
||||
zIndex: 1
|
||||
},
|
||||
notificationTitle: {
|
||||
margin: 0,
|
||||
color: comet
|
||||
},
|
||||
notificationBody: {
|
||||
margin: 0
|
||||
},
|
||||
notificationSubtitle: {
|
||||
margin: 0,
|
||||
marginBottom: spacer,
|
||||
color: comet
|
||||
},
|
||||
stripes: {
|
||||
position: 'absolute',
|
||||
height: '100%',
|
||||
top: '0px',
|
||||
opacity: '60%'
|
||||
},
|
||||
hasUnread: {
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
left: 16,
|
||||
width: '9px',
|
||||
height: '9px',
|
||||
backgroundColor: secondaryColor,
|
||||
borderRadius: '50%'
|
||||
}
|
||||
}
|
||||
|
||||
export default styles
|
||||
|
|
@ -1,4 +1,3 @@
|
|||
import { makeStyles } from '@mui/styles'
|
||||
import classnames from 'classnames'
|
||||
import prettyMs from 'pretty-ms'
|
||||
import * as R from 'ramda'
|
||||
|
|
@ -8,8 +7,7 @@ import Wrench from 'src/styling/icons/action/wrench/zodiac.svg?react'
|
|||
import Transaction from 'src/styling/icons/arrow/transaction.svg?react'
|
||||
import WarningIcon from 'src/styling/icons/warning-icon/tomato.svg?react'
|
||||
|
||||
import styles from './NotificationCenter.styles'
|
||||
const useStyles = makeStyles(styles)
|
||||
import classes from './NotificationCenter.module.css'
|
||||
|
||||
const types = {
|
||||
transaction: {
|
||||
|
|
@ -46,8 +44,6 @@ const NotificationRow = ({
|
|||
valid,
|
||||
toggleClear
|
||||
}) => {
|
||||
const classes = useStyles()
|
||||
|
||||
const typeDisplay = R.path([type, 'display'])(types) ?? null
|
||||
const icon = R.path([type, 'icon'])(types) ?? (
|
||||
<Wrench height={16} width={16} />
|
||||
|
|
|
|||
|
|
@ -1,60 +1,22 @@
|
|||
import Checkbox from '@mui/material/Checkbox'
|
||||
import { makeStyles } from '@mui/styles'
|
||||
import CheckBoxIcon from '@mui/icons-material/CheckBox'
|
||||
import CheckBoxOutlineBlankIcon from '@mui/icons-material/CheckBoxOutlineBlank'
|
||||
import React from 'react'
|
||||
import { Label2, Info3 } from 'src/components/typography'
|
||||
import WarningIcon from 'src/styling/icons/warning-icon/comet.svg?react'
|
||||
|
||||
import {
|
||||
fontSize2,
|
||||
fontSize3,
|
||||
secondaryColor,
|
||||
offColor
|
||||
} from 'src/styling/variables'
|
||||
|
||||
const useStyles = makeStyles({
|
||||
root: {
|
||||
color: secondaryColor,
|
||||
'&.Mui-checked': {
|
||||
color: secondaryColor
|
||||
}
|
||||
},
|
||||
checked: {},
|
||||
checkBoxLabel: {
|
||||
display: 'flex'
|
||||
},
|
||||
wrapper: {
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
'& > svg': {
|
||||
marginRight: 10
|
||||
}
|
||||
},
|
||||
message: {
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
color: offColor,
|
||||
margin: 0,
|
||||
whiteSpace: 'break-spaces'
|
||||
}
|
||||
})
|
||||
import { fontSize2, fontSize3 } from 'src/styling/variables'
|
||||
|
||||
const CheckboxInput = ({ name, onChange, value, settings, ...props }) => {
|
||||
const { enabled, label, disabledMessage, rightSideLabel } = settings
|
||||
const classes = useStyles()
|
||||
|
||||
return (
|
||||
<>
|
||||
{enabled ? (
|
||||
<div className={classes.checkBoxLabel}>
|
||||
<div className="flex">
|
||||
{!rightSideLabel && <Label2>{label}</Label2>}
|
||||
<Checkbox
|
||||
id={name}
|
||||
classes={{
|
||||
root: classes.root,
|
||||
checked: classes.checked
|
||||
}}
|
||||
onChange={onChange}
|
||||
value={value}
|
||||
checked={value}
|
||||
|
|
@ -70,9 +32,11 @@ const CheckboxInput = ({ name, onChange, value, settings, ...props }) => {
|
|||
{rightSideLabel && <Label2>{label}</Label2>}
|
||||
</div>
|
||||
) : (
|
||||
<div className={classes.wrapper}>
|
||||
<div className="flex items-center gap-2">
|
||||
<WarningIcon />
|
||||
<Info3 className={classes.message}>{disabledMessage}</Info3>
|
||||
<Info3 className="flex items-center text-comet m-0 whitespace-break-spaces">
|
||||
{disabledMessage}
|
||||
</Info3>
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
|
|
|
|||
|
|
@ -1,14 +1,8 @@
|
|||
import { makeStyles } from '@mui/styles'
|
||||
import classnames from 'classnames'
|
||||
import React from 'react'
|
||||
import OtpInput from 'react-otp-input'
|
||||
|
||||
import typographyStyles from 'src/components/typography/styles'
|
||||
|
||||
import styles from './CodeInput.styles'
|
||||
|
||||
const useStyles = makeStyles(styles)
|
||||
const useTypographyStyles = makeStyles(typographyStyles)
|
||||
import classes from './CodeInput.module.css'
|
||||
|
||||
const CodeInput = ({
|
||||
name,
|
||||
|
|
@ -19,9 +13,6 @@ const CodeInput = ({
|
|||
inputStyle,
|
||||
containerStyle
|
||||
}) => {
|
||||
const classes = useStyles()
|
||||
const typographyClasses = useTypographyStyles()
|
||||
|
||||
return (
|
||||
<OtpInput
|
||||
id={name}
|
||||
|
|
@ -30,19 +21,15 @@ const CodeInput = ({
|
|||
numInputs={numInputs}
|
||||
renderSeparator={<span> </span>}
|
||||
shouldAutoFocus
|
||||
containerStyle={classnames(containerStyle, classes.container)}
|
||||
containerStyle={classnames(containerStyle, 'justify-evenly')}
|
||||
inputStyle={classnames(
|
||||
inputStyle,
|
||||
classes.input,
|
||||
typographyClasses.confirmationCode,
|
||||
error && classes.error
|
||||
'font-museo font-black text-4xl',
|
||||
error && 'border-tomato'
|
||||
)}
|
||||
inputType={'tel'}
|
||||
renderInput={(props) => (
|
||||
<input
|
||||
{...props}
|
||||
/>
|
||||
)}
|
||||
renderInput={props => <input {...props} />}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,14 @@
|
|||
.input {
|
||||
width: 3.5rem !important;
|
||||
height: 5rem;
|
||||
border: 2px solid;
|
||||
border-color: var(--zircon);
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.input:focus {
|
||||
border: 2px solid;
|
||||
border-color: var(--zodiac);
|
||||
border-radius: 4px;
|
||||
outline: none;
|
||||
}
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
import { primaryColor, zircon, errorColor } from 'src/styling/variables'
|
||||
|
||||
const styles = {
|
||||
input: {
|
||||
width: '3.5rem !important',
|
||||
height: '5rem',
|
||||
border: '2px solid',
|
||||
borderColor: zircon,
|
||||
borderRadius: '4px',
|
||||
'&:focus': {
|
||||
border: '2px solid',
|
||||
borderColor: primaryColor,
|
||||
borderRadius: '4px',
|
||||
'&:focus': {
|
||||
outline: 'none'
|
||||
}
|
||||
},
|
||||
},
|
||||
error: {
|
||||
borderColor: errorColor
|
||||
},
|
||||
container: {
|
||||
justifyContent: 'space-evenly'
|
||||
}
|
||||
}
|
||||
|
||||
export default styles
|
||||
|
|
@ -1,31 +1,10 @@
|
|||
import Radio from '@mui/material/Radio'
|
||||
import MRadioGroup from '@mui/material/RadioGroup'
|
||||
import FormControlLabel from '@mui/material/FormControlLabel'
|
||||
import { makeStyles } from '@mui/styles'
|
||||
import classnames from 'classnames'
|
||||
import React from 'react'
|
||||
import { Label1 } from 'src/components/typography'
|
||||
|
||||
import { offColor, secondaryColor } from 'src/styling/variables'
|
||||
const styles = {
|
||||
label: {
|
||||
height: 16,
|
||||
lineHeight: '16px',
|
||||
margin: [[0, 0, 4, 0]],
|
||||
paddingLeft: 3
|
||||
},
|
||||
subtitle: {
|
||||
marginTop: -8,
|
||||
marginLeft: 32,
|
||||
color: offColor
|
||||
},
|
||||
radio: {
|
||||
color: secondaryColor
|
||||
}
|
||||
}
|
||||
|
||||
const useStyles = makeStyles(styles)
|
||||
|
||||
const RadioGroup = ({
|
||||
name,
|
||||
label,
|
||||
|
|
@ -36,10 +15,11 @@ const RadioGroup = ({
|
|||
labelClassName,
|
||||
radioClassName
|
||||
}) => {
|
||||
const classes = useStyles()
|
||||
return (
|
||||
<>
|
||||
{label && <Label1 className={classes.label}>{label}</Label1>}
|
||||
{label && (
|
||||
<Label1 className="h-4 leading-4 m-0 mb-1 pl-1">{label}</Label1>
|
||||
)}
|
||||
<MRadioGroup
|
||||
name={name}
|
||||
value={value}
|
||||
|
|
@ -51,12 +31,16 @@ const RadioGroup = ({
|
|||
<FormControlLabel
|
||||
disabled={option.disabled}
|
||||
value={option.code}
|
||||
control={<Radio className={classnames(classes.radio, radioClassName)} />}
|
||||
control={
|
||||
<Radio
|
||||
className={classnames('text-spring', radioClassName)}
|
||||
/>
|
||||
}
|
||||
label={option.display}
|
||||
className={classnames(labelClassName)}
|
||||
/>
|
||||
{option.subtitle && (
|
||||
<Label1 className={classes.subtitle}>{option.subtitle}</Label1>
|
||||
<Label1 className="-mt-2 ml-8">{option.subtitle}</Label1>
|
||||
)}
|
||||
</div>
|
||||
</React.Fragment>
|
||||
|
|
|
|||
|
|
@ -1,30 +1,19 @@
|
|||
import { makeStyles } from '@mui/styles'
|
||||
import classNames from 'classnames'
|
||||
import React, { memo, useState } from 'react'
|
||||
import { CashOut } from 'src/components/inputs/cashbox/Cashbox'
|
||||
|
||||
import { NumberInput } from '../base'
|
||||
const useStyles = makeStyles({
|
||||
flex: {
|
||||
display: 'flex'
|
||||
},
|
||||
cashCassette: {
|
||||
height: 36,
|
||||
marginRight: 14
|
||||
}
|
||||
})
|
||||
|
||||
const CashCassetteInput = memo(
|
||||
({ decimalPlaces, width, threshold, inputClassName, ...props }) => {
|
||||
const classes = useStyles()
|
||||
const { name, onChange, onBlur, value } = props.field
|
||||
const { touched, errors } = props.form
|
||||
const [notes, setNotes] = useState(value)
|
||||
const error = !!(touched[name] && errors[name])
|
||||
return (
|
||||
<div className={classes.flex}>
|
||||
<div className="flex">
|
||||
<CashOut
|
||||
className={classNames(classes.cashCassette, inputClassName)}
|
||||
className={classNames('h-9 mr-4', inputClassName)}
|
||||
notes={notes}
|
||||
editingMode={true}
|
||||
width={width}
|
||||
|
|
|
|||
|
|
@ -1,36 +0,0 @@
|
|||
import typographyStyles from 'src/components/typography/styles'
|
||||
import {
|
||||
fontColor,
|
||||
offColor,
|
||||
inputFontSize,
|
||||
inputFontWeight
|
||||
} from 'src/styling/variables'
|
||||
|
||||
const { info3 } = typographyStyles
|
||||
|
||||
const styles = {
|
||||
masked: {
|
||||
position: 'absolute',
|
||||
bottom: 5,
|
||||
left: 4,
|
||||
color: fontColor,
|
||||
fontSize: inputFontSize,
|
||||
fontWeight: inputFontWeight
|
||||
},
|
||||
secretSpan: {
|
||||
extend: info3,
|
||||
color: offColor
|
||||
},
|
||||
hideSpan: {
|
||||
display: 'none'
|
||||
},
|
||||
maskedInput: {
|
||||
'& input': {
|
||||
pointerEvents: 'none',
|
||||
backgroundColor: 'transparent',
|
||||
zIndex: -1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export { styles }
|
||||
|
|
@ -1,7 +1,6 @@
|
|||
import { useQuery, gql } from "@apollo/client";
|
||||
import { useQuery, gql } from '@apollo/client'
|
||||
import ClickAwayListener from '@mui/material/ClickAwayListener'
|
||||
import Popper from '@mui/material/Popper'
|
||||
import { makeStyles } from '@mui/styles'
|
||||
import classnames from 'classnames'
|
||||
import * as R from 'ramda'
|
||||
import React, { memo, useState, useEffect, useRef } from 'react'
|
||||
|
|
@ -16,9 +15,7 @@ import NotificationIcon from 'src/styling/icons/menu/notification.svg?react'
|
|||
import NotificationCenter from 'src/components/NotificationCenter'
|
||||
import AddMachine from 'src/pages/AddMachine'
|
||||
|
||||
import styles from './Header.styles'
|
||||
|
||||
const useStyles = makeStyles(styles)
|
||||
import styles from './Header.module.css'
|
||||
|
||||
const HAS_UNREAD = gql`
|
||||
query getUnread {
|
||||
|
|
@ -26,22 +23,22 @@ const HAS_UNREAD = gql`
|
|||
}
|
||||
`
|
||||
|
||||
const Subheader = ({ item, classes, user }) => {
|
||||
const Subheader = ({ item, user }) => {
|
||||
const [prev, setPrev] = useState(null)
|
||||
|
||||
return (
|
||||
<div className={classes.subheader}>
|
||||
<div className={classes.content}>
|
||||
<div className={styles.subheader}>
|
||||
<div className={styles.content}>
|
||||
<nav>
|
||||
<ul className={classes.subheaderUl}>
|
||||
<ul className={styles.subheaderUl}>
|
||||
{item.children.map((it, idx) => {
|
||||
if (!R.includes(user.role, it.allowedRoles)) return <></>
|
||||
return (
|
||||
<li key={idx} className={classes.subheaderLi}>
|
||||
<li key={idx} className={styles.subheaderLi}>
|
||||
<NavLink
|
||||
to={{ pathname: it.route, state: { prev } }}
|
||||
className={classes.subheaderLink}
|
||||
activeClassName={classes.activeSubheaderLink}
|
||||
className={styles.subheaderLink}
|
||||
activeClassName={styles.activeSubheaderLink}
|
||||
isActive={match => {
|
||||
if (!match) return false
|
||||
setPrev(it.route)
|
||||
|
|
@ -72,7 +69,6 @@ const Header = memo(({ tree, user }) => {
|
|||
const notifCenterButtonRef = useRef()
|
||||
const popperRef = useRef()
|
||||
const history = useHistory()
|
||||
const classes = useStyles()
|
||||
|
||||
useEffect(() => {
|
||||
if (data?.hasUnreadNotifications) return setHasUnread(true)
|
||||
|
|
@ -112,20 +108,20 @@ const Header = memo(({ tree, user }) => {
|
|||
const popperOpen = Boolean(anchorEl)
|
||||
const id = popperOpen ? 'notifications-popper' : undefined
|
||||
return (
|
||||
<header className={classes.headerContainer}>
|
||||
<div className={classes.header}>
|
||||
<div className={classes.content}>
|
||||
<header className={styles.headerContainer}>
|
||||
<div className={styles.header}>
|
||||
<div className={styles.content}>
|
||||
<div
|
||||
onClick={() => {
|
||||
setActive(false)
|
||||
history.push('/dashboard')
|
||||
}}
|
||||
className={classnames(classes.logo, classes.logoLink)}>
|
||||
className={classnames(styles.logo, styles.logoLink)}>
|
||||
<Logo />
|
||||
<H4 className={classes.white}>Lamassu Admin</H4>
|
||||
<H4 className="text-white">Lamassu Admin</H4>
|
||||
</div>
|
||||
<nav className={classes.nav}>
|
||||
<ul className={classes.ul}>
|
||||
<nav className={styles.nav}>
|
||||
<ul className={styles.ul}>
|
||||
{tree.map((it, idx) => {
|
||||
if (!R.includes(user.role, it.allowedRoles)) return <></>
|
||||
return (
|
||||
|
|
@ -137,11 +133,11 @@ const Header = memo(({ tree, user }) => {
|
|||
setActive(it)
|
||||
return true
|
||||
}}
|
||||
className={classnames(classes.link, classes.whiteLink)}
|
||||
activeClassName={classes.activeLink}>
|
||||
<li className={classes.li}>
|
||||
className={classnames(styles.link)}
|
||||
activeClassName={styles.activeLink}>
|
||||
<li className={styles.li}>
|
||||
<span
|
||||
className={classes.forceSize}
|
||||
className={styles.forceSize}
|
||||
data-forcesize={it.label}>
|
||||
{it.label}
|
||||
</span>
|
||||
|
|
@ -151,7 +147,7 @@ const Header = memo(({ tree, user }) => {
|
|||
})}
|
||||
</ul>
|
||||
</nav>
|
||||
<div className={classes.actionButtonsContainer}>
|
||||
<div className={styles.actionButtonsContainer}>
|
||||
<ActionButton
|
||||
color="secondary"
|
||||
Icon={AddIcon}
|
||||
|
|
@ -163,16 +159,16 @@ const Header = memo(({ tree, user }) => {
|
|||
<div ref={notifCenterButtonRef}>
|
||||
<button
|
||||
onClick={handleClick}
|
||||
className={classes.notificationIcon}>
|
||||
className={styles.notificationIcon}>
|
||||
<NotificationIcon />
|
||||
{hasUnread && <div className={classes.hasUnread} />}
|
||||
{hasUnread && <div className={styles.hasUnread} />}
|
||||
</button>
|
||||
<Popper
|
||||
ref={popperRef}
|
||||
id={id}
|
||||
open={popperOpen}
|
||||
anchorEl={anchorEl}
|
||||
className={classes.popper}
|
||||
className={styles.popper}
|
||||
disablePortal={false}
|
||||
placement="bottom-end"
|
||||
modifiers={[
|
||||
|
|
@ -187,8 +183,8 @@ const Header = memo(({ tree, user }) => {
|
|||
name: 'preventOverflow',
|
||||
enabled: true,
|
||||
options: {
|
||||
rootBoundary: 'viewport',
|
||||
},
|
||||
rootBoundary: 'viewport'
|
||||
}
|
||||
}
|
||||
]}>
|
||||
<NotificationCenter
|
||||
|
|
@ -204,9 +200,7 @@ const Header = memo(({ tree, user }) => {
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{active && active.children && (
|
||||
<Subheader item={active} classes={classes} user={user} />
|
||||
)}
|
||||
{active && active.children && <Subheader item={active} user={user} />}
|
||||
{open && <AddMachine close={() => setOpen(false)} onPaired={onPaired} />}
|
||||
</header>
|
||||
)
|
||||
|
|
|
|||
175
new-lamassu-admin/src/components/layout/Header.module.css
Normal file
175
new-lamassu-admin/src/components/layout/Header.module.css
Normal file
|
|
@ -0,0 +1,175 @@
|
|||
.headerContainer {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.header {
|
||||
background-color: var(--zodiac);
|
||||
color: white;
|
||||
height: 56px;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.content {
|
||||
max-width: 1200px;
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.nav {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.ul {
|
||||
display: flex;
|
||||
padding-left: 36px;
|
||||
height: 56px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.li {
|
||||
list-style: none;
|
||||
color: white;
|
||||
margin: 20px 20px 0 20px;
|
||||
position: relative;
|
||||
line-height: 17px;
|
||||
}
|
||||
|
||||
.li:hover {
|
||||
color: white;
|
||||
}
|
||||
|
||||
.li:hover::after {
|
||||
width: 50%;
|
||||
margin-left: -25%;
|
||||
}
|
||||
|
||||
.li::after {
|
||||
content: "";
|
||||
display: block;
|
||||
background: white;
|
||||
width: 0;
|
||||
height: 4px;
|
||||
left: 50%;
|
||||
margin-left: 0;
|
||||
position: absolute;
|
||||
border-radius: 1000px;
|
||||
transition: all 0.2s cubic-bezier(0.95, 0.1, 0.45, 0.94);
|
||||
}
|
||||
|
||||
.link {
|
||||
text-decoration: none;
|
||||
border: none;
|
||||
color: white;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.forceSize {
|
||||
display: inline-block;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.forceSize::after {
|
||||
display: block;
|
||||
content: attr(data-forcesize);
|
||||
font-weight: 700;
|
||||
height: 0;
|
||||
overflow: hidden;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.activeLink {
|
||||
color: white;
|
||||
}
|
||||
|
||||
.activeLink li::after {
|
||||
width: 50%;
|
||||
margin-left: -25%;
|
||||
}
|
||||
|
||||
.addMachine {
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.subheader {
|
||||
background-color: var(--zircon);
|
||||
color: white;
|
||||
height: 40px;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.subheaderUl {
|
||||
display: flex;
|
||||
padding-left: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.subheaderLi {
|
||||
list-style: none;
|
||||
padding: 0 20px;
|
||||
}
|
||||
|
||||
.subheaderLi:first-child {
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
.subheaderLink {
|
||||
text-decoration: none;
|
||||
border: none;
|
||||
color: var(--comet);
|
||||
}
|
||||
|
||||
.activeSubheaderLink {
|
||||
text-shadow: 0.2px 0 0 currentColor;
|
||||
color: var(--zodiac);
|
||||
}
|
||||
|
||||
.logo {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.logo > svg {
|
||||
margin-right: 16px;
|
||||
}
|
||||
|
||||
.logoLink {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.actionButtonsContainer {
|
||||
z-index: 1;
|
||||
position: relative;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
min-width: 200px;
|
||||
transform: translateZ(0);
|
||||
}
|
||||
|
||||
.notificationIcon {
|
||||
margin-top: 4px;
|
||||
cursor: pointer;
|
||||
background: transparent;
|
||||
box-shadow: 0px 0px 0px transparent;
|
||||
border: 0px solid transparent;
|
||||
text-shadow: 0px 0px 0px transparent;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.hasUnread {
|
||||
position: absolute;
|
||||
top: 4px;
|
||||
left: 186px;
|
||||
width: 9px;
|
||||
height: 9px;
|
||||
background-color: var(--spring);
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.popper {
|
||||
z-index: 1;
|
||||
}
|
||||
|
|
@ -1,182 +0,0 @@
|
|||
import typographyStyles from 'src/components/typography/styles'
|
||||
import {
|
||||
version,
|
||||
mainWidth,
|
||||
spacer,
|
||||
white,
|
||||
primaryColor,
|
||||
secondaryColor,
|
||||
placeholderColor,
|
||||
subheaderColor,
|
||||
fontColor
|
||||
} from 'src/styling/variables'
|
||||
|
||||
const { p } = typographyStyles
|
||||
|
||||
let headerHeight = spacer * 7
|
||||
let subheaderHeight = spacer * 5
|
||||
|
||||
if (version === 8) {
|
||||
headerHeight = spacer * 8
|
||||
subheaderHeight = spacer * 7
|
||||
}
|
||||
|
||||
const styles = {
|
||||
headerContainer: {
|
||||
position: 'relative'
|
||||
},
|
||||
header: {
|
||||
backgroundColor: primaryColor,
|
||||
color: white,
|
||||
height: headerHeight,
|
||||
display: 'flex'
|
||||
},
|
||||
content: {
|
||||
maxWidth: mainWidth,
|
||||
flex: 1,
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
margin: '0 auto'
|
||||
},
|
||||
nav: {
|
||||
flex: 1,
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'space-between'
|
||||
},
|
||||
ul: {
|
||||
display: 'flex',
|
||||
paddingLeft: spacer * 4.5,
|
||||
height: spacer * 7,
|
||||
margin: 0
|
||||
},
|
||||
li: {
|
||||
// extend: tl2,
|
||||
// height: spacer * 7,
|
||||
listStyle: 'none',
|
||||
color: white,
|
||||
margin: [[spacer * 2.5, spacer * 2.5, 0, spacer * 2.5]],
|
||||
'&:hover': {
|
||||
color: white
|
||||
},
|
||||
'&:hover::after': {
|
||||
width: '50%',
|
||||
marginLeft: '-25%'
|
||||
},
|
||||
position: 'relative',
|
||||
'&:after': {
|
||||
content: '""',
|
||||
display: 'block',
|
||||
background: white,
|
||||
width: 0,
|
||||
height: 4,
|
||||
left: '50%',
|
||||
marginLeft: 0,
|
||||
bottom: -8,
|
||||
position: 'absolute',
|
||||
borderRadius: 1000,
|
||||
transition: [['all', '0.2s', 'cubic-bezier(0.95, 0.1, 0.45, 0.94)']]
|
||||
}
|
||||
},
|
||||
link: {
|
||||
extend: p,
|
||||
textDecoration: 'none',
|
||||
border: 'none',
|
||||
color: white,
|
||||
backgroundColor: 'transparent'
|
||||
},
|
||||
forceSize: {
|
||||
display: 'inline-block',
|
||||
textAlign: 'center',
|
||||
'&:after': {
|
||||
display: 'block',
|
||||
content: 'attr(data-forcesize)',
|
||||
fontWeight: 700,
|
||||
height: 0,
|
||||
overflow: 'hidden',
|
||||
visibility: 'hidden'
|
||||
}
|
||||
},
|
||||
activeLink: {
|
||||
color: white,
|
||||
'& li::after': {
|
||||
width: '50%',
|
||||
marginLeft: '-25%'
|
||||
}
|
||||
},
|
||||
addMachine: {
|
||||
marginLeft: 'auto'
|
||||
},
|
||||
subheader: {
|
||||
backgroundColor: subheaderColor,
|
||||
color: white,
|
||||
height: subheaderHeight,
|
||||
display: 'flex'
|
||||
},
|
||||
subheaderUl: {
|
||||
display: 'flex',
|
||||
paddingLeft: 0,
|
||||
margin: 0
|
||||
},
|
||||
subheaderLi: {
|
||||
listStyle: 'none',
|
||||
padding: [[0, spacer * 2.5]],
|
||||
'&:first-child': {
|
||||
paddingLeft: 0
|
||||
}
|
||||
},
|
||||
subheaderLink: {
|
||||
extend: p,
|
||||
textDecoration: 'none',
|
||||
border: 'none',
|
||||
color: placeholderColor
|
||||
},
|
||||
activeSubheaderLink: {
|
||||
textShadow: '0.2px 0 0 currentColor',
|
||||
color: fontColor
|
||||
},
|
||||
white: {
|
||||
color: white
|
||||
},
|
||||
logo: {
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
'& > svg': {
|
||||
marginRight: 16
|
||||
}
|
||||
},
|
||||
logoLink: {
|
||||
cursor: 'pointer'
|
||||
},
|
||||
actionButtonsContainer: {
|
||||
zIndex: 1,
|
||||
position: 'relative',
|
||||
display: 'flex',
|
||||
justifyContent: 'space-between',
|
||||
minWidth: 200,
|
||||
transform: 'translateZ(0)'
|
||||
},
|
||||
notificationIcon: {
|
||||
marginTop: spacer / 2,
|
||||
cursor: 'pointer',
|
||||
background: 'transparent',
|
||||
boxShadow: '0px 0px 0px transparent',
|
||||
border: '0px solid transparent',
|
||||
textShadow: '0px 0px 0px transparent',
|
||||
outline: 'none'
|
||||
},
|
||||
hasUnread: {
|
||||
position: 'absolute',
|
||||
top: 4,
|
||||
left: 186,
|
||||
width: '9px',
|
||||
height: '9px',
|
||||
backgroundColor: secondaryColor,
|
||||
borderRadius: '50%'
|
||||
},
|
||||
popper: {
|
||||
zIndex: 1
|
||||
}
|
||||
}
|
||||
|
||||
export default styles
|
||||
|
|
@ -1,19 +1,13 @@
|
|||
import { makeStyles } from '@mui/styles'
|
||||
import React from 'react'
|
||||
import ErrorMessage from 'src/components/ErrorMessage'
|
||||
import Subtitle from 'src/components/Subtitle'
|
||||
|
||||
import styles from './Section.styles'
|
||||
|
||||
const useStyles = makeStyles(styles)
|
||||
|
||||
const Section = ({ error, children, title }) => {
|
||||
const classes = useStyles()
|
||||
return (
|
||||
<div className={classes.section}>
|
||||
<div className="mb-8">
|
||||
{(title || error) && (
|
||||
<div className={classes.sectionHeader}>
|
||||
<Subtitle className={classes.sectionTitle}>{title}</Subtitle>
|
||||
<div className="flex items-center">
|
||||
<Subtitle className="mt-4 mr-5 mb-6 ml-0">{title}</Subtitle>
|
||||
{error && <ErrorMessage>Failed to save changes</ErrorMessage>}
|
||||
</div>
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -1,12 +0,0 @@
|
|||
export default {
|
||||
section: {
|
||||
marginBottom: 72
|
||||
},
|
||||
sectionHeader: {
|
||||
display: 'flex',
|
||||
alignItems: 'center'
|
||||
},
|
||||
sectionTitle: {
|
||||
margin: [[16, 20, 23, 0]]
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,3 @@
|
|||
import { makeStyles } from '@mui/styles'
|
||||
import classnames from 'classnames'
|
||||
import React from 'react'
|
||||
import { P } from 'src/components/typography'
|
||||
|
|
@ -6,9 +5,7 @@ import CompleteStageIconZodiac from 'src/styling/icons/stage/zodiac/complete.svg
|
|||
import CurrentStageIconZodiac from 'src/styling/icons/stage/zodiac/current.svg?react'
|
||||
import EmptyStageIconZodiac from 'src/styling/icons/stage/zodiac/empty.svg?react'
|
||||
|
||||
import styles from './Sidebar.styles'
|
||||
|
||||
const useStyles = makeStyles(styles)
|
||||
import styles from './Sidebar.module.css'
|
||||
|
||||
const Sidebar = ({
|
||||
data,
|
||||
|
|
@ -19,23 +16,21 @@ const Sidebar = ({
|
|||
itemRender,
|
||||
loading = false
|
||||
}) => {
|
||||
const classes = useStyles()
|
||||
|
||||
return (
|
||||
<div className={classes.sidebar}>
|
||||
<div className={styles.sidebar}>
|
||||
{loading && <P>Loading...</P>}
|
||||
{!loading &&
|
||||
data?.map((it, idx) => (
|
||||
<div
|
||||
key={idx}
|
||||
className={classes.linkWrapper}
|
||||
className={styles.linkWrapper}
|
||||
onClick={() => onClick(it)}>
|
||||
<div
|
||||
className={classnames({
|
||||
[classes.activeLink]: isSelected(it),
|
||||
[classes.customRenderActiveLink]: itemRender && isSelected(it),
|
||||
[classes.customRenderLink]: itemRender,
|
||||
[classes.link]: true
|
||||
[styles.activeLink]: isSelected(it),
|
||||
[styles.customRenderActiveLink]: itemRender && isSelected(it),
|
||||
[styles.customRenderLink]: itemRender,
|
||||
[styles.link]: true
|
||||
})}>
|
||||
{itemRender ? itemRender(it, isSelected(it)) : displayName(it)}
|
||||
</div>
|
||||
|
|
@ -49,18 +44,17 @@ const Sidebar = ({
|
|||
export default Sidebar
|
||||
|
||||
const Stepper = ({ step, it, idx, steps }) => {
|
||||
const classes = useStyles()
|
||||
const active = step === idx
|
||||
const past = idx < step
|
||||
const future = idx > step
|
||||
|
||||
return (
|
||||
<div className={classes.item}>
|
||||
<div className={styles.item}>
|
||||
<span
|
||||
className={classnames({
|
||||
[classes.itemText]: true,
|
||||
[classes.itemTextActive]: active,
|
||||
[classes.itemTextPast]: past
|
||||
[styles.itemText]: true,
|
||||
[styles.itemTextActive]: active,
|
||||
[styles.itemTextPast]: past
|
||||
})}>
|
||||
{it.label}
|
||||
</span>
|
||||
|
|
@ -70,8 +64,8 @@ const Stepper = ({ step, it, idx, steps }) => {
|
|||
{idx < steps.length - 1 && (
|
||||
<div
|
||||
className={classnames({
|
||||
[classes.stepperPath]: true,
|
||||
[classes.stepperPast]: past
|
||||
[styles.stepperPath]: true,
|
||||
[styles.stepperPast]: past
|
||||
})}></div>
|
||||
)}
|
||||
</div>
|
||||
|
|
|
|||
106
new-lamassu-admin/src/components/layout/Sidebar.module.css
Normal file
106
new-lamassu-admin/src/components/layout/Sidebar.module.css
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
:root {
|
||||
--sidebar-color: var(--zircon);
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
display: flex;
|
||||
background-color: var(--sidebar-color);
|
||||
width: 520px;
|
||||
margin-left: -300px;
|
||||
box-shadow: -500px 0px 0px 0px var(--sidebar-color);
|
||||
border-radius: 0 20px 0 0;
|
||||
align-items: flex-end;
|
||||
padding: 24px;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
@media (max-width: 1440px) {
|
||||
.sidebar {
|
||||
width: auto;
|
||||
margin-left: 0;
|
||||
min-width: 250px;
|
||||
box-shadow: -200px 0px 0px 0px var(--sidebar-color);
|
||||
}
|
||||
}
|
||||
|
||||
.linkWrapper {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.link {
|
||||
position: relative;
|
||||
color: var(--comet);
|
||||
margin: 12px 24px 12px 0;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.link:hover::after {
|
||||
height: 140%;
|
||||
}
|
||||
|
||||
.link::after {
|
||||
content: "";
|
||||
display: block;
|
||||
background: var(--zodiac);
|
||||
width: 4px;
|
||||
height: 0;
|
||||
left: 100%;
|
||||
margin-left: 20px;
|
||||
bottom: -2px;
|
||||
position: absolute;
|
||||
border-radius: 1000px;
|
||||
transition: all 0.2s cubic-bezier(0.95, 0.1, 0.45, 0.94);
|
||||
}
|
||||
|
||||
.activeLink {
|
||||
font-weight: 700;
|
||||
color: var(--zodiac);
|
||||
}
|
||||
|
||||
.activeLink::after {
|
||||
height: 140%;
|
||||
}
|
||||
|
||||
.customRenderLink:hover::after {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.customRenderLink::after {
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
.customRenderActiveLink::after {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.item {
|
||||
position: relative;
|
||||
margin: 12px 0 12px 0;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.itemText {
|
||||
color: var(--comet);
|
||||
margin-right: 24px;
|
||||
}
|
||||
|
||||
.itemTextActive {
|
||||
color: var(--zodiac);
|
||||
}
|
||||
|
||||
.itemTextPast {
|
||||
color: var(--zodiac);
|
||||
}
|
||||
|
||||
.stepperPath {
|
||||
position: absolute;
|
||||
height: 25px;
|
||||
width: 1px;
|
||||
border: 1px solid var(--comet);
|
||||
right: 8px;
|
||||
top: 18px;
|
||||
}
|
||||
|
||||
.stepperPast {
|
||||
border: 1px solid var(--zodiac);
|
||||
}
|
||||
|
|
@ -1,107 +0,0 @@
|
|||
import typographyStyles from 'src/components/typography/styles'
|
||||
import { respondTo } from 'src/styling/helpers'
|
||||
import {
|
||||
primaryColor,
|
||||
spacer,
|
||||
placeholderColor,
|
||||
zircon,
|
||||
xxl
|
||||
} from 'src/styling/variables'
|
||||
|
||||
const { tl2, p } = typographyStyles
|
||||
|
||||
const sidebarColor = zircon
|
||||
|
||||
export default {
|
||||
sidebar: {
|
||||
display: 'flex',
|
||||
backgroundColor: sidebarColor,
|
||||
width: 520,
|
||||
marginLeft: -300,
|
||||
boxShadow: `-500px 0px 0px 0px ${sidebarColor}`,
|
||||
borderRadius: '0 20px 0 0',
|
||||
alignItems: 'flex-end',
|
||||
padding: spacer * 3,
|
||||
flexDirection: 'column',
|
||||
[respondTo(xxl)]: {
|
||||
width: 'auto',
|
||||
marginLeft: 0,
|
||||
minWidth: 250,
|
||||
boxShadow: `-200px 0px 0px 0px ${sidebarColor}`
|
||||
}
|
||||
},
|
||||
linkWrapper: {
|
||||
cursor: 'pointer'
|
||||
},
|
||||
link: {
|
||||
extend: p,
|
||||
position: 'relative',
|
||||
color: placeholderColor,
|
||||
margin: '12px 24px 12px 0',
|
||||
cursor: 'pointer',
|
||||
'&:hover::after': {
|
||||
height: '140%'
|
||||
},
|
||||
'&:after': {
|
||||
content: '""',
|
||||
display: 'block',
|
||||
background: primaryColor,
|
||||
width: 4,
|
||||
height: 0,
|
||||
left: '100%',
|
||||
marginLeft: 20,
|
||||
bottom: -2,
|
||||
position: 'absolute',
|
||||
borderRadius: 1000,
|
||||
transition: 'all 0.2s cubic-bezier(0.95, 0.1, 0.45, 0.94)'
|
||||
}
|
||||
},
|
||||
activeLink: {
|
||||
extend: tl2,
|
||||
color: primaryColor,
|
||||
'&::after': {
|
||||
height: '140%'
|
||||
}
|
||||
},
|
||||
customRenderLink: {
|
||||
'&:hover::after': {
|
||||
height: '100%'
|
||||
},
|
||||
'&:after': {
|
||||
bottom: 0
|
||||
}
|
||||
},
|
||||
customRenderActiveLink: {
|
||||
'&::after': {
|
||||
height: '100%'
|
||||
}
|
||||
},
|
||||
item: {
|
||||
position: 'relative',
|
||||
margin: '12px 0 12px 0',
|
||||
display: 'flex'
|
||||
},
|
||||
itemText: {
|
||||
extend: p,
|
||||
color: placeholderColor,
|
||||
marginRight: 24
|
||||
},
|
||||
itemTextActive: {
|
||||
extend: tl2,
|
||||
color: primaryColor
|
||||
},
|
||||
itemTextPast: {
|
||||
color: primaryColor
|
||||
},
|
||||
stepperPath: {
|
||||
position: 'absolute',
|
||||
height: 25,
|
||||
width: 1,
|
||||
border: [[1, 'solid', placeholderColor]],
|
||||
right: 8,
|
||||
top: 18
|
||||
},
|
||||
stepperPast: {
|
||||
border: [[1, 'solid', primaryColor]]
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,3 @@
|
|||
import { makeStyles } from '@mui/styles'
|
||||
import classnames from 'classnames'
|
||||
import * as R from 'ramda'
|
||||
import React from 'react'
|
||||
|
|
@ -8,10 +7,6 @@ import { Info1, Label1 } from 'src/components/typography'
|
|||
|
||||
import { SubpageButton } from 'src/components/buttons'
|
||||
|
||||
import styles from './TitleSection.styles'
|
||||
|
||||
const useStyles = makeStyles(styles)
|
||||
|
||||
const TitleSection = ({
|
||||
className,
|
||||
title,
|
||||
|
|
@ -22,15 +17,16 @@ const TitleSection = ({
|
|||
appendix,
|
||||
appendixRight
|
||||
}) => {
|
||||
const classes = useStyles()
|
||||
return (
|
||||
<div className={classnames(classes.titleWrapper, className)}>
|
||||
<div className={classes.titleAndButtonsContainer}>
|
||||
<div
|
||||
className={classnames(
|
||||
'flex justify-between items-center flex-row',
|
||||
className
|
||||
)}>
|
||||
<div className="flex items-center">
|
||||
<Title>{title}</Title>
|
||||
{!!appendix && appendix}
|
||||
{error && (
|
||||
<ErrorMessage className={classes.error}>Failed to save</ErrorMessage>
|
||||
)}
|
||||
{error && <ErrorMessage className="ml-3">Failed to save</ErrorMessage>}
|
||||
{buttons.length > 0 && (
|
||||
<>
|
||||
{buttons.map((button, idx) =>
|
||||
|
|
@ -39,12 +35,14 @@ const TitleSection = ({
|
|||
) : (
|
||||
<SubpageButton
|
||||
key={idx}
|
||||
className={classes.subpageButton}
|
||||
className="ml-3"
|
||||
Icon={button.icon}
|
||||
InverseIcon={button.inverseIcon}
|
||||
toggle={button.toggle}
|
||||
forceDisable={button.forceDisable}>
|
||||
<Info1 className={classes.buttonText}>{button.text}</Info1>
|
||||
<Info1 className="text-ghost font-mont text-base">
|
||||
{button.text}
|
||||
</Info1>
|
||||
</SubpageButton>
|
||||
)
|
||||
)}
|
||||
|
|
@ -54,8 +52,8 @@ const TitleSection = ({
|
|||
<div className="flex flex-row items-center">
|
||||
{(labels ?? []).map(({ icon, label }, idx) => (
|
||||
<div key={idx} className="flex items-center">
|
||||
<div className={classes.icon}>{icon}</div>
|
||||
<Label1 className={classes.label}>{label}</Label1>
|
||||
<div className="mr-1">{icon}</div>
|
||||
<Label1 className="mr-6">{label}</Label1>
|
||||
</div>
|
||||
))}
|
||||
{appendixRight}
|
||||
|
|
|
|||
|
|
@ -1,31 +0,0 @@
|
|||
import { backgroundColor } from 'src/styling/variables'
|
||||
|
||||
export default {
|
||||
titleWrapper: {
|
||||
display: 'flex',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
flexDirection: 'row'
|
||||
},
|
||||
titleAndButtonsContainer: {
|
||||
display: 'flex',
|
||||
alignItems: 'center'
|
||||
},
|
||||
error: {
|
||||
marginLeft: 12
|
||||
},
|
||||
subpageButton: {
|
||||
marginLeft: 12
|
||||
},
|
||||
buttonText: {
|
||||
color: backgroundColor,
|
||||
fontFamily: 'Mont',
|
||||
fontSize: 15
|
||||
},
|
||||
icon: {
|
||||
marginRight: 6
|
||||
},
|
||||
label: {
|
||||
marginRight: 24
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,4 @@
|
|||
import { useLazyQuery, useQuery, gql } from "@apollo/client";
|
||||
import { makeStyles } from '@mui/styles'
|
||||
import { useLazyQuery, useQuery, gql } from '@apollo/client'
|
||||
import { subMinutes } from 'date-fns'
|
||||
import FileSaver from 'file-saver'
|
||||
import React, { useState, useEffect } from 'react'
|
||||
|
|
@ -8,10 +7,6 @@ import { H3, P } from 'src/components/typography'
|
|||
|
||||
import { Button } from 'src/components/buttons'
|
||||
|
||||
import { diagnosticsModal } from './MachineActions.styles'
|
||||
|
||||
const useStyles = makeStyles(diagnosticsModal)
|
||||
|
||||
const STATES = {
|
||||
INITIAL: 'INITIAL',
|
||||
EMPTY: 'EMPTY',
|
||||
|
|
@ -59,7 +54,6 @@ const createCsv = async ({ machineLogsCsv }) => {
|
|||
}
|
||||
|
||||
const DiagnosticsModal = ({ onClose, deviceId, sendAction }) => {
|
||||
const classes = useStyles()
|
||||
const [state, setState] = useState(STATES.INITIAL)
|
||||
const [timestamp, setTimestamp] = useState(null)
|
||||
let timeout = null
|
||||
|
|
@ -103,6 +97,8 @@ const DiagnosticsModal = ({ onClose, deviceId, sendAction }) => {
|
|||
sendAction()
|
||||
}
|
||||
|
||||
const messageClass = 'm-auto flex flex-col items-center justify-center'
|
||||
|
||||
return (
|
||||
<Modal
|
||||
closeOnBackdropClick={true}
|
||||
|
|
@ -111,27 +107,27 @@ const DiagnosticsModal = ({ onClose, deviceId, sendAction }) => {
|
|||
handleClose={onClose}
|
||||
open={true}>
|
||||
{state === STATES.INITIAL && (
|
||||
<div className={classes.message}>
|
||||
<div className={messageClass}>
|
||||
<H3>Loading...</H3>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{state === STATES.EMPTY && (
|
||||
<div className={classes.message}>
|
||||
<div className={messageClass}>
|
||||
<H3>No diagnostics available</H3>
|
||||
<P>Run diagnostics to generate a report</P>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{state === STATES.RUNNING && (
|
||||
<div className={classes.message}>
|
||||
<div className={messageClass}>
|
||||
<H3>Running Diagnostics...</H3>
|
||||
<P>This page should refresh automatically</P>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{state === STATES.FAILURE && (
|
||||
<div className={classes.message}>
|
||||
<div className={messageClass}>
|
||||
<H3>Failed to run diagnostics</H3>
|
||||
<P>Please try again. If the problem persists, contact support.</P>
|
||||
</div>
|
||||
|
|
@ -139,11 +135,11 @@ const DiagnosticsModal = ({ onClose, deviceId, sendAction }) => {
|
|||
|
||||
{state === STATES.FILLED && (
|
||||
<div>
|
||||
<div className={classes.photoWrapper}>
|
||||
<div className="flex mt-6">
|
||||
<div>
|
||||
<H3>Scan</H3>
|
||||
<img
|
||||
className={classes.photo}
|
||||
className="w-88"
|
||||
src={path + 'scan.jpg'}
|
||||
alt="Failure getting photo"
|
||||
/>
|
||||
|
|
@ -151,7 +147,7 @@ const DiagnosticsModal = ({ onClose, deviceId, sendAction }) => {
|
|||
<div>
|
||||
<H3>Front</H3>
|
||||
<img
|
||||
className={classes.photo}
|
||||
className="w-88"
|
||||
src={path + 'front.jpg'}
|
||||
alt="Failure getting photo"
|
||||
/>
|
||||
|
|
@ -163,7 +159,7 @@ const DiagnosticsModal = ({ onClose, deviceId, sendAction }) => {
|
|||
</div>
|
||||
</div>
|
||||
)}
|
||||
<div className={classes.footer}>
|
||||
<div className="flex flex-row mt-auto ml-auto mr-2 mb-0">
|
||||
<Button
|
||||
disabled={state !== STATES.FILLED || !timestamp}
|
||||
onClick={() => {
|
||||
|
|
@ -176,7 +172,7 @@ const DiagnosticsModal = ({ onClose, deviceId, sendAction }) => {
|
|||
}
|
||||
})
|
||||
}}
|
||||
className={classes.downloadLogs}>
|
||||
className="mt-auto ml-auto mr-2 mb-0">
|
||||
Download Logs
|
||||
</Button>
|
||||
<Button
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
import { useMutation, useLazyQuery, gql } from "@apollo/client";
|
||||
import { makeStyles } from '@mui/styles'
|
||||
import { useMutation, useLazyQuery, gql } from '@apollo/client'
|
||||
import React, { memo, useState } from 'react'
|
||||
import { ConfirmDialog } from 'src/components/ConfirmDialog'
|
||||
import ActionButton from 'src/components/buttons/ActionButton'
|
||||
|
|
@ -14,9 +13,6 @@ import UnpairReversedIcon from 'src/styling/icons/button/unpair/white.svg?react'
|
|||
import UnpairIcon from 'src/styling/icons/button/unpair/zodiac.svg?react'
|
||||
|
||||
import DiagnosticsModal from './DiagnosticsModal'
|
||||
import { machineActionsStyles } from './MachineActions.styles'
|
||||
|
||||
const useStyles = makeStyles(machineActionsStyles)
|
||||
|
||||
const MACHINE_ACTION = gql`
|
||||
mutation MachineAction(
|
||||
|
|
@ -67,10 +63,9 @@ const MachineActions = memo(({ machine, onActionSuccess }) => {
|
|||
const [preflightOptions, setPreflightOptions] = useState({})
|
||||
const [showModal, setShowModal] = useState(false)
|
||||
const [errorMessage, setErrorMessage] = useState(null)
|
||||
const classes = useStyles()
|
||||
|
||||
const warningMessage = (
|
||||
<span className={classes.warning}>
|
||||
<span className="text-tomato">
|
||||
A user may be in the middle of a transaction and they could lose their
|
||||
funds if you continue.
|
||||
</span>
|
||||
|
|
@ -113,10 +108,9 @@ const MachineActions = memo(({ machine, onActionSuccess }) => {
|
|||
return (
|
||||
<div>
|
||||
<H3>Actions</H3>
|
||||
<div className={classes.stack}>
|
||||
<div className="flex flex-row flex-wrap justify-start gap-2">
|
||||
<ActionButton
|
||||
color="primary"
|
||||
className={classes.mr}
|
||||
Icon={EditIcon}
|
||||
InverseIcon={EditReversedIcon}
|
||||
disabled={loading}
|
||||
|
|
@ -131,7 +125,6 @@ const MachineActions = memo(({ machine, onActionSuccess }) => {
|
|||
</ActionButton>
|
||||
<ActionButton
|
||||
color="primary"
|
||||
className={classes.mr}
|
||||
Icon={UnpairIcon}
|
||||
InverseIcon={UnpairReversedIcon}
|
||||
disabled={loading}
|
||||
|
|
@ -145,7 +138,6 @@ const MachineActions = memo(({ machine, onActionSuccess }) => {
|
|||
</ActionButton>
|
||||
<ActionButton
|
||||
color="primary"
|
||||
className={classes.mr}
|
||||
Icon={RebootIcon}
|
||||
InverseIcon={RebootReversedIcon}
|
||||
disabled={loading}
|
||||
|
|
@ -159,7 +151,6 @@ const MachineActions = memo(({ machine, onActionSuccess }) => {
|
|||
</ActionButton>
|
||||
<ActionButton
|
||||
color="primary"
|
||||
className={classes.mr}
|
||||
Icon={ShutdownIcon}
|
||||
InverseIcon={ShutdownReversedIcon}
|
||||
disabled={loading}
|
||||
|
|
@ -175,7 +166,6 @@ const MachineActions = memo(({ machine, onActionSuccess }) => {
|
|||
</ActionButton>
|
||||
<ActionButton
|
||||
color="primary"
|
||||
className={classes.inlineChip}
|
||||
Icon={RebootIcon}
|
||||
InverseIcon={RebootReversedIcon}
|
||||
disabled={loading}
|
||||
|
|
@ -190,7 +180,6 @@ const MachineActions = memo(({ machine, onActionSuccess }) => {
|
|||
{machine.model === 'aveiro' && (
|
||||
<ActionButton
|
||||
color="primary"
|
||||
className={classes.mr}
|
||||
Icon={RebootIcon}
|
||||
InverseIcon={RebootReversedIcon}
|
||||
disabled={loading}
|
||||
|
|
@ -208,7 +197,6 @@ const MachineActions = memo(({ machine, onActionSuccess }) => {
|
|||
{machine.model === 'aveiro' && (
|
||||
<ActionButton
|
||||
color="primary"
|
||||
className={classes.inlineChip}
|
||||
Icon={RebootIcon}
|
||||
InverseIcon={RebootReversedIcon}
|
||||
disabled={loading}
|
||||
|
|
@ -225,7 +213,6 @@ const MachineActions = memo(({ machine, onActionSuccess }) => {
|
|||
)}
|
||||
<ActionButton
|
||||
color="primary"
|
||||
className={classes.mr}
|
||||
Icon={RebootIcon}
|
||||
InverseIcon={RebootReversedIcon}
|
||||
disabled={loading}
|
||||
|
|
|
|||
|
|
@ -1,61 +0,0 @@
|
|||
import typographyStyles from 'src/components/typography/styles'
|
||||
import { offColor, spacer, errorColor } from 'src/styling/variables'
|
||||
|
||||
const { label1 } = typographyStyles
|
||||
|
||||
const machineActionsStyles = {
|
||||
label: {
|
||||
extend: label1,
|
||||
color: offColor,
|
||||
marginBottom: 4
|
||||
},
|
||||
inlineChip: {
|
||||
marginInlineEnd: '0.25em'
|
||||
},
|
||||
stack: {
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
flexWrap: 'wrap',
|
||||
justifyContent: 'start'
|
||||
},
|
||||
mr: {
|
||||
marginRight: spacer,
|
||||
marginBottom: spacer
|
||||
},
|
||||
warning: {
|
||||
color: errorColor
|
||||
}
|
||||
}
|
||||
|
||||
const diagnosticsModal = {
|
||||
modal: {
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
alignItems: 'center',
|
||||
padding: '1em'
|
||||
},
|
||||
photo: {
|
||||
width: 350
|
||||
},
|
||||
photoWrapper: {
|
||||
marginTop: spacer * 3,
|
||||
display: 'flex'
|
||||
},
|
||||
footer: {
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
margin: [['auto', 0, spacer * 3, 0]]
|
||||
},
|
||||
downloadLogs: {
|
||||
margin: [['auto', spacer, 0, 'auto']]
|
||||
},
|
||||
message: {
|
||||
margin: 'auto',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center'
|
||||
}
|
||||
}
|
||||
|
||||
export { machineActionsStyles, diagnosticsModal }
|
||||
|
|
@ -1,5 +1,3 @@
|
|||
import { makeStyles } from '@mui/styles'
|
||||
import classnames from 'classnames'
|
||||
import React from 'react'
|
||||
import {
|
||||
Table,
|
||||
|
|
@ -13,9 +11,7 @@ import EditIcon from 'src/styling/icons/action/edit/white.svg?react'
|
|||
|
||||
import { IconButton } from 'src/components/buttons'
|
||||
|
||||
import styles from './SingleRowTable.styles'
|
||||
|
||||
const useStyles = makeStyles(styles)
|
||||
import { Label1, P } from '../typography/index.jsx'
|
||||
|
||||
const SingleRowTable = ({
|
||||
width = 378,
|
||||
|
|
@ -25,34 +21,44 @@ const SingleRowTable = ({
|
|||
onEdit,
|
||||
className
|
||||
}) => {
|
||||
const classes = useStyles({ width, height })
|
||||
|
||||
return (
|
||||
<>
|
||||
<Table className={classnames(className, classes.table)}>
|
||||
<Table className={className} style={{ width }}>
|
||||
<THead>
|
||||
<Th className={classes.head}>
|
||||
<Th className="flex flex-1 justify-between items-center pr-3">
|
||||
{title}
|
||||
<IconButton onClick={onEdit} className={classes.button} size="large">
|
||||
<IconButton onClick={onEdit} className="mb-[1px]" size="large">
|
||||
<EditIcon />
|
||||
</IconButton>
|
||||
</Th>
|
||||
</THead>
|
||||
<TBody>
|
||||
<Tr className={classes.tr}>
|
||||
<Tr className="m-0" style={{ height }}>
|
||||
<Td width={width}>
|
||||
{items && (
|
||||
<>
|
||||
{items[0] && (
|
||||
<div className={classes.itemWrapper}>
|
||||
<div className={classes.label}>{items[0].label}</div>
|
||||
<div className={classes.item}>{items[0].value}</div>
|
||||
<div className="flex flex-col mt-4 min-h-9">
|
||||
<Label1 noMargin className="color-comet mb-1">
|
||||
{items[0].label}
|
||||
</Label1>
|
||||
<P
|
||||
noMargin
|
||||
className="overflow-hidden text-ellipsis whitespace-nowrap">
|
||||
{items[0].value}
|
||||
</P>
|
||||
</div>
|
||||
)}
|
||||
{items[1] && (
|
||||
<div className={classes.itemWrapper}>
|
||||
<div className={classes.label}>{items[1].label}</div>
|
||||
<div className={classes.item}>{items[1].value}</div>
|
||||
<div className="flex flex-col mt-4 min-h-9">
|
||||
<Label1 noMargin className="color-comet mb-1">
|
||||
{items[1].label}
|
||||
</Label1>
|
||||
<P
|
||||
noMargin
|
||||
className="overflow-hidden text-ellipsis whitespace-nowrap">
|
||||
{items[1].value}
|
||||
</P>
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
|
|
@ -62,7 +68,7 @@ const SingleRowTable = ({
|
|||
</TBody>
|
||||
</Table>
|
||||
</>
|
||||
);
|
||||
)
|
||||
}
|
||||
|
||||
export default SingleRowTable
|
||||
|
|
|
|||
|
|
@ -1,41 +0,0 @@
|
|||
import typographyStyles from 'src/components/typography/styles'
|
||||
import { offColor } from 'src/styling/variables'
|
||||
|
||||
const { label1, p } = typographyStyles
|
||||
|
||||
export default {
|
||||
tr: ({ height }) => ({
|
||||
margin: 0,
|
||||
height
|
||||
}),
|
||||
table: ({ width }) => ({
|
||||
width
|
||||
}),
|
||||
head: {
|
||||
display: 'flex',
|
||||
flex: 1,
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
paddingRight: 12
|
||||
},
|
||||
button: {
|
||||
marginBottom: 1
|
||||
},
|
||||
itemWrapper: {
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
marginTop: 16,
|
||||
minHeight: 35
|
||||
},
|
||||
label: {
|
||||
extend: label1,
|
||||
color: offColor,
|
||||
marginBottom: 4
|
||||
},
|
||||
item: {
|
||||
extend: p,
|
||||
overflow: 'hidden',
|
||||
textOverflow: 'ellipsis',
|
||||
whiteSpace: 'nowrap'
|
||||
}
|
||||
}
|
||||
|
|
@ -1,26 +1,15 @@
|
|||
import { makeStyles } from '@mui/styles'
|
||||
import classNames from 'classnames'
|
||||
import React, { memo } from 'react'
|
||||
import { H4 } from 'src/components/typography'
|
||||
import EmptyTableIcon from 'src/styling/icons/table/empty-table.svg?react'
|
||||
|
||||
const styles = {
|
||||
emptyTable: {
|
||||
width: '100%',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
alignItems: 'center',
|
||||
marginTop: 52
|
||||
}
|
||||
}
|
||||
|
||||
const useStyles = makeStyles(styles)
|
||||
|
||||
const EmptyTable = memo(({ message, className }) => {
|
||||
const classes = useStyles()
|
||||
|
||||
return (
|
||||
<div className={classNames(className, classes.emptyTable)}>
|
||||
<div
|
||||
className={classNames(
|
||||
className,
|
||||
'flex flex-col items-center w-full mt-13 text-sm font-bold font-museo'
|
||||
)}>
|
||||
<EmptyTableIcon />
|
||||
<H4>{message}</H4>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,20 +1,14 @@
|
|||
import { makeStyles } from '@mui/styles'
|
||||
import classnames from 'classnames'
|
||||
import React, { memo } from 'react'
|
||||
|
||||
const useStyles = makeStyles({
|
||||
table: {
|
||||
// backgroundColor: tableHeaderColor,
|
||||
tableLayout: 'fixed',
|
||||
borderCollapse: 'separate',
|
||||
borderSpacing: '0 0'
|
||||
}
|
||||
})
|
||||
|
||||
const Table = memo(({ className, children, ...props }) => {
|
||||
const classes = useStyles()
|
||||
return (
|
||||
<table {...props} className={classnames(classes.table, className)}>
|
||||
<table
|
||||
{...props}
|
||||
className={classnames(
|
||||
'table-fixed border-separate border-spacing-0',
|
||||
className
|
||||
)}>
|
||||
{children}
|
||||
</table>
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,24 +1,11 @@
|
|||
import { makeStyles } from '@mui/styles'
|
||||
import classnames from 'classnames'
|
||||
import React, { memo } from 'react'
|
||||
|
||||
import { spacer } from 'src/styling/variables'
|
||||
|
||||
const useStyles = makeStyles({
|
||||
td: {
|
||||
padding: [[0, spacer * 3]]
|
||||
},
|
||||
alignRight: {
|
||||
textAlign: 'right'
|
||||
}
|
||||
})
|
||||
|
||||
const TableCell = memo(
|
||||
({ colspan, rightAlign, className, children, ...props }) => {
|
||||
const classes = useStyles()
|
||||
const styles = {
|
||||
[classes.td]: true,
|
||||
[classes.alignRight]: rightAlign
|
||||
'py-0 px-6': true,
|
||||
'text-right': rightAlign
|
||||
}
|
||||
|
||||
return (
|
||||
|
|
|
|||
|
|
@ -30,8 +30,8 @@ const TableHeaderCell = memo(
|
|||
({ rightAlign, children, className, ...props }) => {
|
||||
const classes = useStyles()
|
||||
const styles = {
|
||||
[classes.th]: true,
|
||||
[classes.alignRight]: rightAlign
|
||||
'bg-zodiac text-white py-0 px-6 h-8 font-': true,
|
||||
'text-right': rightAlign
|
||||
}
|
||||
|
||||
return (
|
||||
|
|
|
|||
|
|
@ -1,54 +1,18 @@
|
|||
import { makeStyles } from '@mui/styles'
|
||||
import classnames from 'classnames'
|
||||
import React, { memo } from 'react'
|
||||
|
||||
import typographyStyles from 'src/components/typography/styles'
|
||||
import {
|
||||
tableCellColor,
|
||||
tableCellHeight,
|
||||
tableSmCellHeight,
|
||||
tableLgCellHeight,
|
||||
tableErrorColor,
|
||||
tableSuccessColor
|
||||
} from 'src/styling/variables'
|
||||
|
||||
const { info2, p } = typographyStyles
|
||||
|
||||
const useStyles = makeStyles({
|
||||
tr: {
|
||||
extend: p,
|
||||
padding: 4,
|
||||
height: tableCellHeight,
|
||||
backgroundColor: tableCellColor
|
||||
},
|
||||
lg: {
|
||||
extend: info2,
|
||||
height: tableLgCellHeight
|
||||
},
|
||||
sm: {
|
||||
height: tableSmCellHeight
|
||||
},
|
||||
error: {
|
||||
backgroundColor: tableErrorColor
|
||||
},
|
||||
success: {
|
||||
backgroundColor: tableSuccessColor
|
||||
}
|
||||
})
|
||||
|
||||
const TableRow = memo(
|
||||
({ className, children, header, error, success, size = 'sm', ...props }) => {
|
||||
const classes = useStyles()
|
||||
const classnamesObj = {
|
||||
[classes.tr]: !header,
|
||||
[classes.sm]: !header && size === 'sm',
|
||||
[classes.lg]: !header && size === 'lg',
|
||||
[classes.error]: error,
|
||||
[classes.success]: success
|
||||
'p-1 h-12 bg-white': !header,
|
||||
'h-8': !header && size === 'sm',
|
||||
'h-9 font-bold text-base ': !header && size === 'lg',
|
||||
'bg-misty-rose': error,
|
||||
'bg-spring3': success
|
||||
}
|
||||
|
||||
return (
|
||||
<tr className={classnames(classnamesObj, className)} {...props}>
|
||||
<tr className={classnames(classnamesObj, className, 'text-')} {...props}>
|
||||
{children}
|
||||
</tr>
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
import { makeStyles } from '@mui/styles'
|
||||
import classnames from 'classnames'
|
||||
import * as R from 'ramda'
|
||||
import React, { useState, useEffect } from 'react'
|
||||
|
|
@ -22,10 +21,6 @@ import ExpandOpenIcon from 'src/styling/icons/action/expand/open.svg?react'
|
|||
|
||||
import { EmptyTable } from 'src/components/table'
|
||||
|
||||
import styles from './DataTable.styles'
|
||||
|
||||
const useStyles = makeStyles(styles)
|
||||
|
||||
const Row = ({
|
||||
id,
|
||||
index,
|
||||
|
|
@ -41,20 +36,18 @@ const Row = ({
|
|||
size,
|
||||
...props
|
||||
}) => {
|
||||
const classes = useStyles()
|
||||
|
||||
const hasPointer = onClick || expandable
|
||||
const trClasses = {
|
||||
[classes.pointer]: hasPointer,
|
||||
[classes.row]: true,
|
||||
[classes.expanded]: expanded
|
||||
'cursor-pointer': hasPointer,
|
||||
'border-2 border-transparent': true,
|
||||
'border-2 border-zircon shadow-xl': expanded
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={classes.rowWrapper}>
|
||||
<div className="p-[1px]">
|
||||
<div
|
||||
data-cy={id}
|
||||
className={classnames({ [classes.before]: expanded && index !== 0 })}>
|
||||
className={classnames({ 'pt-3': expanded && index !== 0 })}>
|
||||
<Tr
|
||||
size={size}
|
||||
className={classnames(trClasses)}
|
||||
|
|
@ -74,7 +67,7 @@ const Row = ({
|
|||
<Td width={expWidth} textAlign="center">
|
||||
<button
|
||||
onClick={() => expandRow(id, data)}
|
||||
className={classes.expandButton}>
|
||||
className="outline-0 border-0 bg-transparent cursor-pointer p-1">
|
||||
{expanded && <ExpandOpenIcon />}
|
||||
{!expanded && <ExpandClosedIcon />}
|
||||
</button>
|
||||
|
|
@ -83,8 +76,11 @@ const Row = ({
|
|||
</Tr>
|
||||
</div>
|
||||
{expanded && (
|
||||
<div className={classes.after}>
|
||||
<Tr className={classnames({ [classes.expanded]: expanded })}>
|
||||
<div className="pb-3">
|
||||
<Tr
|
||||
className={classnames({
|
||||
'border-2 border-zircon shadow-md': expanded
|
||||
})}>
|
||||
<Td width={width}>
|
||||
<Details it={data} timezone={props.timezone} />
|
||||
</Td>
|
||||
|
|
@ -118,8 +114,6 @@ const DataTable = ({
|
|||
const expWidth = maxWidth - coreWidth
|
||||
const width = coreWidth + (expandable ? expWidth : 0)
|
||||
|
||||
const classes = useStyles({ width })
|
||||
|
||||
const expandRow = (id, data) => {
|
||||
if (data.id) {
|
||||
cache.clear(data.id)
|
||||
|
|
@ -176,7 +170,12 @@ const DataTable = ({
|
|||
'flex flex-1 flex-col': true,
|
||||
[className]: !!className
|
||||
})}>
|
||||
<Table className={classnames(classes.table, tableClassName)}>
|
||||
<Table
|
||||
className={classnames(
|
||||
'mb-12 min-h-50 flex-1 flex flex-col',
|
||||
tableClassName
|
||||
)}
|
||||
style={{ width }}>
|
||||
<THead>
|
||||
{elements.map(({ width, className, textAlign, header }, idx) => (
|
||||
<Th
|
||||
|
|
@ -189,7 +188,7 @@ const DataTable = ({
|
|||
))}
|
||||
{expandable && <Th width={expWidth}></Th>}
|
||||
</THead>
|
||||
<TBody className={classes.body}>
|
||||
<TBody className="flex-auto">
|
||||
{loading && <H4>Loading...</H4>}
|
||||
{!loading && R.isEmpty(data) && <EmptyTable message={emptyText} />}
|
||||
{!loading && !R.isEmpty(data) && (
|
||||
|
|
|
|||
|
|
@ -1,50 +0,0 @@
|
|||
import { zircon } from 'src/styling/variables'
|
||||
|
||||
export default {
|
||||
expandButton: {
|
||||
outline: 'none',
|
||||
border: 'none',
|
||||
backgroundColor: 'transparent',
|
||||
cursor: 'pointer',
|
||||
padding: 4
|
||||
},
|
||||
rowWrapper: {
|
||||
// workaround to shadows cut by r-virtualized when scroll is visible
|
||||
padding: 1
|
||||
},
|
||||
row: {
|
||||
border: [[2, 'solid', 'transparent']],
|
||||
borderRadius: 0
|
||||
},
|
||||
expanded: {
|
||||
border: [[2, 'solid', zircon]],
|
||||
boxShadow: '0 0 8px 0 rgba(0,0,0,0.08)'
|
||||
},
|
||||
before: {
|
||||
paddingTop: 12
|
||||
},
|
||||
after: {
|
||||
paddingBottom: 12
|
||||
},
|
||||
pointer: {
|
||||
cursor: 'pointer'
|
||||
},
|
||||
body: {
|
||||
flex: [[1, 1, 'auto']]
|
||||
},
|
||||
table: ({ width }) => ({
|
||||
marginBottom: 30,
|
||||
minHeight: 200,
|
||||
width,
|
||||
flex: 1,
|
||||
display: 'flex',
|
||||
flexDirection: 'column'
|
||||
}),
|
||||
emptyTable: {
|
||||
width: '100%',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
alignItems: 'center',
|
||||
marginTop: 52
|
||||
}
|
||||
}
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
import React from 'react'
|
||||
import { Td } from 'src/components/fake-table/Table'
|
||||
import StripesSvg from 'src/styling/icons/stripes.svg?react'
|
||||
|
||||
const Stripes = ({ width }) => (
|
||||
<Td width={width}>
|
||||
<StripesSvg />
|
||||
</Td>
|
||||
)
|
||||
|
||||
export default Stripes
|
||||
|
|
@ -164,6 +164,16 @@ theme = createTheme(theme, {
|
|||
}
|
||||
}
|
||||
},
|
||||
MuiCheckbox: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
color: secondaryColor,
|
||||
'&.Mui-checked': {
|
||||
color: secondaryColor
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
MuiChip: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue