Refactor code

This commit is contained in:
2023-11-02 23:24:03 +07:00
parent cc147f071c
commit 6560c304c3
28 changed files with 163 additions and 157 deletions
+3 -3
View File
@@ -6,7 +6,7 @@
- Introduce: Build a hotel management web application using HTML5, CSS3, Typescript, json-server, React and compile by Vite. - Introduce: Build a hotel management web application using HTML5, CSS3, Typescript, json-server, React and compile by Vite.
- Plan: [Link](https://docs.google.com/document/d/1t2kx17iGCceEe3EbaKO6-3g70ejOJ1PAu9u3KXSKWi4/edit?usp=sharing) - Plan: [Link](https://docs.google.com/document/d/1t2kx17iGCceEe3EbaKO6-3g70ejOJ1PAu9u3KXSKWi4/edit?usp=sharing)
- Deploy: _Update later_ - Deploy: [Link](https://hotel-management.loiphan.com/)
## Requirements ## Requirements
@@ -31,7 +31,7 @@
## Technical ## Technical
- [HTML5](https://www.tutorialspoint.com/html5/html5_overview.htm): CSS (Cascading Style Sheets) consist of a group of formatting rules that you use to control the layout and appearance of the content on a web page. - [HTML5](https://www.tutorialspoint.com/html5/html5_overview.htm): HTML5 is the latest standard of Hypertext Markup Language, the code that describes the structure and presentation of web pages.
- [CSS3](https://www.htmlgoodies.com/html5/an-overview-of-css3/): Cascading Style Sheets (CSS) is a language used to illustrate a documents look, style, and format in any markup language. In simple words, it is used to style and organize the layout of Web pages. CSS3 is the latest version of an earlier CSS version, CSS2. - [CSS3](https://www.htmlgoodies.com/html5/an-overview-of-css3/): Cascading Style Sheets (CSS) is a language used to illustrate a documents look, style, and format in any markup language. In simple words, it is used to style and organize the layout of Web pages. CSS3 is the latest version of an earlier CSS version, CSS2.
- [Typescript](https://www.typescriptlang.org/): TypeScript is a strongly typed programming language that builds on JavaScript, giving you better tooling at any scale. - [Typescript](https://www.typescriptlang.org/): TypeScript is a strongly typed programming language that builds on JavaScript, giving you better tooling at any scale.
- [React](https://react.dev/): React is a framework that employs Webpack to automatically compile React, JSX, and ES6 code while handling CSS file prefixes. React is a JavaScript-based UI development library. Although React is a library rather than a language, it is widely used in web development. - [React](https://react.dev/): React is a framework that employs Webpack to automatically compile React, JSX, and ES6 code while handling CSS file prefixes. React is a JavaScript-based UI development library. Although React is a library rather than a language, it is widely used in web development.
@@ -42,7 +42,7 @@
- Timeline: - Timeline:
- Estimate: 11 days - Estimate: 11 days
- Actual: -- days. - Actual: 13 days.
- Calendar: - Calendar:
- Start: 2023/10/16 - Start: 2023/10/16
- End: 2023/10/30 - End: 2023/10/30
@@ -10,8 +10,8 @@ import { Main, StyledAppLayout } from './styled';
const AppLayout = () => { const AppLayout = () => {
return ( return (
<StyledAppLayout> <StyledAppLayout>
<Header /> <Header accountName='Admin'/>
<Sidebar /> <Sidebar heading='Hotel Management'/>
<Main> <Main>
<Outlet /> <Outlet />
</Main> </Main>
@@ -1,11 +1,19 @@
import { forwardRef } from 'react'; import { forwardRef } from 'react';
// Components
import { IDialogProps } from '../../globals/interfaces';
// Styled // Styled
import { StyledBody, StyledDialog, StyledTitle } from './styled'; import { StyledBody, StyledDialog, StyledTitle } from './styled';
export interface IDialogProps<T> {
title?: string;
children?: JSX.Element[] | JSX.Element;
onClose?: () => void;
reload?: boolean;
setReload?: React.Dispatch<React.SetStateAction<boolean>>;
ref?: React.MutableRefObject<HTMLDialogElement | undefined>;
data?: T | null;
isAdd?: boolean;
}
const Dialog = forwardRef((props, ref) => { const Dialog = forwardRef((props, ref) => {
const { title, children, onClose } = props as IDialogProps<unknown>; const { title, children, onClose } = props as IDialogProps<unknown>;
return ( return (
@@ -4,10 +4,14 @@ import HeaderMenu from '../HeaderMenu';
// Styled // Styled
import { StyledHeader } from './styled'; import { StyledHeader } from './styled';
const Header = () => { interface IHeader {
accountName: string
}
const Header = ({accountName}: IHeader) => {
return ( return (
<StyledHeader> <StyledHeader>
<p>Hi, Admin!</p> <p>Hi, {accountName}!</p>
<HeaderMenu /> <HeaderMenu />
</StyledHeader> </StyledHeader>
); );
@@ -5,12 +5,15 @@ import { HiEllipsisVertical } from 'react-icons/hi2';
import { useOutsideClick } from '../../hooks/useOutsideClick'; import { useOutsideClick } from '../../hooks/useOutsideClick';
import { StyledMenu, StyledButton, StyledList, StyledToggle } from './styled'; import { StyledMenu, StyledButton, StyledList, StyledToggle } from './styled';
// Interfaces
import { IButton } from '../../globals/interfaces';
// Contexts // Contexts
import MenusContext from '../../contexts/MenuContext'; import MenusContext from '../../contexts/MenuContext';
interface IButton {
children?: string;
icon?: JSX.Element;
onClick?: () => void;
}
const Menus = ({ children }: { children: JSX.Element }) => { const Menus = ({ children }: { children: JSX.Element }) => {
const [openId, setOpenId] = useState(''); const [openId, setOpenId] = useState('');
@@ -30,7 +33,6 @@ const Toggle = ({ id }: { id: string }): React.JSX.Element => {
const handleClick = (e: React.MouseEvent<HTMLButtonElement, MouseEvent>) => { const handleClick = (e: React.MouseEvent<HTMLButtonElement, MouseEvent>) => {
e.stopPropagation(); e.stopPropagation();
// prettier-ignore
openId === '' || openId !== id openId === '' || openId !== id
? open!(id) ? open!(id)
: close!(); : close!();
@@ -6,18 +6,21 @@ import { BsHouseDoorFill } from 'react-icons/bs';
// Styled // Styled
import { StyledNav, StyledNavLink } from './styled'; import { StyledNav, StyledNavLink } from './styled';
// Constants
import { DASHBOARD, ROOM, USER } from '../../constants/path';
const Nav = () => { const Nav = () => {
return ( return (
<StyledNav> <StyledNav>
<StyledNavLink to={'/dashboard'}> <StyledNavLink to={DASHBOARD}>
<MdSpaceDashboard /> <MdSpaceDashboard />
<span>Dashboard</span> <span>Dashboard</span>
</StyledNavLink> </StyledNavLink>
<StyledNavLink to={'/user'}> <StyledNavLink to={USER}>
<HiUsers /> <HiUsers />
<span>User</span> <span>User</span>
</StyledNavLink> </StyledNavLink>
<StyledNavLink to={'/room'}> <StyledNavLink to={ROOM}>
<BsHouseDoorFill /> <BsHouseDoorFill />
<span>Room</span> <span>Room</span>
</StyledNavLink> </StyledNavLink>
@@ -1,6 +1,9 @@
import { ISelectOptions } from '../../globals/interfaces';
import { StyledSelect } from './styled'; import { StyledSelect } from './styled';
export interface ISelectOptions {
value: string;
label: string;
}
interface ISelect { interface ISelect {
options: ISelectOptions[]; options: ISelectOptions[];
value: string; value: string;
@@ -4,10 +4,14 @@ import Nav from '../Nav';
// Styled // Styled
import { Heading, StyledSidebar } from './styled'; import { Heading, StyledSidebar } from './styled';
const Sidebar = () => { interface ISidebar {
heading: string;
}
const Sidebar = ({heading}: ISidebar) => {
return ( return (
<StyledSidebar> <StyledSidebar>
<Heading>Hotel Management</Heading> <Heading>{heading}</Heading>
<Nav /> <Nav />
</StyledSidebar> </StyledSidebar>
); );
@@ -1,8 +1,8 @@
import { useSearchParams } from 'react-router-dom'; import { useSearchParams } from 'react-router-dom';
import { memo } from 'react';
// Components // Components
import Select from '../Select'; import Select from '../Select';
import { memo } from 'react';
interface ISortByProps { interface ISortByProps {
options: { options: {
@@ -3,24 +3,31 @@ import { ReactNode, useContext } from 'react';
// Components // Components
import { StyledBody, StyledHeader, StyledRow, StyledTable } from './styled'; import { StyledBody, StyledHeader, StyledRow, StyledTable } from './styled';
// Interfaces
import { ITable, ITableBody } from '../../globals/interfaces';
// Contexts // Contexts
import TableContext from '../../contexts/TableContext'; import TableContext from '../../contexts/TableContext';
interface ITable {
columns?: string;
children: React.ReactNode;
}
interface ITableBody<T> {
data?: T[];
render?: (value: T) => JSX.Element;
}
type CallbackMapFunc<T> = (value: T, index: number, array: T[]) => ReactNode; type CallbackMapFunc<T> = (value: T, index: number, array: T[]) => ReactNode;
const Table = ({ columns, children }: ITable) => { const Table = ({ columns, children }: ITable) => {
return ( return (
<TableContext.Provider value={columns!}> <TableContext.Provider value={{ columns }}>
<StyledTable>{children}</StyledTable> <StyledTable>{children}</StyledTable>
</TableContext.Provider> </TableContext.Provider>
); );
}; };
const Header = ({ children }: ITable) => { const Header = ({ children }: ITable) => {
const columns = useContext(TableContext); const { columns } = useContext(TableContext);
return <StyledHeader columns={columns}>{children}</StyledHeader>; return <StyledHeader columns={columns}>{children}</StyledHeader>;
}; };
@@ -33,7 +40,7 @@ const Body = <T,>({ data, render }: ITableBody<T>) => {
}; };
const Row = ({ children }: ITable) => { const Row = ({ children }: ITable) => {
const columns = useContext(TableContext); const { columns } = useContext(TableContext);
return <StyledRow columns={columns}>{children}</StyledRow>; return <StyledRow columns={columns}>{children}</StyledRow>;
}; };
+36 -16
View File
@@ -1,26 +1,46 @@
import { Toaster } from 'react-hot-toast'; import { DefaultToastOptions, ToastOptions, ToastPosition, Toaster } from 'react-hot-toast';
import { CSSProperties } from 'styled-components';
const Toast = () => { interface IToast {
position: ToastPosition;
gutter: number;
containerStyle: CSSProperties;
toastOptions: DefaultToastOptions;
success: ToastOptions;
error: ToastOptions;
style: CSSProperties | undefined;
}
const Toast = ({position, gutter, containerStyle, success, error, style}: IToast) => {
return ( return (
<Toaster <Toaster
position="top-center" position={position}
gutter={12} gutter={gutter}
containerStyle={{ margin: '8px', zIndex: 1 }} containerStyle={containerStyle}
toastOptions={{ toastOptions={{
success: { success,
duration: 3000, error,
}, style
error: {
duration: 5000,
},
style: {
fontSize: '16px',
maxWidth: '500px',
padding: '16px 24px',
},
}} }}
/> />
); );
}; };
Toast.defaultProps = {
position: "top-center",
gutter: 12,
containerStyle: { margin: '8px', zIndex: 1 },
success: {
duration: 3000,
},
error:{
duration: 5000,
},
style: {
fontSize: '16px',
maxWidth: '500px',
padding: '16px 24px',
}
}
export default Toast; export default Toast;
+5 -5
View File
@@ -1,7 +1,7 @@
export const DASHBOARD: string = '/dashboard'; export const DASHBOARD = '/dashboard';
export const USER: string = '/user'; export const USER = '/user';
export const ROOM: string = '/room'; export const ROOM = '/room';
export const OTHER_PATH: string = '*'; export const OTHER_PATH = '*';
export const BASE_URL: string = 'https://hotel-management-api.loiphan.com/'; export const BASE_URL = 'https://hotel-management-api.loiphan.com/';
export const USER_PATH = 'users'; export const USER_PATH = 'users';
export const ROOM_PATH = 'rooms'; export const ROOM_PATH = 'rooms';
+10 -1
View File
@@ -74,7 +74,16 @@ const ROOM_PAGE = {
], ],
} }
const INITIAL_STATE_SCHEMA = {
id: '',
name: '',
identifiedCode: '',
phone: '',
roomId: 'undefined',
address: '',
};
const VALUE = 'value'; const VALUE = 'value';
const ERROR = 'error'; const ERROR = 'error';
export { USER_PAGE, ROOM_PAGE, VALUE, ERROR }; export { USER_PAGE, ROOM_PAGE, VALUE, ERROR, INITIAL_STATE_SCHEMA };
+5 -2
View File
@@ -1,7 +1,10 @@
import { createContext } from 'react'; import { createContext } from 'react';
// Interfaces interface IMenusContext {
import { IMenusContext } from '../globals/interfaces'; openId?: string;
close?: () => void;
open?: React.Dispatch<React.SetStateAction<string>>;
}
const MenusContext = createContext<IMenusContext>({}); const MenusContext = createContext<IMenusContext>({});
@@ -1,5 +1,9 @@
import { createContext } from 'react'; import { createContext } from 'react';
const TableContext = createContext(''); interface ITableContext {
columns?: string;
}
const TableContext = createContext<ITableContext>({});
export default TableContext; export default TableContext;
@@ -1,46 +0,0 @@
interface IMenusContext {
openId?: string;
close?: () => void;
open?: React.Dispatch<React.SetStateAction<string>>;
}
interface IButton {
children?: string;
icon?: JSX.Element;
onClick?: () => void;
}
interface ITable {
columns?: string;
children: React.ReactNode;
}
interface ITableBody<T> {
data?: T[];
render?: (value: T) => JSX.Element;
}
interface ISelectOptions {
value: string;
label: string;
}
interface IDialogProps<T> {
title?: string;
children?: JSX.Element[] | JSX.Element;
onClose?: () => void;
reload?: boolean;
setReload?: React.Dispatch<React.SetStateAction<boolean>>;
ref?: React.MutableRefObject<HTMLDialogElement | undefined>;
data?: T | null;
isAdd?: boolean;
}
export type {
IMenusContext,
IButton,
ITable,
ITableBody,
IDialogProps,
ISelectOptions,
};
+1 -1
View File
@@ -124,7 +124,7 @@ const searchQuery = (
columnSearch: string, columnSearch: string,
keySearch: string, keySearch: string,
sort: string, sort: string,
order: string, order: string
) => { ) => {
// prettier-ignore // prettier-ignore
const phoneParams = keySearch const phoneParams = keySearch
@@ -13,7 +13,6 @@ const isValidNumber = (value: string): boolean => {
* @returns A boolean indicating whether or not the argument has valid * @returns A boolean indicating whether or not the argument has valid
*/ */
const isValidDiscount = (value: string): boolean => { const isValidDiscount = (value: string): boolean => {
console.log(Boolean(+value >= 0 && +value <= 100));
return +value >= 0 && +value <= 100; return +value >= 0 && +value <= 100;
}; };
+3 -3
View File
@@ -8,7 +8,7 @@ import { DEFAULT_ORDER_BY, DEFAULT_SORT_BY } from '../constants/config';
import { searchQuery } from '../helpers/utils'; import { searchQuery } from '../helpers/utils';
/** /**
* * The function use to fetch data on server API.
* @param path The path of url * @param path The path of url
* @param columnSearch Column need to search * @param columnSearch Column need to search
* @param keyWord The key word to search * @param keyWord The key word to search
@@ -23,7 +23,7 @@ const useFetch = (
keyWord: string = '', keyWord: string = '',
tempSortBy?: string, tempSortBy?: string,
tempOrderBy?: string, tempOrderBy?: string,
reload?: boolean, reload?: boolean
) => { ) => {
const [data, setData] = useState(null); const [data, setData] = useState(null);
const [isPending, setIsPending] = useState(false); const [isPending, setIsPending] = useState(false);
@@ -56,7 +56,7 @@ const useFetch = (
if (!response.ok) if (!response.ok)
throw new Error( throw new Error(
`Error code: ${response.status} \n Messages: ${response.statusText}`, `Error code: ${response.status} \n Messages: ${response.statusText}`
); );
setIsPending(false); setIsPending(false);
+16 -15
View File
@@ -7,7 +7,7 @@ import { getPropValues, isObject, isRequired } from '../helpers/utils';
import { TKeyValue, TValidator } from '../globals/types'; import { TKeyValue, TValidator } from '../globals/types';
// Constants // Constants
import { ERROR, VALUE } from '../constants/variables'; import { ERROR, INITIAL_STATE_SCHEMA, VALUE } from '../constants/variables';
/** /**
* Custom hooks to validate your Form... * Custom hooks to validate your Form...
@@ -21,11 +21,11 @@ const useForm = (
stateSchema = {}, stateSchema = {},
stateValidatorSchema = {} as TValidator, stateValidatorSchema = {} as TValidator,
submitFormCallback: (values: TKeyValue) => void, submitFormCallback: (values: TKeyValue) => void,
initialValue: string = '', initialValue: string = ''
) => { ) => {
const [values, setValues] = useState(getPropValues(stateSchema, VALUE)); const [values, setValues] = useState<TKeyValue>(INITIAL_STATE_SCHEMA);
const [errors, setErrors] = useState(getPropValues(stateSchema, ERROR)); const [errors, setErrors] = useState(getPropValues(stateSchema, ERROR));
const [dirty, setDirty] = useState(getPropValues(stateSchema)); const [valid, isValid] = useState(getPropValues(stateSchema));
const [disable, setDisable] = useState(true); const [disable, setDisable] = useState(true);
const [isDirty, setIsDirty] = useState(false); const [isDirty, setIsDirty] = useState(false);
@@ -33,7 +33,8 @@ const useForm = (
useEffect(() => { useEffect(() => {
setInitialErrorState(initialValue); setInitialErrorState(initialValue);
setDisable(true); setDisable(true);
setDirty(getPropValues(stateSchema)); isValid(getPropValues(stateSchema));
setValues(getPropValues(stateSchema, VALUE));
// If initial value true, setValues again from stateSchema // If initial value true, setValues again from stateSchema
// and enabled button // and enabled button
@@ -56,7 +57,7 @@ const useForm = (
let error = ''; let error = '';
// Skip check id field // Skip check id field
if (name !== 'id') { if (name !== 'id' && name !== 'roomId') {
error = isRequired(value, field!.required); error = isRequired(value, field!.required);
if (isObject(field['validator']) && error === '') { if (isObject(field['validator']) && error === '') {
@@ -72,7 +73,7 @@ const useForm = (
return error; return error;
}, },
[stateValidatorSchema], [stateValidatorSchema]
); );
// Set Initial Error State // Set Initial Error State
@@ -85,10 +86,10 @@ const useForm = (
[name]: !initialValue // Skip error when initialValue have values [name]: !initialValue // Skip error when initialValue have values
? validateFormFields(name, values[name] as string) ? validateFormFields(name, values[name] as string)
: '', : '',
})), }))
); );
}, },
[errors, values, validateFormFields], [errors, values, validateFormFields]
); );
// Used to disable submit button if there's a value in errors // Used to disable submit button if there's a value in errors
@@ -97,7 +98,7 @@ const useForm = (
// in every re-render in component // in every re-render in component
const validateErrorState = useCallback( const validateErrorState = useCallback(
() => Object.values(errors).some((error) => error), () => Object.values(errors).some((error) => error),
[errors], [errors]
); );
// For every changed in our state this will be fired // For every changed in our state this will be fired
@@ -113,7 +114,7 @@ const useForm = (
( (
event: ChangeEvent< event: ChangeEvent<
HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement
>, >
) => { ) => {
setIsDirty(true); setIsDirty(true);
@@ -133,9 +134,9 @@ const useForm = (
setValues((prevState) => ({ ...prevState, [name]: value })); setValues((prevState) => ({ ...prevState, [name]: value }));
setErrors((prevState) => ({ ...prevState, [name]: error })); setErrors((prevState) => ({ ...prevState, [name]: error }));
setDirty((prevState) => ({ ...prevState, [name]: true })); isValid((prevState) => ({ ...prevState, [name]: true }));
}, },
[validateFormFields], [validateFormFields]
); );
const handleOnSubmit = useCallback( const handleOnSubmit = useCallback(
@@ -151,7 +152,7 @@ const useForm = (
setDisable(true); setDisable(true);
} }
}, },
[validateErrorState, submitFormCallback, values], [validateErrorState, submitFormCallback, values]
); );
return { return {
@@ -162,7 +163,7 @@ const useForm = (
disable, disable,
setValues, setValues,
setErrors, setErrors,
dirty, valid,
}; };
}; };
+1 -4
View File
@@ -1,12 +1,9 @@
import { forwardRef, useEffect } from 'react'; import { forwardRef, useEffect } from 'react';
// Components // Components
import Dialog from '../../components/Dialog'; import Dialog, { IDialogProps } from '../../components/Dialog';
import RoomForm from './Form'; import RoomForm from './Form';
// Interfaces
import { IDialogProps } from '../../globals/interfaces';
// Types // Types
import { TRoom } from '../../globals/types'; import { TRoom } from '../../globals/types';
+9 -9
View File
@@ -8,7 +8,7 @@ import TextArea from '../../commons/styles/TextArea.ts';
// Components // Components
import Form from '../../components/Form/index.tsx'; import Form from '../../components/Form/index.tsx';
import FormRow from '../../components/FormRow/index.tsx'; import FormRow from '../../components/LabelControl/index.tsx';
import Button from '../../commons/styles/Button.ts'; import Button from '../../commons/styles/Button.ts';
// Types // Types
@@ -170,7 +170,7 @@ const RoomForm = ({
const response = await sendRequest( const response = await sendRequest(
ROOM_PATH, ROOM_PATH,
JSON.stringify(data), JSON.stringify(data),
'POST', 'POST'
); );
if (response.statusCode === STATUS_CODE.CREATE) { if (response.statusCode === STATUS_CODE.CREATE) {
@@ -185,7 +185,7 @@ const RoomForm = ({
const response = await sendRequest( const response = await sendRequest(
ROOM_PATH + `/${room!.id}`, ROOM_PATH + `/${room!.id}`,
JSON.stringify(data), JSON.stringify(data),
'PUT', 'PUT'
); );
if (response.statusCode == STATUS_CODE.OK) { if (response.statusCode == STATUS_CODE.OK) {
@@ -215,7 +215,7 @@ const RoomForm = ({
const { const {
values, values,
errors, errors,
dirty, valid,
handleOnChange, handleOnChange,
handleOnSubmit, handleOnSubmit,
disable } = disable } =
@@ -257,7 +257,7 @@ const RoomForm = ({
label="Name" label="Name"
error={ error={
// prettier-ignore // prettier-ignore
errors.name && dirty.name errors.name && valid.name
? (errors.name as string) ? (errors.name as string)
: '' : ''
} }
@@ -274,7 +274,7 @@ const RoomForm = ({
label="Amount" label="Amount"
// prettier-ignore // prettier-ignore
error={ error={
errors.amount && dirty.amount errors.amount && valid.amount
? (errors.amount as string) ? (errors.amount as string)
: '' : ''
} }
@@ -291,7 +291,7 @@ const RoomForm = ({
label="Price" label="Price"
error={ error={
// prettier-ignore // prettier-ignore
errors.price && dirty.price errors.price && valid.price
? (errors.price as string) ? (errors.price as string)
: '' : ''
} }
@@ -308,7 +308,7 @@ const RoomForm = ({
label="Discount" label="Discount"
error={ error={
// prettier-ignore // prettier-ignore
errors.discount && dirty.discount errors.discount && valid.discount
? (errors.discount as string) ? (errors.discount as string)
: '' : ''
} }
@@ -334,7 +334,7 @@ const RoomForm = ({
label="Description" label="Description"
error={ error={
// prettier-ignore // prettier-ignore
errors.description && dirty.description errors.description && valid.description
? (errors.description as string) ? (errors.description as string)
: '' : ''
} }
+1 -1
View File
@@ -6,7 +6,7 @@ import toast from 'react-hot-toast';
import { HiSquare2Stack } from 'react-icons/hi2'; import { HiSquare2Stack } from 'react-icons/hi2';
import { HiTrash } from 'react-icons/hi'; import { HiTrash } from 'react-icons/hi';
import { StyledOperationTable } from './styled'; import { StyledOperationTable } from './styled';
import Menus from '../../components/Menus/Menus'; import Menus from '../../components/Menus';
import Table from '../../components/Table'; import Table from '../../components/Table';
import Direction from '../../commons/styles/Direction'; import Direction from '../../commons/styles/Direction';
import Message from '../../components/Message'; import Message from '../../components/Message';
+1 -4
View File
@@ -1,12 +1,9 @@
import { forwardRef, useEffect } from 'react'; import { forwardRef, useEffect } from 'react';
// Components // Components
import Dialog from '../../components/Dialog'; import Dialog, { IDialogProps } from '../../components/Dialog';
import UserForm from './Form'; import UserForm from './Form';
// Interfaces
import { IDialogProps } from '../../globals/interfaces';
// Types // Types
import { TUser } from '../../globals/types'; import { TUser } from '../../globals/types';
+11 -20
View File
@@ -8,7 +8,7 @@ import TextArea from '../../commons/styles/TextArea';
// Components // Components
import Form from '../../components/Form'; import Form from '../../components/Form';
import FormRow from '../../components/FormRow'; import FormRow from '../../components/LabelControl/index.tsx';
import Button from '../../commons/styles/Button.ts'; import Button from '../../commons/styles/Button.ts';
// Types // Types
@@ -39,12 +39,9 @@ import {
errorMsg, errorMsg,
} from '../../constants/messages.ts'; } from '../../constants/messages.ts';
import { USER_PATH } from '../../constants/path.ts'; import { USER_PATH } from '../../constants/path.ts';
import Select from '../../components/Select/index.tsx'; import Select, { ISelectOptions } from '../../components/Select/index.tsx';
import { useFetch } from '../../hooks/useFetch.ts'; import { useFetch } from '../../hooks/useFetch.ts';
// Interfaces
import { ISelectOptions } from '../../globals/interfaces.ts';
const FormBtn = styled(Button)` const FormBtn = styled(Button)`
width: 100%; width: 100%;
@@ -130,7 +127,7 @@ const UserForm = ({
error: '', error: '',
}, },
roomId: { roomId: {
value: roomIdValue || '', value: roomIdValue || '' + (options && options[0].value),
error: '' , error: '' ,
}, },
address: { address: {
@@ -181,7 +178,7 @@ const UserForm = ({
const response = await sendRequest( const response = await sendRequest(
USER_PATH, USER_PATH,
JSON.stringify(data), JSON.stringify(data),
'POST', 'POST'
); );
if (response.statusCode === STATUS_CODE.CREATE) { if (response.statusCode === STATUS_CODE.CREATE) {
@@ -196,7 +193,7 @@ const UserForm = ({
const response = await sendRequest( const response = await sendRequest(
USER_PATH + `/${user!.id}`, USER_PATH + `/${user!.id}`,
JSON.stringify(data), JSON.stringify(data),
'PUT', 'PUT'
); );
if (response.statusCode == STATUS_CODE.OK) { if (response.statusCode == STATUS_CODE.OK) {
@@ -226,7 +223,7 @@ const UserForm = ({
const { const {
values, values,
errors, errors,
dirty, valid,
handleOnChange, handleOnChange,
handleOnSubmit, handleOnSubmit,
disable } = disable } =
@@ -266,7 +263,7 @@ const UserForm = ({
label="Full Name" label="Full Name"
error={ error={
// prettier-ignore // prettier-ignore
errors.name && dirty.name errors.name && valid.name
? (errors.name as string) ? (errors.name as string)
: '' : ''
} }
@@ -282,7 +279,7 @@ const UserForm = ({
<FormRow <FormRow
label="Identified Code" label="Identified Code"
error={ error={
errors.identifiedCode && dirty.identifiedCode errors.identifiedCode && valid.identifiedCode
? (errors.identifiedCode as string) ? (errors.identifiedCode as string)
: '' : ''
} }
@@ -299,7 +296,7 @@ const UserForm = ({
label="Phone" label="Phone"
error={ error={
// prettier-ignore // prettier-ignore
errors.phone && dirty.phone errors.phone && valid.phone
? (errors.phone as string) ? (errors.phone as string)
: '' : ''
} }
@@ -316,17 +313,11 @@ const UserForm = ({
label="Room" label="Room"
error={ error={
// prettier-ignore // prettier-ignore
errors.roomId && dirty.roomId errors.roomId && valid.roomId
? (errors.roomId as string) ? (errors.roomId as string)
: '' : ''
} }
> >
{/* <Input
type="text"
name="roomId"
value={roomId as string}
onChange={handleOnChange}
/> */}
<Select <Select
name="roomId" name="roomId"
value={roomId as string} value={roomId as string}
@@ -339,7 +330,7 @@ const UserForm = ({
label="Address" label="Address"
error={ error={
// prettier-ignore // prettier-ignore
errors.address && dirty.address errors.address && valid.address
? (errors.address as string) ? (errors.address as string)
: '' : ''
} }
+1 -1
View File
@@ -6,7 +6,7 @@ import toast from 'react-hot-toast';
import { HiSquare2Stack } from 'react-icons/hi2'; import { HiSquare2Stack } from 'react-icons/hi2';
import { HiTrash } from 'react-icons/hi'; import { HiTrash } from 'react-icons/hi';
import { StyledOperationTable } from './styled'; import { StyledOperationTable } from './styled';
import Menus from '../../components/Menus/Menus'; import Menus from '../../components/Menus';
import Table from '../../components/Table'; import Table from '../../components/Table';
import Direction from '../../commons/styles/Direction'; import Direction from '../../commons/styles/Direction';
import Message from '../../components/Message'; import Message from '../../components/Message';