Fix comments

This commit is contained in:
2023-11-08 17:46:26 +07:00
parent a99d81a411
commit 8fce206f7f
35 changed files with 471 additions and 342 deletions
@@ -1,8 +1,8 @@
import { Outlet } from 'react-router-dom';
// Components
import Header from '../Header';
import Sidebar from '../Sidebar';
import Header from '@component/Header';
import Sidebar from '@component/Sidebar';
// Styled
import { Main, StyledAppLayout } from './styled';
@@ -0,0 +1,131 @@
import { COLOR, SIZE } from '@constant/styles';
import { ReactNode } from 'react';
import styled, { css } from 'styled-components';
interface IStyledButtonIcon {
isHaveChildren: boolean;
style?: {
fontSize?: string;
backgroundColor?: string;
color?: string;
};
iconStyle?: {
color?: string;
size?: string;
};
}
const StyledButtonIcon = styled.button<IStyledButtonIcon>`
background: none;
padding: 10px;
transition: all 0.2s;
border: none;
${(props) =>
props.style?.fontSize &&
css`
font-size: ${props.style.fontSize};
`}
${(props) =>
props.style?.fontSize &&
css`
font-size: ${props.style.fontSize};
`}
${(props) =>
props.color &&
css`
font-size: ${props.color};
`}
${(props) =>
props.isHaveChildren
? css`
display: flex;
align-items: center;
gap: 10px;
text-align: left;
width: 100%;
`
: css`
border-radius: var(--radius-md);
`}
&:hover {
background-color: var(--hover-background-color);
}
& svg {
${(props) =>
props.iconStyle?.size &&
css`
width: ${props.iconStyle.size};
height: ${props.iconStyle.size};
`}
${(props) =>
props.iconStyle?.color &&
css`
color: ${props.iconStyle.color};
`}
transition: all 0.3s;
}
`;
StyledButtonIcon.defaultProps = {
style: {
fontSize: SIZE.DEFAULT,
backgroundColor: COLOR.DEFAULT,
color: COLOR.BLACK,
},
iconStyle: {
color: COLOR.BLACK,
size: SIZE.DEFAULT,
},
};
interface IButtonIcon {
icon: ReactNode;
children?: ReactNode;
style?: {
fontSize?: string;
backgroundColor?: string;
color?: string;
};
iconStyle?: {
color?: string;
size?: string;
};
onClick?: () => void;
}
const ButtonIcon = ({
icon,
children,
style,
iconStyle,
onClick,
}: IButtonIcon) => {
const isHaveChildren = Boolean(children);
return (
<StyledButtonIcon
isHaveChildren={isHaveChildren}
style={{
fontSize: style?.fontSize,
backgroundColor: style?.backgroundColor,
color: style?.color,
}}
iconStyle={iconStyle}
onClick={onClick}
>
{icon} <span>{children}</span>
</StyledButtonIcon>
);
};
export default ButtonIcon;
@@ -1,7 +1,7 @@
// Components
import { IoPersonCircleOutline } from 'react-icons/io5';
import { HiOutlineLogout } from 'react-icons/hi';
import ButtonIcon from '../../commons/styles/ButtonIcon';
import ButtonIcon from '@component/ButtonIcon/ButtonIcon';
// Styled
import { StyledHeaderMenu } from './styled';
@@ -10,14 +10,18 @@ const HeaderMenu = () => {
return (
<StyledHeaderMenu>
<li>
<ButtonIcon aria-label="Profile">
<IoPersonCircleOutline />
</ButtonIcon>
<ButtonIcon
aria-label="Profile"
icon={<IoPersonCircleOutline />}
iconStyle={{ size: '23px' }}
/>
</li>
<li>
<ButtonIcon aria-label="Logout">
<HiOutlineLogout />
</ButtonIcon>
<ButtonIcon
aria-label="Logout"
icon={<HiOutlineLogout />}
iconStyle={{size: '23px' }}
/>
</li>
</StyledHeaderMenu>
);
@@ -4,16 +4,18 @@ import { MouseEvent, ReactNode, useContext, useState } from 'react';
import { HiEllipsisVertical } from 'react-icons/hi2';
// Hooks
import { useOutsideClick } from '../../hooks/useOutsideClick';
import { useOutsideClick } from '@hook/useOutsideClick';
// Styled
import { StyledMenu, StyledButton, StyledList, StyledToggle } from './styled';
import { StyledMenu, StyledList, StyledToggle } from './styled';
// Contexts
import MenusContext from '../../contexts/MenuContext';
import MenusContext from '@context/MenuContext';
// Types
import { Nullable } from '../../types/common';
import { Nullable } from '@type/common';
import ButtonIcon from '@component/ButtonIcon/ButtonIcon';
import { COLOR } from '@constant/styles';
interface IButton {
children?: string;
@@ -74,9 +76,14 @@ const Button = ({ children, icon, onClick }: IButton): ReactNode => {
return (
<li>
<StyledButton onClick={handleClick}>
{icon} <span>{children}</span>
</StyledButton>
<ButtonIcon
icon={icon}
onClick={handleClick}
iconStyle={{ color: COLOR.PRIMARY, size: '19px' }}
style={{ fontSize: '16px' }}
>
{children}
</ButtonIcon>
</li>
);
};
@@ -8,10 +8,10 @@ import {
import { createPortal } from 'react-dom';
// Hooks
import { useOutsideClick } from '../../hooks/useOutsideClick';
import { useOutsideClick } from '@hook/useOutsideClick';
// Contexts
import { ModalContext } from '../../contexts/ModalContext';
import { ModalContext } from '@context/ModalContext';
// Styled
import { Overlay, StyledModal, StyledModalContent, TitleModal } from './styled';
@@ -34,14 +34,14 @@ const Modal = ({ children }: IModal) => {
};
interface IOpen {
children: ReactElement;
renderChildren: (onCloseModal: () => void) => ReactNode;
modalName: string;
}
const Open = ({ children, modalName }: IOpen) => {
const Open = ({ renderChildren, modalName }: IOpen) => {
const { open } = useContext(ModalContext);
return cloneElement(children, { onClick: () => open!(modalName) });
return renderChildren(() => open!(modalName));
};
interface IWindow {
@@ -54,9 +54,6 @@ const Window = ({ children, name, title }: IWindow) => {
const { openName, close } = useContext(ModalContext);
const ref = useOutsideClick<HTMLDivElement>(close!);
console.log('name: ', name);
console.log('openName: ', openName);
if (name !== openName) return null;
return createPortal(
@@ -7,7 +7,7 @@ import { BsHouseDoorFill } from 'react-icons/bs';
import { StyledNav, StyledNavLink } from './styled';
// Constants
import { DASHBOARD, ROOM, USER } from '../../constants/path';
import { DASHBOARD, ROOM, USER } from '@constant/path';
const Nav = () => {
return (
@@ -1,4 +1,3 @@
import { memo } from 'react';
import { useSearchParams } from 'react-router-dom';
// Styled
@@ -11,7 +10,7 @@ interface IOrderProps {
}[];
}
const OrderBy = memo(({ options }: IOrderProps) => {
const OrderBy = ({ options }: IOrderProps) => {
const field = 'orderBy';
const [searchParams, setSearchParams] = useSearchParams();
const currentOrder = searchParams.get(field) || options[0].value;
@@ -35,6 +34,6 @@ const OrderBy = memo(({ options }: IOrderProps) => {
))}
</StyledOrder>
);
});
};
export default OrderBy;
@@ -4,7 +4,7 @@ import { useEffect, useState } from 'react';
import { StyledSearch } from './styled';
// Hooks
import { useDebounce } from '../../hooks/useDebounce';
import { useDebounce } from '@hook/useDebounce';
interface ISearch {
setPlaceHolder: string;
@@ -1,10 +1,9 @@
import {
FieldValues,
RegisterOptions,
UseFormRegister,
useFormContext,
} from 'react-hook-form';
import { ChangeEventHandler, ReactNode } from 'react';
import { ChangeEventHandler } from 'react';
// Styled
import { StyledSelect } from './styled';
@@ -22,46 +21,6 @@ interface ISelect {
ariaLabel: string;
}
interface IRender extends ISelect {
register: UseFormRegister<FieldValues>;
children: ReactNode[];
}
const RenderSelect = ({
options,
id,
value,
optionsConfigForm,
onChange,
register,
children,
ariaLabel,
}: IRender) => {
if (options && !register) {
return (
<StyledSelect
aria-label={ariaLabel}
id={id}
value={value}
onChange={onChange}
>
{children}
</StyledSelect>
);
}
return (
<StyledSelect
aria-label={ariaLabel}
id={id}
value={value}
{...register(id!, optionsConfigForm)}
>
{children}
</StyledSelect>
);
};
const Select = ({
options,
id,
@@ -75,21 +34,20 @@ const Select = ({
if (!options) return;
return (
<RenderSelect
register={register}
options={options}
optionsConfigForm={optionsConfigForm}
<StyledSelect
aria-label={ariaLabel}
id={id}
value={value}
onChange={onChange}
ariaLabel={ariaLabel}
{...(register
? { ...register(id!, optionsConfigForm) }
: { onChange: onChange })}
>
{options.map((option) => (
<option value={option.value} key={option.value}>
{option.label}
</option>
))}
</RenderSelect>
</StyledSelect>
);
};
@@ -1,5 +1,5 @@
// Components
import Nav from '../Nav';
import Nav from '@component/Nav';
// Styled
import { Heading, StyledSidebar } from './styled';
@@ -1,8 +1,8 @@
import { useSearchParams } from 'react-router-dom';
import { ChangeEvent, memo } from 'react';
import { ChangeEvent } from 'react';
// Components
import Select from '../Select';
import Select from '@component/Select';
interface ISortByProps {
options: {
@@ -11,7 +11,7 @@ interface ISortByProps {
}[];
}
const SortBy = memo(({ options }: ISortByProps) => {
const SortBy = ({ options }: ISortByProps) => {
const [searchParams, setSearchParams] = useSearchParams();
const sortBy = searchParams.get('sortBy') || '';
const handleChange = (event: ChangeEvent<HTMLSelectElement>) => {
@@ -27,6 +27,6 @@ const SortBy = memo(({ options }: ISortByProps) => {
ariaLabel="Sort"
/>
);
});
};
export default SortBy;
@@ -4,13 +4,17 @@ import { ReactNode, useContext } from 'react';
import { StyledBody, StyledHeader, StyledRow, StyledTable } from './styled';
// Contexts
import TableContext from '../../contexts/TableContext';
import TableContext from '@context/TableContext';
export interface ITable {
columns?: string;
children: ReactNode;
}
export interface IHeader {
headerColumn: string[];
}
interface ITableBody<T> {
data?: T[];
render?: CallbackMapFunc<T>;
@@ -26,10 +30,12 @@ const Table = ({ columns, children }: ITable) => {
);
};
const Header = ({ children }: ITable) => {
const Header = ({ headerColumn }: IHeader) => {
const { columns } = useContext(TableContext);
return <StyledHeader columns={columns}>{children}</StyledHeader>;
return <StyledHeader columns={columns}>
{headerColumn.map((item) => <div key={item}>{item}</div>)}
</StyledHeader>;
};
const Body = <T,>({ data, render }: ITableBody<T>) => {