mirror of
https://github.com/Nezumi-2711/react-training.git
synced 2026-09-22 20:01:59 +00:00
Fix all comments
This commit is contained in:
@@ -4,6 +4,7 @@ const StyledAppLayout = styled.div`
|
||||
display: grid;
|
||||
grid-template-columns: 300px 1fr;
|
||||
grid-template-rows: auto 1fr;
|
||||
|
||||
height: 100vh;
|
||||
`;
|
||||
|
||||
|
||||
@@ -1,26 +1,29 @@
|
||||
import { forwardRef } from 'react';
|
||||
import { MutableRefObject, ReactNode, forwardRef } from 'react';
|
||||
|
||||
// Styled
|
||||
import { StyledBody, StyledDialog, StyledTitle } from './styled';
|
||||
|
||||
// Type
|
||||
import { Nullable } from '../../globals/types';
|
||||
|
||||
export interface IDialogProps {
|
||||
title?: string;
|
||||
children?: JSX.Element[] | JSX.Element;
|
||||
children?: ReactNode;
|
||||
onClose?: () => void;
|
||||
ref?: React.MutableRefObject<HTMLDialogElement | null>;
|
||||
ref?: MutableRefObject<Nullable<HTMLDialogElement>>;
|
||||
}
|
||||
|
||||
const Dialog = forwardRef((props: IDialogProps, ref) => {
|
||||
const { title, children, onClose } = props;
|
||||
return (
|
||||
<StyledDialog
|
||||
ref={ref as React.LegacyRef<HTMLDialogElement> | undefined}
|
||||
onClose={onClose}
|
||||
>
|
||||
<StyledTitle>{title}</StyledTitle>
|
||||
<StyledBody>{children}</StyledBody>
|
||||
</StyledDialog>
|
||||
);
|
||||
});
|
||||
const Dialog = forwardRef<HTMLDialogElement, IDialogProps>(
|
||||
(props: IDialogProps, ref) => {
|
||||
const { title, children, onClose } = props;
|
||||
|
||||
return (
|
||||
<StyledDialog ref={ref} onClose={onClose}>
|
||||
<StyledTitle>{title}</StyledTitle>
|
||||
<StyledBody>{children}</StyledBody>
|
||||
</StyledDialog>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
export default Dialog;
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
import { FormEvent, ReactNode } from 'react';
|
||||
|
||||
// Styled
|
||||
import { StyledActionBtn, StyledForm } from './styled';
|
||||
|
||||
interface IFormProps {
|
||||
children: JSX.Element | JSX.Element[];
|
||||
onSubmit: (event: React.FormEvent<HTMLFormElement>) => void;
|
||||
children: ReactNode;
|
||||
onSubmit: (event: FormEvent<HTMLFormElement>) => void;
|
||||
id?: string;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ import styled from 'styled-components';
|
||||
|
||||
const StyledHeader = styled.header`
|
||||
border-bottom: 1px solid var(--border-color);
|
||||
|
||||
padding: 20px 40px;
|
||||
|
||||
display: flex;
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
import { ReactNode } from 'react';
|
||||
|
||||
// Styled
|
||||
import { Error, Label, StyledFormRow } from './styled';
|
||||
|
||||
interface IFormRow {
|
||||
label: string;
|
||||
error?: string;
|
||||
children: JSX.Element | JSX.Element[];
|
||||
children: ReactNode;
|
||||
}
|
||||
|
||||
const FormRow = ({ label, error, children }: IFormRow) => {
|
||||
|
||||
@@ -15,8 +15,10 @@ const Label = styled.label`
|
||||
const Error = styled.p`
|
||||
color: var(--error-text);
|
||||
font-size: var(--fs-sm-2x);
|
||||
|
||||
margin-top: 5px;
|
||||
padding-inline: 5px;
|
||||
|
||||
width: 220px;
|
||||
`;
|
||||
|
||||
|
||||
@@ -1,22 +1,28 @@
|
||||
import { useContext, useState } from 'react';
|
||||
import { MouseEvent, ReactNode, useContext, useState } from 'react';
|
||||
|
||||
// Components
|
||||
import { HiEllipsisVertical } from 'react-icons/hi2';
|
||||
|
||||
// Hooks
|
||||
import { useOutsideClick } from '../../hooks/useOutsideClick';
|
||||
|
||||
// Styled
|
||||
import { StyledMenu, StyledButton, StyledList, StyledToggle } from './styled';
|
||||
|
||||
// Contexts
|
||||
import MenusContext from '../../contexts/MenuContext';
|
||||
|
||||
// Types
|
||||
import { Nullable } from '../../globals/types';
|
||||
|
||||
interface IButton {
|
||||
children?: string;
|
||||
icon?: JSX.Element;
|
||||
icon?: ReactNode;
|
||||
onClick?: () => void;
|
||||
}
|
||||
|
||||
const Menus = ({ children }: { children: JSX.Element }) => {
|
||||
const Menus = ({ children }: { children: ReactNode }) => {
|
||||
const [openId, setOpenId] = useState('');
|
||||
|
||||
const close = () => setOpenId('');
|
||||
const open = setOpenId;
|
||||
|
||||
@@ -27,13 +33,14 @@ const Menus = ({ children }: { children: JSX.Element }) => {
|
||||
);
|
||||
};
|
||||
|
||||
const Toggle = ({ id }: { id: string }): React.JSX.Element => {
|
||||
const Toggle = ({ id }: { id: string }): ReactNode => {
|
||||
const { openId, close, open } = useContext(MenusContext);
|
||||
|
||||
const handleClick = (e: React.MouseEvent<HTMLButtonElement, MouseEvent>) => {
|
||||
const handleClick = (e: MouseEvent<HTMLButtonElement>) => {
|
||||
e.stopPropagation();
|
||||
|
||||
openId === '' || openId !== id ? open!(id) : close!();
|
||||
openId === '' || openId !== id
|
||||
? open!(id)
|
||||
: close!();
|
||||
};
|
||||
|
||||
return (
|
||||
@@ -48,8 +55,8 @@ const List = ({
|
||||
children,
|
||||
}: {
|
||||
id: string;
|
||||
children: JSX.Element[];
|
||||
}): React.JSX.Element | null => {
|
||||
children: ReactNode;
|
||||
}): Nullable<ReactNode> => {
|
||||
const { openId, close } = useContext(MenusContext);
|
||||
const ref = useOutsideClick(close!, false);
|
||||
|
||||
@@ -58,9 +65,8 @@ const List = ({
|
||||
return <StyledList ref={ref}>{children}</StyledList>;
|
||||
};
|
||||
|
||||
const Button = ({ children, icon, onClick }: IButton): React.JSX.Element => {
|
||||
const Button = ({ children, icon, onClick }: IButton): ReactNode => {
|
||||
const { close } = useContext(MenusContext);
|
||||
|
||||
const handleClick = () => {
|
||||
onClick?.();
|
||||
close!();
|
||||
|
||||
@@ -3,6 +3,7 @@ import styled from 'styled-components';
|
||||
const StyledMessage = styled.p`
|
||||
font-size: var(--fs-sm);
|
||||
text-align: center;
|
||||
|
||||
padding: 20px;
|
||||
`;
|
||||
|
||||
|
||||
@@ -13,10 +13,8 @@ interface IOrderProps {
|
||||
|
||||
const OrderBy = memo(({ options }: IOrderProps) => {
|
||||
const field = 'orderBy';
|
||||
|
||||
const [searchParams, setSearchParams] = useSearchParams();
|
||||
const currentOrder = searchParams.get(field) || options[0].value;
|
||||
|
||||
const handleClick = (value: string) => {
|
||||
searchParams.set(field, value);
|
||||
|
||||
|
||||
@@ -14,8 +14,16 @@ interface IOrderBtn {
|
||||
|
||||
const OrderButton = styled.button<IOrderBtn>`
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
border-radius: var(--radius-sm);
|
||||
|
||||
cursor: pointer;
|
||||
transition: all 0.3s;
|
||||
|
||||
font-weight: 500;
|
||||
font-size: var(--fs-sm-x);
|
||||
|
||||
padding: 5px 10px;
|
||||
|
||||
${(props) =>
|
||||
props.active &&
|
||||
css`
|
||||
@@ -24,12 +32,6 @@ const OrderButton = styled.button<IOrderBtn>`
|
||||
cursor: no-drop;
|
||||
`}
|
||||
|
||||
border-radius: var(--radius-sm);
|
||||
font-weight: 500;
|
||||
font-size: var(--fs-sm-x);
|
||||
padding: 5px 10px;
|
||||
transition: all 0.3s;
|
||||
|
||||
&:hover:not(:disabled) {
|
||||
background-color: var(--hover-dark-background-color);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
import { memo, useEffect, useState } from 'react';
|
||||
|
||||
// Styled
|
||||
import { StyledSearch } from './styled';
|
||||
|
||||
// Hooks
|
||||
import { useDebounce } from '../../hooks/useDebounce';
|
||||
|
||||
interface ISearch {
|
||||
setPlaceHolder: string;
|
||||
setValueSearch: (phone: string) => void;
|
||||
@@ -8,14 +13,11 @@ interface ISearch {
|
||||
|
||||
const Search = memo(({ setValueSearch, setPlaceHolder }: ISearch) => {
|
||||
const [query, setQuery] = useState('');
|
||||
const debounceValue = useDebounce<string>(query, 700);
|
||||
|
||||
useEffect(() => {
|
||||
const timeOut = setTimeout(() => {
|
||||
setValueSearch(query);
|
||||
}, 500);
|
||||
|
||||
return () => clearTimeout(timeOut);
|
||||
}, [setValueSearch, query]);
|
||||
setValueSearch(debounceValue);
|
||||
}, [debounceValue, setValueSearch]);
|
||||
|
||||
return (
|
||||
<StyledSearch
|
||||
|
||||
@@ -4,8 +4,10 @@ import {
|
||||
UseFormRegister,
|
||||
useFormContext,
|
||||
} from 'react-hook-form';
|
||||
import { ChangeEventHandler, ReactNode } from 'react';
|
||||
|
||||
// Styled
|
||||
import { StyledSelect } from './styled';
|
||||
import React, { ReactNode } from 'react';
|
||||
|
||||
export interface ISelectOptions {
|
||||
value: string;
|
||||
@@ -15,7 +17,7 @@ interface ISelect {
|
||||
options: ISelectOptions[];
|
||||
optionsConfigForm?: RegisterOptions<FieldValues, string> | undefined;
|
||||
value?: string;
|
||||
onChange?: React.ChangeEventHandler<HTMLSelectElement> | undefined;
|
||||
onChange?: ChangeEventHandler<HTMLSelectElement> | undefined;
|
||||
id?: string;
|
||||
ariaLabel: string;
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ const StyledSidebar = styled.aside`
|
||||
padding: 50px 20px;
|
||||
|
||||
grid-row: 1 / 3;
|
||||
|
||||
border: 1px solid var(--border-color);
|
||||
`;
|
||||
|
||||
@@ -11,6 +12,7 @@ const Heading = styled.h1`
|
||||
font-size: var(--fs-md);
|
||||
text-transform: uppercase;
|
||||
text-align: center;
|
||||
|
||||
color: var(--primary-color);
|
||||
`;
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { useSearchParams } from 'react-router-dom';
|
||||
import { memo } from 'react';
|
||||
import { ChangeEvent, memo } from 'react';
|
||||
|
||||
// Components
|
||||
import Select from '../Select';
|
||||
@@ -14,8 +14,7 @@ interface ISortByProps {
|
||||
const SortBy = memo(({ options }: ISortByProps) => {
|
||||
const [searchParams, setSearchParams] = useSearchParams();
|
||||
const sortBy = searchParams.get('sortBy') || '';
|
||||
|
||||
const handleChange = (event: React.ChangeEvent<HTMLSelectElement>) => {
|
||||
const handleChange = (event: ChangeEvent<HTMLSelectElement>) => {
|
||||
searchParams.set('sortBy', event.target.value);
|
||||
setSearchParams(searchParams);
|
||||
};
|
||||
|
||||
@@ -8,12 +8,12 @@ import TableContext from '../../contexts/TableContext';
|
||||
|
||||
export interface ITable {
|
||||
columns?: string;
|
||||
children: React.ReactNode;
|
||||
children: ReactNode;
|
||||
}
|
||||
|
||||
interface ITableBody<T> {
|
||||
data?: T[];
|
||||
render?: (value: T) => JSX.Element;
|
||||
render?: CallbackMapFunc<T>;
|
||||
}
|
||||
|
||||
type CallbackMapFunc<T> = (value: T, index: number, array: T[]) => ReactNode;
|
||||
@@ -28,6 +28,7 @@ const Table = ({ columns, children }: ITable) => {
|
||||
|
||||
const Header = ({ children }: ITable) => {
|
||||
const { columns } = useContext(TableContext);
|
||||
|
||||
return <StyledHeader columns={columns}>{children}</StyledHeader>;
|
||||
};
|
||||
|
||||
@@ -41,6 +42,7 @@ const Body = <T,>({ data, render }: ITableBody<T>) => {
|
||||
|
||||
const Row = ({ children }: ITable) => {
|
||||
const { columns } = useContext(TableContext);
|
||||
|
||||
return <StyledRow columns={columns}>{children}</StyledRow>;
|
||||
};
|
||||
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
import styled from 'styled-components';
|
||||
|
||||
// Interfaces
|
||||
import { ITable } from '.';
|
||||
|
||||
const StyledTable = styled.div`
|
||||
border: 1px solid var(--border-color);
|
||||
border-radius: var(--radius-md);
|
||||
|
||||
font-size: 20px;
|
||||
border-radius: var(--radius-md);
|
||||
`;
|
||||
|
||||
const CommonRow = styled.div<ITable>`
|
||||
|
||||
Reference in New Issue
Block a user