mirror of
https://github.com/Nezumi-2711/react-training.git
synced 2026-09-22 13:38:51 +00:00
Merge pull request #45 from Nez27/feat/update-common-file-login-method
Update common files, components
This commit is contained in:
Binary file not shown.
|
After Width: | Height: | Size: 15 KiB |
@@ -37,6 +37,7 @@ const Button = styled.button<IButtonStyle>`
|
|||||||
&:disabled,
|
&:disabled,
|
||||||
&[disabled] {
|
&[disabled] {
|
||||||
cursor: not-allowed;
|
cursor: not-allowed;
|
||||||
|
background-color: var(--disabled-btn-color);
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import styled, { css } from 'styled-components';
|
import styled, { css } from 'styled-components';
|
||||||
|
|
||||||
type TDirection = 'vertical' | 'horizontal';
|
// Types
|
||||||
|
import { TDirection } from '@type/common';
|
||||||
|
|
||||||
interface IDirection {
|
interface IDirection {
|
||||||
type?: TDirection;
|
type?: TDirection;
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
import { ReactNode } from 'react';
|
import { ReactNode } from 'react';
|
||||||
|
|
||||||
|
// Styled
|
||||||
import { StyledButtonIcon } from './styled';
|
import { StyledButtonIcon } from './styled';
|
||||||
|
|
||||||
interface IButtonIcon {
|
interface IButtonIcon {
|
||||||
@@ -14,6 +16,7 @@ interface IButtonIcon {
|
|||||||
size?: string;
|
size?: string;
|
||||||
};
|
};
|
||||||
onClick?: () => void;
|
onClick?: () => void;
|
||||||
|
disabled?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ButtonIcon = ({
|
const ButtonIcon = ({
|
||||||
@@ -22,6 +25,7 @@ const ButtonIcon = ({
|
|||||||
style,
|
style,
|
||||||
iconStyle,
|
iconStyle,
|
||||||
onClick,
|
onClick,
|
||||||
|
disabled,
|
||||||
}: IButtonIcon) => {
|
}: IButtonIcon) => {
|
||||||
const isHaveChildren = Boolean(children);
|
const isHaveChildren = Boolean(children);
|
||||||
|
|
||||||
@@ -35,6 +39,7 @@ const ButtonIcon = ({
|
|||||||
}}
|
}}
|
||||||
iconStyle={iconStyle}
|
iconStyle={iconStyle}
|
||||||
onClick={onClick}
|
onClick={onClick}
|
||||||
|
disabled={disabled}
|
||||||
>
|
>
|
||||||
{icon} <span>{children}</span>
|
{icon} <span>{children}</span>
|
||||||
</StyledButtonIcon>
|
</StyledButtonIcon>
|
||||||
|
|||||||
@@ -10,6 +10,9 @@ import {
|
|||||||
FormBtn,
|
FormBtn,
|
||||||
} from './styled';
|
} from './styled';
|
||||||
|
|
||||||
|
// Types
|
||||||
|
import { TDirection } from '@type/common';
|
||||||
|
|
||||||
interface IFormProps {
|
interface IFormProps {
|
||||||
children: ReactNode;
|
children: ReactNode;
|
||||||
onSubmit: (event: FormEvent<HTMLFormElement>) => void;
|
onSubmit: (event: FormEvent<HTMLFormElement>) => void;
|
||||||
@@ -20,6 +23,7 @@ interface IFormRow {
|
|||||||
label: string;
|
label: string;
|
||||||
error?: string;
|
error?: string;
|
||||||
children: ReactNode;
|
children: ReactNode;
|
||||||
|
direction?: TDirection;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Form = ({ children, onSubmit, id }: IFormProps) => {
|
const Form = ({ children, onSubmit, id }: IFormProps) => {
|
||||||
@@ -30,9 +34,9 @@ const Form = ({ children, onSubmit, id }: IFormProps) => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const FormRow = ({ label, error, children }: IFormRow) => {
|
const FormRow = ({ label, error, children, direction }: IFormRow) => {
|
||||||
return (
|
return (
|
||||||
<StyledFormRow>
|
<StyledFormRow direction={direction}>
|
||||||
<Label>{label}</Label>
|
<Label>{label}</Label>
|
||||||
<div>
|
<div>
|
||||||
{children}
|
{children}
|
||||||
|
|||||||
@@ -1,4 +1,11 @@
|
|||||||
import styled from 'styled-components';
|
import styled, { css } from 'styled-components';
|
||||||
|
|
||||||
|
// Types
|
||||||
|
import { TDirection } from '@type/common';
|
||||||
|
|
||||||
|
interface IStyledFormRow {
|
||||||
|
direction?: TDirection;
|
||||||
|
}
|
||||||
|
|
||||||
// Styled
|
// Styled
|
||||||
import Button from '@commonStyle/Button';
|
import Button from '@commonStyle/Button';
|
||||||
@@ -16,11 +23,20 @@ const StyledActionBtn = styled.div`
|
|||||||
gap: 100px;
|
gap: 100px;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const StyledFormRow = styled.div`
|
const StyledFormRow = styled.div<IStyledFormRow>`
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
|
|
||||||
|
${(props) =>
|
||||||
|
props.direction === 'horizontal'
|
||||||
|
? css`
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 100px;
|
gap: 100px;
|
||||||
|
`
|
||||||
|
: css`
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 15px;
|
||||||
|
`}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const Label = styled.label`
|
const Label = styled.label`
|
||||||
@@ -45,4 +61,8 @@ const FormBtn = styled(Button)`
|
|||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
StyledFormRow.defaultProps = {
|
||||||
|
direction: 'horizontal',
|
||||||
|
};
|
||||||
|
|
||||||
export { StyledForm, StyledActionBtn, StyledFormRow, Label, Error, FormBtn };
|
export { StyledForm, StyledActionBtn, StyledFormRow, Label, Error, FormBtn };
|
||||||
|
|||||||
@@ -6,7 +6,12 @@ import ButtonIcon from '@component/ButtonIcon';
|
|||||||
// Styled
|
// Styled
|
||||||
import { StyledHeaderMenu } from './styled';
|
import { StyledHeaderMenu } from './styled';
|
||||||
|
|
||||||
|
// Hooks
|
||||||
|
import { useLogout } from '@hook/authentication/useLogout';
|
||||||
|
|
||||||
const HeaderMenu = () => {
|
const HeaderMenu = () => {
|
||||||
|
const { logout, isPending } = useLogout();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<StyledHeaderMenu>
|
<StyledHeaderMenu>
|
||||||
<li>
|
<li>
|
||||||
@@ -18,6 +23,8 @@ const HeaderMenu = () => {
|
|||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<ButtonIcon
|
<ButtonIcon
|
||||||
|
onClick={logout}
|
||||||
|
disabled={isPending}
|
||||||
aria-label="Logout"
|
aria-label="Logout"
|
||||||
icon={<HiOutlineLogout />}
|
icon={<HiOutlineLogout />}
|
||||||
iconStyle={{ size: '23px' }}
|
iconStyle={{ size: '23px' }}
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
import { Outlet } from 'react-router-dom';
|
||||||
|
|
||||||
|
// Styled
|
||||||
|
import Spinner from '@commonStyle/Spinner';
|
||||||
|
import { FullPageLayout } from './styled';
|
||||||
|
|
||||||
|
// Hooks
|
||||||
|
import { useAccount } from '@hook/authentication/useAccount';
|
||||||
|
|
||||||
|
const RootLayout = () => {
|
||||||
|
const { isPending } = useAccount();
|
||||||
|
|
||||||
|
return isPending ? (
|
||||||
|
<FullPageLayout>
|
||||||
|
<Spinner />
|
||||||
|
</FullPageLayout>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<Outlet />
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default RootLayout;
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
import styled from 'styled-components';
|
||||||
|
|
||||||
|
const FullPageLayout = styled.div`
|
||||||
|
height: 100vh;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
`;
|
||||||
|
|
||||||
|
export { FullPageLayout };
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
import { useAccount } from '@hook/authentication/useAccount';
|
||||||
|
import { ReactNode } from 'react';
|
||||||
|
import { Navigate } from 'react-router-dom';
|
||||||
|
|
||||||
|
interface IRouteProtected {
|
||||||
|
children: ReactNode;
|
||||||
|
}
|
||||||
|
const RouteProtected = ({ children }: IRouteProtected) => {
|
||||||
|
// Load user login
|
||||||
|
const { account } = useAccount();
|
||||||
|
|
||||||
|
return !account ? <Navigate to="/login" /> : children;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default RouteProtected;
|
||||||
@@ -4,3 +4,4 @@ export const ROOM = '/room';
|
|||||||
export const OTHER_PATH = '*';
|
export const OTHER_PATH = '*';
|
||||||
export const USER_PATH = 'users';
|
export const USER_PATH = 'users';
|
||||||
export const ROOM_PATH = 'rooms';
|
export const ROOM_PATH = 'rooms';
|
||||||
|
export const LOGIN = 'login';
|
||||||
|
|||||||
@@ -23,6 +23,8 @@
|
|||||||
|
|
||||||
--form-color: #fff;
|
--form-color: #fff;
|
||||||
|
|
||||||
|
--background-login: #f8f8f8;
|
||||||
|
|
||||||
--shadow-sm: 0px 10px 20px rgba(0, 0, 0, 0.2);
|
--shadow-sm: 0px 10px 20px rgba(0, 0, 0, 0.2);
|
||||||
|
|
||||||
--fs-md: 30px;
|
--fs-md: 30px;
|
||||||
|
|||||||
@@ -7,4 +7,11 @@ interface IDataState {
|
|||||||
isBooked?: boolean;
|
isBooked?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type { Nullable, IDataState };
|
interface ILogin {
|
||||||
|
email: string;
|
||||||
|
password: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
type TDirection = 'vertical' | 'horizontal';
|
||||||
|
|
||||||
|
export type { Nullable, IDataState, TDirection, ILogin };
|
||||||
|
|||||||
Reference in New Issue
Block a user