mirror of
https://github.com/Nezumi-2711/react-training.git
synced 2026-09-22 20:01:59 +00:00
Implement edit, delete user
This commit is contained in:
@@ -22,3 +22,5 @@ dist-ssr
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
||||
|
||||
db.json
|
||||
|
||||
+27
-11
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"users": [
|
||||
{
|
||||
"id": "123",
|
||||
"id": 1,
|
||||
"name": "Nezumi",
|
||||
"identifiedCode": "123",
|
||||
"phone": "0937425123",
|
||||
@@ -9,7 +9,7 @@
|
||||
"address": "Da Nang"
|
||||
},
|
||||
{
|
||||
"id": "231",
|
||||
"id": 2,
|
||||
"name": "Phan Huu Loi",
|
||||
"identifiedCode": "123",
|
||||
"phone": "0937425123",
|
||||
@@ -17,7 +17,7 @@
|
||||
"address": "Ho Chi Minh"
|
||||
},
|
||||
{
|
||||
"id": "312",
|
||||
"id": 3,
|
||||
"name": "Nezumi",
|
||||
"identifiedCode": "123",
|
||||
"phone": "0937425123",
|
||||
@@ -25,7 +25,7 @@
|
||||
"address": "Da Nang"
|
||||
},
|
||||
{
|
||||
"id": "523",
|
||||
"id": 4,
|
||||
"name": "Nezumi",
|
||||
"identifiedCode": "123",
|
||||
"phone": "0937425123",
|
||||
@@ -33,7 +33,7 @@
|
||||
"address": "Da Nang"
|
||||
},
|
||||
{
|
||||
"id": "534",
|
||||
"id": 5,
|
||||
"name": "Nezumi",
|
||||
"identifiedCode": "123",
|
||||
"phone": "0937425123",
|
||||
@@ -41,7 +41,7 @@
|
||||
"address": "Da Nang"
|
||||
},
|
||||
{
|
||||
"id": "756",
|
||||
"id": 6,
|
||||
"name": "Nezumi",
|
||||
"identifiedCode": "123",
|
||||
"phone": "0937425123",
|
||||
@@ -49,7 +49,7 @@
|
||||
"address": "Da Nang"
|
||||
},
|
||||
{
|
||||
"id": "23",
|
||||
"id": 8,
|
||||
"name": "Nezumi",
|
||||
"identifiedCode": "123",
|
||||
"phone": "0937425123",
|
||||
@@ -57,7 +57,7 @@
|
||||
"address": "Da Nang"
|
||||
},
|
||||
{
|
||||
"id": "756",
|
||||
"id": 9,
|
||||
"name": "Nezumi",
|
||||
"identifiedCode": "123",
|
||||
"phone": "0937425123",
|
||||
@@ -65,12 +65,28 @@
|
||||
"address": "Da Nang"
|
||||
},
|
||||
{
|
||||
"id": "756",
|
||||
"name": "Nezumi",
|
||||
"identifiedCode": "3212",
|
||||
"phone": "0327768351",
|
||||
"roomId": "213",
|
||||
"address": "32131212312",
|
||||
"id": 10
|
||||
},
|
||||
{
|
||||
"name": "Nezumi",
|
||||
"identifiedCode": "123",
|
||||
"phone": "0937425123",
|
||||
"roomId": 246,
|
||||
"address": "Da Nang"
|
||||
"roomId": "24632",
|
||||
"address": "Da Nang232321",
|
||||
"id": 13
|
||||
},
|
||||
{
|
||||
"id": 16,
|
||||
"name": "Phan Huu Loi",
|
||||
"identifiedCode": "3213123212312",
|
||||
"phone": "0327768321",
|
||||
"roomId": "3123",
|
||||
"address": "32131312332131"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -2,12 +2,20 @@ const INVALID_FORMAT_MSG = (field: string) => {
|
||||
return `Invalid ${field} format`;
|
||||
};
|
||||
|
||||
const ADD_SUCCESS = 'Add success';
|
||||
|
||||
const ERROR_MSG = (errorCode: number, msg: string) => {
|
||||
return `Error code: ${errorCode}. Message: ${msg}`;
|
||||
};
|
||||
|
||||
const TIME_OUT_MSG = 'Connection time out!';
|
||||
const ADD_SUCCESS = 'Add success';
|
||||
const EDIT_SUCCESS = 'Edit success';
|
||||
const CONFIRM_DELETE = 'Are you sure to delete it?';
|
||||
const DELETE_SUCCESS = 'Delete success';
|
||||
|
||||
export { INVALID_FORMAT_MSG, ADD_SUCCESS, ERROR_MSG, TIME_OUT_MSG };
|
||||
export {
|
||||
INVALID_FORMAT_MSG,
|
||||
ADD_SUCCESS,
|
||||
ERROR_MSG,
|
||||
EDIT_SUCCESS,
|
||||
CONFIRM_DELETE,
|
||||
DELETE_SUCCESS,
|
||||
};
|
||||
|
||||
@@ -2,4 +2,5 @@ export const DASHBOARD: string = '/dashboard';
|
||||
export const USER: string = '/user';
|
||||
export const ROOM: string = '/room';
|
||||
export const OTHER_PATH: string = '*';
|
||||
export const BASE_URL: string = 'https://hotel-management-api.loiphan.com/';
|
||||
export const BASE_URL: string = 'http://localhost:3000/';
|
||||
export const USER_PATH = 'users';
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
const STATUS_CODE = {
|
||||
OK: 200,
|
||||
CREATE: 201,
|
||||
NOT_FOUND: 404,
|
||||
CONNECTION_TIME_OUT: 522,
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { TUser } from './types';
|
||||
|
||||
interface IMenusContext {
|
||||
openId?: string;
|
||||
close?: () => void;
|
||||
@@ -27,6 +29,8 @@ interface IDialogProps {
|
||||
reload?: boolean;
|
||||
setReload?: React.Dispatch<React.SetStateAction<boolean>>;
|
||||
ref?: React.MutableRefObject<HTMLDialogElement | undefined>;
|
||||
user?: TUser | null;
|
||||
isAdd?: boolean;
|
||||
}
|
||||
|
||||
export type { IMenusContext, IButton, ITable, ITableBody, IDialogProps };
|
||||
|
||||
@@ -8,9 +8,6 @@ export const sendRequest = async (
|
||||
body: BodyInit | null | undefined,
|
||||
method: TMethodRequest = 'GET',
|
||||
): Promise<TResponse> => {
|
||||
const controller = new AbortController();
|
||||
const signal = controller.signal;
|
||||
|
||||
const response = await fetch(BASE_URL + path, {
|
||||
method,
|
||||
body,
|
||||
@@ -19,7 +16,6 @@ export const sendRequest = async (
|
||||
'Accept': 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
signal,
|
||||
});
|
||||
|
||||
return {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { INVALID_FORMAT_MSG } from '../constants/messages';
|
||||
import { TKeyValue, TPropValues, TStateSchema } from '../globals/types';
|
||||
import { TKeyValue, TPropValues, TStateSchema, TUser } from '../globals/types';
|
||||
|
||||
const VALUE = 'value';
|
||||
const ERROR = 'error';
|
||||
@@ -44,10 +44,19 @@ const addValidator = ({ validatorFunc, prop, required = true }: TValidator) => {
|
||||
};
|
||||
};
|
||||
|
||||
const getValueUser = (user: TUser | null = null, prop: string): string => {
|
||||
if (user) {
|
||||
return user[prop as keyof TUser];
|
||||
}
|
||||
|
||||
return '';
|
||||
};
|
||||
|
||||
export {
|
||||
isObject,
|
||||
isRequired,
|
||||
getPropValues,
|
||||
getValueUser,
|
||||
addValidator,
|
||||
VALUE,
|
||||
ERROR,
|
||||
|
||||
@@ -24,6 +24,7 @@ const useForm = (
|
||||
stateSchema = {},
|
||||
stateValidatorSchema = {} as TValidator,
|
||||
submitFormCallback: (values: TKeyValue) => void,
|
||||
initialValue: string = '',
|
||||
) => {
|
||||
const [values, setValues] = useState(getPropValues(stateSchema, VALUE));
|
||||
const [errors, setErrors] = useState(getPropValues(stateSchema, ERROR));
|
||||
@@ -33,8 +34,15 @@ const useForm = (
|
||||
|
||||
// Get a local copy of stateSchema
|
||||
useEffect(() => {
|
||||
setInitialErrorState();
|
||||
}, []); // eslint-disable-line
|
||||
setInitialErrorState(initialValue);
|
||||
setDisable(true);
|
||||
|
||||
if (initialValue) {
|
||||
setValues({});
|
||||
setValues(getPropValues(stateSchema, VALUE));
|
||||
setDisable(false);
|
||||
}
|
||||
}, [initialValue]); // eslint-disable-line
|
||||
|
||||
// Validate fields in forms
|
||||
const validateFormFields = useCallback(
|
||||
@@ -47,15 +55,19 @@ const useForm = (
|
||||
const field = validator[name];
|
||||
|
||||
let error = '';
|
||||
error = isRequired(value, field!.required);
|
||||
|
||||
if (isObject(field['validator']) && error === '') {
|
||||
const fieldValidator = field['validator'];
|
||||
// Skip check id field
|
||||
if (name !== 'id') {
|
||||
error = isRequired(value, field!.required);
|
||||
|
||||
// Test the function callback if the value is meet the criteria
|
||||
const testFunc = fieldValidator!['func'];
|
||||
if (!testFunc!(value)) {
|
||||
error = fieldValidator!['error']!;
|
||||
if (isObject(field['validator']) && error === '') {
|
||||
const fieldValidator = field['validator'];
|
||||
|
||||
// Test the function callback if the value is meet the criteria
|
||||
const testFunc = fieldValidator!['func'];
|
||||
if (!testFunc!(value)) {
|
||||
error = fieldValidator!['error']!;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,14 +78,19 @@ const useForm = (
|
||||
|
||||
// Set Initial Error State
|
||||
// When hooks was first rendered...
|
||||
const setInitialErrorState = useCallback(() => {
|
||||
Object.keys(errors).map((name) =>
|
||||
setErrors((prevState) => ({
|
||||
...prevState,
|
||||
[name]: validateFormFields(name, values[name] as string),
|
||||
})),
|
||||
);
|
||||
}, [errors, values, validateFormFields]);
|
||||
const setInitialErrorState = useCallback(
|
||||
(initialValue: string) => {
|
||||
Object.keys(errors).map((name) =>
|
||||
setErrors((prevState) => ({
|
||||
...prevState,
|
||||
[name]: !initialValue
|
||||
? validateFormFields(name, values[name] as string)
|
||||
: '',
|
||||
})),
|
||||
);
|
||||
},
|
||||
[errors, values, validateFormFields],
|
||||
);
|
||||
|
||||
// Used to disable submit button if there's a value in errors
|
||||
// or the required field in state has no value.
|
||||
@@ -116,6 +133,7 @@ const useForm = (
|
||||
// Making sure that there's no error in the state
|
||||
// before calling the submit callback function
|
||||
// and disabled button
|
||||
|
||||
if (!validateErrorState()) {
|
||||
submitFormCallback(values);
|
||||
setDisable(true);
|
||||
|
||||
@@ -11,7 +11,7 @@ const UserDialog = forwardRef((props, ref) => {
|
||||
const dialogRef = ref as React.MutableRefObject<
|
||||
HTMLDialogElement | undefined
|
||||
>;
|
||||
const { onClose, setReload, reload } = props;
|
||||
const { onClose, setReload, reload, user, isAdd } = props;
|
||||
|
||||
useEffect(() => {
|
||||
if (dialogRef.current) {
|
||||
@@ -31,7 +31,13 @@ const UserDialog = forwardRef((props, ref) => {
|
||||
|
||||
return (
|
||||
<Dialog title={'Add user'} onClose={onClose} ref={dialogRef}>
|
||||
<UserForm onClose={onClose!} reload={reload!} setReload={setReload!} />
|
||||
<UserForm
|
||||
onClose={onClose!}
|
||||
reload={reload!}
|
||||
setReload={setReload!}
|
||||
user={user}
|
||||
isAdd={isAdd!}
|
||||
/>
|
||||
</Dialog>
|
||||
);
|
||||
}) as React.FC<IDialogProps>;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useState } from 'react';
|
||||
import { useEffect, useState } from 'react';
|
||||
import styled from 'styled-components';
|
||||
import toast from 'react-hot-toast';
|
||||
|
||||
@@ -14,8 +14,8 @@ import Button from '../../commons/styles/Button.ts';
|
||||
// Types
|
||||
import {
|
||||
TKeyValue,
|
||||
TResponse,
|
||||
TStateSchema,
|
||||
TUser,
|
||||
TValidator,
|
||||
} from '../../globals/types';
|
||||
|
||||
@@ -29,12 +29,17 @@ import {
|
||||
isValidPhoneNumber,
|
||||
isValidString,
|
||||
} from '../../helpers/validators';
|
||||
import { addValidator } from '../../helpers/utils.ts';
|
||||
import { addValidator, getValueUser } from '../../helpers/utils.ts';
|
||||
import { sendRequest } from '../../helpers/sendRequest.ts';
|
||||
|
||||
// Constants
|
||||
import { STATUS_CODE } from '../../constants/statusCode.ts';
|
||||
import { ADD_SUCCESS, ERROR_MSG } from '../../constants/messages.ts';
|
||||
import {
|
||||
ADD_SUCCESS,
|
||||
EDIT_SUCCESS,
|
||||
ERROR_MSG,
|
||||
} from '../../constants/messages.ts';
|
||||
import { USER_PATH } from '../../constants/path.ts';
|
||||
|
||||
const FormBtn = styled(Button)`
|
||||
width: 100%;
|
||||
@@ -49,18 +54,34 @@ interface IUserFormProp {
|
||||
onClose: () => void;
|
||||
reload: boolean;
|
||||
setReload: React.Dispatch<React.SetStateAction<boolean>>;
|
||||
user?: TUser | null;
|
||||
isAdd: boolean;
|
||||
}
|
||||
|
||||
const UserForm = ({ onClose, reload, setReload }: IUserFormProp) => {
|
||||
const UserForm = ({
|
||||
onClose,
|
||||
reload,
|
||||
setReload,
|
||||
user,
|
||||
isAdd,
|
||||
}: IUserFormProp) => {
|
||||
const [reset, setReset] = useState(true);
|
||||
let initialValue: string = '';
|
||||
|
||||
if (isAdd) {
|
||||
initialValue = '';
|
||||
} else if (user) {
|
||||
initialValue = user.id;
|
||||
}
|
||||
|
||||
// Define your state schema
|
||||
const stateSchema: TStateSchema = {
|
||||
name: { value: '', error: '' },
|
||||
identifiedCode: { value: '', error: '' },
|
||||
phone: { value: '', error: '' },
|
||||
roomId: { value: '', error: '' },
|
||||
address: { value: '', error: '' },
|
||||
id: { value: getValueUser(user, 'id') },
|
||||
name: { value: getValueUser(user, 'name'), error: '' },
|
||||
identifiedCode: { value: getValueUser(user, 'identifiedCode'), error: '' },
|
||||
phone: { value: getValueUser(user, 'phone'), error: '' },
|
||||
roomId: { value: getValueUser(user, 'roomId'), error: '' },
|
||||
address: { value: getValueUser(user, 'address'), error: '' },
|
||||
};
|
||||
|
||||
// prettier-ignore
|
||||
@@ -90,31 +111,51 @@ const UserForm = ({ onClose, reload, setReload }: IUserFormProp) => {
|
||||
// Submit form
|
||||
const onSubmitForm = async (state: TKeyValue) => {
|
||||
try {
|
||||
const response = await sendRequest(
|
||||
'users',
|
||||
JSON.stringify(state),
|
||||
'POST',
|
||||
);
|
||||
if (isAdd) {
|
||||
// Add request
|
||||
const response = await sendRequest(
|
||||
USER_PATH,
|
||||
JSON.stringify(state),
|
||||
'POST',
|
||||
);
|
||||
|
||||
if (response.statusCode === STATUS_CODE.CREATE) {
|
||||
toast.success(ADD_SUCCESS);
|
||||
|
||||
// Reload table data
|
||||
setReload(!reload);
|
||||
if (response.statusCode === STATUS_CODE.CREATE) {
|
||||
toast.success(ADD_SUCCESS);
|
||||
} else {
|
||||
throw new Error(ERROR_MSG(response.statusCode, response.msg));
|
||||
}
|
||||
} else {
|
||||
toast.error(ERROR_MSG(response.statusCode, response.msg));
|
||||
}
|
||||
// Edit request
|
||||
const response = await sendRequest(
|
||||
USER_PATH + `/${user!.id}`,
|
||||
JSON.stringify(state),
|
||||
'PUT',
|
||||
);
|
||||
|
||||
if (response.statusCode == STATUS_CODE.OK) {
|
||||
toast.success(EDIT_SUCCESS);
|
||||
} else {
|
||||
throw new Error(ERROR_MSG(response.statusCode, response.msg));
|
||||
}
|
||||
}
|
||||
// Reload table data
|
||||
setReload(!reload);
|
||||
onResetForm();
|
||||
} catch (error) {
|
||||
toast.error(
|
||||
ERROR_MSG((error as TResponse).statusCode, (error as TResponse).msg),
|
||||
);
|
||||
} catch (error: unknown) {
|
||||
if (error instanceof Error) {
|
||||
toast.error(error.message);
|
||||
}
|
||||
}
|
||||
|
||||
onClose();
|
||||
};
|
||||
|
||||
// Close form
|
||||
const closeAndReset = () => {
|
||||
onClose();
|
||||
onResetForm();
|
||||
};
|
||||
|
||||
// prettier-ignore
|
||||
const {
|
||||
values,
|
||||
@@ -127,10 +168,12 @@ const UserForm = ({ onClose, reload, setReload }: IUserFormProp) => {
|
||||
stateSchema,
|
||||
stateValidatorSchema,
|
||||
onSubmitForm,
|
||||
initialValue
|
||||
);
|
||||
|
||||
// prettier-ignore
|
||||
const {
|
||||
id,
|
||||
name,
|
||||
identifiedCode,
|
||||
phone,
|
||||
@@ -138,6 +181,12 @@ const UserForm = ({ onClose, reload, setReload }: IUserFormProp) => {
|
||||
address
|
||||
} = values;
|
||||
|
||||
useEffect(() => {
|
||||
if (isAdd) {
|
||||
Object.keys(values).forEach((key) => (values[key] = ''));
|
||||
}
|
||||
}, [isAdd]); // eslint-disable-line
|
||||
|
||||
// Reset form
|
||||
const onResetForm = () => {
|
||||
setReset(!reset);
|
||||
@@ -146,7 +195,7 @@ const UserForm = ({ onClose, reload, setReload }: IUserFormProp) => {
|
||||
|
||||
return (
|
||||
<Form onSubmit={handleOnSubmit}>
|
||||
<Input type="hidden" id="id" />
|
||||
<Input type="hidden" name="id" value={id as string} />
|
||||
<FormRow
|
||||
label="Full Name"
|
||||
error={
|
||||
@@ -235,7 +284,7 @@ const UserForm = ({ onClose, reload, setReload }: IUserFormProp) => {
|
||||
<FormBtn type="submit" name="submit" disabled={disable}>
|
||||
Add
|
||||
</FormBtn>
|
||||
<FormBtn type="button" styled="secondary" onClick={onClose}>
|
||||
<FormBtn type="button" styled="secondary" onClick={closeAndReset}>
|
||||
Close
|
||||
</FormBtn>
|
||||
</Form.Action>
|
||||
|
||||
@@ -17,12 +17,47 @@ import { useFetch } from '../../hooks/useFetch';
|
||||
|
||||
// Styled
|
||||
import Spinner from '../../commons/styles/Spinner';
|
||||
import { sendRequest } from '../../helpers/sendRequest';
|
||||
import { USER_PATH } from '../../constants/path';
|
||||
import toast from 'react-hot-toast';
|
||||
import { STATUS_CODE } from '../../constants/statusCode';
|
||||
import { CONFIRM_DELETE, DELETE_SUCCESS } from '../../constants/messages';
|
||||
|
||||
type TUserModal = { user: TUser };
|
||||
interface IUserRow {
|
||||
user: TUser;
|
||||
openFormDialog: () => void;
|
||||
setUser: React.Dispatch<React.SetStateAction<TUser | null>>;
|
||||
reload: boolean;
|
||||
setReload: React.Dispatch<React.SetStateAction<boolean>>;
|
||||
}
|
||||
|
||||
const UserRow = ({ user }: TUserModal) => {
|
||||
const handleOnClick = (id: string) => {
|
||||
alert(`Id: ${id}`);
|
||||
const UserRow = ({
|
||||
user,
|
||||
openFormDialog,
|
||||
setUser,
|
||||
reload,
|
||||
setReload,
|
||||
}: IUserRow) => {
|
||||
const handleOnEdit = (user: TUser) => {
|
||||
setUser(user);
|
||||
openFormDialog();
|
||||
};
|
||||
|
||||
const handleOnDelete = async (user: TUser) => {
|
||||
if (confirm(CONFIRM_DELETE)) {
|
||||
const response = await sendRequest(
|
||||
USER_PATH + `/${user.id}`,
|
||||
null,
|
||||
'DELETE',
|
||||
);
|
||||
|
||||
if (response.statusCode === STATUS_CODE.OK) {
|
||||
toast.success(DELETE_SUCCESS);
|
||||
|
||||
// Reload table
|
||||
setReload(!reload);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const { id, name, identifiedCode, phone, roomId } = user;
|
||||
@@ -41,11 +76,11 @@ const UserRow = ({ user }: TUserModal) => {
|
||||
<Menus.List id={id}>
|
||||
<Menus.Button
|
||||
icon={<HiSquare2Stack />}
|
||||
onClick={() => handleOnClick(id)}
|
||||
onClick={() => handleOnEdit(user)}
|
||||
>
|
||||
Edit
|
||||
</Menus.Button>
|
||||
<Menus.Button icon={<HiTrash />} onClick={() => handleOnClick(id)}>
|
||||
<Menus.Button icon={<HiTrash />} onClick={() => handleOnDelete(user)}>
|
||||
Delete
|
||||
</Menus.Button>
|
||||
</Menus.List>
|
||||
@@ -56,9 +91,17 @@ const UserRow = ({ user }: TUserModal) => {
|
||||
|
||||
interface IUserTable {
|
||||
reload: boolean;
|
||||
setReload: React.Dispatch<React.SetStateAction<boolean>>;
|
||||
openFormDialog: () => void;
|
||||
setUser?: React.Dispatch<React.SetStateAction<TUser | null>>;
|
||||
}
|
||||
|
||||
const UserTable = ({ reload }: IUserTable) => {
|
||||
const UserTable = ({
|
||||
reload,
|
||||
setReload,
|
||||
openFormDialog,
|
||||
setUser,
|
||||
}: IUserTable) => {
|
||||
const { data, isPending, errorMsg } = useFetch('users', reload);
|
||||
const [users, setUsers] = useState<TUser[]>([]);
|
||||
|
||||
@@ -94,7 +137,16 @@ const UserTable = ({ reload }: IUserTable) => {
|
||||
</Table.Header>
|
||||
<Table.Body<TUser>
|
||||
data={users}
|
||||
render={(user: TUser) => <UserRow user={user} key={user.id} />}
|
||||
render={(user: TUser) => (
|
||||
<UserRow
|
||||
user={user}
|
||||
key={user.id}
|
||||
reload={reload}
|
||||
setReload={setReload}
|
||||
openFormDialog={openFormDialog}
|
||||
setUser={setUser!}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
</Table>
|
||||
</Menus>
|
||||
|
||||
@@ -8,12 +8,16 @@ import UserTable from './Table';
|
||||
// Styled
|
||||
import { StyledUser, Title } from './styled';
|
||||
import UserDialog from './Dialog';
|
||||
import { TUser } from '../../globals/types';
|
||||
|
||||
const User = () => {
|
||||
const dialogRef = useRef<HTMLDialogElement>();
|
||||
const [reload, setReload] = useState(true);
|
||||
const [user, setUser] = useState<TUser | null>(null);
|
||||
const [isAdd, setIsAdd] = useState(false);
|
||||
|
||||
const openDialog = () => {
|
||||
const openDialog = (isAdd: boolean) => {
|
||||
setIsAdd(isAdd);
|
||||
dialogRef.current?.showModal();
|
||||
};
|
||||
|
||||
@@ -26,10 +30,15 @@ const User = () => {
|
||||
<StyledUser>
|
||||
<Direction type="horizontal">
|
||||
<Title>List User</Title>
|
||||
<Button onClick={openDialog}>Add user</Button>
|
||||
<Button onClick={() => openDialog(true)}>Add user</Button>
|
||||
</Direction>
|
||||
|
||||
<UserTable reload={reload} />
|
||||
<UserTable
|
||||
reload={reload}
|
||||
setReload={setReload}
|
||||
openFormDialog={() => openDialog(false)}
|
||||
setUser={setUser}
|
||||
/>
|
||||
</StyledUser>
|
||||
|
||||
<UserDialog
|
||||
@@ -37,6 +46,8 @@ const User = () => {
|
||||
ref={dialogRef}
|
||||
setReload={setReload}
|
||||
reload={reload}
|
||||
user={user}
|
||||
isAdd={isAdd}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user