mirror of
https://github.com/Nezumi-2711/react-training.git
synced 2026-09-22 20:01:59 +00:00
Fix bug and optimzed code
This commit is contained in:
@@ -1,7 +1,9 @@
|
|||||||
import styled, { css } from 'styled-components';
|
import styled, { css } from 'styled-components';
|
||||||
|
|
||||||
|
type TButtonStyle = 'primary' | 'secondary';
|
||||||
|
|
||||||
interface IButtonStyle {
|
interface IButtonStyle {
|
||||||
styled?: 'primary' | 'secondary';
|
styled?: TButtonStyle;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Button = styled.button<IButtonStyle>`
|
const Button = styled.button<IButtonStyle>`
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
import styled, { css } from 'styled-components';
|
import styled, { css } from 'styled-components';
|
||||||
|
|
||||||
|
type TDirection = 'vertical' | 'horizontal';
|
||||||
|
|
||||||
interface IDirection {
|
interface IDirection {
|
||||||
type?: 'vertical' | 'horizontal';
|
type?: TDirection;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Direction = styled.div<IDirection>`
|
const Direction = styled.div<IDirection>`
|
||||||
|
|||||||
@@ -3,8 +3,10 @@ import styled, { css } from 'styled-components';
|
|||||||
// Styled
|
// Styled
|
||||||
import CommonInput from './CommonInput';
|
import CommonInput from './CommonInput';
|
||||||
|
|
||||||
|
type TInput = 'text' | 'checkbox' | 'hidden';
|
||||||
|
|
||||||
interface IInputTyped {
|
interface IInputTyped {
|
||||||
type?: 'text' | 'checkbox' | 'hidden';
|
type?: TInput;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Input = styled.input<IInputTyped>`
|
const Input = styled.input<IInputTyped>`
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { memo, useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
|
|
||||||
// Styled
|
// Styled
|
||||||
import { StyledSearch } from './styled';
|
import { StyledSearch } from './styled';
|
||||||
@@ -11,7 +11,7 @@ interface ISearch {
|
|||||||
setValueSearch: (phone: string) => void;
|
setValueSearch: (phone: string) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Search = memo(({ setValueSearch, setPlaceHolder }: ISearch) => {
|
const Search = ({ setValueSearch, setPlaceHolder }: ISearch) => {
|
||||||
const [query, setQuery] = useState('');
|
const [query, setQuery] = useState('');
|
||||||
const debounceValue = useDebounce<string>(query, 700);
|
const debounceValue = useDebounce<string>(query, 700);
|
||||||
|
|
||||||
@@ -25,6 +25,6 @@ const Search = memo(({ setValueSearch, setPlaceHolder }: ISearch) => {
|
|||||||
placeholder={setPlaceHolder}
|
placeholder={setPlaceHolder}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
});
|
};
|
||||||
|
|
||||||
export default Search;
|
export default Search;
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ const Select = ({
|
|||||||
optionsConfigForm,
|
optionsConfigForm,
|
||||||
value,
|
value,
|
||||||
onChange,
|
onChange,
|
||||||
ariaLabel
|
ariaLabel,
|
||||||
}: ISelect) => {
|
}: ISelect) => {
|
||||||
const { register } = useFormContext() ?? {};
|
const { register } = useFormContext() ?? {};
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ const SortBy = memo(({ options }: ISortByProps) => {
|
|||||||
options={options}
|
options={options}
|
||||||
value={sortBy}
|
value={sortBy}
|
||||||
onChange={handleChange}
|
onChange={handleChange}
|
||||||
ariaLabel='Sort'
|
ariaLabel="Sort"
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,20 +1,17 @@
|
|||||||
const errorMsg = (errorCode: number, msg: string) => {
|
|
||||||
return `Error code: ${errorCode}. Message: ${msg}`;
|
|
||||||
};
|
|
||||||
|
|
||||||
const ADD_SUCCESS = 'Add success';
|
const ADD_SUCCESS = 'Add success';
|
||||||
const EDIT_SUCCESS = 'Edit success';
|
const EDIT_SUCCESS = 'Edit success';
|
||||||
const CONFIRM_MESSAGE = 'Do you want to checkout this user?';
|
const CONFIRM_MESSAGE = 'Do you want to checkout this user?';
|
||||||
const CONFIRM_DELETE = 'Are you sure to delete it?'
|
const CONFIRM_DELETE = 'Are you sure to delete it?'
|
||||||
const DELETE_SUCCESS = 'Delete success';
|
const DELETE_SUCCESS = 'Delete success';
|
||||||
const CHECKOUT_SUCCESS = 'Check out success';
|
const CHECKOUT_SUCCESS = 'Check out success';
|
||||||
|
const DENIED_ACTION = "Can't checkout user not in room!";
|
||||||
|
|
||||||
export {
|
export {
|
||||||
ADD_SUCCESS,
|
ADD_SUCCESS,
|
||||||
errorMsg,
|
|
||||||
EDIT_SUCCESS,
|
EDIT_SUCCESS,
|
||||||
CONFIRM_MESSAGE,
|
CONFIRM_MESSAGE,
|
||||||
CONFIRM_DELETE,
|
CONFIRM_DELETE,
|
||||||
DELETE_SUCCESS,
|
DELETE_SUCCESS,
|
||||||
CHECKOUT_SUCCESS,
|
CHECKOUT_SUCCESS,
|
||||||
|
DENIED_ACTION
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ const STATUS_CODE = {
|
|||||||
OK: 200,
|
OK: 200,
|
||||||
CREATE: 201,
|
CREATE: 201,
|
||||||
NOT_FOUND: 404,
|
NOT_FOUND: 404,
|
||||||
INTERNAL_SERVER_ERROR: 500,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const RESPONSE_MESSAGE = {
|
const RESPONSE_MESSAGE = {
|
||||||
|
|||||||
@@ -61,6 +61,13 @@ const INIT_VALUE_USER_FORM = {
|
|||||||
phone: '',
|
phone: '',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const INIT_VALUE_ROOM_FORM = {
|
||||||
|
name: '',
|
||||||
|
id: 0,
|
||||||
|
price: 0,
|
||||||
|
discount: 0,
|
||||||
|
};
|
||||||
|
|
||||||
export {
|
export {
|
||||||
USER_PAGE,
|
USER_PAGE,
|
||||||
ROOM_PAGE,
|
ROOM_PAGE,
|
||||||
@@ -68,4 +75,5 @@ export {
|
|||||||
ERROR,
|
ERROR,
|
||||||
ORDERBY_OPTIONS,
|
ORDERBY_OPTIONS,
|
||||||
INIT_VALUE_USER_FORM,
|
INIT_VALUE_USER_FORM,
|
||||||
|
INIT_VALUE_ROOM_FORM,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,17 +1,6 @@
|
|||||||
// Constants
|
// Constants
|
||||||
import { REQUIRED_FIELD_ERROR } from '../constants/formValidateMessage';
|
import { REQUIRED_FIELD_ERROR } from '../constants/formValidateMessage';
|
||||||
|
|
||||||
/**
|
|
||||||
* Set required error for value
|
|
||||||
* @param value The value set required or not
|
|
||||||
* @param isRequired Set required for value
|
|
||||||
* @returns Return error text if value has required
|
|
||||||
*/
|
|
||||||
const isRequired = (value: string | number, isRequired: unknown) => {
|
|
||||||
if (!value && isRequired) return REQUIRED_FIELD_ERROR;
|
|
||||||
return '';
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create query url for search
|
* Create query url for search
|
||||||
* @param columnSearch Column want to search
|
* @param columnSearch Column want to search
|
||||||
@@ -53,6 +42,11 @@ const searchQuery = (
|
|||||||
return query;
|
return query;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert value to currency format with value
|
||||||
|
* @param value Value need to be converted
|
||||||
|
* @returns Return the string value with currency
|
||||||
|
*/
|
||||||
const formatCurrency = (value: number): string => {
|
const formatCurrency = (value: number): string => {
|
||||||
return Intl.NumberFormat('en-US', {
|
return Intl.NumberFormat('en-US', {
|
||||||
style: 'currency',
|
style: 'currency',
|
||||||
@@ -60,4 +54,14 @@ const formatCurrency = (value: number): string => {
|
|||||||
}).format(value);
|
}).format(value);
|
||||||
};
|
};
|
||||||
|
|
||||||
export { isRequired, searchQuery, formatCurrency, REQUIRED_FIELD_ERROR };
|
/**
|
||||||
|
* Create error string
|
||||||
|
* @param errorCode Error code
|
||||||
|
* @param msg Message error
|
||||||
|
* @returns Return the full error string
|
||||||
|
*/
|
||||||
|
const errorMsg = (errorCode: number, msg: string) => {
|
||||||
|
return `Error code: ${errorCode}. Message: ${msg}`;
|
||||||
|
};
|
||||||
|
|
||||||
|
export { errorMsg, searchQuery, formatCurrency, REQUIRED_FIELD_ERROR };
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
import { BASE_URL } from '../constants/path';
|
import { BASE_URL } from '../constants/path';
|
||||||
|
|
||||||
// Types
|
// Types
|
||||||
import { TResponse } from '../types/response';
|
import { IResponse } from '../types/responses';
|
||||||
|
|
||||||
type TMethodRequest = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';
|
type TMethodRequest = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';
|
||||||
|
|
||||||
@@ -17,7 +17,7 @@ export const sendRequest = async <T>(
|
|||||||
path: string,
|
path: string,
|
||||||
method: TMethodRequest = 'GET',
|
method: TMethodRequest = 'GET',
|
||||||
body?: BodyInit
|
body?: BodyInit
|
||||||
): Promise<TResponse<T>> => {
|
): Promise<IResponse<T>> => {
|
||||||
const response = await fetch(BASE_URL + path, {
|
const response = await fetch(BASE_URL + path, {
|
||||||
method,
|
method,
|
||||||
body,
|
body,
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { BASE_URL } from '../constants/path';
|
|||||||
import { DEFAULT_ORDER_BY, DEFAULT_SORT_BY } from '../constants/config';
|
import { DEFAULT_ORDER_BY, DEFAULT_SORT_BY } from '../constants/config';
|
||||||
|
|
||||||
// Helpers
|
// Helpers
|
||||||
import { searchQuery } from '../helpers/utils';
|
import { searchQuery } from '../helpers/helper';
|
||||||
|
|
||||||
// Types
|
// Types
|
||||||
import { Nullable } from '../types/common';
|
import { Nullable } from '../types/common';
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import { Nullable } from '../types/common';
|
|||||||
*/
|
*/
|
||||||
export const useOutsideClick = (
|
export const useOutsideClick = (
|
||||||
handler: () => void,
|
handler: () => void,
|
||||||
listeningCapturing = true,
|
listeningCapturing = true
|
||||||
): MutableRefObject<Nullable<HTMLUListElement>> => {
|
): MutableRefObject<Nullable<HTMLUListElement>> => {
|
||||||
const ref = useRef<HTMLUListElement>(null);
|
const ref = useRef<HTMLUListElement>(null);
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import RoomForm from './Form';
|
|||||||
|
|
||||||
// Types
|
// Types
|
||||||
import { Nullable } from '../../types/common';
|
import { Nullable } from '../../types/common';
|
||||||
import { TRoom } from '../../types/rooms';
|
import { IRoom } from '../../types/rooms';
|
||||||
|
|
||||||
// Hooks
|
// Hooks
|
||||||
import { useForwardRef } from '../../hooks/useForwardRef';
|
import { useForwardRef } from '../../hooks/useForwardRef';
|
||||||
@@ -22,7 +22,7 @@ interface IRoomDialog {
|
|||||||
reload?: boolean;
|
reload?: boolean;
|
||||||
setReload?: Dispatch<SetStateAction<boolean>>;
|
setReload?: Dispatch<SetStateAction<boolean>>;
|
||||||
ref?: MutableRefObject<Nullable<HTMLDialogElement>>;
|
ref?: MutableRefObject<Nullable<HTMLDialogElement>>;
|
||||||
room?: Nullable<TRoom>;
|
room?: Nullable<IRoom>;
|
||||||
isAdd?: boolean;
|
isAdd?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,15 +11,12 @@ import Input from '../../commons/styles/Input.ts';
|
|||||||
|
|
||||||
// Types
|
// Types
|
||||||
import { Nullable } from '../../types/common';
|
import { Nullable } from '../../types/common';
|
||||||
import { TRoom } from '../../types/rooms.ts';
|
import { IRoom } from '../../types/rooms';
|
||||||
|
|
||||||
// Constants
|
// Constants
|
||||||
import { ROOM_PATH } from '../../constants/path.ts';
|
|
||||||
import { STATUS_CODE } from '../../constants/responseStatus.ts';
|
|
||||||
import {
|
import {
|
||||||
ADD_SUCCESS,
|
ADD_SUCCESS,
|
||||||
EDIT_SUCCESS,
|
EDIT_SUCCESS,
|
||||||
errorMsg,
|
|
||||||
} from '../../constants/messages.ts';
|
} from '../../constants/messages.ts';
|
||||||
import {
|
import {
|
||||||
INVALID_DISCOUNT,
|
INVALID_DISCOUNT,
|
||||||
@@ -28,7 +25,6 @@ import {
|
|||||||
} from '../../constants/formValidateMessage.ts';
|
} from '../../constants/formValidateMessage.ts';
|
||||||
|
|
||||||
// Helpers
|
// Helpers
|
||||||
import { sendRequest } from '../../helpers/sendRequest.ts';
|
|
||||||
import {
|
import {
|
||||||
isValidDiscount,
|
isValidDiscount,
|
||||||
isValidNumber,
|
isValidNumber,
|
||||||
@@ -38,6 +34,8 @@ import {
|
|||||||
// Components
|
// Components
|
||||||
import FormRow from '../../components/LabelControl/index.tsx';
|
import FormRow from '../../components/LabelControl/index.tsx';
|
||||||
import Form from '../../components/Form/index.tsx';
|
import Form from '../../components/Form/index.tsx';
|
||||||
|
import { addRoom, updateRoom } from '../../services/roomServices.ts';
|
||||||
|
import { INIT_VALUE_ROOM_FORM } from '../../constants/variables.ts';
|
||||||
|
|
||||||
const FormBtn = styled(Button)`
|
const FormBtn = styled(Button)`
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@@ -53,7 +51,7 @@ interface IRoomFormProp {
|
|||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
reload: boolean;
|
reload: boolean;
|
||||||
setReload: Dispatch<SetStateAction<boolean>>;
|
setReload: Dispatch<SetStateAction<boolean>>;
|
||||||
room?: Nullable<TRoom>;
|
room?: Nullable<IRoom>;
|
||||||
isAdd: boolean;
|
isAdd: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,7 +62,7 @@ const RoomForm = ({
|
|||||||
room,
|
room,
|
||||||
isAdd,
|
isAdd,
|
||||||
}: IRoomFormProp) => {
|
}: IRoomFormProp) => {
|
||||||
const formMethods = useForm<TRoom>();
|
const formMethods = useForm<IRoom>();
|
||||||
const {
|
const {
|
||||||
register,
|
register,
|
||||||
handleSubmit,
|
handleSubmit,
|
||||||
@@ -74,43 +72,32 @@ const RoomForm = ({
|
|||||||
} = formMethods;
|
} = formMethods;
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (room) {
|
if (room && !isAdd) {
|
||||||
reset(room);
|
reset(room);
|
||||||
|
} else {
|
||||||
|
reset(INIT_VALUE_ROOM_FORM);
|
||||||
}
|
}
|
||||||
}, [room, reset]);
|
}, [room, reset, isAdd]);
|
||||||
|
|
||||||
// Submit form
|
// Submit form
|
||||||
const onSubmit = async (room: TRoom) => {
|
const onSubmit = async (room: IRoom) => {
|
||||||
// Calculate final price
|
// Calculate final price
|
||||||
room.finalPrice = room.price - (room.price * room.discount) / 100;
|
room.finalPrice = room.price - (room.price * room.discount) / 100;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (isAdd) {
|
if (isAdd) {
|
||||||
// Add request
|
// Add request
|
||||||
|
const response = await addRoom(room);
|
||||||
|
|
||||||
const response = await sendRequest(
|
if(response) {
|
||||||
ROOM_PATH,
|
|
||||||
'POST',
|
|
||||||
JSON.stringify(room)
|
|
||||||
);
|
|
||||||
|
|
||||||
if (response.statusCode === STATUS_CODE.CREATE) {
|
|
||||||
toast.success(ADD_SUCCESS);
|
toast.success(ADD_SUCCESS);
|
||||||
} else {
|
|
||||||
throw new Error(errorMsg(response.statusCode, response.msg));
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Edit request
|
// Edit request
|
||||||
const response = await sendRequest(
|
const response = await updateRoom(room);
|
||||||
ROOM_PATH + `/${room!.id}`,
|
|
||||||
'PUT',
|
|
||||||
JSON.stringify(room)
|
|
||||||
);
|
|
||||||
|
|
||||||
if (response.statusCode == STATUS_CODE.OK) {
|
if (response) {
|
||||||
toast.success(EDIT_SUCCESS);
|
toast.success(EDIT_SUCCESS);
|
||||||
} else {
|
|
||||||
throw new Error(errorMsg(response.statusCode, response.msg));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Reload table data
|
// Reload table data
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ import OrderBy from '../../components/OrderBy';
|
|||||||
|
|
||||||
// Types
|
// Types
|
||||||
import { Nullable } from '../../types/common';
|
import { Nullable } from '../../types/common';
|
||||||
import { TRoom } from '../../types/rooms';
|
import { IRoom } from '../../types/rooms';
|
||||||
|
|
||||||
// Constants
|
// Constants
|
||||||
import { useFetch } from '../../hooks/useFetch';
|
import { useFetch } from '../../hooks/useFetch';
|
||||||
@@ -30,12 +30,12 @@ import Spinner from '../../commons/styles/Spinner';
|
|||||||
|
|
||||||
// Helpers
|
// Helpers
|
||||||
import { sendRequest } from '../../helpers/sendRequest';
|
import { sendRequest } from '../../helpers/sendRequest';
|
||||||
import { formatCurrency } from '../../helpers/utils';
|
import { formatCurrency } from '../../helpers/helper';
|
||||||
|
|
||||||
interface IRoomRow {
|
interface IRoomRow {
|
||||||
room: TRoom;
|
room: IRoom;
|
||||||
openFormDialog: () => void;
|
openFormDialog: () => void;
|
||||||
setRoom: Dispatch<SetStateAction<Nullable<TRoom>>>;
|
setRoom: Dispatch<SetStateAction<Nullable<IRoom>>>;
|
||||||
reload: boolean;
|
reload: boolean;
|
||||||
setReload: Dispatch<SetStateAction<boolean>>;
|
setReload: Dispatch<SetStateAction<boolean>>;
|
||||||
}
|
}
|
||||||
@@ -47,12 +47,12 @@ const RoomRow = ({
|
|||||||
reload,
|
reload,
|
||||||
setReload,
|
setReload,
|
||||||
}: IRoomRow) => {
|
}: IRoomRow) => {
|
||||||
const handleEdit = (room: TRoom) => {
|
const handleEdit = (room: IRoom) => {
|
||||||
setRoom(room);
|
setRoom(room);
|
||||||
openFormDialog();
|
openFormDialog();
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleDelete = async (room: TRoom) => {
|
const handleDelete = async (room: IRoom) => {
|
||||||
if (confirm(CONFIRM_DELETE)) {
|
if (confirm(CONFIRM_DELETE)) {
|
||||||
const response = await sendRequest(ROOM_PATH + `/${room.id}`, 'DELETE');
|
const response = await sendRequest(ROOM_PATH + `/${room.id}`, 'DELETE');
|
||||||
|
|
||||||
@@ -101,7 +101,7 @@ interface IRoomTable {
|
|||||||
reload: boolean;
|
reload: boolean;
|
||||||
setReload: Dispatch<SetStateAction<boolean>>;
|
setReload: Dispatch<SetStateAction<boolean>>;
|
||||||
openFormDialog: () => void;
|
openFormDialog: () => void;
|
||||||
setRoom?: Dispatch<SetStateAction<Nullable<TRoom>>>;
|
setRoom?: Dispatch<SetStateAction<Nullable<IRoom>>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
const RoomTable = ({
|
const RoomTable = ({
|
||||||
@@ -112,7 +112,7 @@ const RoomTable = ({
|
|||||||
}: IRoomTable) => {
|
}: IRoomTable) => {
|
||||||
const [nameSearch, setNameSearch] = useState('');
|
const [nameSearch, setNameSearch] = useState('');
|
||||||
const [searchParams] = useSearchParams();
|
const [searchParams] = useSearchParams();
|
||||||
const [rooms, setRooms] = useState<TRoom[]>([]);
|
const [rooms, setRooms] = useState<IRoom[]>([]);
|
||||||
const sortByValue = searchParams.get('sortBy')
|
const sortByValue = searchParams.get('sortBy')
|
||||||
? searchParams.get('sortBy')!
|
? searchParams.get('sortBy')!
|
||||||
: '';
|
: '';
|
||||||
@@ -165,9 +165,9 @@ const RoomTable = ({
|
|||||||
<div>Price</div>
|
<div>Price</div>
|
||||||
<div>Status</div>
|
<div>Status</div>
|
||||||
</Table.Header>
|
</Table.Header>
|
||||||
<Table.Body<TRoom>
|
<Table.Body<IRoom>
|
||||||
data={rooms}
|
data={rooms}
|
||||||
render={(room: TRoom) => (
|
render={(room: IRoom) => (
|
||||||
<RoomRow
|
<RoomRow
|
||||||
room={room}
|
room={room}
|
||||||
key={room.id}
|
key={room.id}
|
||||||
|
|||||||
@@ -11,12 +11,12 @@ import RoomDialog from './Dialog';
|
|||||||
|
|
||||||
// Types
|
// Types
|
||||||
import { Nullable } from '../../types/common';
|
import { Nullable } from '../../types/common';
|
||||||
import { TRoom } from '../../types/rooms';
|
import { IRoom } from '../../types/rooms';
|
||||||
|
|
||||||
const Room = () => {
|
const Room = () => {
|
||||||
const dialogRef = useRef<HTMLDialogElement>(null);
|
const dialogRef = useRef<HTMLDialogElement>(null);
|
||||||
const [reload, setReload] = useState(true);
|
const [reload, setReload] = useState(true);
|
||||||
const [room, setRoom] = useState<Nullable<TRoom>>(null);
|
const [room, setRoom] = useState<Nullable<IRoom>>(null);
|
||||||
const [isAdd, setIsAdd] = useState(false);
|
const [isAdd, setIsAdd] = useState(false);
|
||||||
|
|
||||||
const openFormDialog = (isAddForm: boolean = false) => {
|
const openFormDialog = (isAddForm: boolean = false) => {
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import UserForm from './Form';
|
|||||||
|
|
||||||
// Types
|
// Types
|
||||||
import { Nullable } from '../../types/common';
|
import { Nullable } from '../../types/common';
|
||||||
import { TUser } from '../../types/user';
|
import { IUser } from '../../types/users';
|
||||||
|
|
||||||
// Hooks
|
// Hooks
|
||||||
import { useForwardRef } from '../../hooks/useForwardRef';
|
import { useForwardRef } from '../../hooks/useForwardRef';
|
||||||
@@ -22,7 +22,7 @@ interface IUserDialog {
|
|||||||
reload: boolean;
|
reload: boolean;
|
||||||
setReload: Dispatch<SetStateAction<boolean>>;
|
setReload: Dispatch<SetStateAction<boolean>>;
|
||||||
ref: MutableRefObject<Nullable<HTMLDialogElement>>;
|
ref: MutableRefObject<Nullable<HTMLDialogElement>>;
|
||||||
user: Nullable<TUser>;
|
user: Nullable<IUser>;
|
||||||
isAdd: boolean;
|
isAdd: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ import FormRow from '../../components/LabelControl/index.tsx';
|
|||||||
import Select, { ISelectOptions } from '../../components/Select';
|
import Select, { ISelectOptions } from '../../components/Select';
|
||||||
|
|
||||||
// Helpers
|
// Helpers
|
||||||
import { sendRequest } from '../../helpers/sendRequest.ts';
|
|
||||||
import {
|
import {
|
||||||
isEmptyObj,
|
isEmptyObj,
|
||||||
isValidName,
|
isValidName,
|
||||||
@@ -28,13 +27,7 @@ import {
|
|||||||
} from '../../helpers/validators.ts';
|
} from '../../helpers/validators.ts';
|
||||||
|
|
||||||
// Constants
|
// Constants
|
||||||
import { STATUS_CODE } from '../../constants/responseStatus.ts';
|
import { ADD_SUCCESS, EDIT_SUCCESS } from '../../constants/messages.ts';
|
||||||
import {
|
|
||||||
ADD_SUCCESS,
|
|
||||||
EDIT_SUCCESS,
|
|
||||||
errorMsg,
|
|
||||||
} from '../../constants/messages.ts';
|
|
||||||
import { USER_PATH } from '../../constants/path.ts';
|
|
||||||
import {
|
import {
|
||||||
INVALID_FIELD,
|
INVALID_FIELD,
|
||||||
INVALID_PHONE,
|
INVALID_PHONE,
|
||||||
@@ -49,15 +42,16 @@ import { FormBtn } from './styled.ts';
|
|||||||
import { getAllRoom, updateRoomStatus } from '../../services/roomServices.ts';
|
import { getAllRoom, updateRoomStatus } from '../../services/roomServices.ts';
|
||||||
|
|
||||||
// Types
|
// Types
|
||||||
import { Nullable } from '../../types/common';
|
import { Nullable } from '../../types/common.ts';
|
||||||
import { TUser } from '../../types/user.ts';
|
import { IUser } from '../../types/users.ts';
|
||||||
import { TRoom } from '../../types/rooms.ts';
|
import { IRoom } from '../../types/rooms.ts';
|
||||||
|
import { createUser, updateUser } from '../../services/userServices.ts';
|
||||||
|
|
||||||
interface IUserFormProp {
|
interface IUserFormProp {
|
||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
reload: boolean;
|
reload: boolean;
|
||||||
setReload: Dispatch<SetStateAction<boolean>>;
|
setReload: Dispatch<SetStateAction<boolean>>;
|
||||||
user: Nullable<TUser>;
|
user: Nullable<IUser>;
|
||||||
isAdd: boolean;
|
isAdd: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,7 +62,7 @@ const UserForm = ({
|
|||||||
user,
|
user,
|
||||||
isAdd,
|
isAdd,
|
||||||
}: IUserFormProp) => {
|
}: IUserFormProp) => {
|
||||||
const formMethods = useForm<TUser>();
|
const formMethods = useForm<IUser>();
|
||||||
const {
|
const {
|
||||||
register,
|
register,
|
||||||
handleSubmit,
|
handleSubmit,
|
||||||
@@ -76,17 +70,25 @@ const UserForm = ({
|
|||||||
formState: { errors, isDirty, isValid },
|
formState: { errors, isDirty, isValid },
|
||||||
trigger,
|
trigger,
|
||||||
} = formMethods;
|
} = formMethods;
|
||||||
const [rooms, setRooms] = useState<TRoom[]>([]);
|
const [rooms, setRooms] = useState<IRoom[]>([]);
|
||||||
const [options, setOptions] = useState<ISelectOptions[]>();
|
const [options, setOptions] = useState<ISelectOptions[]>();
|
||||||
|
|
||||||
// Init value when edit form and load options
|
// Init value when edit form and load options
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const load = async () => {
|
const load = async () => {
|
||||||
const options: ISelectOptions[] = [];
|
const options: ISelectOptions[] = [];
|
||||||
const tempUser = isAdd ? {} : { ...user };
|
const tempUser = isAdd
|
||||||
|
? {}
|
||||||
|
: { ...user };
|
||||||
|
|
||||||
// Load and set default options room
|
// Load and set default options room
|
||||||
if (rooms.length > 0) {
|
if (rooms.length > 0) {
|
||||||
|
// Init first options
|
||||||
|
options.push({
|
||||||
|
label: '---Select---',
|
||||||
|
value: '0',
|
||||||
|
});
|
||||||
|
|
||||||
rooms.forEach((item) => {
|
rooms.forEach((item) => {
|
||||||
if (!item.status || tempUser?.roomId === item.id)
|
if (!item.status || tempUser?.roomId === item.id)
|
||||||
options.push({
|
options.push({
|
||||||
@@ -98,16 +100,10 @@ const UserForm = ({
|
|||||||
|
|
||||||
if (options.length > 0) {
|
if (options.length > 0) {
|
||||||
setOptions(options);
|
setOptions(options);
|
||||||
reset({ roomId: +options[0].value });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isEmptyObj(tempUser)) {
|
if (!isEmptyObj(tempUser)) {
|
||||||
// Init value
|
// Init value
|
||||||
// Set default value when user not have room yet.
|
|
||||||
if (!tempUser.roomId) {
|
|
||||||
tempUser.roomId = +options[0].value;
|
|
||||||
}
|
|
||||||
|
|
||||||
reset(tempUser);
|
reset(tempUser);
|
||||||
} else {
|
} else {
|
||||||
reset(INIT_VALUE_USER_FORM);
|
reset(INIT_VALUE_USER_FORM);
|
||||||
@@ -119,36 +115,24 @@ const UserForm = ({
|
|||||||
|
|
||||||
// Submit form
|
// Submit form
|
||||||
const onSubmit = useCallback(
|
const onSubmit = useCallback(
|
||||||
async (newUser: TUser) => {
|
async (newUser: IUser) => {
|
||||||
try {
|
try {
|
||||||
if (isAdd) {
|
if (isAdd) {
|
||||||
// Add request
|
// Add request
|
||||||
const response = await sendRequest(
|
const response = await createUser(newUser);
|
||||||
USER_PATH,
|
|
||||||
'POST',
|
|
||||||
JSON.stringify(newUser)
|
|
||||||
);
|
|
||||||
|
|
||||||
if (response.statusCode === STATUS_CODE.CREATE) {
|
if (response) {
|
||||||
toast.success(ADD_SUCCESS);
|
toast.success(ADD_SUCCESS);
|
||||||
} else {
|
|
||||||
throw new Error(errorMsg(response.statusCode, response.msg));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update room status
|
// Update room status
|
||||||
updateRoomStatus(newUser.roomId, true);
|
updateRoomStatus(newUser.roomId, true);
|
||||||
} else {
|
} else {
|
||||||
// Edit request
|
// Edit request
|
||||||
const response = await sendRequest(
|
const response = await updateUser(newUser);
|
||||||
USER_PATH + `/${newUser.id}`,
|
|
||||||
'PUT',
|
|
||||||
JSON.stringify(newUser)
|
|
||||||
);
|
|
||||||
|
|
||||||
if (response.statusCode == STATUS_CODE.OK) {
|
if (response) {
|
||||||
toast.success(EDIT_SUCCESS);
|
toast.success(EDIT_SUCCESS);
|
||||||
} else {
|
|
||||||
throw new Error(errorMsg(response.statusCode, response.msg));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update room status
|
// Update room status
|
||||||
@@ -232,7 +216,7 @@ const UserForm = ({
|
|||||||
</FormRow>
|
</FormRow>
|
||||||
|
|
||||||
<FormRow label="Room">
|
<FormRow label="Room">
|
||||||
{options && options.length > 0 ? (
|
{options && options.length > 1 ? (
|
||||||
<Select
|
<Select
|
||||||
id="roomId"
|
id="roomId"
|
||||||
options={options!}
|
options={options!}
|
||||||
@@ -240,6 +224,7 @@ const UserForm = ({
|
|||||||
optionsConfigForm={{
|
optionsConfigForm={{
|
||||||
valueAsNumber: true,
|
valueAsNumber: true,
|
||||||
onChange: () => trigger('roomId'),
|
onChange: () => trigger('roomId'),
|
||||||
|
validate: (v) => v !== 0,
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
@@ -249,7 +234,11 @@ const UserForm = ({
|
|||||||
|
|
||||||
<Form.Action>
|
<Form.Action>
|
||||||
<FormBtn type="submit" name="submit" disabled={!isDirty || !isValid}>
|
<FormBtn type="submit" name="submit" disabled={!isDirty || !isValid}>
|
||||||
{isAdd ? 'Add' : 'Save'}
|
{
|
||||||
|
isAdd
|
||||||
|
? 'Add'
|
||||||
|
: 'Save'
|
||||||
|
}
|
||||||
</FormBtn>
|
</FormBtn>
|
||||||
<FormBtn type="button" styled="secondary" onClick={onClose}>
|
<FormBtn type="button" styled="secondary" onClick={onClose}>
|
||||||
Close
|
Close
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ import OrderBy from '../../components/OrderBy';
|
|||||||
|
|
||||||
// Types
|
// Types
|
||||||
import { Nullable } from '../../types/common';
|
import { Nullable } from '../../types/common';
|
||||||
import { TUser } from '../../types/user';
|
import { IUser } from '../../types/users';
|
||||||
|
|
||||||
// Hooks
|
// Hooks
|
||||||
import { useFetch } from '../../hooks/useFetch';
|
import { useFetch } from '../../hooks/useFetch';
|
||||||
@@ -23,7 +23,7 @@ import { useFetch } from '../../hooks/useFetch';
|
|||||||
// Constants
|
// Constants
|
||||||
import { STATUS_CODE } from '../../constants/responseStatus';
|
import { STATUS_CODE } from '../../constants/responseStatus';
|
||||||
import { ORDERBY_OPTIONS, USER_PAGE } from '../../constants/variables';
|
import { ORDERBY_OPTIONS, USER_PAGE } from '../../constants/variables';
|
||||||
import { CONFIRM_MESSAGE } from '../../constants/messages';
|
import { CONFIRM_MESSAGE, DENIED_ACTION } from '../../constants/messages';
|
||||||
|
|
||||||
// Styled
|
// Styled
|
||||||
import { StyledOperationTable } from './styled';
|
import { StyledOperationTable } from './styled';
|
||||||
@@ -34,9 +34,9 @@ import { updateRoomStatus } from '../../services/roomServices';
|
|||||||
import { checkOutUser } from '../../services/userServices';
|
import { checkOutUser } from '../../services/userServices';
|
||||||
|
|
||||||
interface IUserRow {
|
interface IUserRow {
|
||||||
user: TUser;
|
user: IUser;
|
||||||
openFormDialog: () => void;
|
openFormDialog: () => void;
|
||||||
setUser: Dispatch<SetStateAction<Nullable<TUser>>>;
|
setUser: Dispatch<SetStateAction<Nullable<IUser>>>;
|
||||||
reload: boolean;
|
reload: boolean;
|
||||||
setReload: Dispatch<SetStateAction<boolean>>;
|
setReload: Dispatch<SetStateAction<boolean>>;
|
||||||
}
|
}
|
||||||
@@ -48,12 +48,13 @@ const UserRow = ({
|
|||||||
reload,
|
reload,
|
||||||
setReload,
|
setReload,
|
||||||
}: IUserRow) => {
|
}: IUserRow) => {
|
||||||
const handleEdit = (user: TUser) => {
|
const handleEdit = (user: IUser) => {
|
||||||
setUser(user);
|
setUser(user);
|
||||||
openFormDialog();
|
openFormDialog();
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleCheckOut = async (user: TUser) => {
|
const handleCheckOut = async (user: IUser) => {
|
||||||
|
if(user.roomId !== 0) {
|
||||||
if (confirm(CONFIRM_MESSAGE)) {
|
if (confirm(CONFIRM_MESSAGE)) {
|
||||||
const resUpdateStatus = await updateRoomStatus(user.roomId, false);
|
const resUpdateStatus = await updateRoomStatus(user.roomId, false);
|
||||||
const resCheckoutUser = await checkOutUser(user);
|
const resCheckoutUser = await checkOutUser(user);
|
||||||
@@ -68,6 +69,10 @@ const UserRow = ({
|
|||||||
setReload(!reload);
|
setReload(!reload);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
toast.error(DENIED_ACTION);
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const { id, name, identifiedCode, phone, roomId } = user;
|
const { id, name, identifiedCode, phone, roomId } = user;
|
||||||
@@ -107,7 +112,7 @@ interface IUserTable {
|
|||||||
reload: boolean;
|
reload: boolean;
|
||||||
setReload: Dispatch<SetStateAction<boolean>>;
|
setReload: Dispatch<SetStateAction<boolean>>;
|
||||||
openFormDialog: () => void;
|
openFormDialog: () => void;
|
||||||
setUser?: Dispatch<SetStateAction<Nullable<TUser>>>;
|
setUser?: Dispatch<SetStateAction<Nullable<IUser>>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
const UserTable = ({
|
const UserTable = ({
|
||||||
@@ -116,7 +121,7 @@ const UserTable = ({
|
|||||||
openFormDialog,
|
openFormDialog,
|
||||||
setUser,
|
setUser,
|
||||||
}: IUserTable) => {
|
}: IUserTable) => {
|
||||||
const [users, setUsers] = useState<TUser[]>([]);
|
const [users, setUsers] = useState<IUser[]>([]);
|
||||||
const [phoneSearch, setPhoneSearch] = useState('');
|
const [phoneSearch, setPhoneSearch] = useState('');
|
||||||
const [searchParams] = useSearchParams();
|
const [searchParams] = useSearchParams();
|
||||||
const sortByValue = searchParams.get('sortBy')
|
const sortByValue = searchParams.get('sortBy')
|
||||||
@@ -172,9 +177,9 @@ const UserTable = ({
|
|||||||
<div>Phone</div>
|
<div>Phone</div>
|
||||||
<div>Room Id</div>
|
<div>Room Id</div>
|
||||||
</Table.Header>
|
</Table.Header>
|
||||||
<Table.Body<TUser>
|
<Table.Body<IUser>
|
||||||
data={users}
|
data={users}
|
||||||
render={(user: TUser) => (
|
render={(user: IUser) => (
|
||||||
<UserRow
|
<UserRow
|
||||||
user={user}
|
user={user}
|
||||||
key={user.id}
|
key={user.id}
|
||||||
|
|||||||
@@ -11,12 +11,12 @@ import UserDialog from './Dialog';
|
|||||||
|
|
||||||
// Types
|
// Types
|
||||||
import { Nullable } from '../../types/common';
|
import { Nullable } from '../../types/common';
|
||||||
import { TUser } from '../../types/user';
|
import { IUser } from '../../types/users';
|
||||||
|
|
||||||
const User = () => {
|
const User = () => {
|
||||||
const dialogRef = useRef<HTMLDialogElement>(null);
|
const dialogRef = useRef<HTMLDialogElement>(null);
|
||||||
const [reload, setReload] = useState(true);
|
const [reload, setReload] = useState(true);
|
||||||
const [user, setUser] = useState<Nullable<TUser>>(null);
|
const [user, setUser] = useState<Nullable<IUser>>(null);
|
||||||
const [isAdd, setIsAdd] = useState(false);
|
const [isAdd, setIsAdd] = useState(false);
|
||||||
|
|
||||||
const openFormDialog = (isAddForm: boolean = false) => {
|
const openFormDialog = (isAddForm: boolean = false) => {
|
||||||
|
|||||||
@@ -2,24 +2,24 @@ import toast from 'react-hot-toast';
|
|||||||
|
|
||||||
// Types
|
// Types
|
||||||
import { Nullable } from '../types/common';
|
import { Nullable } from '../types/common';
|
||||||
import { TRoom } from '../types/rooms';
|
import { IResponse } from '../types/responses';
|
||||||
import { TResponse } from '../types/response';
|
import { IRoom } from '../types/rooms';
|
||||||
|
|
||||||
// Helpers
|
// Helpers
|
||||||
import { sendRequest } from '../helpers/sendRequest';
|
import { sendRequest } from '../helpers/sendRequest';
|
||||||
|
import { errorMsg } from '../helpers/helper';
|
||||||
|
|
||||||
// Constants
|
// Constants
|
||||||
import { STATUS_CODE, RESPONSE_MESSAGE } from '../constants/responseStatus';
|
import { STATUS_CODE, RESPONSE_MESSAGE } from '../constants/responseStatus';
|
||||||
import { errorMsg } from '../constants/messages';
|
|
||||||
import { ROOM_PATH } from '../constants/path';
|
import { ROOM_PATH } from '../constants/path';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get all rooms from server
|
* Get all rooms from server
|
||||||
* @returns Return all rooms in server
|
* @returns Return all rooms in server
|
||||||
*/
|
*/
|
||||||
const getAllRoom = async (): Promise<Nullable<TRoom[]>> => {
|
const getAllRoom = async (): Promise<Nullable<IRoom[]>> => {
|
||||||
try {
|
try {
|
||||||
const response = await sendRequest<TRoom[]>(ROOM_PATH);
|
const response = await sendRequest<IRoom[]>(ROOM_PATH);
|
||||||
|
|
||||||
if (response.statusCode === STATUS_CODE.OK) {
|
if (response.statusCode === STATUS_CODE.OK) {
|
||||||
const rooms = response.data!;
|
const rooms = response.data!;
|
||||||
@@ -42,17 +42,17 @@ const getAllRoom = async (): Promise<Nullable<TRoom[]>> => {
|
|||||||
* @param roomId The id room need to be get
|
* @param roomId The id room need to be get
|
||||||
* @returns Return the room object depend on room id
|
* @returns Return the room object depend on room id
|
||||||
*/
|
*/
|
||||||
const getRoom = async (roomId: number): Promise<Nullable<TRoom>> => {
|
const getRoom = async (roomId: number): Promise<Nullable<IRoom>> => {
|
||||||
try {
|
try {
|
||||||
const response = await sendRequest<TRoom>(ROOM_PATH + '/' + roomId);
|
const response = await sendRequest<IRoom>(ROOM_PATH + '/' + roomId);
|
||||||
|
|
||||||
|
if (response.statusCode !== STATUS_CODE.OK) {
|
||||||
|
throw new Error(errorMsg(response.statusCode, response.msg));
|
||||||
|
}
|
||||||
|
|
||||||
if (response.statusCode === STATUS_CODE.OK) {
|
|
||||||
const rooms = response.data!;
|
const rooms = response.data!;
|
||||||
|
|
||||||
return rooms;
|
return rooms;
|
||||||
} else {
|
|
||||||
throw new Error(errorMsg(response.statusCode, response.msg));
|
|
||||||
}
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (error instanceof Error) {
|
if (error instanceof Error) {
|
||||||
toast.error(error.message);
|
toast.error(error.message);
|
||||||
@@ -67,18 +67,14 @@ const getRoom = async (roomId: number): Promise<Nullable<TRoom>> => {
|
|||||||
* @param room Room object need to be updated
|
* @param room Room object need to be updated
|
||||||
* @returns The response object
|
* @returns The response object
|
||||||
*/
|
*/
|
||||||
const updateRoom = async (room: TRoom): Promise<Nullable<TResponse<TRoom>>> => {
|
const updateRoom = async (room: IRoom): Promise<Nullable<IResponse<IRoom>>> => {
|
||||||
try {
|
try {
|
||||||
const response = await sendRequest<TRoom>(
|
const response = await sendRequest<IRoom>(
|
||||||
ROOM_PATH + '/' + room.id,
|
ROOM_PATH + '/' + room.id,
|
||||||
'PUT',
|
'PUT',
|
||||||
JSON.stringify(room)
|
JSON.stringify(room)
|
||||||
);
|
);
|
||||||
|
|
||||||
if (response.statusCode !== STATUS_CODE.OK) {
|
|
||||||
throw new Error(errorMsg(response.statusCode, response.msg));
|
|
||||||
}
|
|
||||||
|
|
||||||
return response;
|
return response;
|
||||||
} catch (error: unknown) {
|
} catch (error: unknown) {
|
||||||
if (error instanceof Error) {
|
if (error instanceof Error) {
|
||||||
@@ -100,9 +96,10 @@ const updateRoomStatus = async (
|
|||||||
roomId: number,
|
roomId: number,
|
||||||
status: boolean,
|
status: boolean,
|
||||||
roomIdNew?: number
|
roomIdNew?: number
|
||||||
): Promise<Nullable<TResponse<TRoom>>> => {
|
): Promise<Nullable<IResponse<IRoom>>> => {
|
||||||
|
try {
|
||||||
if (!roomIdNew) {
|
if (!roomIdNew) {
|
||||||
const response = await sendRequest<TRoom>(
|
const response = await sendRequest<IRoom>(
|
||||||
ROOM_PATH + '/' + roomId,
|
ROOM_PATH + '/' + roomId,
|
||||||
'PATCH',
|
'PATCH',
|
||||||
JSON.stringify({ status: status })
|
JSON.stringify({ status: status })
|
||||||
@@ -112,14 +109,14 @@ const updateRoomStatus = async (
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Update new room status
|
// Update new room status
|
||||||
const resNewRoom = await sendRequest<TRoom>(
|
const resNewRoom = await sendRequest<IRoom>(
|
||||||
ROOM_PATH + '/' + roomIdNew,
|
ROOM_PATH + '/' + roomIdNew,
|
||||||
'PATCH',
|
'PATCH',
|
||||||
JSON.stringify({ status: status })
|
JSON.stringify({ status: status })
|
||||||
);
|
);
|
||||||
|
|
||||||
// Update old room status;
|
// Update old room status;
|
||||||
const resOldRoom = await sendRequest<TRoom>(
|
const resOldRoom = await sendRequest<IRoom>(
|
||||||
ROOM_PATH + '/' + roomId,
|
ROOM_PATH + '/' + roomId,
|
||||||
'PATCH',
|
'PATCH',
|
||||||
JSON.stringify({ status: !status })
|
JSON.stringify({ status: !status })
|
||||||
@@ -134,11 +131,43 @@ const updateRoomStatus = async (
|
|||||||
msg: RESPONSE_MESSAGE.UPDATE_SUCCESS,
|
msg: RESPONSE_MESSAGE.UPDATE_SUCCESS,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
} catch (error) {
|
||||||
|
if (error instanceof Error) {
|
||||||
|
toast.error(error.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return null;
|
||||||
statusCode: STATUS_CODE.INTERNAL_SERVER_ERROR,
|
|
||||||
msg: 'Something went wrong!',
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export { getRoom, updateRoom, updateRoomStatus, getAllRoom };
|
/**
|
||||||
|
* Add room to server
|
||||||
|
* @param room The room object need to be add
|
||||||
|
* @returns The response object if complete or null
|
||||||
|
*/
|
||||||
|
const addRoom = async (room: IRoom): Promise<Nullable<IResponse<IRoom>>> => {
|
||||||
|
try {
|
||||||
|
// Set default status room
|
||||||
|
room.status = false;
|
||||||
|
|
||||||
|
const response = await sendRequest<IRoom>(
|
||||||
|
ROOM_PATH,
|
||||||
|
'POST',
|
||||||
|
JSON.stringify(room)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (response.statusCode !== STATUS_CODE.CREATE) {
|
||||||
|
throw new Error(errorMsg(response.statusCode, response.msg));
|
||||||
|
}
|
||||||
|
|
||||||
|
return response;
|
||||||
|
} catch (error: unknown) {
|
||||||
|
if (error instanceof Error) {
|
||||||
|
toast.error(error.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
|
export { getRoom, updateRoom, updateRoomStatus, getAllRoom, addRoom };
|
||||||
|
|||||||
@@ -1,21 +1,53 @@
|
|||||||
import toast from 'react-hot-toast';
|
import toast from 'react-hot-toast';
|
||||||
|
|
||||||
// Constants
|
// Constants
|
||||||
import { errorMsg } from '../constants/messages';
|
|
||||||
import { USER_PATH } from '../constants/path';
|
import { USER_PATH } from '../constants/path';
|
||||||
import { STATUS_CODE } from '../constants/responseStatus';
|
import { STATUS_CODE } from '../constants/responseStatus';
|
||||||
|
|
||||||
// Types
|
// Types
|
||||||
import { Nullable } from '../types/common';
|
import { Nullable } from '../types/common';
|
||||||
import { TUser } from '../types/user';
|
import { IResponse } from '../types/responses';
|
||||||
import { TResponse } from '../types/response';
|
import { IUser } from '../types/users';
|
||||||
|
|
||||||
// Helpers
|
// Helpers
|
||||||
import { sendRequest } from '../helpers/sendRequest';
|
import { sendRequest } from '../helpers/sendRequest';
|
||||||
|
import { errorMsg } from '../helpers/helper';
|
||||||
|
|
||||||
const updateUser = async (user: TUser): Promise<Nullable<TResponse<TUser>>> => {
|
/**
|
||||||
|
* Create user to the server
|
||||||
|
* @param user The user object need to be created
|
||||||
|
* @returns The IResponse object if success or null
|
||||||
|
*/
|
||||||
|
const createUser = async (user: IUser): Promise<Nullable<IResponse<IUser>>> => {
|
||||||
try {
|
try {
|
||||||
const response = await sendRequest<TUser>(
|
const response = await sendRequest<IUser>(
|
||||||
|
USER_PATH,
|
||||||
|
'POST',
|
||||||
|
JSON.stringify(user)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (response.statusCode !== STATUS_CODE.CREATE) {
|
||||||
|
throw new Error(errorMsg(response.statusCode, response.msg));
|
||||||
|
}
|
||||||
|
|
||||||
|
return response;
|
||||||
|
} catch (error: unknown) {
|
||||||
|
if (error instanceof Error) {
|
||||||
|
toast.error(error.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the user to the server
|
||||||
|
* @param user The user object need to be updated
|
||||||
|
* @returns The IResponse object if update success or null
|
||||||
|
*/
|
||||||
|
const updateUser = async (user: IUser): Promise<Nullable<IResponse<IUser>>> => {
|
||||||
|
try {
|
||||||
|
const response = await sendRequest<IUser>(
|
||||||
USER_PATH + '/' + user.id,
|
USER_PATH + '/' + user.id,
|
||||||
'PUT',
|
'PUT',
|
||||||
JSON.stringify(user)
|
JSON.stringify(user)
|
||||||
@@ -35,7 +67,12 @@ const updateUser = async (user: TUser): Promise<Nullable<TResponse<TUser>>> => {
|
|||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
|
|
||||||
const checkOutUser = async (user: TUser): Promise<Nullable<TResponse<TUser>>> => {
|
/**
|
||||||
|
* Checkout user
|
||||||
|
* @param user The user need to be checkout
|
||||||
|
* @returns The IResponse object if checkout success or not
|
||||||
|
*/
|
||||||
|
const checkOutUser = async (user: IUser): Promise<Nullable<IResponse<IUser>>> => {
|
||||||
const tempUser = user;
|
const tempUser = user;
|
||||||
|
|
||||||
if (tempUser) {
|
if (tempUser) {
|
||||||
@@ -48,4 +85,4 @@ const checkOutUser = async (user: TUser): Promise<Nullable<TResponse<TUser>>> =>
|
|||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
|
|
||||||
export { updateUser, checkOutUser };
|
export { updateUser, checkOutUser, createUser };
|
||||||
|
|||||||
@@ -1,7 +0,0 @@
|
|||||||
type TResponse<T> = {
|
|
||||||
statusCode: number;
|
|
||||||
msg: string;
|
|
||||||
data?: T;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type { TResponse };
|
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
interface IResponse<T> {
|
||||||
|
statusCode: number;
|
||||||
|
msg: string;
|
||||||
|
data?: T;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type { IResponse };
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
type TRoom = {
|
interface IRoom {
|
||||||
id: number;
|
id: number;
|
||||||
name: string;
|
name: string;
|
||||||
price: number;
|
price: number;
|
||||||
discount: number;
|
discount: number;
|
||||||
finalPrice: number;
|
finalPrice: number;
|
||||||
status: boolean;
|
status: boolean;
|
||||||
};
|
}
|
||||||
|
|
||||||
export type { TRoom };
|
export type { IRoom };
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
type TUser = {
|
interface IUser {
|
||||||
id: number;
|
id: number;
|
||||||
name: string;
|
name: string;
|
||||||
identifiedCode: string;
|
identifiedCode: string;
|
||||||
phone: string;
|
phone: string;
|
||||||
roomId: number;
|
roomId: number;
|
||||||
};
|
}
|
||||||
|
|
||||||
export type { TUser };
|
export type { IUser };
|
||||||
Reference in New Issue
Block a user