feat: register create user form

This commit is contained in:
Sergey Yarkov 2021-09-20 22:05:29 +03:00
parent 7bb1141af2
commit 5f04242d88
6 changed files with 114 additions and 51 deletions

View File

@ -12,7 +12,11 @@ const UserBadge: React.FC<{ roles: IUserRole[] }> = ({ roles }) => {
if (userHasRoles(roles, [UserRoleEnum.ADMIN])) return { name: 'Administrator', color: 'purple' };
if (userHasRoles(roles, [UserRoleEnum.TEACHER])) return { name: 'Teacher', color: 'orange' };
if (userHasRoles(roles, [UserRoleEnum.STUDENT])) return { name: 'Student', color: 'blue' };
if (roles.length === 0) return { name: 'Guest', color: 'gray' };
/**
* The user has no roles
*/
return { name: 'Guest', color: 'gray' };
};
const role = getCurrentRole();

View File

@ -94,6 +94,9 @@ export interface IMe extends IUser {
* does not have the STUDENT role
*/
courses?: UserCourseType[];
isAdmin: boolean;
isTeacher: boolean;
isStudent: boolean;
}
export interface IUserContacts {

View File

@ -19,19 +19,48 @@ import {
} from '@chakra-ui/react';
import { AddIcon } from '@chakra-ui/icons';
import { MdSupervisorAccount } from 'react-icons/md';
import { yupResolver } from '@hookform/resolvers/yup';
import { SubmitHandler } from 'react-hook-form';
import CreateUserSchema from './CreateUserModal.validator';
/**
* Types
*/
import { IMe } from 'interfaces';
import { UserRoleEnum } from 'enums';
/**
* Hooks
*/
import { useDisclosure } from '@chakra-ui/hooks';
import { useForm } from 'react-hook-form';
const CreateUserModal: React.FC = () => {
type CreateUserModalPropsType = {
me: IMe;
};
type CreateUserInputType = {
first_name: string;
last_name: string;
login: string;
email: string;
role: UserRoleEnum;
password: string;
};
const CreateUserModal: React.FC<CreateUserModalPropsType> = ({ me }) => {
const { isOpen, onOpen, onClose } = useDisclosure();
const {
register,
handleSubmit,
formState: { errors },
} = useForm<CreateUserInputType>({
resolver: yupResolver(CreateUserSchema),
});
const onSubmit: SubmitHandler<CreateUserInputType> = data => {
console.log(data);
};
return (
<>
@ -41,52 +70,71 @@ const CreateUserModal: React.FC = () => {
<Modal isOpen={isOpen} onClose={onClose}>
<ModalOverlay />
<ModalContent>
<ModalHeader>
<Flex alignItems='center'>
<MdSupervisorAccount />
<Text ml={2}>Create new user</Text>
</Flex>
</ModalHeader>
<ModalCloseButton />
<Divider />
<ModalBody pb={6}>
<FormControl>
<FormLabel>First name</FormLabel>
<Input placeholder='First name' />
</FormControl>
<FormControl mt={4}>
<FormLabel>Last name</FormLabel>
<Input placeholder='Last name' />
</FormControl>
<FormControl mt={4}>
<FormLabel>Login</FormLabel>
<Input placeholder='e.g student893' />
</FormControl>
<FormControl mt={4}>
<FormLabel>Email</FormLabel>
<Input placeholder='example@email.com' />
</FormControl>
<FormControl mt={4}>
<FormLabel>Role</FormLabel>
<Select w='full' mr='2'>
<option value={UserRoleEnum.STUDENT}>Student</option>
<option value={UserRoleEnum.TEACHER}>Teacher</option>
<option value={UserRoleEnum.ADMIN}>Administrator</option>
</Select>
</FormControl>
<FormControl mt={4}>
<FormLabel>Password</FormLabel>
<Input placeholder='******' />
<FormHelperText>Must be at least 6 characters</FormHelperText>
</FormControl>
</ModalBody>
<form onSubmit={handleSubmit(onSubmit)}>
<ModalHeader>
<Flex alignItems='center'>
<MdSupervisorAccount />
<Text ml={2}>Create new user</Text>
</Flex>
</ModalHeader>
<ModalCloseButton />
<Divider />
<ModalBody pb={6}>
<FormControl>
<FormLabel>First name</FormLabel>
<Input
placeholder='First name'
{...register('first_name')}
isInvalid={errors.first_name ? true : false}
/>
{errors.first_name ? (
<FormHelperText color='red.500'>{errors.first_name.message}</FormHelperText>
) : null}
</FormControl>
<FormControl mt={4}>
<FormLabel>Last name</FormLabel>
<Input placeholder='Last name' {...register('last_name')} isInvalid={errors.last_name ? true : false} />
{errors.last_name ? <FormHelperText color='red.500'>{errors.last_name.message}</FormHelperText> : null}
</FormControl>
<FormControl mt={4}>
<FormLabel>Login</FormLabel>
<Input placeholder='e.g student893' {...register('login')} isInvalid={errors.login ? true : false} />
{errors.login ? <FormHelperText color='red.500'>{errors.login.message}</FormHelperText> : null}
</FormControl>
<FormControl mt={4}>
<FormLabel>Email</FormLabel>
<Input placeholder='example@email.com' {...register('email')} isInvalid={errors.email ? true : false} />
{errors.email ? <FormHelperText color='red.500'>{errors.email.message}</FormHelperText> : null}
</FormControl>
<FormControl mt={4}>
<FormLabel>Role</FormLabel>
<Select w='full' mr='2' {...register('role')} isInvalid={errors.role ? true : false}>
<option value={UserRoleEnum.STUDENT}>Student</option>
{me.isAdmin ? (
<>
<option value={UserRoleEnum.TEACHER}>Teacher</option>
<option value={UserRoleEnum.ADMIN}>Administrator</option>
</>
) : null}
</Select>
{errors.role ? <FormHelperText color='red.500'>{errors.role.message}</FormHelperText> : null}
</FormControl>
<FormControl mt={4}>
<FormLabel>Password</FormLabel>
<Input placeholder='******' {...register('password')} isInvalid={errors.password ? true : false} />
<FormHelperText color={errors.password ? 'red' : 'gray.500'}>
{errors.password ? errors.password.message : 'Must be at least 6 characters.'}
</FormHelperText>
</FormControl>
</ModalBody>
<ModalFooter>
<Button variant='outline' mr={3} colorScheme='blue' leftIcon={<AddIcon />}>
Create
</Button>
<Button onClick={onClose}>Cancel</Button>
</ModalFooter>
<ModalFooter>
<Button type='submit' variant='outline' mr={3} colorScheme='blue' leftIcon={<AddIcon />}>
Create
</Button>
<Button onClick={onClose}>Cancel</Button>
</ModalFooter>
</form>
</ModalContent>
</Modal>
</>

View File

@ -5,8 +5,11 @@ const CreateUserSchema = yup.object().shape({
first_name: yup.string().required('First field name is required'),
last_name: yup.string().required('Last field name is required'),
login: yup.string().required('Login field is required'),
email: yup.string().required('Email field is required'),
role: yup.mixed<UserRoleEnum>().required('Role field is required').oneOf(Object.values(UserRoleEnum)),
email: yup.string().email('Email is invalid').required('Email field is required'),
role: yup
.mixed<UserRoleEnum>()
.required('Role field is required')
.oneOf(Object.values(UserRoleEnum), `Available roles: ${Object.keys(UserRoleEnum).join(', ')}`),
password: yup.string().required('Password field is required').min(6, 'Password must be at least 6 characters.'),
});

View File

@ -49,12 +49,12 @@ const UsersPage: React.FC<IPageProps> = ({ title }) => {
<Box h='100%'>
<Heading as='h1'>User management</Heading>
<Text mt='2'>You can add or delete your users on this page.</Text>
{userStore.users !== null && userStore.pagination !== undefined ? (
{userStore.users !== null && userStore.me !== null && userStore.pagination !== undefined ? (
<Flex mt='5' flexDir='column' h='full'>
<Flex justifyContent='space-between' sx={{ gap: '10px' }} flexWrap='wrap'>
<UserSearch />
<Flex sx={{ gap: '10px' }}>
<CreateUserModal />
<CreateUserModal me={userStore.me} />
<Button variant='outline' colorScheme='green' leftIcon={<FaFileExcel />}>
Import
</Button>

View File

@ -1,6 +1,7 @@
import { AxiosInstance } from 'axios';
import { makeAutoObservable, runInAction } from 'mobx';
import { IUser, IUserContacts, IMe, IPaginationMeta } from 'interfaces';
import * as helpers from 'helpers';
/**
* Services
@ -11,6 +12,7 @@ import UserService, { FetchUsersParamsType } from 'services/UserService';
* Stores
*/
import RootStore from './RootStore';
import { UserRoleEnum } from 'enums';
export default class UserStore {
public root: RootStore;
@ -64,6 +66,9 @@ export default class UserStore {
roles,
contacts,
courses,
isAdmin: helpers.userContainRoles(roles, [UserRoleEnum.ADMIN]),
isTeacher: helpers.userContainRoles(roles, [UserRoleEnum.TEACHER]),
isStudent: helpers.userContainRoles(roles, [UserRoleEnum.STUDENT]),
};
});