mirror of
https://github.com/Nezumi-2711/react-training.git
synced 2026-09-23 04:19:48 +00:00
Refactor code
This commit is contained in:
@@ -10,8 +10,8 @@ import { Main, StyledAppLayout } from './styled';
|
||||
const AppLayout = () => {
|
||||
return (
|
||||
<StyledAppLayout>
|
||||
<Header />
|
||||
<Sidebar />
|
||||
<Header accountName='Admin'/>
|
||||
<Sidebar heading='Hotel Management'/>
|
||||
<Main>
|
||||
<Outlet />
|
||||
</Main>
|
||||
|
||||
@@ -1,11 +1,19 @@
|
||||
import { forwardRef } from 'react';
|
||||
|
||||
// Components
|
||||
import { IDialogProps } from '../../globals/interfaces';
|
||||
|
||||
// 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 { title, children, onClose } = props as IDialogProps<unknown>;
|
||||
return (
|
||||
|
||||
@@ -4,10 +4,14 @@ import HeaderMenu from '../HeaderMenu';
|
||||
// Styled
|
||||
import { StyledHeader } from './styled';
|
||||
|
||||
const Header = () => {
|
||||
interface IHeader {
|
||||
accountName: string
|
||||
}
|
||||
|
||||
const Header = ({accountName}: IHeader) => {
|
||||
return (
|
||||
<StyledHeader>
|
||||
<p>Hi, Admin!</p>
|
||||
<p>Hi, {accountName}!</p>
|
||||
<HeaderMenu />
|
||||
</StyledHeader>
|
||||
);
|
||||
|
||||
+6
-4
@@ -5,12 +5,15 @@ import { HiEllipsisVertical } from 'react-icons/hi2';
|
||||
import { useOutsideClick } from '../../hooks/useOutsideClick';
|
||||
import { StyledMenu, StyledButton, StyledList, StyledToggle } from './styled';
|
||||
|
||||
// Interfaces
|
||||
import { IButton } from '../../globals/interfaces';
|
||||
|
||||
// Contexts
|
||||
import MenusContext from '../../contexts/MenuContext';
|
||||
|
||||
interface IButton {
|
||||
children?: string;
|
||||
icon?: JSX.Element;
|
||||
onClick?: () => void;
|
||||
}
|
||||
|
||||
const Menus = ({ children }: { children: JSX.Element }) => {
|
||||
const [openId, setOpenId] = useState('');
|
||||
|
||||
@@ -30,7 +33,6 @@ const Toggle = ({ id }: { id: string }): React.JSX.Element => {
|
||||
const handleClick = (e: React.MouseEvent<HTMLButtonElement, MouseEvent>) => {
|
||||
e.stopPropagation();
|
||||
|
||||
// prettier-ignore
|
||||
openId === '' || openId !== id
|
||||
? open!(id)
|
||||
: close!();
|
||||
@@ -6,18 +6,21 @@ import { BsHouseDoorFill } from 'react-icons/bs';
|
||||
// Styled
|
||||
import { StyledNav, StyledNavLink } from './styled';
|
||||
|
||||
// Constants
|
||||
import { DASHBOARD, ROOM, USER } from '../../constants/path';
|
||||
|
||||
const Nav = () => {
|
||||
return (
|
||||
<StyledNav>
|
||||
<StyledNavLink to={'/dashboard'}>
|
||||
<StyledNavLink to={DASHBOARD}>
|
||||
<MdSpaceDashboard />
|
||||
<span>Dashboard</span>
|
||||
</StyledNavLink>
|
||||
<StyledNavLink to={'/user'}>
|
||||
<StyledNavLink to={USER}>
|
||||
<HiUsers />
|
||||
<span>User</span>
|
||||
</StyledNavLink>
|
||||
<StyledNavLink to={'/room'}>
|
||||
<StyledNavLink to={ROOM}>
|
||||
<BsHouseDoorFill />
|
||||
<span>Room</span>
|
||||
</StyledNavLink>
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
import { ISelectOptions } from '../../globals/interfaces';
|
||||
import { StyledSelect } from './styled';
|
||||
|
||||
export interface ISelectOptions {
|
||||
value: string;
|
||||
label: string;
|
||||
}
|
||||
interface ISelect {
|
||||
options: ISelectOptions[];
|
||||
value: string;
|
||||
|
||||
@@ -4,10 +4,14 @@ import Nav from '../Nav';
|
||||
// Styled
|
||||
import { Heading, StyledSidebar } from './styled';
|
||||
|
||||
const Sidebar = () => {
|
||||
interface ISidebar {
|
||||
heading: string;
|
||||
}
|
||||
|
||||
const Sidebar = ({heading}: ISidebar) => {
|
||||
return (
|
||||
<StyledSidebar>
|
||||
<Heading>Hotel Management</Heading>
|
||||
<Heading>{heading}</Heading>
|
||||
<Nav />
|
||||
</StyledSidebar>
|
||||
);
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { useSearchParams } from 'react-router-dom';
|
||||
import { memo } from 'react';
|
||||
|
||||
// Components
|
||||
import Select from '../Select';
|
||||
import { memo } from 'react';
|
||||
|
||||
interface ISortByProps {
|
||||
options: {
|
||||
|
||||
@@ -3,24 +3,31 @@ import { ReactNode, useContext } from 'react';
|
||||
// Components
|
||||
import { StyledBody, StyledHeader, StyledRow, StyledTable } from './styled';
|
||||
|
||||
// Interfaces
|
||||
import { ITable, ITableBody } from '../../globals/interfaces';
|
||||
|
||||
// Contexts
|
||||
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;
|
||||
|
||||
const Table = ({ columns, children }: ITable) => {
|
||||
return (
|
||||
<TableContext.Provider value={columns!}>
|
||||
<TableContext.Provider value={{ columns }}>
|
||||
<StyledTable>{children}</StyledTable>
|
||||
</TableContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
const Header = ({ children }: ITable) => {
|
||||
const columns = useContext(TableContext);
|
||||
const { columns } = useContext(TableContext);
|
||||
return <StyledHeader columns={columns}>{children}</StyledHeader>;
|
||||
};
|
||||
|
||||
@@ -33,7 +40,7 @@ const Body = <T,>({ data, render }: ITableBody<T>) => {
|
||||
};
|
||||
|
||||
const Row = ({ children }: ITable) => {
|
||||
const columns = useContext(TableContext);
|
||||
const { columns } = useContext(TableContext);
|
||||
return <StyledRow columns={columns}>{children}</StyledRow>;
|
||||
};
|
||||
|
||||
|
||||
@@ -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 (
|
||||
<Toaster
|
||||
position="top-center"
|
||||
gutter={12}
|
||||
containerStyle={{ margin: '8px', zIndex: 1 }}
|
||||
position={position}
|
||||
gutter={gutter}
|
||||
containerStyle={containerStyle}
|
||||
toastOptions={{
|
||||
success: {
|
||||
duration: 3000,
|
||||
},
|
||||
error: {
|
||||
duration: 5000,
|
||||
},
|
||||
style: {
|
||||
fontSize: '16px',
|
||||
maxWidth: '500px',
|
||||
padding: '16px 24px',
|
||||
},
|
||||
success,
|
||||
error,
|
||||
style
|
||||
}}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
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;
|
||||
|
||||
Reference in New Issue
Block a user