refactor(auth): migrate login, account, user and error screens to v3
- Login/forgot/reset, create/edit user, profile: Field/Dialog/Toaster shims, colorPalette/button renames, typed hookstate handlers - DeleteDialogue, NotFound, SomethingWentWrong: dialog + centered layout on v3 tokens with legacy copy intact
This commit is contained in:
@@ -3,13 +3,9 @@ import agent from '../api/agent'
|
||||
import { useNavigate } from 'react-router-dom'
|
||||
import { Data } from '../models/game'
|
||||
import {
|
||||
AlertDialog,
|
||||
AlertDialogBody,
|
||||
AlertDialogContent, AlertDialogFooter,
|
||||
AlertDialogHeader,
|
||||
AlertDialogOverlay,
|
||||
Button, Icon, Text
|
||||
Button, Text
|
||||
} from '@chakra-ui/react'
|
||||
import {DialogBody, DialogContent, DialogFooter, DialogHeader, DialogRoot} from './ui/dialog'
|
||||
|
||||
type Props = {
|
||||
id: string
|
||||
@@ -44,34 +40,31 @@ export default function DeleteDialogue({
|
||||
}
|
||||
}
|
||||
|
||||
const cancelRef = useRef(null)
|
||||
const cancelRef = useRef<HTMLButtonElement | null>(null)
|
||||
|
||||
return (
|
||||
<AlertDialog isOpen={open} leastDestructiveRef={cancelRef} onClose={handleClose}>
|
||||
<AlertDialogOverlay>
|
||||
<AlertDialogContent>
|
||||
|
||||
<AlertDialogHeader fontSize='lg' fontWeight='bold'>Delete?</AlertDialogHeader>
|
||||
<AlertDialogBody>
|
||||
Are you sure you would like to delete <strong>{game.title}</strong>?
|
||||
</AlertDialogBody>
|
||||
<AlertDialogFooter>
|
||||
<Button ref={cancelRef} onMouseDown={handleClose}>
|
||||
<Icon name='remove' mr='1' /> <Text mt='1'>No</Text>
|
||||
</Button>
|
||||
<Button
|
||||
colorScheme='red'
|
||||
onMouseDown={() => {
|
||||
deleteGame(id)
|
||||
}}
|
||||
ml={3}
|
||||
autoFocus
|
||||
>
|
||||
<Icon name='checkmark' mr='1' /> <Text mt='1'>Yes</Text>
|
||||
</Button>
|
||||
</AlertDialogFooter>
|
||||
</AlertDialogContent>
|
||||
</AlertDialogOverlay>
|
||||
</AlertDialog>
|
||||
<DialogRoot open={open} onOpenChange={(e) => { if (!e.open) handleClose() }} role="alertdialog" initialFocusEl={() => cancelRef.current}>
|
||||
<DialogContent>
|
||||
<DialogHeader fontSize='lg' fontWeight='bold'>Delete?</DialogHeader>
|
||||
<DialogBody>
|
||||
Are you sure you would like to delete <strong>{game.title}</strong>?
|
||||
</DialogBody>
|
||||
<DialogFooter>
|
||||
<Button ref={cancelRef} onMouseDown={handleClose}>
|
||||
<Text mt='1'>No</Text>
|
||||
</Button>
|
||||
<Button
|
||||
colorPalette='red'
|
||||
onMouseDown={() => {
|
||||
deleteGame(id)
|
||||
}}
|
||||
ml={3}
|
||||
autoFocus
|
||||
>
|
||||
<Text mt='1'>Yes</Text>
|
||||
</Button>
|
||||
</DialogFooter>
|
||||
</DialogContent>
|
||||
</DialogRoot>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import React from 'react'
|
||||
import { Checkbox, Text } from '@chakra-ui/react'
|
||||
import { Text } from '@chakra-ui/react'
|
||||
import {Checkbox} from '../ui/checkbox'
|
||||
import { adminModeToggle, loggedInUser, adminMode } from '../../stateManagement/userState'
|
||||
import { useHookstate } from '@hookstate/core'
|
||||
|
||||
@@ -8,7 +9,7 @@ export default function AdminMode() {
|
||||
const admin = useHookstate(adminMode).get()
|
||||
|
||||
return (
|
||||
<Checkbox size={'lg'} onChange={() => adminModeToggle()} isChecked={admin} isDisabled={!(user.role === 'admin')}>
|
||||
<Checkbox colorPalette="blue" size={'lg'} onCheckedChange={() => adminModeToggle()} checked={admin} disabled={!(user.role === 'admin')}>
|
||||
<Text mt={'1'}>Administrator Mode</Text>
|
||||
</Checkbox>
|
||||
)
|
||||
|
||||
@@ -3,11 +3,11 @@ import { useForm } from 'react-hook-form'
|
||||
import {
|
||||
Container,
|
||||
Button,
|
||||
FormControl,
|
||||
FormLabel,
|
||||
Input,
|
||||
useColorModeValue, FormErrorMessage, useToast,
|
||||
} from '@chakra-ui/react'
|
||||
import {Field} from '../ui/field'
|
||||
import {useColorModeValue} from '../ui/color-mode'
|
||||
import {toaster} from '../ui/toaster'
|
||||
import agent from '../../api/agent'
|
||||
import { IForgotPassword } from '../../models/user'
|
||||
|
||||
@@ -18,7 +18,6 @@ export default function ForgotPassword() {
|
||||
handleSubmit,
|
||||
formState: { errors, isSubmitting, isDirty },
|
||||
} = useForm()
|
||||
const toast = useToast()
|
||||
|
||||
interface Message {
|
||||
success: boolean
|
||||
@@ -27,27 +26,25 @@ export default function ForgotPassword() {
|
||||
|
||||
const onSubmit = handleSubmit(async (values) => {
|
||||
const message = await agent.Account.forgot(values as IForgotPassword) as Message
|
||||
toast({
|
||||
toaster.create({
|
||||
title: 'Email Sent',
|
||||
status: 'success',
|
||||
type: 'success',
|
||||
description: message.data,
|
||||
isClosable: true,
|
||||
closable: true,
|
||||
duration: 10000,
|
||||
position: 'top'
|
||||
})
|
||||
})
|
||||
|
||||
return (
|
||||
<Container style={{ marginTop: '7rem', paddingBottom: '5rem' }}>
|
||||
<form onSubmit={onSubmit}>
|
||||
<FormControl isInvalid={Boolean(errors.email)} mb={'3'}>
|
||||
<FormLabel htmlFor="email">Email</FormLabel>
|
||||
<Field label="Email" invalid={Boolean(errors.email)} errorText={errors.email?.type === 'required' ? errors.email.message?.toString() : errors.email?.type === 'pattern' ? 'Invalid Email Address' : undefined} mb={'3'}>
|
||||
<Input
|
||||
id="email"
|
||||
bg={bg}
|
||||
_placeholder={{ color: 'gray.500' }}
|
||||
border="1px"
|
||||
borderColor="gray.500"
|
||||
borderWidth="1px" borderStyle="solid"
|
||||
borderColor={{ base: "gray.500", _invalid: "red.500" }}
|
||||
rounded="md"
|
||||
placeholder="Email"
|
||||
{...register('email', {
|
||||
@@ -55,16 +52,13 @@ export default function ForgotPassword() {
|
||||
pattern: /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i,
|
||||
})}
|
||||
/>
|
||||
<FormErrorMessage>
|
||||
{errors.email?.type === 'required' && errors.email.message?.toString()}
|
||||
{errors.email?.type === 'pattern' && 'Invalid Email Address'}
|
||||
</FormErrorMessage>
|
||||
</FormControl>
|
||||
</Field>
|
||||
<br/>
|
||||
<Button
|
||||
type="submit"
|
||||
colorPalette="blue"
|
||||
disabled={!isDirty}
|
||||
isLoading={isSubmitting}
|
||||
loading={isSubmitting}
|
||||
>
|
||||
Submit
|
||||
</Button>
|
||||
|
||||
@@ -5,11 +5,10 @@ import { login } from '../../stateManagement/userState'
|
||||
import {
|
||||
Container,
|
||||
Button,
|
||||
FormControl,
|
||||
FormLabel,
|
||||
Input,
|
||||
useColorModeValue, HStack, Center, FormErrorMessage,
|
||||
Input, HStack, Center,
|
||||
} from '@chakra-ui/react'
|
||||
import {Field} from '../ui/field'
|
||||
import {useColorModeValue} from '../ui/color-mode'
|
||||
import { Link } from 'react-router-dom'
|
||||
|
||||
export default function LoginForm() {
|
||||
@@ -38,14 +37,13 @@ export default function LoginForm() {
|
||||
return (
|
||||
<Container style={{ marginTop: '7rem', paddingBottom: '5rem' }}>
|
||||
<form onSubmit={onSubmit}>
|
||||
<FormControl isInvalid={Boolean(errors.email)} mb={'3'}>
|
||||
<FormLabel htmlFor="email">Email</FormLabel>
|
||||
<Field label="Email" invalid={Boolean(errors.email)} errorText={errors.email?.type === 'required' ? errors.email.message?.toString() : errors.email?.type === 'pattern' ? 'Invalid Email Address' : undefined} mb={'3'}>
|
||||
<Input
|
||||
id="email"
|
||||
bg={bg}
|
||||
_placeholder={{ color: 'gray.500' }}
|
||||
border="1px"
|
||||
borderColor="gray.500"
|
||||
borderWidth="1px" borderStyle="solid"
|
||||
borderColor={{ base: "gray.500", _invalid: "red.500" }}
|
||||
rounded="md"
|
||||
placeholder="Email"
|
||||
{...register('email', {
|
||||
@@ -53,40 +51,33 @@ export default function LoginForm() {
|
||||
pattern: /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i,
|
||||
})}
|
||||
/>
|
||||
<FormErrorMessage>
|
||||
{errors.email?.type === 'required' && errors.email.message?.toString()}
|
||||
{errors.email?.type === 'pattern' && 'Invalid Email Address'}
|
||||
</FormErrorMessage>
|
||||
</FormControl>
|
||||
<FormControl isInvalid={Boolean(errors.password)} mb={'3'}>
|
||||
<FormLabel htmlFor="password">Password</FormLabel>
|
||||
</Field>
|
||||
<Field label="Password" invalid={Boolean(errors.password)} errorText={errors.password?.message?.toString()} mb={'3'}>
|
||||
<Input
|
||||
id="password"
|
||||
bg={bg}
|
||||
_placeholder={{ color: 'gray.500' }}
|
||||
border="1px"
|
||||
borderColor="gray.500"
|
||||
borderWidth="1px" borderStyle="solid"
|
||||
borderColor={{ base: "gray.500", _invalid: "red.500" }}
|
||||
rounded="md"
|
||||
placeholder="Password"
|
||||
type="password"
|
||||
{...register('password', { required: 'You must specify a password' })}
|
||||
/>
|
||||
<FormErrorMessage>
|
||||
{errors.password && errors.password.message?.toString()}
|
||||
</FormErrorMessage>
|
||||
</FormControl>
|
||||
</Field>
|
||||
<br/>
|
||||
<HStack>
|
||||
<Button
|
||||
type="submit"
|
||||
colorPalette="blue"
|
||||
disabled={!isDirty}
|
||||
isLoading={isSubmitting}
|
||||
loading={isSubmitting}
|
||||
>
|
||||
Submit
|
||||
</Button>
|
||||
</HStack>
|
||||
<Center mt={'5rem'}>
|
||||
<Button as={Link} to={'/forgotpassword'}>Forgot Password</Button>
|
||||
<Button asChild variant="outline"><Link to={'/forgotpassword'}>Forgot Password</Link></Button>
|
||||
</Center>
|
||||
</form>
|
||||
</Container>
|
||||
|
||||
@@ -4,10 +4,11 @@ import { IResetPassword } from '../../models/user'
|
||||
import {
|
||||
Button,
|
||||
Container,
|
||||
FormControl,
|
||||
FormLabel,
|
||||
Input, useToast, useColorModeValue, FormErrorMessage,
|
||||
Input,
|
||||
} from '@chakra-ui/react'
|
||||
import {Field} from '../ui/field'
|
||||
import {useColorModeValue} from '../ui/color-mode'
|
||||
import {toaster} from '../ui/toaster'
|
||||
import agent from '../../api/agent'
|
||||
import { useNavigate, useParams } from 'react-router-dom'
|
||||
|
||||
@@ -17,7 +18,7 @@ interface Message {
|
||||
}
|
||||
|
||||
interface URL {
|
||||
token: string
|
||||
token?: string
|
||||
}
|
||||
|
||||
export default function ResetPassword() {
|
||||
@@ -27,32 +28,29 @@ export default function ResetPassword() {
|
||||
watch,
|
||||
formState: { errors, isSubmitting, isDirty },
|
||||
} = useForm()
|
||||
const { token } = useParams<URL>()
|
||||
const { token } = useParams()
|
||||
const history = useNavigate()
|
||||
const toast = useToast()
|
||||
const password = useRef({})
|
||||
password.current = watch('password', '')
|
||||
|
||||
const onSubmit = handleSubmit(async (data) => {
|
||||
const message = await agent.Account.reset(token, data as IResetPassword) as Message
|
||||
const message = await agent.Account.reset(token!, data as IResetPassword) as Message
|
||||
if (message.success) {
|
||||
setTimeout(() => history('/login'), 3000)
|
||||
toast({
|
||||
toaster.create({
|
||||
title: 'Password Reset',
|
||||
status: 'success',
|
||||
type: 'success',
|
||||
description: 'Your password has been reset. You will be redirected to login automatically',
|
||||
isClosable: true,
|
||||
closable: true,
|
||||
duration: 5000,
|
||||
position: 'top',
|
||||
})
|
||||
} else {
|
||||
toast({
|
||||
toaster.create({
|
||||
title: 'Password Not Reset',
|
||||
status: 'error',
|
||||
type: 'error',
|
||||
description: 'Something went wrong, please contact the website administrator',
|
||||
isClosable: true,
|
||||
closable: true,
|
||||
duration: 10000,
|
||||
position: 'top',
|
||||
})
|
||||
}
|
||||
})
|
||||
@@ -62,15 +60,14 @@ export default function ResetPassword() {
|
||||
return (
|
||||
<Container style={{ marginTop: '7rem', paddingBottom: '5rem' }}>
|
||||
<form onSubmit={onSubmit}>
|
||||
<FormControl isInvalid={Boolean(errors.password)} mb={'3'}>
|
||||
<FormLabel htmlFor="password">Password</FormLabel>
|
||||
<Field label="Password" invalid={Boolean(errors.password)} errorText={errors.password?.message?.toString()} mb={'3'}>
|
||||
<Input
|
||||
id="password"
|
||||
bg={bg}
|
||||
_placeholder={{ color: 'gray.500' }}
|
||||
|
||||
border="1px"
|
||||
borderColor="gray.500"
|
||||
borderWidth="1px" borderStyle="solid"
|
||||
borderColor={{ base: "gray.500", _invalid: "red.500" }}
|
||||
rounded="md"
|
||||
placeholder="Password"
|
||||
type="password"
|
||||
@@ -82,18 +79,14 @@ export default function ResetPassword() {
|
||||
},
|
||||
})}
|
||||
/>
|
||||
<FormErrorMessage>
|
||||
{errors.password && errors.password.message?.toString()}
|
||||
</FormErrorMessage>
|
||||
</FormControl>
|
||||
<FormControl isInvalid={Boolean(errors.repeat_password)} mb={'3'}>
|
||||
<FormLabel htmlFor="repeat_password">Repeat Password</FormLabel>
|
||||
</Field>
|
||||
<Field label="Repeat Password" invalid={Boolean(errors.repeat_password)} errorText={errors.repeat_password?.message?.toString()} mb={'3'}>
|
||||
<Input
|
||||
id="repeat_password"
|
||||
bg={bg}
|
||||
_placeholder={{ color: 'gray.500' }}
|
||||
border="1px"
|
||||
borderColor="gray.500"
|
||||
borderWidth="1px" borderStyle="solid"
|
||||
borderColor={{ base: "gray.500", _invalid: "red.500" }}
|
||||
rounded="md"
|
||||
placeholder="Repeat Password"
|
||||
type="password"
|
||||
@@ -102,15 +95,13 @@ export default function ResetPassword() {
|
||||
value === password.current || 'The passwords do not match',
|
||||
})}
|
||||
/>
|
||||
<FormErrorMessage>
|
||||
{errors.repeat_password && errors.repeat_password.message?.toString()}
|
||||
</FormErrorMessage>
|
||||
</FormControl>
|
||||
</Field>
|
||||
<br/>
|
||||
<Button
|
||||
type="submit"
|
||||
colorPalette="blue"
|
||||
disabled={!isDirty}
|
||||
isLoading={isSubmitting}
|
||||
loading={isSubmitting}
|
||||
>
|
||||
Submit
|
||||
</Button>
|
||||
|
||||
@@ -3,15 +3,13 @@ import { useForm } from 'react-hook-form'
|
||||
import { UserFormValues } from '../../models/user'
|
||||
import { createUser } from '../../stateManagement/userState'
|
||||
import {
|
||||
Alert,
|
||||
AlertDescription,
|
||||
AlertIcon,
|
||||
Button,
|
||||
Container,
|
||||
FormControl, FormErrorMessage,
|
||||
FormLabel,
|
||||
Input, useColorModeValue,
|
||||
Input,
|
||||
} from '@chakra-ui/react'
|
||||
import {Field} from '../ui/field'
|
||||
import {Alert} from '../ui/alert'
|
||||
import {useColorModeValue} from '../ui/color-mode'
|
||||
|
||||
export default function CreateUser() {
|
||||
const {
|
||||
@@ -44,59 +42,52 @@ export default function CreateUser() {
|
||||
return (
|
||||
<Container style={{ marginTop: '7rem', paddingBottom: '5rem' }}>
|
||||
<form onSubmit={onSubmit}>
|
||||
<FormControl isInvalid={Boolean(errors.name)} mb={'3'}>
|
||||
<FormLabel htmlFor='name'>Full Name</FormLabel>
|
||||
<Field label="Full Name" invalid={Boolean(errors.name)} errorText={errors.name?.message?.toString()} mb={'3'}>
|
||||
<Input
|
||||
id='name'
|
||||
bg={bg}
|
||||
_placeholder={{ color: 'gray.500' }}
|
||||
border="1px"
|
||||
borderColor="gray.500"
|
||||
borderWidth="1px" borderStyle="solid"
|
||||
borderColor={{ base: "gray.500", _invalid: "red.500" }}
|
||||
rounded="md"
|
||||
placeholder='Full Name'
|
||||
{...register('name', { required: 'Name is required' })}
|
||||
/>
|
||||
{errors.name && <FormErrorMessage>{ errors.name.message?.toString()}</FormErrorMessage>}
|
||||
</FormControl>
|
||||
<FormControl isInvalid={Boolean(errors.displayName)} mb={'3'}>
|
||||
<FormLabel htmlFor='displayName'>Display Name</FormLabel>
|
||||
</Field>
|
||||
<Field label="Display Name" invalid={Boolean(errors.displayName)} errorText={errors.displayName?.message?.toString()} mb={'3'}>
|
||||
<Input
|
||||
id='displayName'
|
||||
bg={bg}
|
||||
_placeholder={{ color: 'gray.500' }}
|
||||
|
||||
border="1px"
|
||||
borderColor="gray.500"
|
||||
borderWidth="1px" borderStyle="solid"
|
||||
borderColor={{ base: "gray.500", _invalid: "red.500" }}
|
||||
rounded="md"
|
||||
placeholder='Display Name'
|
||||
{...register('displayName', { required: 'Display Name is required' })}
|
||||
/>
|
||||
{errors.displayName && <FormErrorMessage>{ errors.displayName.message?.toString()}</FormErrorMessage>}
|
||||
</FormControl>
|
||||
<FormControl isInvalid={Boolean(errors.email)} mb={'3'}>
|
||||
<FormLabel htmlFor='email'>Email</FormLabel>
|
||||
</Field>
|
||||
<Field label="Email" invalid={Boolean(errors.email)} errorText={errors.email?.message?.toString()} mb={'3'}>
|
||||
<Input
|
||||
id='email'
|
||||
bg={bg}
|
||||
_placeholder={{ color: 'gray.500' }}
|
||||
|
||||
border="1px"
|
||||
borderColor="gray.500"
|
||||
borderWidth="1px" borderStyle="solid"
|
||||
borderColor={{ base: "gray.500", _invalid: "red.500" }}
|
||||
rounded="md"
|
||||
placeholder='Email'
|
||||
{...register('email', { required: 'Email is required' })}
|
||||
/>
|
||||
{errors.email && <FormErrorMessage>{ errors.email.message?.toString()}</FormErrorMessage>}
|
||||
</FormControl>
|
||||
<FormControl isInvalid={Boolean(errors.password)} mb={'3'}>
|
||||
<FormLabel htmlFor='password'>Password</FormLabel>
|
||||
</Field>
|
||||
<Field label="Password" invalid={Boolean(errors.password)} errorText={errors.password?.message?.toString()} mb={'3'}>
|
||||
<Input
|
||||
id='password'
|
||||
bg={bg}
|
||||
_placeholder={{ color: 'gray.500' }}
|
||||
|
||||
border="1px"
|
||||
borderColor="gray.500"
|
||||
borderWidth="1px" borderStyle="solid"
|
||||
borderColor={{ base: "gray.500", _invalid: "red.500" }}
|
||||
rounded="md"
|
||||
placeholder='Password'
|
||||
type='password'
|
||||
@@ -108,26 +99,22 @@ export default function CreateUser() {
|
||||
},
|
||||
})}
|
||||
/>
|
||||
{errors.password && <FormErrorMessage>{ errors.password.message?.toString()}</FormErrorMessage>}
|
||||
</FormControl>
|
||||
</Field>
|
||||
{errors.password && (
|
||||
<>
|
||||
<Alert status='error' style={{ marginBottom: 10 }}>
|
||||
<AlertIcon />
|
||||
<AlertDescription>{errors.password.message?.toString()}</AlertDescription>
|
||||
{/*<CloseButton position='absolute' right='8px' top='8px' />*/}
|
||||
<Alert status='error' title={errors.password.message?.toString()} style={{ marginBottom: 10 }}>
|
||||
{errors.password.message?.toString()}
|
||||
</Alert>
|
||||
<br />
|
||||
</>
|
||||
)}
|
||||
<FormControl isInvalid={Boolean(errors.repeat_password)} mb={'3'}>
|
||||
<FormLabel htmlFor='repeat_password'>Repeat Password</FormLabel>
|
||||
<Field label="Repeat Password" invalid={Boolean(errors.repeat_password)} errorText={errors.repeat_password?.message?.toString()} mb={'3'}>
|
||||
<Input
|
||||
id='repeat_password'
|
||||
bg={bg}
|
||||
_placeholder={{ color: 'gray.500' }}
|
||||
border="1px"
|
||||
borderColor="gray.500"
|
||||
borderWidth="1px" borderStyle="solid"
|
||||
borderColor={{ base: "gray.500", _invalid: "red.500" }}
|
||||
rounded="md"
|
||||
placeholder='Repeat Password'
|
||||
type='password'
|
||||
@@ -136,22 +123,20 @@ export default function CreateUser() {
|
||||
value === password.current || 'The passwords do not match',
|
||||
})}
|
||||
/>
|
||||
{errors.repeat_password && <FormErrorMessage>{ errors.repeat_password.message?.toString()}</FormErrorMessage>}
|
||||
</FormControl>
|
||||
</Field>
|
||||
{errors.repeat_password && (
|
||||
<>
|
||||
<Alert status='error' style={{ marginBottom: 10 }}>
|
||||
<AlertIcon />
|
||||
<AlertDescription>{errors.repeat_password.message?.toString()}</AlertDescription>
|
||||
{/*<CloseButton position='absolute' right='8px' top='8px' />*/}
|
||||
<Alert status='error' title={errors.repeat_password.message?.toString()} style={{ marginBottom: 10 }}>
|
||||
{errors.repeat_password.message?.toString()}
|
||||
</Alert>
|
||||
</>
|
||||
)}
|
||||
<br />
|
||||
<Button
|
||||
type='submit'
|
||||
colorPalette="blue"
|
||||
disabled={!isDirty}
|
||||
isLoading={isSubmitting}
|
||||
loading={isSubmitting}
|
||||
>
|
||||
Submit
|
||||
</Button>
|
||||
|
||||
@@ -5,14 +5,14 @@ import { loadedPreferences, loggedInUser, updateUserPreferences } from '../../st
|
||||
import {
|
||||
Button,
|
||||
Container, Flex,
|
||||
FormControl,
|
||||
FormLabel,
|
||||
Heading,
|
||||
Input,
|
||||
Stack, Switch,
|
||||
useColorModeValue,
|
||||
useToast,
|
||||
Stack,
|
||||
} from '@chakra-ui/react'
|
||||
import {Field} from '../ui/field'
|
||||
import {Switch} from '../ui/switch'
|
||||
import {useColorModeValue} from '../ui/color-mode'
|
||||
import {toaster} from '../ui/toaster'
|
||||
import { useHookstate } from '@hookstate/core'
|
||||
import agent from '../../api/agent'
|
||||
import { useNavigate } from 'react-router-dom'
|
||||
@@ -43,12 +43,10 @@ export default function EditUser() {
|
||||
const history = useNavigate()
|
||||
|
||||
useEffect(() => {
|
||||
reset(user)
|
||||
reset(user as any)
|
||||
return
|
||||
}, [user.name !== ''])
|
||||
|
||||
const toast = useToast()
|
||||
|
||||
interface Message {
|
||||
success: boolean
|
||||
data: string
|
||||
@@ -66,13 +64,12 @@ export default function EditUser() {
|
||||
|
||||
const engageChangePassword = async (values: IForgotPassword) => {
|
||||
const message = await agent.Account.forgot(values as IForgotPassword) as Message
|
||||
toast({
|
||||
toaster.create({
|
||||
title: 'Email Sent',
|
||||
status: 'success',
|
||||
type: 'success',
|
||||
description: message.data,
|
||||
isClosable: true,
|
||||
closable: true,
|
||||
duration: 10000,
|
||||
position: 'top'
|
||||
})
|
||||
}
|
||||
|
||||
@@ -90,78 +87,70 @@ export default function EditUser() {
|
||||
<Container style={{ marginTop: '7rem', paddingBottom: '5rem' }}>
|
||||
<Heading as="h1" marginBottom={'3rem'}>Edit {user.displayName}</Heading>
|
||||
<form onSubmit={onSubmit}>
|
||||
<FormControl>
|
||||
<FormLabel htmlFor="name">Full Name</FormLabel>
|
||||
<Field label="Full Name">
|
||||
<Input
|
||||
id="name"
|
||||
bg={bg}
|
||||
border="1px"
|
||||
borderColor="gray.500"
|
||||
borderWidth="1px" borderStyle="solid"
|
||||
borderColor={{ base: "gray.500", _invalid: "red.500" }}
|
||||
rounded="md"
|
||||
{...register('name', { required: 'Name is required' })}
|
||||
/>
|
||||
</FormControl>
|
||||
<FormControl mt={'3'}>
|
||||
<FormLabel htmlFor="displayName">Display Name</FormLabel>
|
||||
</Field>
|
||||
<Field label="Display Name" mt={'3'}>
|
||||
<Input
|
||||
id="displayName"
|
||||
bg={bg}
|
||||
border="1px"
|
||||
borderColor="gray.500"
|
||||
borderWidth="1px" borderStyle="solid"
|
||||
borderColor={{ base: "gray.500", _invalid: "red.500" }}
|
||||
rounded="md"
|
||||
{...register('displayName', { required: 'Display Name is required' })}
|
||||
/>
|
||||
</FormControl>
|
||||
<FormControl mt={'3'}>
|
||||
<FormLabel htmlFor="email">Email</FormLabel>
|
||||
</Field>
|
||||
<Field label="Email" mt={'3'}>
|
||||
<Input
|
||||
id="email"
|
||||
bg={bg}
|
||||
_placeholder={{ color: 'gray.500' }}
|
||||
isDisabled
|
||||
border="1px"
|
||||
borderColor="gray.500"
|
||||
disabled
|
||||
borderWidth="1px" borderStyle="solid"
|
||||
borderColor={{ base: "gray.500", _invalid: "red.500" }}
|
||||
rounded="md"
|
||||
placeholder="Email"
|
||||
{...register('email', { required: 'Email is required' })}
|
||||
/>
|
||||
</FormControl>
|
||||
<FormControl>
|
||||
<Flex mt={'6'}>
|
||||
<FormLabel htmlFor={"theme"}>Dark Mode:</FormLabel>
|
||||
</Field>
|
||||
<Field label="Dark Mode:" orientation="horizontal" mt={'6'}>
|
||||
<Controller
|
||||
control={control}
|
||||
name="theme"
|
||||
render={({ field: { onChange, value, ref } }) => (
|
||||
<Switch isChecked={value} onChange={onChange} ref={ref} />
|
||||
<Switch colorPalette="blue" checked={value} onCheckedChange={({ checked }: any) => onChange(checked)} ref={ref} />
|
||||
)}
|
||||
/>
|
||||
</Flex>
|
||||
</FormControl>
|
||||
<FormControl>
|
||||
<Flex mt={'6'}>
|
||||
<FormLabel htmlFor={"stickyNav"}>Sticky Navbar:</FormLabel>
|
||||
</Field>
|
||||
<Field label="Sticky Navbar:" orientation="horizontal" mt={'6'}>
|
||||
<Controller
|
||||
control={control}
|
||||
name="stickyNav"
|
||||
render={({ field: { onChange, value, ref } }) => (
|
||||
<Switch isChecked={value} onChange={onChange} ref={ref} />
|
||||
<Switch colorPalette="blue" checked={value} onCheckedChange={({ checked }: any) => onChange(checked)} ref={ref} />
|
||||
)}
|
||||
/>
|
||||
</Flex>
|
||||
</FormControl>
|
||||
</Field>
|
||||
<br />
|
||||
<Stack spacing={[1, 5]} direction={'row'} align="self-end" pb="3">
|
||||
<Stack gap={[1, 5]} direction={'row'} alignSelf="flex-end" pb="3">
|
||||
<Button
|
||||
type="submit"
|
||||
colorPalette="blue"
|
||||
disabled={!isDirty}
|
||||
isLoading={isSubmitting}
|
||||
loading={isSubmitting}
|
||||
>
|
||||
Submit
|
||||
</Button>
|
||||
<Button
|
||||
isLoading={passwordLoading.get()}
|
||||
isDisabled={passwordDisabled.get()}
|
||||
loading={passwordLoading.get()}
|
||||
disabled={passwordDisabled.get()}
|
||||
onMouseDown={async () => {
|
||||
passwordLoading.set(true)
|
||||
passwordDisabled.set(true)
|
||||
|
||||
@@ -7,14 +7,10 @@ import {
|
||||
GridItem,
|
||||
Heading,
|
||||
Image,
|
||||
Table,
|
||||
TableContainer,
|
||||
Tbody,
|
||||
Td,
|
||||
Text,
|
||||
Tr,
|
||||
useColorModeValue
|
||||
Table,
|
||||
} from '@chakra-ui/react'
|
||||
import {useColorModeValue} from '../ui/color-mode'
|
||||
import {useHookstate} from '@hookstate/core'
|
||||
import {loggedInUser} from '../../stateManagement/userState'
|
||||
import {Link} from 'react-router-dom'
|
||||
@@ -28,10 +24,12 @@ const UserProfile = () => {
|
||||
<Heading mb={'1rem'} as="h1">User Profile</Heading>
|
||||
<Grid templateColumns={`repeat(7, 1fr)`} templateRows={'2'} gap={6}>
|
||||
<GridItem rowStart={1} rowEnd={1} colStart={7} alignSelf={'end'} justifySelf={'end'}>
|
||||
<Button as={Link} to={`/edit-user`} colorScheme="blue" style={{textAlign: 'right'}}>
|
||||
<Text mt={'1'}>
|
||||
Edit
|
||||
</Text>
|
||||
<Button asChild colorPalette="blue" style={{textAlign: 'right'}}>
|
||||
<Link to={`/edit-user`}>
|
||||
<Text mt={'1'}>
|
||||
Edit
|
||||
</Text>
|
||||
</Link>
|
||||
</Button>
|
||||
</GridItem>
|
||||
<GridItem rowStart={2} rowEnd={2} colSpan={2} colStart={2}>
|
||||
@@ -42,28 +40,28 @@ const UserProfile = () => {
|
||||
</GridItem>
|
||||
<GridItem rowStart={2} rowEnd={2} colStart={4} colEnd={8}>
|
||||
<Box bg={bg} p="5" rounded="md">
|
||||
<TableContainer>
|
||||
<Table variant="simple">
|
||||
<Tbody>
|
||||
<Tr>
|
||||
<Td><Text fontSize={'1.5rem'}>Display Name: </Text></Td>
|
||||
<Td><Text fontSize={'1.5rem'}>{user.displayName}</Text></Td>
|
||||
</Tr>
|
||||
<Tr>
|
||||
<Td><Text fontSize={'1.5rem'}>Full Name: </Text></Td>
|
||||
<Td><Text fontSize={'1.5rem'}>{user.name}</Text></Td>
|
||||
</Tr>
|
||||
<Tr>
|
||||
<Td><Text fontSize={'1.5rem'}>Email: </Text></Td>
|
||||
<Td><Text fontSize={'1.5rem'}>{user.email}</Text></Td>
|
||||
</Tr>
|
||||
<Tr>
|
||||
<Td><Text fontSize={'1.5rem'}>Role: </Text></Td>
|
||||
<Td><Text fontSize={'1.5rem'}>{user.role}</Text></Td>
|
||||
</Tr>
|
||||
</Tbody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
<Table.ScrollArea>
|
||||
<Table.Root variant="outline">
|
||||
<Table.Body>
|
||||
<Table.Row>
|
||||
<Table.Cell><Text fontSize={'1.5rem'}>Display Name: </Text></Table.Cell>
|
||||
<Table.Cell><Text fontSize={'1.5rem'}>{user.displayName}</Text></Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell><Text fontSize={'1.5rem'}>Full Name: </Text></Table.Cell>
|
||||
<Table.Cell><Text fontSize={'1.5rem'}>{user.name}</Text></Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell><Text fontSize={'1.5rem'}>Email: </Text></Table.Cell>
|
||||
<Table.Cell><Text fontSize={'1.5rem'}>{user.email}</Text></Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell><Text fontSize={'1.5rem'}>Role: </Text></Table.Cell>
|
||||
<Table.Cell><Text fontSize={'1.5rem'}>{user.role}</Text></Table.Cell>
|
||||
</Table.Row>
|
||||
</Table.Body>
|
||||
</Table.Root>
|
||||
</Table.ScrollArea>
|
||||
</Box>
|
||||
</GridItem>
|
||||
</Grid>
|
||||
|
||||
@@ -29,8 +29,8 @@ export default function NotFound() {
|
||||
It looks like you hit a{' '}
|
||||
{<span style={styles.retroFontBody}>DEAD</span>} end!
|
||||
</Heading>
|
||||
<Button colorScheme='blue' as={Link} to={'/games'} style={{fontSize: '1.2rem', marginLeft: '5rem'}}>
|
||||
Back to Games List
|
||||
<Button colorPalette='blue' asChild style={{fontSize: '1.2rem', marginLeft: '5rem'}}>
|
||||
<Link to={'/games'}>Back to Games List</Link>
|
||||
</Button>
|
||||
<Suspense fallback={<LoadingModal />}>
|
||||
<Video/>
|
||||
|
||||
@@ -29,10 +29,12 @@ export default function SomethingWentWrong() {
|
||||
{<span style={styles.retroFontBody}>WE APOLOGIZE!</span>}<br/>
|
||||
Please contact the website administrator!
|
||||
</Heading>
|
||||
<Button colorScheme='blue' as={Link} to={'/games'} style={{fontSize: '1.2rem', marginLeft: '5rem'}}>
|
||||
<Button colorPalette='blue' asChild style={{fontSize: '1.2rem', marginLeft: '5rem'}}>
|
||||
<Link to={'/games'}>
|
||||
<div style={{marginTop: '.25rem'}}>
|
||||
Back to Games List
|
||||
</div>
|
||||
</Link>
|
||||
</Button>
|
||||
<Suspense fallback={<LoadingModal/>}>
|
||||
<Video/>
|
||||
|
||||
Reference in New Issue
Block a user