partial: User Management and Wallet css migration

This commit is contained in:
Rafael Taranto 2025-05-08 08:17:09 +01:00
parent 42ab9e8fa4
commit 8d7f507d6e
18 changed files with 182 additions and 323 deletions

View file

@ -29,7 +29,7 @@ const WizardSplash = ({ name, onContinue }) => {
bills before adding the new ones.
</P>
</div>
<Button className="m-auto mb-0" onClick={onContinue}>
<Button className="ml-auto mt-auto mb-0" onClick={onContinue}>
Get started
</Button>
</div>

View file

@ -1,7 +1,6 @@
import { useQuery, useMutation, useLazyQuery, gql } from '@apollo/client'
import Chip from '@mui/material/Chip'
import Switch from '@mui/material/Switch'
import { makeStyles } from '@mui/styles'
import { startAttestation } from '@simplewebauthn/browser'
import * as R from 'ramda'
import React, { useReducer, useState, useContext } from 'react'
@ -18,7 +17,6 @@ import AppContext from 'src/AppContext'
import { ActionButton, Link } from 'src/components/buttons'
import { IP_CHECK_REGEX } from 'src/utils/constants'
import styles from './UserManagement.styles'
import ChangeRoleModal from './modals/ChangeRoleModal'
import CreateUserModal from './modals/CreateUserModal'
import EnableUserModal from './modals/EnableUserModal'
@ -26,7 +24,7 @@ import FIDOModal from './modals/FIDOModal'
import Reset2FAModal from './modals/Reset2FAModal'
import ResetPasswordModal from './modals/ResetPasswordModal'
const useStyles = makeStyles(styles)
import classes from './UserManagement.module.css'
const GET_USERS = gql`
query users {
@ -88,7 +86,6 @@ const roleMapper = {
}
const Users = () => {
const classes = useStyles()
const { userData } = useContext(AppContext)
const { data: userResponse } = useQuery(GET_USERS)

View file

@ -0,0 +1,134 @@
.footer {
display: flex;
flex-direction: row;
margin: auto 0 24px 0;
}
.modalTitle {
margin-top: -5px;
color: var(--zodiac);
font-family: var(--mont);
}
.modalLabel1 {
margin-top: 20px;
}
.modalLabel2 {
margin-top: 40px;
}
.inputLabel {
color: var(--zodiac);
font-family: var(--mont);
font-size: 24px;
margin-left: 8px;
margin-top: 15px;
}
.tableWidth {
width: 1132px;
}
.radioGroup {
flex-direction: row;
width: 500px;
}
.radioLabel {
width: 150px;
height: 48px;
}
.copyToClipboard {
margin-left: auto;
padding-top: 7px;
margin-right: -5px;
}
.chip {
background-color: var(--zircon);
font-family: var(--mont);
margin-left: 10px;
}
.info {
font-family: var(--museo);
text-align: justify;
}
.addressWrapper {
background-color: var(--zircon);
margin-top: 8px;
height: 35px;
}
.address {
margin: 0px 16px 0px 16px;
padding-right: -15px;
}
.errorMessage {
font-family: var(--museo);
color: var(--tomato);
}
.codeContainer {
margin-top: 15px;
margin-bottom: 15px;
}
.form {
display: flex;
flex-direction: column;
height: 100%;
}
.submit {
margin: auto 0 0 auto;
}
.error {
color: var(--tomato);
}
.link {
position: absolute;
top: 10px;
left: 0;
bottom: -20px;
right: -20px;
white-space: nowrap;
overflow-x: auto;
width: 92.5%;
}
.linkWrapper {
width: 100%;
height: 100%;
overflow: hidden;
position: relative;
}
.loginWrapper {
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
}
.username {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
width: 100%;
}
.roleSwitch {
margin-left: 15px;
}
.actionButtonWrapper {
display: flex;
gap: 12px;
}

View file

@ -1,124 +0,0 @@
import {
spacer,
fontPrimary,
fontSecondary,
primaryColor,
subheaderColor,
errorColor
} from 'src/styling/variables'
const styles = {
footer: {
display: 'flex',
flexDirection: 'row',
margin: [['auto', 0, spacer * 3, 0]]
},
modalTitle: {
marginTop: -5,
color: primaryColor,
fontFamily: fontPrimary
},
modalLabel1: {
marginTop: 20
},
modalLabel2: {
marginTop: 40
},
inputLabel: {
color: primaryColor,
fontFamily: fontPrimary,
fontSize: 24,
marginLeft: 8,
marginTop: 15
},
tableWidth: {
width: 1132
},
radioGroup: {
flexDirection: 'row',
width: 500
},
radioLabel: {
width: 150,
height: 48
},
copyToClipboard: {
marginLeft: 'auto',
paddingTop: 7,
marginRight: -5
},
chip: {
backgroundColor: subheaderColor,
fontFamily: fontPrimary,
marginLeft: 10
},
info: {
fontFamily: fontSecondary,
textAlign: 'justify'
},
addressWrapper: {
backgroundColor: subheaderColor,
marginTop: 8,
height: 35
},
address: {
margin: `0px ${spacer * 2}px 0px ${spacer * 2}px`,
paddingRight: -15
},
errorMessage: {
fontFamily: fontSecondary,
color: errorColor
},
codeContainer: {
marginTop: 15,
marginBottom: 15
},
form: {
display: 'flex',
flexDirection: 'column',
height: '100%'
},
submit: {
margin: [['auto', 0, 0, 'auto']]
},
error: {
color: errorColor
},
link: {
position: 'absolute',
top: 10,
left: 0,
bottom: '-20px',
right: '-20px',
whiteSpace: 'nowrap',
overflowX: 'auto',
width: '92.5%'
},
linkWrapper: {
width: '100%',
height: '100%',
overflow: 'hidden',
position: 'relative'
},
loginWrapper: {
display: 'flex',
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between'
},
username: {
overflow: 'hidden',
whiteSpace: 'nowrap',
textOverflow: 'ellipsis',
width: '100%'
},
roleSwitch: {
marginLeft: 15
},
actionButtonWrapper: {
display: 'flex',
gap: 12
}
}
export default styles

View file

@ -1,5 +1,4 @@
import { useMutation, gql } from "@apollo/client";
import { makeStyles } from '@mui/styles'
import { useMutation, gql } from '@apollo/client'
import React, { useState } from 'react'
import ErrorMessage from 'src/components/ErrorMessage'
import Modal from 'src/components/Modal'
@ -7,9 +6,8 @@ import { Info2, P } from 'src/components/typography'
import { Button } from 'src/components/buttons'
import styles from '../UserManagement.styles'
import Input2FAModal from './Input2FAModal'
import classes from '../UserManagement.module.css'
const CHANGE_USER_ROLE = gql`
mutation changeUserRole(
@ -27,11 +25,7 @@ const CHANGE_USER_ROLE = gql`
}
`
const useStyles = makeStyles(styles)
const ChangeRoleModal = ({ state, dispatch, user, requiresConfirmation }) => {
const classes = useStyles()
const [changeUserRole, { error }] = useMutation(CHANGE_USER_ROLE, {
onCompleted: () => handleClose(),
refetchQueries: () => ['users']

View file

@ -1,5 +1,4 @@
import { useMutation, gql } from '@apollo/client'
import { makeStyles } from '@mui/styles'
import classnames from 'classnames'
import { Field, Form, Formik } from 'formik'
import React, { useState } from 'react'
@ -13,9 +12,7 @@ import { Button } from 'src/components/buttons'
import { TextInput, RadioGroup } from 'src/components/inputs/formik'
import { urlResolver } from 'src/utils/urlResolver'
import styles from '../UserManagement.styles'
const useStyles = makeStyles(styles)
import classes from '../UserManagement.module.css'
const CREATE_USER = gql`
mutation createRegisterToken($username: String!, $role: String!) {
@ -58,8 +55,6 @@ const getErrorMsg = (formikErrors, formikTouched, mutationError) => {
}
const CreateUserModal = ({ state, dispatch }) => {
const classes = useStyles()
const [usernameField, setUsernameField] = useState('')
const [createUserURL, setCreateUserURL] = useState(null)

View file

@ -1,5 +1,4 @@
import { useMutation, gql } from "@apollo/client";
import { makeStyles } from '@mui/styles'
import { useMutation, gql } from '@apollo/client'
import React, { useState } from 'react'
import ErrorMessage from 'src/components/ErrorMessage'
import Modal from 'src/components/Modal'
@ -7,9 +6,8 @@ import { Info2, P } from 'src/components/typography'
import { Button } from 'src/components/buttons'
import styles from '../UserManagement.styles'
import Input2FAModal from './Input2FAModal'
import classes from '../UserManagement.module.css'
const ENABLE_USER = gql`
mutation enableUser($confirmationCode: String, $id: ID!) {
@ -27,11 +25,7 @@ const DISABLE_USER = gql`
}
`
const useStyles = makeStyles(styles)
const EnableUserModal = ({ state, dispatch, user, requiresConfirmation }) => {
const classes = useStyles()
const [enableUser, { error: enableError }] = useMutation(ENABLE_USER, {
onCompleted: () => handleClose(),
refetchQueries: () => ['users']

View file

@ -1,17 +1,12 @@
import { makeStyles } from '@mui/styles'
import React from 'react'
import Modal from 'src/components/Modal'
import { Info2, P } from 'src/components/typography'
import { Button } from 'src/components/buttons'
import styles from '../UserManagement.styles'
const useStyles = makeStyles(styles)
import classes from '../UserManagement.module.css'
const ChangeRoleModal = ({ state, dispatch }) => {
const classes = useStyles()
const handleClose = () => {
dispatch({
type: 'close',

View file

@ -1,16 +1,13 @@
import { useLazyQuery, gql } from '@apollo/client'
import { makeStyles } from '@mui/styles'
import { Form, Formik } from 'formik'
import React, { useState } from 'react'
import Modal from 'src/components/Modal'
import { Info2, P } from 'src/components/typography'
import { Button } from 'src/components/buttons'
import { CodeInput } from 'src/components/inputs/base'
import styles from '../UserManagement.styles'
const useStyles = makeStyles(styles)
import classes from '../UserManagement.module.css'
const CONFIRM_2FA = gql`
query confirm2FA($code: String!) {
@ -19,8 +16,6 @@ const CONFIRM_2FA = gql`
`
const Input2FAModal = ({ showModal, handleClose, setConfirmation }) => {
const classes = useStyles()
const [twoFACode, setTwoFACode] = useState('')
const [invalidCode, setInvalidCode] = useState(false)

View file

@ -1,16 +1,14 @@
import { useMutation, gql } from '@apollo/client'
import { makeStyles } from '@mui/styles'
import React, { useEffect, useState } from 'react'
import ErrorMessage from 'src/components/ErrorMessage'
import Modal from 'src/components/Modal'
import { Info2, P, Mono } from 'src/components/typography'
import CopyToClipboard from 'src/components/CopyToClipboard.jsx'
import { urlResolver } from 'src/utils/urlResolver'
import styles from '../UserManagement.styles'
import Input2FAModal from './Input2FAModal'
import classes from '../UserManagement.module.css'
const CREATE_RESET_2FA_TOKEN = gql`
mutation createReset2FAToken($confirmationCode: String, $userID: ID!) {
@ -22,10 +20,7 @@ const CREATE_RESET_2FA_TOKEN = gql`
}
`
const useStyles = makeStyles(styles)
const Reset2FAModal = ({ state, dispatch, user, requiresConfirmation }) => {
const classes = useStyles()
const [reset2FAUrl, setReset2FAUrl] = useState('')
const [createReset2FAToken, { loading, error }] = useMutation(

View file

@ -1,5 +1,4 @@
import { useMutation, gql } from '@apollo/client'
import { makeStyles } from '@mui/styles'
import React, { useEffect, useState } from 'react'
import ErrorMessage from 'src/components/ErrorMessage'
import Modal from 'src/components/Modal'
@ -8,9 +7,8 @@ import CopyToClipboard from 'src/components/CopyToClipboard.jsx'
import { urlResolver } from 'src/utils/urlResolver'
import styles from '../UserManagement.styles'
import Input2FAModal from './Input2FAModal'
import classes from '../UserManagement.module.css'
const CREATE_RESET_PASSWORD_TOKEN = gql`
mutation createResetPasswordToken($confirmationCode: String, $userID: ID!) {
@ -25,15 +23,12 @@ const CREATE_RESET_PASSWORD_TOKEN = gql`
}
`
const useStyles = makeStyles(styles)
const ResetPasswordModal = ({
state,
dispatch,
user,
requiresConfirmation
}) => {
const classes = useStyles()
const [resetPasswordUrl, setResetPasswordUrl] = useState('')
const [createResetPasswordToken, { loading, error }] = useMutation(

View file

@ -1,5 +1,4 @@
import { useQuery, useMutation, gql } from "@apollo/client";
import { makeStyles } from '@mui/styles'
import * as R from 'ramda'
import React, { useState } from 'react'
import Modal from 'src/components/Modal'
@ -17,7 +16,6 @@ import { fromNamespace, toNamespace } from 'src/utils/config'
import { P } from '../../components/typography'
import AdvancedWallet from './AdvancedWallet'
import styles from './Wallet.styles'
import Wizard from './Wizard'
import { WalletSchema, getElements } from './helper'
@ -61,10 +59,7 @@ const GET_MARKETS = gql`
const LOCALE = 'locale'
const useStyles = makeStyles(styles)
const Wallet = ({ name: SCREEN_KEY }) => {
const classes = useStyles()
const [editingSchema, setEditingSchema] = useState(null)
const [onChangeFunction, setOnChangeFunction] = useState(null)
const [wizard, setWizard] = useState(false)
@ -128,7 +123,7 @@ const Wallet = ({ name: SCREEN_KEY }) => {
return (
<>
<div className={classes.header}>
<div className="flex items-center justify-between">
<TitleSection
title="Wallet settings"
buttons={[

View file

@ -1,7 +0,0 @@
export default {
header: {
display: 'flex',
alignItems: 'center',
justifyContent: 'space-between'
}
}

View file

@ -1,4 +1,3 @@
import { makeStyles } from '@mui/styles'
import React from 'react'
import { H1, P } from 'src/components/typography'
import BitcoinLogo from 'src/styling/logos/icon-bitcoin-colour.svg?react'
@ -14,32 +13,6 @@ import ZCashLogo from 'src/styling/logos/icon-zcash-colour.svg?react'
import { Button } from 'src/components/buttons'
const styles = {
logo: {
maxHeight: 80,
maxWidth: 200
},
title: {
margin: [[24, 0, 32, 0]]
},
text: {
margin: 0
},
button: {
marginTop: 'auto',
marginBottom: 58
},
modalContent: {
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
padding: [[0, 42]],
flex: 1
}
}
const useStyles = makeStyles(styles)
const getLogo = code => {
switch (code) {
case 'BTC':
@ -71,19 +44,18 @@ const getLogo = code => {
}
const WizardSplash = ({ code, name, onContinue }) => {
const classes = useStyles()
const Logo = getLogo(code)
return (
<div className={classes.modalContent}>
<Logo className={classes.logo} />
<H1 className={classes.title}>Enable {name}</H1>
<P className={classes.text}>
<div className="flex flex-col items-center px-10 flex-1">
<Logo className="max-h-20 max-w-50" />
<H1 className="mt-6 mb-8">Enable {name}</H1>
<P className="m-0">
You are about to enable {name} on your system. This will allow you to
use this cryptocurrency on your machines. To be able to do that, youll
have to set up all the necessary 3rd party services.
</P>
<Button className={classes.button} onClick={onContinue}>
<Button className="mt-auto mb-15" onClick={onContinue}>
Start configuration
</Button>
</div>

View file

@ -1,4 +1,3 @@
import { makeStyles } from '@mui/styles'
import classnames from 'classnames'
import { Formik, Form, Field } from 'formik'
import * as R from 'ramda'
@ -13,10 +12,6 @@ import { RadioGroup, Autocomplete } from 'src/components/inputs'
import { NumberInput } from 'src/components/inputs/formik'
import { startCase } from 'src/utils/string'
import styles from './WizardStep.styles'
const useStyles = makeStyles(styles)
const initialState = {
form: null,
selected: null,
@ -69,7 +64,6 @@ const WizardStep = ({
unfilled,
getValue
}) => {
const classes = useStyles()
const [{ innerError, selected, form, isNew }, dispatch] = useReducer(
reducer,
initialState
@ -88,15 +82,16 @@ const WizardStep = ({
const label = isLastStep ? 'Finish' : 'Next'
const displayName = name ?? type
const subtitleClass = {
[classes.subtitle]: true,
[classes.error]: innerError
}
const subtitleClass = classnames('mt-8 mb-5 mx-0', {
'text-tomato': innerError
})
return (
<>
<Info2 className={classes.title}>{startCase(displayName)}</Info2>
<Info2 noMargin className="mb-3">
{startCase(displayName)}
</Info2>
<Stepper steps={lastStep} currentStep={step} />
<H4 className={classnames(subtitleClass)}>
<H4 className={subtitleClass}>
{step < maxSteps - 1
? `Select a ${displayName} or set up a new one`
: `Select ${displayName} for ${coin}`}
@ -105,12 +100,12 @@ const WizardStep = ({
<RadioGroup
options={filled}
value={selected}
className={classes.radioGroup}
className="flex-row"
onChange={(evt, it) => {
dispatch({ type: 'select', selected: it })
}}
labelClassName={classes.radioLabel}
radioClassName={classes.radio}
labelClassName="w-37 h-12"
radioClassName="p-1 m-1"
/>
)}
{type === 'zeroConfLimit' && (
@ -122,11 +117,7 @@ const WizardStep = ({
validationSchema={stepSchema}>
{({ values, setFieldValue }) => (
<Form>
<div
className={classnames(
classes.horizontalAlign,
classes.lineAlignment
)}>
<div className="flex flex-row">
<Field
component={NumberInput}
decimalPlaces={0}
@ -140,7 +131,7 @@ const WizardStep = ({
})
setFieldValue(event.target.id, event.target.value)
}}
className={classes.zeroConfLimit}
className="mr-1 text-2xl font-mont font-normal"
/>
<Info2>{fiatCurrency}</Info2>
</div>
@ -148,15 +139,15 @@ const WizardStep = ({
)}
</Formik>
)}
<div className={classes.setupNew}>
<div className="flex items-center h-12">
{!R.isEmpty(unfilled) && !R.isNil(unfilled) && (
<RadioGroup
value={isNew}
onChange={(evt, it) => {
dispatch({ type: 'new' })
}}
labelClassName={classes.radioLabel}
radioClassName={classes.radio}
labelClassName="w-[150px] h-12"
radioClassName="p-1 m-1"
options={[{ display: 'Set up new', code: true }]}
/>
)}
@ -164,7 +155,7 @@ const WizardStep = ({
<Autocomplete
fullWidth
label={`Select ${displayName}`}
className={classes.picker}
className="w-[150px]"
isOptionEqualToValue={R.eqProps('code')}
labelProp={'display'}
options={unfilled}
@ -178,23 +169,25 @@ const WizardStep = ({
<FormRenderer
save={it => innerContinue({ [type]: form.code }, { [form.code]: it })}
elements={schemas[form.code].elements}
validationSchema={schemas[form.code].getValidationSchema(accounts[form.code])}
validationSchema={schemas[form.code].getValidationSchema(
accounts[form.code]
)}
value={getValue(form.code)}
buttonLabel={label}
/>
)}
{!form && (
<div className={classes.submit}>
<div className="flex flex-row ml-auto mt-auto mb-6">
{error && <ErrorMessage>Failed to save</ErrorMessage>}
<Button
className={classes.button}
className="ml-auto"
onClick={() => innerContinue({ [type]: selected })}>
{label}
</Button>
</div>
)}
</>
);
)
}
export default WizardStep

View file

@ -1,60 +0,0 @@
import { errorColor, fontSize1, fontPrimary } from 'src/styling/variables'
const LABEL_WIDTH = 150
export default {
title: {
margin: [[0, 0, 12, 0]]
},
subtitle: {
margin: [[32, 0, 21, 0]]
},
error: {
color: errorColor
},
button: {
marginLeft: 'auto'
},
submit: {
display: 'flex',
flexDirection: 'row',
margin: [['auto', 0, 24]]
},
radioGroup: {
flexDirection: 'row'
},
radioLabel: {
width: LABEL_WIDTH,
height: 48
},
radio: {
padding: 4,
margin: 4
},
setupNew: {
display: 'flex',
alignItems: 'center',
height: 48
},
picker: {
width: LABEL_WIDTH
},
horizontalAlign: {
display: 'flex',
flexDirection: 'row'
},
centerAlignment: {
alignItems: 'center'
},
zeroConfLimit: {
marginRight: 5,
'& > div': {
fontSize: fontSize1,
fontFamily: fontPrimary,
fontWeight: 300,
'& > input': {
padding: [[6, 0, 2]]
}
}
}
}

View file

@ -8,15 +8,9 @@ import {
Checkbox,
NumberInput
} from 'src/components/inputs/formik'
import { disabledColor } from 'src/styling/variables'
import { CURRENCY_MAX } from 'src/utils/constants'
import { defaultToZero } from 'src/utils/number'
const classes = {
editDisabled: {
color: disabledColor
}
}
const filterClass = type => R.filter(it => it.class === type)
const filterCoins = ({ id }) => R.filter(it => R.contains(id)(it.cryptos))
@ -172,7 +166,7 @@ const getAdvancedWalletElementsOverrides = (
width: 250,
view: (_, ite) => {
if (ite.cryptoCurrency !== 'BTC')
return <span style={classes.editDisabled}>{`No`}</span>
return <span className="text-dust">{`No`}</span>
return ite.allowTransactionBatching ? 'Yes' : 'No'
},
input: Checkbox,
@ -186,7 +180,7 @@ const getAdvancedWalletElementsOverrides = (
width: 250,
view: (_, ite) => {
if (ite.cryptoCurrency !== 'BTC')
return <span style={classes.editDisabled}>{`Default`}</span>
return <span className="test-dust">{`Default`}</span>
return viewFeeMultiplier(ite.feeMultiplier)
},
input: Autocomplete,
@ -289,7 +283,7 @@ const getElements = (cryptoCurrencies, accounts, onChange, wizard = false) => {
return has0Conf(row) ? (
displayName
) : (
<span style={classes.editDisabled}>{displayName}</span>
<span className="text-dust">{displayName}</span>
)
},
input: Autocomplete,
@ -309,7 +303,7 @@ const getElements = (cryptoCurrencies, accounts, onChange, wizard = false) => {
size: 'sm',
stripe: true,
view: (it, row) =>
has0Conf(row) ? it : <span style={classes.editDisabled}>{it}</span>,
has0Conf(row) ? it : <span className="text-dust">{it}</span>,
input: NumberInput,
width: 145 - widthAdjust,
inputProps: {

View file

@ -20,6 +20,7 @@
--tomato: #ff584a;
--dust: #dddddd;
--ghost: #fafbff;
--zircon: #ebefff;
--zircon2: #dbdfed;
@ -44,6 +45,7 @@
--color-comet2: var(--comet2);
--color-comet3: var(--comet3);
--color-tomato: var(--tomato);
--color--dust: var(--dust);
--color-ghost: var(--ghost);
--color-zircon: var(--zircon);
--color-zircon2: var(--zircon2);