diff --git a/api/Schema/Queries/UserQuery.cs b/api/Schema/Queries/UserQuery.cs index 21b983d3..2a431a92 100644 --- a/api/Schema/Queries/UserQuery.cs +++ b/api/Schema/Queries/UserQuery.cs @@ -27,5 +27,15 @@ public async Task> GetAllESLUsers([Service] UserService _userService, { return await _userService.ESLUsers(exceptUserId); } + + public async Task> GetAllPositions() + { + return await _userService.GetAllPositions(); + } + + public async Task> GetAllRoles() + { + return await _userService.GetAllRoles(); + } } } diff --git a/api/Services/UserService.cs b/api/Services/UserService.cs index 62284864..92b5117f 100644 --- a/api/Services/UserService.cs +++ b/api/Services/UserService.cs @@ -56,5 +56,21 @@ public async Task> ESLUsers(int? exceptUserId) .ToListAsync(); } } + + public async Task> GetAllPositions() + { + using (HrisContext context = _contextFactory.CreateDbContext()) + { + return await context.Positions.ToListAsync(); + } + } + + public async Task> GetAllRoles() + { + using (HrisContext context = _contextFactory.CreateDbContext()) + { + return await context.Roles.ToListAsync(); + } + } } } diff --git a/client/src/components/molecules/AddNewEmployeeModal/index.tsx b/client/src/components/molecules/AddNewEmployeeModal/index.tsx index 3154ed13..73f7274a 100644 --- a/client/src/components/molecules/AddNewEmployeeModal/index.tsx +++ b/client/src/components/molecules/AddNewEmployeeModal/index.tsx @@ -1,16 +1,23 @@ -import { useForm } from 'react-hook-form' -import { yupResolver } from '@hookform/resolvers/yup' +import toast from 'react-hot-toast' +import isEmpty from 'lodash/isEmpty' +import ReactSelect from 'react-select' import React, { FC, useEffect } from 'react' -import { User, Save, Mail, Award, RefreshCcw, X } from 'react-feather' +import { yupResolver } from '@hookform/resolvers/yup' +import { User, Save, Mail, RefreshCcw, X } from 'react-feather' +import { Controller, SubmitHandler, useForm } from 'react-hook-form' import TextField from './../TextField' import Input from '~/components/atoms/Input' +import useEmployee from '~/hooks/useEmployee' +import { queryClient } from '~/lib/queryClient' +import useUserQuery from '~/hooks/useUserQuery' import SpinnerIcon from '~/utils/icons/SpinnerIcon' import { NewEmployeeSchema } from '~/utils/validation' import Button from '~/components/atoms/Buttons/ButtonAction' import { customStyles } from '~/utils/customReactSelectStyles' import ModalTemplate from '~/components/templates/ModalTemplate' import { NewEmployeeFormValues } from '~/utils/types/formValues' +import { IEmployeeInput } from '~/utils/interfaces/employeeInterface' import ModalHeader from '~/components/templates/ModalTemplate/ModalHeader' import ModalFooter from '~/components/templates/ModalTemplate/ModalFooter' @@ -20,8 +27,18 @@ type Props = { } const AddNewEmployeeModal: FC = ({ isOpen, closeModal }): JSX.Element => { + // USER HOOKS -> Get Positions, Get Roles + const { getAllPositionQuery, getAllRoleQuery } = useUserQuery() + const positionData = getAllPositionQuery() + const roleData = getAllRoleQuery() + + // EMPLOYEE HOOKS + const { handleAddNewEmployeeMutation } = useEmployee() + const addEmployeeMutation = handleAddNewEmployeeMutation() + const { reset, + control, register, handleSubmit, formState: { errors, isSubmitting } @@ -31,12 +48,27 @@ const AddNewEmployeeModal: FC = ({ isOpen, closeModal }): JSX.Element => }) // This will handle Submit and Save New Overtime - const handleSave = async (data: NewEmployeeFormValues): Promise => { + const handleSave: SubmitHandler = async (data): Promise => { return await new Promise((resolve) => { - setTimeout(() => { - alert(JSON.stringify({ ...data }, null, 2)) - resolve() - }, 2000) + const request: IEmployeeInput = { + email: data.email, + firstName: data.first_name, + middleName: data.middle_name ?? '', + lastName: data.last_name, + positionId: parseInt(data.position.value), + roleId: parseInt(data.role.value) + } + + addEmployeeMutation.mutate(request, { + onSuccess: () => { + // TODO: Please Specify the query key of all Employee + void queryClient.invalidateQueries().then(() => { + toast.success('Added New Employee Successfully!') + resolve() + closeModal() + }) + } + }) }) } @@ -58,9 +90,14 @@ const AddNewEmployeeModal: FC = ({ isOpen, closeModal }): JSX.Element => }, [isOpen]) const handleReset = (): void => { + const emptySelect = { + value: '', + label: '' + } reset({ email: '', - position: '', + position: emptySelect, + role: emptySelect, first_name: '', middle_name: '', last_name: '' @@ -107,18 +144,73 @@ const AddNewEmployeeModal: FC = ({ isOpen, closeModal }): JSX.Element => {/* Position */}
- - + ( + + state.isFocused + ? 'border-primary' + : !isEmpty(errors.position) + ? 'border-rose-500 ring-rose-500' + : 'border-slate-300' + }} + value={field.value} + onChange={field.onChange} + isLoading={positionData.isLoading} + isDisabled={isSubmitting || positionData.isLoading} + options={positionData.data} + /> + )} + /> + + {errors.position !== null && errors.position !== undefined && ( + Position is required + )} +
+ + {/* Role */} +
+ + ( + + state.isFocused + ? 'border-primary' + : !isEmpty(errors.role) + ? 'border-rose-500 ring-rose-500' + : 'border-slate-300' + }} + value={field.value} + onChange={field.onChange} + isLoading={roleData.isLoading} + isDisabled={isSubmitting || roleData.isLoading} + options={roleData.data} + /> + )} /> - {errors?.position !== null && errors?.position !== undefined && ( - {errors.position?.message} + {errors.role !== null && errors.role !== undefined && ( + Role is required )}
diff --git a/client/src/components/molecules/TextField/index.tsx b/client/src/components/molecules/TextField/index.tsx index 079cd110..4c7b5a63 100644 --- a/client/src/components/molecules/TextField/index.tsx +++ b/client/src/components/molecules/TextField/index.tsx @@ -20,7 +20,7 @@ const TextField: FC = (props): JSX.Element => { return (