2024-02-26 09:39:09 -05:00
import React from 'react' ;
2024-02-28 18:30:59 -05:00
import { Button , Checkbox , Flex , FormControl , FormErrorMessage , FormLabel , Input , Modal , ModalBody , ModalCloseButton , ModalContent , ModalFooter , ModalHeader , ModalOverlay } from '@chakra-ui/react' ;
2024-02-26 09:39:09 -05:00
import { SubmitHandler , useForm } from 'react-hook-form' ;
2024-03-07 19:16:23 +01:00
import { useMutation , useQueryClient } from 'react-query' ;
2024-02-26 09:39:09 -05:00
2024-03-07 19:16:23 +01:00
import { ApiError , UserOut , UserUpdate , UsersService } from '../../client' ;
2024-02-26 09:39:09 -05:00
import useCustomToast from '../../hooks/useCustomToast' ;
interface EditUserProps {
2024-03-07 19:16:23 +01:00
user : UserOut ;
2024-02-26 09:39:09 -05:00
isOpen : boolean ;
onClose : ( ) = > void ;
}
interface UserUpdateForm extends UserUpdate {
confirm_password : string ;
}
2024-03-07 19:16:23 +01:00
const EditUser : React.FC < EditUserProps > = ( { user , isOpen , onClose } ) = > {
const queryClient = useQueryClient ( ) ;
2024-02-26 09:39:09 -05:00
const showToast = useCustomToast ( ) ;
2024-03-07 19:16:23 +01:00
const { register , handleSubmit , reset , getValues , formState : { errors , isSubmitting , isDirty } } = useForm < UserUpdateForm > ( {
2024-02-28 18:30:59 -05:00
mode : 'onBlur' ,
criteriaMode : 'all' ,
2024-03-07 19:16:23 +01:00
defaultValues : user
2024-02-28 18:30:59 -05:00
} ) ;
2024-03-07 19:16:23 +01:00
const updateUser = async ( data : UserUpdateForm ) = > {
await UsersService . updateUser ( { userId : user.id , requestBody : data } ) ;
}
2024-02-26 09:39:09 -05:00
2024-03-07 19:16:23 +01:00
const mutation = useMutation ( updateUser , {
onSuccess : ( ) = > {
2024-02-28 18:30:59 -05:00
showToast ( 'Success!' , 'User updated successfully.' , 'success' ) ;
onClose ( ) ;
2024-03-07 19:16:23 +01:00
} ,
onError : ( err : ApiError ) = > {
const errDetail = err . body . detail ;
2024-02-28 18:30:59 -05:00
showToast ( 'Something went wrong.' , ` ${ errDetail } ` , 'error' ) ;
2024-03-07 19:16:23 +01:00
} ,
onSettled : ( ) = > {
queryClient . invalidateQueries ( 'users' ) ;
}
} ) ;
const onSubmit : SubmitHandler < UserUpdateForm > = async ( data ) = > {
if ( data . password === '' ) {
delete data . password ;
2024-02-26 09:39:09 -05:00
}
2024-03-07 19:16:23 +01:00
mutation . mutate ( data )
2024-02-26 09:39:09 -05:00
}
const onCancel = ( ) = > {
reset ( ) ;
onClose ( ) ;
}
return (
< >
< Modal
isOpen = { isOpen }
onClose = { onClose }
size = { { base : 'sm' , md : 'md' } }
isCentered
>
< ModalOverlay / >
< ModalContent as = 'form' onSubmit = { handleSubmit ( onSubmit ) } >
< ModalHeader > Edit User < / ModalHeader >
< ModalCloseButton / >
< ModalBody pb = { 6 } >
2024-02-28 18:30:59 -05:00
< FormControl isInvalid = { ! ! errors . email } >
2024-02-26 09:39:09 -05:00
< FormLabel htmlFor = 'email' > Email < / FormLabel >
2024-03-07 19:16:23 +01:00
< Input id = 'email' { ...register ( 'email' , { required : 'Email is required' , pattern : { value : / ^ [ A - Z0 - 9._ % + - ] + @ [ A - Z0 - 9. - ] + \ . [ A - Z ] { 2 , 4 } $ / i , message : 'Invalid email address' } } ) } placeholder = 'Email' type = 'email' / >
2024-02-28 18:30:59 -05:00
{ errors . email && < FormErrorMessage > { errors . email . message } < / FormErrorMessage > }
2024-02-26 09:39:09 -05:00
< / FormControl >
< FormControl mt = { 4 } >
< FormLabel htmlFor = 'name' > Full name < / FormLabel >
2024-03-07 19:16:23 +01:00
< Input id = 'name' { ...register ( 'full_name' ) } type = 'text' / >
2024-02-26 09:39:09 -05:00
< / FormControl >
2024-02-28 18:30:59 -05:00
< FormControl mt = { 4 } isInvalid = { ! ! errors . password } >
< FormLabel htmlFor = 'password' > Set Password < / FormLabel >
< Input id = 'password' { ...register ( 'password' , { minLength : { value : 8 , message : 'Password must be at least 8 characters' } } ) } placeholder = '••••••••' type = 'password' / >
{ errors . password && < FormErrorMessage > { errors . password . message } < / FormErrorMessage > }
2024-02-26 09:39:09 -05:00
< / FormControl >
2024-02-28 18:30:59 -05:00
< FormControl mt = { 4 } isInvalid = { ! ! errors . confirm_password } >
< FormLabel htmlFor = 'confirm_password' > Confirm Password < / FormLabel >
< Input id = 'confirm_password' { ...register ( 'confirm_password' , {
validate : value = > value === getValues ( ) . password || 'The passwords do not match'
} ) } placeholder = '••••••••' type = 'password' / >
{ errors . confirm_password && < FormErrorMessage > { errors . confirm_password . message } < / FormErrorMessage > }
2024-02-26 09:39:09 -05:00
< / FormControl >
< Flex >
< FormControl mt = { 4 } >
2024-02-28 18:30:59 -05:00
< Checkbox { ...register ( 'is_superuser' ) } colorScheme = 'teal' > Is superuser ? < / Checkbox >
2024-02-26 09:39:09 -05:00
< / FormControl >
< FormControl mt = { 4 } >
2024-02-28 18:30:59 -05:00
< Checkbox { ...register ( 'is_active' ) } colorScheme = 'teal' > Is active ? < / Checkbox >
2024-02-26 09:39:09 -05:00
< / FormControl >
< / Flex >
< / ModalBody >
< ModalFooter gap = { 3 } >
2024-03-07 19:16:23 +01:00
< Button bg = 'ui.main' color = 'white' _hover = { { opacity : 0.8 } } type = 'submit' isLoading = { isSubmitting } isDisabled = { ! isDirty } >
2024-02-26 09:39:09 -05:00
Save
< / Button >
< Button onClick = { onCancel } > Cancel < / Button >
< / ModalFooter >
< / ModalContent >
< / Modal >
< / >
)
}
export default EditUser ;