mirror of
https://github.com/Nezumi-2711/react-training.git
synced 2026-09-22 20:01:59 +00:00
Fix all comments
This commit is contained in:
@@ -1,60 +1,69 @@
|
||||
import { forwardRef, useEffect } from 'react';
|
||||
import {
|
||||
Dispatch,
|
||||
MutableRefObject,
|
||||
SetStateAction,
|
||||
forwardRef,
|
||||
useEffect,
|
||||
} from 'react';
|
||||
|
||||
// Components
|
||||
import Dialog from '../../components/Dialog';
|
||||
import RoomForm from './Form';
|
||||
import { TRoom } from '../../globals/types';
|
||||
|
||||
// Types
|
||||
import { Nullable, TRoom } from '../../globals/types';
|
||||
|
||||
// Hooks
|
||||
import { useForwardRef } from '../../hooks/useForwardRef';
|
||||
|
||||
interface IRoomDialog {
|
||||
onClose?: () => void;
|
||||
reload?: boolean;
|
||||
setReload?: React.Dispatch<React.SetStateAction<boolean>>;
|
||||
ref?: React.MutableRefObject<HTMLDialogElement | null>;
|
||||
room?: TRoom | null;
|
||||
setReload?: Dispatch<SetStateAction<boolean>>;
|
||||
ref?: MutableRefObject<Nullable<HTMLDialogElement>>;
|
||||
room?: Nullable<TRoom>;
|
||||
isAdd?: boolean;
|
||||
}
|
||||
|
||||
const RoomDialog = forwardRef((props: IRoomDialog, ref) => {
|
||||
const dialogRef = ref as React.MutableRefObject<
|
||||
HTMLDialogElement | undefined
|
||||
>;
|
||||
// prettier-ignore
|
||||
const {
|
||||
onClose,
|
||||
setReload,
|
||||
reload,
|
||||
room,
|
||||
isAdd
|
||||
} = props;
|
||||
const RoomDialog = forwardRef<HTMLDialogElement, IRoomDialog>(
|
||||
(props: IRoomDialog, ref) => {
|
||||
const dialogRef = useForwardRef(ref);
|
||||
const {
|
||||
onClose,
|
||||
setReload,
|
||||
reload,
|
||||
room,
|
||||
isAdd
|
||||
} = props;
|
||||
|
||||
useEffect(() => {
|
||||
if (dialogRef.current) {
|
||||
dialogRef.current.addEventListener('click', (e: MouseEvent) => {
|
||||
const dialogDimensions = dialogRef.current!.getBoundingClientRect();
|
||||
if (
|
||||
e.clientX < dialogDimensions.left ||
|
||||
e.clientX > dialogDimensions.right ||
|
||||
e.clientY < dialogDimensions.top ||
|
||||
e.clientY > dialogDimensions.bottom
|
||||
) {
|
||||
dialogRef.current!.close();
|
||||
}
|
||||
});
|
||||
}
|
||||
}, [dialogRef]);
|
||||
useEffect(() => {
|
||||
if (dialogRef.current) {
|
||||
dialogRef.current.addEventListener('click', (e: MouseEvent) => {
|
||||
const dialogDimensions = dialogRef.current!.getBoundingClientRect();
|
||||
if (
|
||||
e.clientX < dialogDimensions.left ||
|
||||
e.clientX > dialogDimensions.right ||
|
||||
e.clientY < dialogDimensions.top ||
|
||||
e.clientY > dialogDimensions.bottom
|
||||
) {
|
||||
dialogRef.current!.close();
|
||||
}
|
||||
});
|
||||
}
|
||||
}, [dialogRef]);
|
||||
|
||||
return (
|
||||
<Dialog title={'Add room'} onClose={onClose} ref={dialogRef}>
|
||||
<RoomForm
|
||||
onClose={onClose!}
|
||||
reload={reload!}
|
||||
setReload={setReload!}
|
||||
room={room}
|
||||
isAdd={isAdd!}
|
||||
/>
|
||||
</Dialog>
|
||||
);
|
||||
});
|
||||
return (
|
||||
<Dialog title={'Add room'} onClose={onClose} ref={dialogRef}>
|
||||
<RoomForm
|
||||
onClose={onClose!}
|
||||
reload={reload!}
|
||||
setReload={setReload!}
|
||||
room={room}
|
||||
isAdd={isAdd!}
|
||||
/>
|
||||
</Dialog>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
export default RoomDialog;
|
||||
|
||||
@@ -1,20 +1,42 @@
|
||||
import { Dispatch, SetStateAction, useEffect } from 'react';
|
||||
import toast from 'react-hot-toast';
|
||||
import styled from 'styled-components';
|
||||
|
||||
// Hooks
|
||||
import { useForm } from 'react-hook-form';
|
||||
|
||||
// Styled
|
||||
import Button from '../../commons/styles/Button.ts';
|
||||
import Input from '../../commons/styles/Input.ts';
|
||||
|
||||
// Types
|
||||
import { TRoom } from '../../globals/types.ts';
|
||||
import { useForm } from 'react-hook-form';
|
||||
import { Nullable, TRoom } from '../../globals/types.ts';
|
||||
|
||||
// Constants
|
||||
import { ROOM_PATH } from '../../constants/path.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 {
|
||||
ADD_SUCCESS,
|
||||
EDIT_SUCCESS,
|
||||
errorMsg,
|
||||
} from '../../constants/messages.ts';
|
||||
import {
|
||||
INVALID_DISCOUNT,
|
||||
INVALID_FIELD,
|
||||
REQUIRED_FIELD_ERROR,
|
||||
} from '../../constants/formValidateMessage.ts';
|
||||
|
||||
// Helpers
|
||||
import { sendRequest } from '../../helpers/sendRequest.ts';
|
||||
import Input from '../../commons/styles/Input.ts';
|
||||
import {
|
||||
isValidDiscount,
|
||||
isValidNumber,
|
||||
isValidString,
|
||||
} from '../../helpers/validators.ts';
|
||||
|
||||
// Components
|
||||
import FormRow from '../../components/LabelControl/index.tsx';
|
||||
import { INVALID_DISCOUNT, INVALID_FIELD, REQUIRED_FIELD_ERROR } from '../../constants/formValidateMessage.ts';
|
||||
import { isValidDiscount, isValidNumber, isValidString } from '../../helpers/validators.ts';
|
||||
import Form from '../../components/Form/index.tsx';
|
||||
import { useEffect } from 'react';
|
||||
|
||||
const FormBtn = styled(Button)`
|
||||
width: 100%;
|
||||
@@ -29,8 +51,8 @@ const FormBtn = styled(Button)`
|
||||
interface IRoomFormProp {
|
||||
onClose: () => void;
|
||||
reload: boolean;
|
||||
setReload: React.Dispatch<React.SetStateAction<boolean>>;
|
||||
room?: TRoom | null;
|
||||
setReload: Dispatch<SetStateAction<boolean>>;
|
||||
room?: Nullable<TRoom>;
|
||||
isAdd: boolean;
|
||||
}
|
||||
|
||||
@@ -51,20 +73,24 @@ const RoomForm = ({
|
||||
} = formMethods;
|
||||
|
||||
useEffect(() => {
|
||||
if(room) {
|
||||
if (room) {
|
||||
reset(room);
|
||||
}
|
||||
}, [room, reset]);
|
||||
|
||||
// Submit form
|
||||
const onSubmit = async (room: TRoom) => {
|
||||
// Calculate final price
|
||||
room.finalPrice = room.price - (room.price * room.discount) / 100;
|
||||
|
||||
try {
|
||||
if (isAdd) {
|
||||
// Add request
|
||||
|
||||
const response = await sendRequest(
|
||||
ROOM_PATH,
|
||||
'POST',
|
||||
JSON.stringify(room),
|
||||
JSON.stringify(room)
|
||||
);
|
||||
|
||||
if (response.statusCode === STATUS_CODE.CREATE) {
|
||||
@@ -77,7 +103,7 @@ const RoomForm = ({
|
||||
const response = await sendRequest(
|
||||
ROOM_PATH + `/${room!.id}`,
|
||||
'PUT',
|
||||
JSON.stringify(room),
|
||||
JSON.stringify(room)
|
||||
);
|
||||
|
||||
if (response.statusCode == STATUS_CODE.OK) {
|
||||
@@ -99,68 +125,66 @@ const RoomForm = ({
|
||||
};
|
||||
|
||||
return (
|
||||
<Form onSubmit={handleSubmit(onSubmit)}>
|
||||
<Input type="hidden" id="id" {...register('id')} />
|
||||
<FormRow label="Name" error={errors?.name?.message}>
|
||||
<Input
|
||||
type="text"
|
||||
id="name"
|
||||
{...register('name', {
|
||||
required: REQUIRED_FIELD_ERROR,
|
||||
validate: {
|
||||
checkValidName: (value) =>
|
||||
isValidString(value) || INVALID_FIELD,
|
||||
},
|
||||
onChange: () => trigger('name'),
|
||||
})}
|
||||
/>
|
||||
</FormRow>
|
||||
<Form onSubmit={handleSubmit(onSubmit)}>
|
||||
<Input type="hidden" id="id" {...register('id')} />
|
||||
<FormRow label="Name" error={errors?.name?.message}>
|
||||
<Input
|
||||
type="text"
|
||||
id="name"
|
||||
{...register('name', {
|
||||
required: REQUIRED_FIELD_ERROR,
|
||||
validate: {
|
||||
checkValidName: (value) => isValidString(value) || INVALID_FIELD,
|
||||
},
|
||||
onChange: () => trigger('name'),
|
||||
})}
|
||||
/>
|
||||
</FormRow>
|
||||
|
||||
<FormRow
|
||||
label="Price"
|
||||
error={errors?.price?.message}
|
||||
>
|
||||
<Input
|
||||
type="text"
|
||||
id="price"
|
||||
{...register('price', {
|
||||
required: REQUIRED_FIELD_ERROR,
|
||||
validate: {
|
||||
checkIdentifiedCode: (v) => isValidNumber(v) || INVALID_FIELD,
|
||||
},
|
||||
onChange: () => trigger('price'),
|
||||
})}
|
||||
/>
|
||||
</FormRow>
|
||||
<FormRow label="Price" error={errors?.price?.message}>
|
||||
<Input
|
||||
type="text"
|
||||
id="price"
|
||||
{...register('price', {
|
||||
valueAsNumber: true,
|
||||
required: REQUIRED_FIELD_ERROR,
|
||||
validate: {
|
||||
checkIdentifiedCode: (v) =>
|
||||
isValidNumber(v.toString()) || INVALID_FIELD,
|
||||
},
|
||||
onChange: () => trigger('price'),
|
||||
})}
|
||||
/>
|
||||
</FormRow>
|
||||
|
||||
<FormRow label="discount" error={errors?.discount?.message}>
|
||||
<Input
|
||||
type="text"
|
||||
id="phone"
|
||||
{...register('discount', {
|
||||
required: REQUIRED_FIELD_ERROR,
|
||||
validate: {
|
||||
checkPhoneNum: (v) => isValidDiscount(v) || INVALID_DISCOUNT,
|
||||
},
|
||||
onChange: () => trigger('discount'),
|
||||
})}
|
||||
/>
|
||||
</FormRow>
|
||||
<FormRow label="discount" error={errors?.discount?.message}>
|
||||
<Input
|
||||
type="text"
|
||||
id="phone"
|
||||
{...register('discount', {
|
||||
valueAsNumber: true,
|
||||
required: REQUIRED_FIELD_ERROR,
|
||||
validate: {
|
||||
checkPhoneNum: (v) => isValidDiscount(v) || INVALID_DISCOUNT,
|
||||
},
|
||||
onChange: () => trigger('discount'),
|
||||
})}
|
||||
/>
|
||||
</FormRow>
|
||||
|
||||
<Form.Action>
|
||||
<FormBtn type="submit" name="submit" disabled={!isDirty || !isValid}>
|
||||
{
|
||||
// prettier-ignore
|
||||
isAdd
|
||||
? 'Add'
|
||||
<Form.Action>
|
||||
<FormBtn type="submit" name="submit" disabled={!isDirty || !isValid}>
|
||||
{
|
||||
isAdd
|
||||
? 'Add'
|
||||
: 'Save'
|
||||
}
|
||||
</FormBtn>
|
||||
<FormBtn type="button" styled="secondary" onClick={onClose}>
|
||||
Close
|
||||
</FormBtn>
|
||||
</Form.Action>
|
||||
</Form>
|
||||
}
|
||||
</FormBtn>
|
||||
<FormBtn type="button" styled="secondary" onClick={onClose}>
|
||||
Close
|
||||
</FormBtn>
|
||||
</Form.Action>
|
||||
</Form>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { useSearchParams } from 'react-router-dom';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { Dispatch, SetStateAction, useEffect, useState } from 'react';
|
||||
import toast from 'react-hot-toast';
|
||||
|
||||
// Components
|
||||
@@ -15,7 +15,7 @@ import SortBy from '../../components/SortBy';
|
||||
import OrderBy from '../../components/OrderBy';
|
||||
|
||||
// Types
|
||||
import { TRoom } from '../../globals/types';
|
||||
import { Nullable, TRoom } from '../../globals/types';
|
||||
|
||||
// Constants
|
||||
import { useFetch } from '../../hooks/useFetch';
|
||||
@@ -27,16 +27,16 @@ import { ORDERBY_OPTIONS, ROOM_PAGE } from '../../constants/variables';
|
||||
// Styled
|
||||
import Spinner from '../../commons/styles/Spinner';
|
||||
|
||||
// Utils
|
||||
// Helpers
|
||||
import { sendRequest } from '../../helpers/sendRequest';
|
||||
import { formatCurrency } from '../../helpers/utils';
|
||||
|
||||
interface IRoomRow {
|
||||
room: TRoom;
|
||||
openFormDialog: () => void;
|
||||
setRoom: React.Dispatch<React.SetStateAction<TRoom | null>>;
|
||||
setRoom: Dispatch<SetStateAction<Nullable<TRoom>>>;
|
||||
reload: boolean;
|
||||
setReload: React.Dispatch<React.SetStateAction<boolean>>;
|
||||
setReload: Dispatch<SetStateAction<boolean>>;
|
||||
}
|
||||
|
||||
const RoomRow = ({
|
||||
@@ -46,12 +46,12 @@ const RoomRow = ({
|
||||
reload,
|
||||
setReload,
|
||||
}: IRoomRow) => {
|
||||
const handleOnEdit = (room: TRoom) => {
|
||||
const handleEdit = (room: TRoom) => {
|
||||
setRoom(room);
|
||||
openFormDialog();
|
||||
};
|
||||
|
||||
const handleOnDelete = async (room: TRoom) => {
|
||||
const handleDelete = async (room: TRoom) => {
|
||||
if (confirm(CONFIRM_DELETE)) {
|
||||
const response = await sendRequest(ROOM_PATH + `/${room.id}`, 'DELETE');
|
||||
|
||||
@@ -64,12 +64,8 @@ const RoomRow = ({
|
||||
}
|
||||
};
|
||||
|
||||
const { id, name, price, discount, status } = room;
|
||||
const { id, name, finalPrice, status } = room;
|
||||
|
||||
// Calculate final price
|
||||
const finalPrice = price - (price * discount / 100);
|
||||
|
||||
// prettier-ignore
|
||||
const statusText = status
|
||||
? 'Unavailable'
|
||||
: 'Available';
|
||||
@@ -87,11 +83,11 @@ const RoomRow = ({
|
||||
<Menus.List id={id.toString()}>
|
||||
<Menus.Button
|
||||
icon={<RiEditBoxFill />}
|
||||
onClick={() => handleOnEdit(room)}
|
||||
onClick={() => handleEdit(room)}
|
||||
>
|
||||
Edit
|
||||
</Menus.Button>
|
||||
<Menus.Button icon={<HiTrash />} onClick={() => handleOnDelete(room)}>
|
||||
<Menus.Button icon={<HiTrash />} onClick={() => handleDelete(room)}>
|
||||
Delete
|
||||
</Menus.Button>
|
||||
</Menus.List>
|
||||
@@ -102,9 +98,9 @@ const RoomRow = ({
|
||||
|
||||
interface IRoomTable {
|
||||
reload: boolean;
|
||||
setReload: React.Dispatch<React.SetStateAction<boolean>>;
|
||||
setReload: Dispatch<SetStateAction<boolean>>;
|
||||
openFormDialog: () => void;
|
||||
setRoom?: React.Dispatch<React.SetStateAction<TRoom | null>>;
|
||||
setRoom?: Dispatch<SetStateAction<Nullable<TRoom>>>;
|
||||
}
|
||||
|
||||
const RoomTable = ({
|
||||
|
||||
@@ -1,21 +1,21 @@
|
||||
import { useRef, useState } from 'react';
|
||||
|
||||
// Components
|
||||
import Direction from '../../commons/styles/Direction';
|
||||
import Button from '../../commons/styles/Button';
|
||||
import RoomTable from './Table';
|
||||
|
||||
// Styled
|
||||
import { StyledRoom, Title } from './styled';
|
||||
import Direction from '../../commons/styles/Direction';
|
||||
import Button from '../../commons/styles/Button';
|
||||
import RoomDialog from './Dialog';
|
||||
|
||||
// Types
|
||||
import { TRoom } from '../../globals/types';
|
||||
import { Nullable, TRoom } from '../../globals/types';
|
||||
|
||||
const Room = () => {
|
||||
const dialogRef = useRef<HTMLDialogElement>();
|
||||
const dialogRef = useRef<HTMLDialogElement>(null);
|
||||
const [reload, setReload] = useState(true);
|
||||
const [room, setRoom] = useState<TRoom | null>(null);
|
||||
const [room, setRoom] = useState<Nullable<TRoom>>(null);
|
||||
const [isAdd, setIsAdd] = useState(false);
|
||||
|
||||
const openFormDialog = (isAddForm: boolean = false) => {
|
||||
|
||||
@@ -1,26 +1,33 @@
|
||||
import { forwardRef, useEffect } from 'react';
|
||||
import {
|
||||
Dispatch,
|
||||
MutableRefObject,
|
||||
SetStateAction,
|
||||
forwardRef,
|
||||
useEffect,
|
||||
} from 'react';
|
||||
|
||||
// Components
|
||||
import Dialog from '../../components/Dialog';
|
||||
import UserForm from './Form';
|
||||
|
||||
// Types
|
||||
import { TUser } from '../../globals/types';
|
||||
import { Nullable, TUser } from '../../globals/types';
|
||||
|
||||
// Hooks
|
||||
import { useForwardRef } from '../../hooks/useForwardRef';
|
||||
|
||||
interface IUserDialog {
|
||||
onClose: () => void;
|
||||
reload: boolean;
|
||||
setReload: React.Dispatch<React.SetStateAction<boolean>>;
|
||||
ref: React.MutableRefObject<HTMLDialogElement | null>;
|
||||
user: TUser | null;
|
||||
setReload: Dispatch<SetStateAction<boolean>>;
|
||||
ref: MutableRefObject<Nullable<HTMLDialogElement>>;
|
||||
user: Nullable<TUser>;
|
||||
isAdd: boolean;
|
||||
}
|
||||
|
||||
const UserDialog = forwardRef((props, ref) => {
|
||||
const UserDialog = forwardRef<HTMLDialogElement, IUserDialog>((props, ref) => {
|
||||
const dialogRef = useForwardRef(ref);
|
||||
|
||||
// prettier-ignore
|
||||
const {
|
||||
onClose,
|
||||
setReload,
|
||||
@@ -56,6 +63,6 @@ const UserDialog = forwardRef((props, ref) => {
|
||||
/>
|
||||
</Dialog>
|
||||
);
|
||||
}) as React.FC<IUserDialog>;
|
||||
});
|
||||
|
||||
export default UserDialog;
|
||||
|
||||
@@ -1,5 +1,13 @@
|
||||
import { useCallback, useEffect, useState } from 'react';
|
||||
import {
|
||||
Dispatch,
|
||||
SetStateAction,
|
||||
useCallback,
|
||||
useEffect,
|
||||
useState,
|
||||
} from 'react';
|
||||
import toast from 'react-hot-toast';
|
||||
|
||||
// Hooks
|
||||
import { FormProvider, useForm } from 'react-hook-form';
|
||||
|
||||
// Styled
|
||||
@@ -8,14 +16,15 @@ import Input from '../../commons/styles/Input';
|
||||
// Components
|
||||
import Form from '../../components/Form';
|
||||
import FormRow from '../../components/LabelControl/index.tsx';
|
||||
import Select, { ISelectOptions } from '../../components/Select';
|
||||
|
||||
// Utils
|
||||
// Helpers
|
||||
import { sendRequest } from '../../helpers/sendRequest.ts';
|
||||
import {
|
||||
isEmptyObj,
|
||||
isValidName,
|
||||
isValidNumber,
|
||||
isValidPhoneNumber,
|
||||
isValidString,
|
||||
} from '../../helpers/validators.ts';
|
||||
|
||||
// Constants
|
||||
@@ -26,26 +35,27 @@ import {
|
||||
errorMsg,
|
||||
} from '../../constants/messages.ts';
|
||||
import { USER_PATH } from '../../constants/path.ts';
|
||||
import Select, { ISelectOptions } from '../../components/Select';
|
||||
|
||||
// Hooks
|
||||
|
||||
// Styled
|
||||
import { FormBtn } from './styled.ts';
|
||||
import {
|
||||
INVALID_FIELD,
|
||||
INVALID_PHONE,
|
||||
REQUIRED_FIELD_ERROR,
|
||||
} from '../../constants/formValidateMessage.ts';
|
||||
import { getAllRoom, updateRoomStatus } from '../../services/roomServices.ts';
|
||||
import { TRoom, TUser } from '../../globals/types.ts';
|
||||
import { INIT_VALUE_USER_FORM } from '../../constants/variables.ts';
|
||||
|
||||
// Styled
|
||||
import { FormBtn } from './styled.ts';
|
||||
|
||||
// Services
|
||||
import { getAllRoom, updateRoomStatus } from '../../services/roomServices.ts';
|
||||
|
||||
// Types
|
||||
import { Nullable, TRoom, TUser } from '../../globals/types.ts';
|
||||
|
||||
interface IUserFormProp {
|
||||
onClose: () => void;
|
||||
reload: boolean;
|
||||
setReload: React.Dispatch<React.SetStateAction<boolean>>;
|
||||
user: TUser | null;
|
||||
setReload: Dispatch<SetStateAction<boolean>>;
|
||||
user: Nullable<TUser>;
|
||||
isAdd: boolean;
|
||||
}
|
||||
|
||||
@@ -78,11 +88,13 @@ const UserForm = ({
|
||||
rooms.forEach((item) => {
|
||||
if (!item.status || tempUser?.roomId === item.id)
|
||||
options.push({
|
||||
label: item.name! as string,
|
||||
label: item.name!,
|
||||
value: item.id!.toString(),
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
if (options.length > 0) {
|
||||
setOptions(options);
|
||||
reset({ roomId: +options[0].value });
|
||||
}
|
||||
@@ -178,8 +190,7 @@ const UserForm = ({
|
||||
{...register('name', {
|
||||
required: REQUIRED_FIELD_ERROR,
|
||||
validate: {
|
||||
checkValidName: (value) =>
|
||||
isValidString(value) || INVALID_FIELD,
|
||||
checkValidName: (value) => isValidName(value) || INVALID_FIELD,
|
||||
},
|
||||
onChange: () => trigger('name'),
|
||||
})}
|
||||
@@ -196,7 +207,8 @@ const UserForm = ({
|
||||
{...register('identifiedCode', {
|
||||
required: REQUIRED_FIELD_ERROR,
|
||||
validate: {
|
||||
checkIdentifiedCode: (v) => isValidNumber(v) || INVALID_FIELD,
|
||||
checkIdentifiedCode: (v) =>
|
||||
isValidNumber(v.toString()) || INVALID_FIELD,
|
||||
},
|
||||
onChange: () => trigger('identifiedCode'),
|
||||
})}
|
||||
@@ -218,25 +230,24 @@ const UserForm = ({
|
||||
</FormRow>
|
||||
|
||||
<FormRow label="Room">
|
||||
<Select
|
||||
id="roomId"
|
||||
options={options!}
|
||||
ariaLabel="RoomId"
|
||||
optionsConfigForm={{
|
||||
valueAsNumber: true,
|
||||
onChange: () => trigger('roomId'),
|
||||
}}
|
||||
/>
|
||||
{options && options.length > 0 ? (
|
||||
<Select
|
||||
id="roomId"
|
||||
options={options!}
|
||||
ariaLabel="RoomId"
|
||||
optionsConfigForm={{
|
||||
valueAsNumber: true,
|
||||
onChange: () => trigger('roomId'),
|
||||
}}
|
||||
/>
|
||||
) : (
|
||||
<p>No room available!</p>
|
||||
)}
|
||||
</FormRow>
|
||||
|
||||
<Form.Action>
|
||||
<FormBtn type="submit" name="submit" disabled={!isDirty || !isValid}>
|
||||
{
|
||||
// prettier-ignore
|
||||
isAdd
|
||||
? 'Add'
|
||||
: 'Save'
|
||||
}
|
||||
{isAdd ? 'Add' : 'Save'}
|
||||
</FormBtn>
|
||||
<FormBtn type="button" styled="secondary" onClick={onClose}>
|
||||
Close
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
import { useSearchParams } from 'react-router-dom';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { Dispatch, SetStateAction, useEffect, useState } from 'react';
|
||||
import toast from 'react-hot-toast';
|
||||
|
||||
// Components
|
||||
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';
|
||||
import Direction from '../../commons/styles/Direction';
|
||||
@@ -15,27 +14,30 @@ import SortBy from '../../components/SortBy';
|
||||
import OrderBy from '../../components/OrderBy';
|
||||
|
||||
// Types
|
||||
import { TUser } from '../../globals/types';
|
||||
import { Nullable, TUser } from '../../globals/types';
|
||||
|
||||
// Hooks
|
||||
import { useFetch } from '../../hooks/useFetch';
|
||||
|
||||
// Constants
|
||||
import { useFetch } from '../../hooks/useFetch';
|
||||
import { STATUS_CODE } from '../../constants/responseStatus';
|
||||
import { ORDERBY_OPTIONS, USER_PAGE } from '../../constants/variables';
|
||||
import { CONFIRM_MESSAGE } from '../../constants/messages';
|
||||
|
||||
// Styled
|
||||
import { StyledOperationTable } from './styled';
|
||||
import Spinner from '../../commons/styles/Spinner';
|
||||
|
||||
// Utils
|
||||
// Services
|
||||
import { updateRoomStatus } from '../../services/roomServices';
|
||||
import { checkOutUser } from '../../services/userServices';
|
||||
import { CONFIRM_MESSAGE } from '../../constants/messages';
|
||||
|
||||
interface IUserRow {
|
||||
user: TUser;
|
||||
openFormDialog: () => void;
|
||||
setUser: React.Dispatch<React.SetStateAction<TUser | null>>;
|
||||
setUser: Dispatch<SetStateAction<Nullable<TUser>>>;
|
||||
reload: boolean;
|
||||
setReload: React.Dispatch<React.SetStateAction<boolean>>;
|
||||
setReload: Dispatch<SetStateAction<boolean>>;
|
||||
}
|
||||
|
||||
const UserRow = ({
|
||||
@@ -45,12 +47,12 @@ const UserRow = ({
|
||||
reload,
|
||||
setReload,
|
||||
}: IUserRow) => {
|
||||
const handleOnEdit = (user: TUser) => {
|
||||
const handleEdit = (user: TUser) => {
|
||||
setUser(user);
|
||||
openFormDialog();
|
||||
};
|
||||
|
||||
const handleOnCheckOut = async (user: TUser) => {
|
||||
const handleCheckOut = async (user: TUser) => {
|
||||
if (confirm(CONFIRM_MESSAGE)) {
|
||||
const resUpdateStatus = await updateRoomStatus(user.roomId, false);
|
||||
const resCheckoutUser = await checkOutUser(user);
|
||||
@@ -75,7 +77,11 @@ const UserRow = ({
|
||||
<div>{name}</div>
|
||||
<div>{identifiedCode}</div>
|
||||
<div>{phone}</div>
|
||||
<div>{roomId ? roomId : 'None'}</div>
|
||||
<div>{
|
||||
roomId
|
||||
? roomId
|
||||
: 'None'
|
||||
}</div>
|
||||
|
||||
<Menus.Menu>
|
||||
<Menus.Toggle id={id.toString()} />
|
||||
@@ -83,14 +89,11 @@ const UserRow = ({
|
||||
<Menus.List id={id.toString()}>
|
||||
<Menus.Button
|
||||
icon={<RiEditBoxFill />}
|
||||
onClick={() => handleOnEdit(user)}
|
||||
onClick={() => handleEdit(user)}
|
||||
>
|
||||
Edit
|
||||
</Menus.Button>
|
||||
<Menus.Button
|
||||
icon={<IoExit />}
|
||||
onClick={() => handleOnCheckOut(user)}
|
||||
>
|
||||
<Menus.Button icon={<IoExit />} onClick={() => handleCheckOut(user)}>
|
||||
Check out
|
||||
</Menus.Button>
|
||||
</Menus.List>
|
||||
@@ -101,9 +104,9 @@ const UserRow = ({
|
||||
|
||||
interface IUserTable {
|
||||
reload: boolean;
|
||||
setReload: React.Dispatch<React.SetStateAction<boolean>>;
|
||||
setReload: Dispatch<SetStateAction<boolean>>;
|
||||
openFormDialog: () => void;
|
||||
setUser?: React.Dispatch<React.SetStateAction<TUser | null>>;
|
||||
setUser?: Dispatch<SetStateAction<Nullable<TUser>>>;
|
||||
}
|
||||
|
||||
const UserTable = ({
|
||||
|
||||
@@ -1,21 +1,21 @@
|
||||
import { useRef, useState } from 'react';
|
||||
|
||||
// Components
|
||||
import Direction from '../../commons/styles/Direction';
|
||||
import Button from '../../commons/styles/Button';
|
||||
import UserTable from './Table';
|
||||
|
||||
// Styled
|
||||
import Button from '../../commons/styles/Button';
|
||||
import Direction from '../../commons/styles/Direction';
|
||||
import { StyledUser, Title } from './styled';
|
||||
import UserDialog from './Dialog';
|
||||
|
||||
// Types
|
||||
import { TUser } from '../../globals/types';
|
||||
import { Nullable, TUser } from '../../globals/types';
|
||||
|
||||
const User = () => {
|
||||
const dialogRef = useRef<HTMLDialogElement>(null);
|
||||
const [reload, setReload] = useState(true);
|
||||
const [user, setUser] = useState<TUser | null>(null);
|
||||
const [user, setUser] = useState<Nullable<TUser>>(null);
|
||||
const [isAdd, setIsAdd] = useState(false);
|
||||
|
||||
const openFormDialog = (isAddForm: boolean = false) => {
|
||||
|
||||
Reference in New Issue
Block a user