fix: remove logic unnecessarily tied to components and error handling

This commit is contained in:
Sérgio Salgado 2021-04-20 20:15:22 +01:00 committed by Josh Harvey
parent 75a2ecd3c2
commit 26a051ff07
10 changed files with 123 additions and 112 deletions

View file

@ -13,22 +13,22 @@ import { STATES } from './states'
const useStyles = makeStyles(styles) const useStyles = makeStyles(styles)
const initialState = {
twoFAField: '',
clientField: '',
passwordField: '',
rememberMeField: false,
loginState: STATES.LOGIN
}
const reducer = (state, action) => {
const { type, payload } = action
return { ...state, ...payload, loginState: type }
}
const LoginCard = () => { const LoginCard = () => {
const classes = useStyles() const classes = useStyles()
const initialState = {
twoFAField: '',
clientField: '',
passwordField: '',
rememberMeField: false,
loginState: STATES.LOGIN
}
const reducer = (state, action) => {
const { type, payload } = action
return { ...state, ...payload, loginState: type }
}
const [state, dispatch] = useReducer(reducer, initialState) const [state, dispatch] = useReducer(reducer, initialState)
const renderState = () => { const renderState = () => {

View file

@ -61,46 +61,44 @@ const initialValues = {
confirmPassword: '' confirmPassword: ''
} }
const initialState = {
username: null,
role: null,
result: ''
}
const reducer = (state, action) => {
const { type, payload } = action
return { ...state, ...payload, result: type }
}
const Register = () => { const Register = () => {
const classes = useStyles() const classes = useStyles()
const history = useHistory() const history = useHistory()
const token = QueryParams().get('t') const token = QueryParams().get('t')
const initialState = {
username: null,
role: null,
result: ''
}
const reducer = (state, action) => {
const { type, payload } = action
return { ...state, ...payload, result: type }
}
const [state, dispatch] = useReducer(reducer, initialState) const [state, dispatch] = useReducer(reducer, initialState)
const { error: queryError, loading } = useQuery(VALIDATE_REGISTER_LINK, { const { error: queryError, loading } = useQuery(VALIDATE_REGISTER_LINK, {
variables: { token: token }, variables: { token: token },
onCompleted: ({ validateRegisterLink: info }) => { onCompleted: ({ validateRegisterLink: info }) => {
if (!info) { if (!info) {
dispatch({ return dispatch({
type: 'failure' type: 'failure'
}) })
} else {
dispatch({
type: 'success',
payload: {
username: info.username,
role: info.role
}
})
} }
dispatch({
type: 'success',
payload: {
username: info.username,
role: info.role
}
})
}, },
onError: () => { onError: () =>
dispatch({ dispatch({
type: 'failure' type: 'failure'
}) })
}
}) })
const [register, { error: mutationError }] = useMutation(REGISTER, { const [register, { error: mutationError }] = useMutation(REGISTER, {

View file

@ -14,7 +14,6 @@ import { primaryColor } from 'src/styling/variables'
import styles from './shared.styles' import styles from './shared.styles'
const QueryParams = () => new URLSearchParams(useLocation().search)
const useStyles = makeStyles(styles) const useStyles = makeStyles(styles)
const VALIDATE_RESET_2FA_LINK = gql` const VALIDATE_RESET_2FA_LINK = gql`
@ -33,27 +32,28 @@ const RESET_2FA = gql`
} }
` `
const initialState = {
userID: null,
secret: null,
otpauth: null,
result: null
}
const reducer = (state, action) => {
const { type, payload } = action
return { ...state, ...payload, result: type }
}
const Reset2FA = () => { const Reset2FA = () => {
const classes = useStyles() const classes = useStyles()
const history = useHistory() const history = useHistory()
const QueryParams = () => new URLSearchParams(useLocation().search)
const token = QueryParams().get('t') const token = QueryParams().get('t')
const [isShowing, setShowing] = useState(false) const [isShowing, setShowing] = useState(false)
const [invalidToken, setInvalidToken] = useState(false) const [invalidToken, setInvalidToken] = useState(false)
const [twoFAConfirmation, setTwoFAConfirmation] = useState('') const [twoFAConfirmation, setTwoFAConfirmation] = useState('')
const initialState = {
userID: null,
secret: null,
otpauth: null,
result: null
}
const reducer = (state, action) => {
const { type, payload } = action
return { ...state, ...payload, result: type }
}
const [state, dispatch] = useReducer(reducer, initialState) const [state, dispatch] = useReducer(reducer, initialState)
const handle2FAChange = value => { const handle2FAChange = value => {

View file

@ -14,7 +14,6 @@ import { ReactComponent as Logo } from 'src/styling/icons/menu/logo.svg'
import styles from './shared.styles' import styles from './shared.styles'
const QueryParams = () => new URLSearchParams(useLocation().search)
const useStyles = makeStyles(styles) const useStyles = makeStyles(styles)
const VALIDATE_RESET_PASSWORD_LINK = gql` const VALIDATE_RESET_PASSWORD_LINK = gql`
@ -53,6 +52,7 @@ const initialValues = {
const ResetPassword = () => { const ResetPassword = () => {
const classes = useStyles() const classes = useStyles()
const history = useHistory() const history = useHistory()
const QueryParams = () => new URLSearchParams(useLocation().search)
const token = QueryParams().get('t') const token = QueryParams().get('t')
const [userID, setUserID] = useState(null) const [userID, setUserID] = useState(null)
const [isLoading, setLoading] = useState(true) const [isLoading, setLoading] = useState(true)

View file

@ -33,32 +33,31 @@ const GET_USERS = gql`
} }
` `
const initialState = {
showCreateUserModal: false,
showResetPasswordModal: false,
showReset2FAModal: false,
showRoleModal: false,
showEnableUserModal: false
}
const reducer = (_, action) => {
const { type, payload } = action
switch (type) {
case 'close':
return initialState
case 'open':
return { ...initialState, [payload]: true }
default:
return initialState
}
}
const Users = () => { const Users = () => {
const classes = useStyles() const classes = useStyles()
const { userData } = useContext(AppContext) const { userData } = useContext(AppContext)
const { data: userResponse } = useQuery(GET_USERS) const { data: userResponse } = useQuery(GET_USERS)
const initialState = {
showCreateUserModal: false,
showResetPasswordModal: false,
showReset2FAModal: false,
showRoleModal: false,
showEnableUserModal: false
}
const reducer = (_, action) => {
const { type, payload } = action
switch (type) {
case 'close':
return initialState
case 'open':
return { ...initialState, [payload]: true }
default:
return initialState
}
}
const [state, dispatch] = useReducer(reducer, initialState) const [state, dispatch] = useReducer(reducer, initialState)
const [userInfo, setUserInfo] = useState(null) const [userInfo, setUserInfo] = useState(null)

View file

@ -3,6 +3,7 @@ import { makeStyles } from '@material-ui/core/styles'
import gql from 'graphql-tag' import gql from 'graphql-tag'
import React, { useState } from 'react' import React, { useState } from 'react'
import ErrorMessage from 'src/components/ErrorMessage'
import Modal from 'src/components/Modal' import Modal from 'src/components/Modal'
import { Button } from 'src/components/buttons' import { Button } from 'src/components/buttons'
import { Info2, P } from 'src/components/typography' import { Info2, P } from 'src/components/typography'
@ -32,7 +33,8 @@ const useStyles = makeStyles(styles)
const ChangeRoleModal = ({ state, dispatch, user, requiresConfirmation }) => { const ChangeRoleModal = ({ state, dispatch, user, requiresConfirmation }) => {
const classes = useStyles() const classes = useStyles()
const [changeUserRole] = useMutation(CHANGE_USER_ROLE, { const [changeUserRole, { error }] = useMutation(CHANGE_USER_ROLE, {
onCompleted: () => handleClose(),
refetchQueries: () => ['users'] refetchQueries: () => ['users']
}) })
@ -46,7 +48,6 @@ const ChangeRoleModal = ({ state, dispatch, user, requiresConfirmation }) => {
newRole: user.role === 'superuser' ? 'user' : 'superuser' newRole: user.role === 'superuser' ? 'user' : 'superuser'
} }
}) })
handleClose()
} }
const handleClose = () => { const handleClose = () => {
@ -81,6 +82,7 @@ const ChangeRoleModal = ({ state, dispatch, user, requiresConfirmation }) => {
</P> </P>
<P className={classes.info}>Do you wish to proceed?</P> <P className={classes.info}>Do you wish to proceed?</P>
<div className={classes.footer}> <div className={classes.footer}>
{error && <ErrorMessage>{error}</ErrorMessage>}
<Button className={classes.submit} onClick={() => submit()}> <Button className={classes.submit} onClick={() => submit()}>
Confirm Confirm
</Button> </Button>

View file

@ -39,23 +39,23 @@ const initialValues = {
role: '' role: ''
} }
const radioOptions = [
{
code: 'user',
display: 'Regular user'
},
{
code: 'superuser',
display: 'Superuser'
}
]
const CreateUserModal = ({ state, dispatch }) => { const CreateUserModal = ({ state, dispatch }) => {
const classes = useStyles() const classes = useStyles()
const [usernameField, setUsernameField] = useState('') const [usernameField, setUsernameField] = useState('')
const [createUserURL, setCreateUserURL] = useState(null) const [createUserURL, setCreateUserURL] = useState(null)
const radioOptions = [
{
code: 'user',
display: 'Regular user'
},
{
code: 'superuser',
display: 'Superuser'
}
]
const handleClose = () => { const handleClose = () => {
setCreateUserURL(null) setCreateUserURL(null)
dispatch({ dispatch({

View file

@ -3,6 +3,7 @@ import { makeStyles } from '@material-ui/core/styles'
import gql from 'graphql-tag' import gql from 'graphql-tag'
import React, { useState } from 'react' import React, { useState } from 'react'
import ErrorMessage from 'src/components/ErrorMessage'
import Modal from 'src/components/Modal' import Modal from 'src/components/Modal'
import { Button } from 'src/components/buttons' import { Button } from 'src/components/buttons'
import { Info2, P } from 'src/components/typography' import { Info2, P } from 'src/components/typography'
@ -32,11 +33,13 @@ const useStyles = makeStyles(styles)
const EnableUserModal = ({ state, dispatch, user, requiresConfirmation }) => { const EnableUserModal = ({ state, dispatch, user, requiresConfirmation }) => {
const classes = useStyles() const classes = useStyles()
const [enableUser] = useMutation(ENABLE_USER, { const [enableUser, { error: enableError }] = useMutation(ENABLE_USER, {
onCompleted: () => handleClose(),
refetchQueries: () => ['users'] refetchQueries: () => ['users']
}) })
const [disableUser] = useMutation(DISABLE_USER, { const [disableUser, { error: disableError }] = useMutation(DISABLE_USER, {
onCompleted: () => handleClose(),
refetchQueries: () => ['users'] refetchQueries: () => ['users']
}) })
@ -62,7 +65,6 @@ const EnableUserModal = ({ state, dispatch, user, requiresConfirmation }) => {
const submit = () => { const submit = () => {
user?.enabled ? disable() : enable() user?.enabled ? disable() : enable()
handleClose()
} }
const handleClose = () => { const handleClose = () => {
@ -115,6 +117,8 @@ const EnableUserModal = ({ state, dispatch, user, requiresConfirmation }) => {
</> </>
)} )}
<div className={classes.footer}> <div className={classes.footer}>
{disableError && <ErrorMessage>{disableError}</ErrorMessage>}
{enableError && <ErrorMessage>{enableError}</ErrorMessage>}
<Button className={classes.submit} onClick={() => submit()}> <Button className={classes.submit} onClick={() => submit()}>
Confirm Confirm
</Button> </Button>

View file

@ -3,6 +3,7 @@ import { makeStyles } from '@material-ui/core/styles'
import gql from 'graphql-tag' import gql from 'graphql-tag'
import React, { useEffect, useState } from 'react' import React, { useEffect, useState } from 'react'
import ErrorMessage from 'src/components/ErrorMessage'
import Modal from 'src/components/Modal' import Modal from 'src/components/Modal'
import { Info2, P, Mono } from 'src/components/typography' import { Info2, P, Mono } from 'src/components/typography'
import CopyToClipboard from 'src/pages/Transactions/CopyToClipboard' import CopyToClipboard from 'src/pages/Transactions/CopyToClipboard'
@ -28,7 +29,7 @@ const Reset2FAModal = ({ state, dispatch, user, requiresConfirmation }) => {
const classes = useStyles() const classes = useStyles()
const [reset2FAUrl, setReset2FAUrl] = useState('') const [reset2FAUrl, setReset2FAUrl] = useState('')
const [createReset2FAToken, { loading }] = useMutation( const [createReset2FAToken, { loading, error }] = useMutation(
CREATE_RESET_2FA_TOKEN, CREATE_RESET_2FA_TOKEN,
{ {
onCompleted: ({ createReset2FAToken: token }) => { onCompleted: ({ createReset2FAToken: token }) => {
@ -88,18 +89,21 @@ const Reset2FAModal = ({ state, dispatch, user, requiresConfirmation }) => {
Safely share this link with {user.username} for a two-factor Safely share this link with {user.username} for a two-factor
authentication reset. authentication reset.
</P> </P>
<div className={classes.addressWrapper}> {!error && (
<Mono className={classes.address}> <div className={classes.addressWrapper}>
<strong> <Mono className={classes.address}>
<CopyToClipboard <strong>
className={classes.link} <CopyToClipboard
buttonClassname={classes.copyToClipboard} className={classes.link}
wrapperClassname={classes.linkWrapper}> buttonClassname={classes.copyToClipboard}
{reset2FAUrl} wrapperClassname={classes.linkWrapper}>
</CopyToClipboard> {reset2FAUrl}
</strong> </CopyToClipboard>
</Mono> </strong>
</div> </Mono>
</div>
)}
{error && <ErrorMessage>{error}</ErrorMessage>}
</Modal> </Modal>
)) ))
) )

View file

@ -3,6 +3,7 @@ import { makeStyles } from '@material-ui/core/styles'
import gql from 'graphql-tag' import gql from 'graphql-tag'
import React, { useEffect, useState } from 'react' import React, { useEffect, useState } from 'react'
import ErrorMessage from 'src/components/ErrorMessage'
import Modal from 'src/components/Modal' import Modal from 'src/components/Modal'
import { Info2, P, Mono } from 'src/components/typography' import { Info2, P, Mono } from 'src/components/typography'
import CopyToClipboard from 'src/pages/Transactions/CopyToClipboard' import CopyToClipboard from 'src/pages/Transactions/CopyToClipboard'
@ -36,7 +37,7 @@ const ResetPasswordModal = ({
const classes = useStyles() const classes = useStyles()
const [resetPasswordUrl, setResetPasswordUrl] = useState('') const [resetPasswordUrl, setResetPasswordUrl] = useState('')
const [createResetPasswordToken, { loading }] = useMutation( const [createResetPasswordToken, { loading, error }] = useMutation(
CREATE_RESET_PASSWORD_TOKEN, CREATE_RESET_PASSWORD_TOKEN,
{ {
onCompleted: ({ createResetPasswordToken: token }) => { onCompleted: ({ createResetPasswordToken: token }) => {
@ -95,18 +96,21 @@ const ResetPasswordModal = ({
<P className={classes.info}> <P className={classes.info}>
Safely share this link with {user.username} for a password reset. Safely share this link with {user.username} for a password reset.
</P> </P>
<div className={classes.addressWrapper}> {!error && (
<Mono className={classes.address}> <div className={classes.addressWrapper}>
<strong> <Mono className={classes.address}>
<CopyToClipboard <strong>
className={classes.link} <CopyToClipboard
buttonClassname={classes.copyToClipboard} className={classes.link}
wrapperClassname={classes.linkWrapper}> buttonClassname={classes.copyToClipboard}
{resetPasswordUrl} wrapperClassname={classes.linkWrapper}>
</CopyToClipboard> {resetPasswordUrl}
</strong> </CopyToClipboard>
</Mono> </strong>
</div> </Mono>
</div>
)}
{error && <ErrorMessage>{error}</ErrorMessage>}
</Modal> </Modal>
)) ))
) )