Fix logic code relative user and room

This commit is contained in:
2023-11-04 19:47:41 +07:00
parent 938fbb069e
commit aeb1923e40
18 changed files with 343 additions and 103 deletions
+3 -3
View File
@@ -5,7 +5,7 @@ import Button from '../../commons/styles/Button.ts';
import { TRoom } from '../../globals/types.ts';
import { useForm } from 'react-hook-form';
import { ROOM_PATH } from '../../constants/path.ts';
import { STATUS_CODE } from '../../constants/statusCode.ts';
import { STATUS_CODE } from '../../constants/responseStatus.ts';
import toast from 'react-hot-toast';
import { ADD_SUCCESS, EDIT_SUCCESS, errorMsg } from '../../constants/messages.ts';
import { sendRequest } from '../../helpers/sendRequest.ts';
@@ -63,8 +63,8 @@ const RoomForm = ({
// Add request
const response = await sendRequest(
ROOM_PATH,
'POST',
JSON.stringify(room),
'POST'
);
if (response.statusCode === STATUS_CODE.CREATE) {
@@ -76,8 +76,8 @@ const RoomForm = ({
// Edit request
const response = await sendRequest(
ROOM_PATH + `/${room!.id}`,
'PUT',
JSON.stringify(room),
'PUT'
);
if (response.statusCode == STATUS_CODE.OK) {
+4 -5
View File
@@ -20,9 +20,9 @@ import { TRoom } from '../../globals/types';
// Constants
import { useFetch } from '../../hooks/useFetch';
import { ROOM_PATH } from '../../constants/path';
import { STATUS_CODE } from '../../constants/statusCode';
import { STATUS_CODE } from '../../constants/responseStatus';
import { CONFIRM_DELETE, DELETE_SUCCESS } from '../../constants/messages';
import { ROOM_PAGE } from '../../constants/variables';
import { ORDERBY_OPTIONS, ROOM_PAGE } from '../../constants/variables';
// Styled
import Spinner from '../../commons/styles/Spinner';
@@ -54,8 +54,7 @@ const RoomRow = ({
if (confirm(CONFIRM_DELETE)) {
const response = await sendRequest(
ROOM_PATH + `/${room.id}`,
null,
'DELETE',
'DELETE'
);
if (response.statusCode === STATUS_CODE.OK) {
@@ -148,7 +147,7 @@ const RoomTable = ({
<>
<Direction>
<StyledOperationTable>
<OrderBy options={ROOM_PAGE.ORDERBY_OPTIONS} />
<OrderBy options={ORDERBY_OPTIONS} />
<SortBy options={ROOM_PAGE.SORTBY_OPTIONS} />
<Search
+67 -46
View File
@@ -10,19 +10,17 @@ import TextArea from '../../commons/styles/TextArea';
import Form from '../../components/Form';
import FormRow from '../../components/LabelControl/index.tsx';
// Types
import { TKeyValue, TUser } from '../../globals/types';
// Utils
import { sendRequest } from '../../helpers/sendRequest.ts';
import {
isEmptyObj,
isValidNumber,
isValidPhoneNumber,
isValidString,
} from '../../helpers/validators.ts';
// Constants
import { STATUS_CODE } from '../../constants/statusCode.ts';
import { STATUS_CODE } from '../../constants/responseStatus.ts';
import {
ADD_SUCCESS,
EDIT_SUCCESS,
@@ -32,11 +30,17 @@ import { USER_PATH } from '../../constants/path.ts';
import Select, { ISelectOptions } from '../../components/Select';
// Hooks
import { useFetch } from '../../hooks/useFetch.ts';
// Styled
import { FormBtn } from './styled.ts';
import { INVALID_FIELD, INVALID_PHONE, REQUIRED_FIELD_ERROR } from '../../constants/formValidateMessage.ts';
import {
INVALID_FIELD,
INVALID_PHONE,
REQUIRED_FIELD_ERROR,
} from '../../constants/formValidateMessage.ts';
import { getAllRoom, updateRoomStatus } from '../../services/roomServices.ts';
import { TUser } from '../../globals/types.ts';
import { INIT_VALUE_USER_FORM } from '../../constants/variables.ts';
interface IUserFormProp {
onClose: () => void;
@@ -53,11 +57,7 @@ const UserForm = ({
user,
isAdd,
}: IUserFormProp) => {
const formMethods = useForm<TUser>({
defaultValues: {
roomId: 1,
},
});
const formMethods = useForm<TUser>();
const {
register,
handleSubmit,
@@ -66,42 +66,55 @@ const UserForm = ({
trigger,
} = formMethods;
const [options, setOptions] = useState<ISelectOptions[]>();
const { data, errorFetchMsg } = useFetch('rooms');
// Init value when edit form and load options
useEffect(() => {
if (user) {
reset(user);
}
}, [reset, user]);
const load = async () => {
const rooms = await getAllRoom();
const options: ISelectOptions[] = [];
const tempUser = isAdd
? {}
: {...user};
useEffect(() => {
if (data) {
const tempData = data as TKeyValue[];
const tempOptions: ISelectOptions[] = [];
tempData.forEach((item) => {
tempOptions.push({
label: item.name! as string,
value: item.id! as string,
// Load and set default options room
if (rooms) {
rooms.forEach((item) => {
if (!item.status || tempUser?.roomId === item.id)
options.push({
label: item.name! as string,
value: item.id!.toString(),
});
});
});
setOptions(tempOptions);
}
setOptions(options);
reset({ roomId: +options[0].value });
}
if (errorFetchMsg) {
toast.error(errorFetchMsg);
}
}, [data, errorFetchMsg]);
if (!isEmptyObj(tempUser)) {
// Init value
// Set default value when user not have room yet.
if (!tempUser.roomId) {
tempUser.roomId = +options[0].value;
}
reset(tempUser);
} else {
reset(INIT_VALUE_USER_FORM);
}
};
load();
}, [reset, user, isAdd]);
// Submit form
const onSubmit = async (user: TUser) => {
const onSubmit = async (newUser: TUser) => {
try {
if (isAdd) {
// Add request
const response = await sendRequest(
USER_PATH,
JSON.stringify(user),
'POST'
'POST',
JSON.stringify(newUser)
);
if (response.statusCode === STATUS_CODE.CREATE) {
@@ -110,14 +123,14 @@ const UserForm = ({
throw new Error(errorMsg(response.statusCode, response.msg));
}
// TODO Update status when user create
// Update room status
updateRoomStatus(newUser.roomId, true);
} else {
// Edit request
const response = await sendRequest(
USER_PATH + `/${user!.id}`,
JSON.stringify(user),
'PUT'
USER_PATH + `/${newUser.id}`,
'PUT',
JSON.stringify(newUser)
);
if (response.statusCode == STATUS_CODE.OK) {
@@ -125,6 +138,9 @@ const UserForm = ({
} else {
throw new Error(errorMsg(response.statusCode, response.msg));
}
// Update room status
updateRoomStatus(user!.roomId, true, newUser.roomId);
}
// Reload table data
setReload(!reload);
@@ -167,8 +183,7 @@ const UserForm = ({
{...register('identifiedCode', {
required: REQUIRED_FIELD_ERROR,
validate: {
checkIdentifiedCode: (v) =>
isValidNumber(v) || INVALID_FIELD,
checkIdentifiedCode: (v) => isValidNumber(v) || INVALID_FIELD,
},
onChange: () => trigger('identifiedCode'),
})}
@@ -182,8 +197,7 @@ const UserForm = ({
{...register('phone', {
required: REQUIRED_FIELD_ERROR,
validate: {
checkPhoneNum: (v) =>
isValidPhoneNumber(v) || INVALID_PHONE,
checkPhoneNum: (v) => isValidPhoneNumber(v) || INVALID_PHONE,
},
onChange: () => trigger('phone'),
})}
@@ -191,7 +205,15 @@ const UserForm = ({
</FormRow>
<FormRow label="Room">
<Select id="roomId" options={options!} ariaLabel='RoomId'/>
<Select
id="roomId"
options={options!}
ariaLabel="RoomId"
optionsConfigForm={{
valueAsNumber: true,
onChange: () => trigger('roomId'),
}}
/>
</FormRow>
<FormRow label="Address" error={errors.address?.message}>
@@ -201,8 +223,7 @@ const UserForm = ({
{...register('address', {
required: REQUIRED_FIELD_ERROR,
validate: {
checkValidString: (v) =>
isValidString(v) || INVALID_FIELD,
checkValidString: (v) => isValidString(v) || INVALID_FIELD,
},
onChange: () => trigger('address'),
})}
+30 -22
View File
@@ -3,8 +3,8 @@ import { useEffect, useState } from 'react';
import toast from 'react-hot-toast';
// Components
import { HiSquare2Stack } from 'react-icons/hi2';
import { HiTrash } from 'react-icons/hi';
import { RiEditBoxFill } from 'react-icons/ri';
import { IoExit } from 'react-icons/io5';
import { StyledOperationTable } from './styled';
import Menus from '../../components/Menus';
import Table from '../../components/Table';
@@ -19,16 +19,16 @@ import { TUser } from '../../globals/types';
// Constants
import { useFetch } from '../../hooks/useFetch';
import { USER_PATH } from '../../constants/path';
import { STATUS_CODE } from '../../constants/statusCode';
import { CONFIRM_DELETE, DELETE_SUCCESS } from '../../constants/messages';
import { USER_PAGE } from '../../constants/variables';
import { STATUS_CODE } from '../../constants/responseStatus';
import { ORDERBY_OPTIONS, USER_PAGE } from '../../constants/variables';
// Styled
import Spinner from '../../commons/styles/Spinner';
// Utils
import { sendRequest } from '../../helpers/sendRequest';
import { updateRoomStatus } from '../../services/roomServices';
import { checkOutUser } from '../../services/userServices';
import { CONFIRM_MESSAGE } from '../../constants/messages';
interface IUserRow {
user: TUser;
@@ -50,16 +50,16 @@ const UserRow = ({
openFormDialog();
};
const handleOnDelete = async (user: TUser) => {
if (confirm(CONFIRM_DELETE)) {
const response = await sendRequest(
USER_PATH + `/${user.id}`,
null,
'DELETE',
);
const handleOnCheckOut = async (user: TUser) => {
if (confirm(CONFIRM_MESSAGE)) {
const resUpdateStatus = await updateRoomStatus(user.roomId, false);
const resCheckoutUser = await checkOutUser(user);
if (response.statusCode === STATUS_CODE.OK) {
toast.success(DELETE_SUCCESS);
if (
resCheckoutUser?.statusCode === STATUS_CODE.OK &&
resUpdateStatus?.statusCode === STATUS_CODE.OK
) {
toast.success('Check out complete!');
// Reload table
setReload(!reload);
@@ -75,20 +75,27 @@ const UserRow = ({
<div>{name}</div>
<div>{identifiedCode}</div>
<div>{phone}</div>
<div>{roomId}</div>
<div>{
roomId
? roomId
: 'None'
}</div>
<Menus.Menu>
<Menus.Toggle id={id.toString()} />
<Menus.List id={id.toString()}>
<Menus.Button
icon={<HiSquare2Stack />}
icon={<RiEditBoxFill />}
onClick={() => handleOnEdit(user)}
>
Edit
</Menus.Button>
<Menus.Button icon={<HiTrash />} onClick={() => handleOnDelete(user)}>
Delete
<Menus.Button
icon={<IoExit />}
onClick={() => handleOnCheckOut(user)}
>
Check out
</Menus.Button>
</Menus.List>
</Menus.Menu>
@@ -125,7 +132,7 @@ const UserTable = ({
phoneSearch,
sortByValue,
orderByValue,
reload,
reload
);
useEffect(() => {
@@ -140,11 +147,12 @@ const UserTable = ({
}
}, [data, errorFetchMsg]);
return (
<>
<Direction>
<StyledOperationTable>
<OrderBy options={USER_PAGE.ORDERBY_OPTIONS} />
<OrderBy options={ORDERBY_OPTIONS} />
<SortBy options={USER_PAGE.SORTBY_OPTIONS} />
<Search