fix: remove logic unnecessarily tied to components and error handling
This commit is contained in:
parent
75a2ecd3c2
commit
26a051ff07
10 changed files with 123 additions and 112 deletions
|
|
@ -13,22 +13,22 @@ import { STATES } from './states'
|
|||
|
||||
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 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 renderState = () => {
|
||||
|
|
|
|||
|
|
@ -61,46 +61,44 @@ const initialValues = {
|
|||
confirmPassword: ''
|
||||
}
|
||||
|
||||
const initialState = {
|
||||
username: null,
|
||||
role: null,
|
||||
result: ''
|
||||
}
|
||||
|
||||
const reducer = (state, action) => {
|
||||
const { type, payload } = action
|
||||
return { ...state, ...payload, result: type }
|
||||
}
|
||||
|
||||
const Register = () => {
|
||||
const classes = useStyles()
|
||||
const history = useHistory()
|
||||
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 { error: queryError, loading } = useQuery(VALIDATE_REGISTER_LINK, {
|
||||
variables: { token: token },
|
||||
onCompleted: ({ validateRegisterLink: info }) => {
|
||||
if (!info) {
|
||||
dispatch({
|
||||
return dispatch({
|
||||
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({
|
||||
type: 'failure'
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
const [register, { error: mutationError }] = useMutation(REGISTER, {
|
||||
|
|
|
|||
|
|
@ -14,7 +14,6 @@ import { primaryColor } from 'src/styling/variables'
|
|||
|
||||
import styles from './shared.styles'
|
||||
|
||||
const QueryParams = () => new URLSearchParams(useLocation().search)
|
||||
const useStyles = makeStyles(styles)
|
||||
|
||||
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 classes = useStyles()
|
||||
const history = useHistory()
|
||||
const QueryParams = () => new URLSearchParams(useLocation().search)
|
||||
const token = QueryParams().get('t')
|
||||
|
||||
const [isShowing, setShowing] = useState(false)
|
||||
const [invalidToken, setInvalidToken] = useState(false)
|
||||
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 handle2FAChange = value => {
|
||||
|
|
|
|||
|
|
@ -14,7 +14,6 @@ import { ReactComponent as Logo } from 'src/styling/icons/menu/logo.svg'
|
|||
|
||||
import styles from './shared.styles'
|
||||
|
||||
const QueryParams = () => new URLSearchParams(useLocation().search)
|
||||
const useStyles = makeStyles(styles)
|
||||
|
||||
const VALIDATE_RESET_PASSWORD_LINK = gql`
|
||||
|
|
@ -53,6 +52,7 @@ const initialValues = {
|
|||
const ResetPassword = () => {
|
||||
const classes = useStyles()
|
||||
const history = useHistory()
|
||||
const QueryParams = () => new URLSearchParams(useLocation().search)
|
||||
const token = QueryParams().get('t')
|
||||
const [userID, setUserID] = useState(null)
|
||||
const [isLoading, setLoading] = useState(true)
|
||||
|
|
|
|||
|
|
@ -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 classes = useStyles()
|
||||
const { userData } = useContext(AppContext)
|
||||
|
||||
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 [userInfo, setUserInfo] = useState(null)
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import { makeStyles } from '@material-ui/core/styles'
|
|||
import gql from 'graphql-tag'
|
||||
import React, { useState } from 'react'
|
||||
|
||||
import ErrorMessage from 'src/components/ErrorMessage'
|
||||
import Modal from 'src/components/Modal'
|
||||
import { Button } from 'src/components/buttons'
|
||||
import { Info2, P } from 'src/components/typography'
|
||||
|
|
@ -32,7 +33,8 @@ const useStyles = makeStyles(styles)
|
|||
const ChangeRoleModal = ({ state, dispatch, user, requiresConfirmation }) => {
|
||||
const classes = useStyles()
|
||||
|
||||
const [changeUserRole] = useMutation(CHANGE_USER_ROLE, {
|
||||
const [changeUserRole, { error }] = useMutation(CHANGE_USER_ROLE, {
|
||||
onCompleted: () => handleClose(),
|
||||
refetchQueries: () => ['users']
|
||||
})
|
||||
|
||||
|
|
@ -46,7 +48,6 @@ const ChangeRoleModal = ({ state, dispatch, user, requiresConfirmation }) => {
|
|||
newRole: user.role === 'superuser' ? 'user' : 'superuser'
|
||||
}
|
||||
})
|
||||
handleClose()
|
||||
}
|
||||
|
||||
const handleClose = () => {
|
||||
|
|
@ -81,6 +82,7 @@ const ChangeRoleModal = ({ state, dispatch, user, requiresConfirmation }) => {
|
|||
</P>
|
||||
<P className={classes.info}>Do you wish to proceed?</P>
|
||||
<div className={classes.footer}>
|
||||
{error && <ErrorMessage>{error}</ErrorMessage>}
|
||||
<Button className={classes.submit} onClick={() => submit()}>
|
||||
Confirm
|
||||
</Button>
|
||||
|
|
|
|||
|
|
@ -39,23 +39,23 @@ const initialValues = {
|
|||
role: ''
|
||||
}
|
||||
|
||||
const radioOptions = [
|
||||
{
|
||||
code: 'user',
|
||||
display: 'Regular user'
|
||||
},
|
||||
{
|
||||
code: 'superuser',
|
||||
display: 'Superuser'
|
||||
}
|
||||
]
|
||||
|
||||
const CreateUserModal = ({ state, dispatch }) => {
|
||||
const classes = useStyles()
|
||||
|
||||
const [usernameField, setUsernameField] = useState('')
|
||||
const [createUserURL, setCreateUserURL] = useState(null)
|
||||
|
||||
const radioOptions = [
|
||||
{
|
||||
code: 'user',
|
||||
display: 'Regular user'
|
||||
},
|
||||
{
|
||||
code: 'superuser',
|
||||
display: 'Superuser'
|
||||
}
|
||||
]
|
||||
|
||||
const handleClose = () => {
|
||||
setCreateUserURL(null)
|
||||
dispatch({
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import { makeStyles } from '@material-ui/core/styles'
|
|||
import gql from 'graphql-tag'
|
||||
import React, { useState } from 'react'
|
||||
|
||||
import ErrorMessage from 'src/components/ErrorMessage'
|
||||
import Modal from 'src/components/Modal'
|
||||
import { Button } from 'src/components/buttons'
|
||||
import { Info2, P } from 'src/components/typography'
|
||||
|
|
@ -32,11 +33,13 @@ const useStyles = makeStyles(styles)
|
|||
const EnableUserModal = ({ state, dispatch, user, requiresConfirmation }) => {
|
||||
const classes = useStyles()
|
||||
|
||||
const [enableUser] = useMutation(ENABLE_USER, {
|
||||
const [enableUser, { error: enableError }] = useMutation(ENABLE_USER, {
|
||||
onCompleted: () => handleClose(),
|
||||
refetchQueries: () => ['users']
|
||||
})
|
||||
|
||||
const [disableUser] = useMutation(DISABLE_USER, {
|
||||
const [disableUser, { error: disableError }] = useMutation(DISABLE_USER, {
|
||||
onCompleted: () => handleClose(),
|
||||
refetchQueries: () => ['users']
|
||||
})
|
||||
|
||||
|
|
@ -62,7 +65,6 @@ const EnableUserModal = ({ state, dispatch, user, requiresConfirmation }) => {
|
|||
|
||||
const submit = () => {
|
||||
user?.enabled ? disable() : enable()
|
||||
handleClose()
|
||||
}
|
||||
|
||||
const handleClose = () => {
|
||||
|
|
@ -115,6 +117,8 @@ const EnableUserModal = ({ state, dispatch, user, requiresConfirmation }) => {
|
|||
</>
|
||||
)}
|
||||
<div className={classes.footer}>
|
||||
{disableError && <ErrorMessage>{disableError}</ErrorMessage>}
|
||||
{enableError && <ErrorMessage>{enableError}</ErrorMessage>}
|
||||
<Button className={classes.submit} onClick={() => submit()}>
|
||||
Confirm
|
||||
</Button>
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import { makeStyles } from '@material-ui/core/styles'
|
|||
import gql from 'graphql-tag'
|
||||
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/pages/Transactions/CopyToClipboard'
|
||||
|
|
@ -28,7 +29,7 @@ const Reset2FAModal = ({ state, dispatch, user, requiresConfirmation }) => {
|
|||
const classes = useStyles()
|
||||
const [reset2FAUrl, setReset2FAUrl] = useState('')
|
||||
|
||||
const [createReset2FAToken, { loading }] = useMutation(
|
||||
const [createReset2FAToken, { loading, error }] = useMutation(
|
||||
CREATE_RESET_2FA_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
|
||||
authentication reset.
|
||||
</P>
|
||||
<div className={classes.addressWrapper}>
|
||||
<Mono className={classes.address}>
|
||||
<strong>
|
||||
<CopyToClipboard
|
||||
className={classes.link}
|
||||
buttonClassname={classes.copyToClipboard}
|
||||
wrapperClassname={classes.linkWrapper}>
|
||||
{reset2FAUrl}
|
||||
</CopyToClipboard>
|
||||
</strong>
|
||||
</Mono>
|
||||
</div>
|
||||
{!error && (
|
||||
<div className={classes.addressWrapper}>
|
||||
<Mono className={classes.address}>
|
||||
<strong>
|
||||
<CopyToClipboard
|
||||
className={classes.link}
|
||||
buttonClassname={classes.copyToClipboard}
|
||||
wrapperClassname={classes.linkWrapper}>
|
||||
{reset2FAUrl}
|
||||
</CopyToClipboard>
|
||||
</strong>
|
||||
</Mono>
|
||||
</div>
|
||||
)}
|
||||
{error && <ErrorMessage>{error}</ErrorMessage>}
|
||||
</Modal>
|
||||
))
|
||||
)
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import { makeStyles } from '@material-ui/core/styles'
|
|||
import gql from 'graphql-tag'
|
||||
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/pages/Transactions/CopyToClipboard'
|
||||
|
|
@ -36,7 +37,7 @@ const ResetPasswordModal = ({
|
|||
const classes = useStyles()
|
||||
const [resetPasswordUrl, setResetPasswordUrl] = useState('')
|
||||
|
||||
const [createResetPasswordToken, { loading }] = useMutation(
|
||||
const [createResetPasswordToken, { loading, error }] = useMutation(
|
||||
CREATE_RESET_PASSWORD_TOKEN,
|
||||
{
|
||||
onCompleted: ({ createResetPasswordToken: token }) => {
|
||||
|
|
@ -95,18 +96,21 @@ const ResetPasswordModal = ({
|
|||
<P className={classes.info}>
|
||||
Safely share this link with {user.username} for a password reset.
|
||||
</P>
|
||||
<div className={classes.addressWrapper}>
|
||||
<Mono className={classes.address}>
|
||||
<strong>
|
||||
<CopyToClipboard
|
||||
className={classes.link}
|
||||
buttonClassname={classes.copyToClipboard}
|
||||
wrapperClassname={classes.linkWrapper}>
|
||||
{resetPasswordUrl}
|
||||
</CopyToClipboard>
|
||||
</strong>
|
||||
</Mono>
|
||||
</div>
|
||||
{!error && (
|
||||
<div className={classes.addressWrapper}>
|
||||
<Mono className={classes.address}>
|
||||
<strong>
|
||||
<CopyToClipboard
|
||||
className={classes.link}
|
||||
buttonClassname={classes.copyToClipboard}
|
||||
wrapperClassname={classes.linkWrapper}>
|
||||
{resetPasswordUrl}
|
||||
</CopyToClipboard>
|
||||
</strong>
|
||||
</Mono>
|
||||
</div>
|
||||
)}
|
||||
{error && <ErrorMessage>{error}</ErrorMessage>}
|
||||
</Modal>
|
||||
))
|
||||
)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue