mirror of
https://github.com/sergeyyarkov/educt-client.git
synced 2026-10-11 10:19:22 +03:00
refactor: auth page
This commit is contained in:
parent
16613a22a7
commit
2b185c57de
21712
package-lock.json
generated
21712
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -21,7 +21,7 @@
|
|||||||
"react-dom": "^17.0.2",
|
"react-dom": "^17.0.2",
|
||||||
"react-helmet": "^6.1.0",
|
"react-helmet": "^6.1.0",
|
||||||
"react-hook-form": "^7.12.2",
|
"react-hook-form": "^7.12.2",
|
||||||
"react-icons": "^3.0.0",
|
"react-icons": "^3.11.0",
|
||||||
"react-router-dom": "^5.2.0",
|
"react-router-dom": "^5.2.0",
|
||||||
"react-scripts": "4.0.3",
|
"react-scripts": "4.0.3",
|
||||||
"typescript": "^3.9.5",
|
"typescript": "^3.9.5",
|
||||||
|
|||||||
@ -1,110 +0,0 @@
|
|||||||
import React, { useState } from 'react';
|
|
||||||
import { MdAccountCircle, MdVpnKey } from 'react-icons/md';
|
|
||||||
import {
|
|
||||||
Flex,
|
|
||||||
Box,
|
|
||||||
FormControl,
|
|
||||||
FormLabel,
|
|
||||||
InputGroup,
|
|
||||||
Input,
|
|
||||||
InputLeftElement,
|
|
||||||
Button,
|
|
||||||
Icon,
|
|
||||||
} from '@chakra-ui/react';
|
|
||||||
import { useRootStore } from '../../hooks/useRootStore';
|
|
||||||
import { useHistory } from 'react-router-dom';
|
|
||||||
import { observer } from 'mobx-react';
|
|
||||||
|
|
||||||
type LoginDataInput = {
|
|
||||||
login: string;
|
|
||||||
password: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Authorize user through a form.
|
|
||||||
*/
|
|
||||||
const Auth: React.FC = () => {
|
|
||||||
const [loginFormData, setLoginFormData] = useState<LoginDataInput>({
|
|
||||||
login: '',
|
|
||||||
password: '',
|
|
||||||
});
|
|
||||||
const { authStore } = useRootStore();
|
|
||||||
const history = useHistory();
|
|
||||||
|
|
||||||
const handleLoginForm = async (e: React.FormEvent<HTMLFormElement>) => {
|
|
||||||
e.preventDefault();
|
|
||||||
|
|
||||||
const { login, password } = loginFormData;
|
|
||||||
await authStore.login(login, password);
|
|
||||||
history.push('/');
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Flex minHeight='100vh' align='center' justifyContent='center'>
|
|
||||||
<Box
|
|
||||||
p={8}
|
|
||||||
my={40}
|
|
||||||
width='full'
|
|
||||||
maxWidth='450px'
|
|
||||||
borderWidth={1}
|
|
||||||
borderRadius={8}>
|
|
||||||
<Box textAlign='center'>
|
|
||||||
<Flex justifyContent='center'>
|
|
||||||
{/* <LogoIcon viewBox='0 0 24 24' boxSize={'64px'} fill='blue.600' /> */}
|
|
||||||
</Flex>
|
|
||||||
</Box>
|
|
||||||
<Box my='30px'>
|
|
||||||
<form onSubmit={handleLoginForm}>
|
|
||||||
<FormControl isRequired={true}>
|
|
||||||
<FormLabel>Login</FormLabel>
|
|
||||||
<InputGroup>
|
|
||||||
<InputLeftElement children={<Icon as={MdAccountCircle} />} />
|
|
||||||
<Input
|
|
||||||
type='text'
|
|
||||||
name='login'
|
|
||||||
placeholder='email@mail.com'
|
|
||||||
value={loginFormData.login}
|
|
||||||
onChange={(e) =>
|
|
||||||
setLoginFormData({
|
|
||||||
...loginFormData,
|
|
||||||
login: e.target.value,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</InputGroup>
|
|
||||||
</FormControl>
|
|
||||||
<FormControl mt={5} isRequired={true}>
|
|
||||||
<FormLabel>Password</FormLabel>
|
|
||||||
<InputGroup>
|
|
||||||
<InputLeftElement children={<Icon as={MdVpnKey} />} />
|
|
||||||
<Input
|
|
||||||
type='password'
|
|
||||||
name='password'
|
|
||||||
placeholder='********'
|
|
||||||
value={loginFormData.password}
|
|
||||||
onChange={(e) =>
|
|
||||||
setLoginFormData({
|
|
||||||
...loginFormData,
|
|
||||||
password: e.target.value,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</InputGroup>
|
|
||||||
</FormControl>
|
|
||||||
<Button
|
|
||||||
loadingText='Logging in...'
|
|
||||||
type='submit'
|
|
||||||
colorScheme='blue'
|
|
||||||
variant='outline'
|
|
||||||
width='full'
|
|
||||||
mt={4}>
|
|
||||||
Log in
|
|
||||||
</Button>
|
|
||||||
</form>
|
|
||||||
</Box>
|
|
||||||
</Box>
|
|
||||||
</Flex>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default observer(Auth);
|
|
||||||
87
src/components/Auth/AuthForm.tsx
Normal file
87
src/components/Auth/AuthForm.tsx
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
import React, { useState } from 'react';
|
||||||
|
import { MdAccountCircle, MdVpnKey } from 'react-icons/md';
|
||||||
|
import {
|
||||||
|
FormControl,
|
||||||
|
FormLabel,
|
||||||
|
InputGroup,
|
||||||
|
Input,
|
||||||
|
InputLeftElement,
|
||||||
|
Button,
|
||||||
|
Icon,
|
||||||
|
} from '@chakra-ui/react';
|
||||||
|
import { useRootStore } from '../../hooks/useRootStore';
|
||||||
|
import { useHistory } from 'react-router-dom';
|
||||||
|
import { observer } from 'mobx-react';
|
||||||
|
|
||||||
|
type AuthFormState = {
|
||||||
|
login: string;
|
||||||
|
password: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
const AuthForm: React.FC = () => {
|
||||||
|
const [authFormState, setAuthFormState] = useState<AuthFormState>({
|
||||||
|
login: '',
|
||||||
|
password: '',
|
||||||
|
});
|
||||||
|
const { authStore } = useRootStore();
|
||||||
|
const history = useHistory();
|
||||||
|
const handleLoginForm = async (e: React.FormEvent<HTMLFormElement>) => {
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
const { login, password } = authFormState;
|
||||||
|
await authStore.login(login, password);
|
||||||
|
history.push('/');
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<form onSubmit={handleLoginForm}>
|
||||||
|
<FormControl isRequired={true}>
|
||||||
|
<FormLabel>Login</FormLabel>
|
||||||
|
<InputGroup>
|
||||||
|
<InputLeftElement children={<Icon as={MdAccountCircle} />} />
|
||||||
|
<Input
|
||||||
|
type='text'
|
||||||
|
name='login'
|
||||||
|
placeholder='email@mail.com'
|
||||||
|
value={authFormState.login}
|
||||||
|
onChange={(e) =>
|
||||||
|
setAuthFormState({
|
||||||
|
...authFormState,
|
||||||
|
login: e.target.value,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</InputGroup>
|
||||||
|
</FormControl>
|
||||||
|
<FormControl mt={5} isRequired={true}>
|
||||||
|
<FormLabel>Password</FormLabel>
|
||||||
|
<InputGroup>
|
||||||
|
<InputLeftElement children={<Icon as={MdVpnKey} />} />
|
||||||
|
<Input
|
||||||
|
type='password'
|
||||||
|
name='password'
|
||||||
|
placeholder='********'
|
||||||
|
value={authFormState.password}
|
||||||
|
onChange={(e) =>
|
||||||
|
setAuthFormState({
|
||||||
|
...authFormState,
|
||||||
|
password: e.target.value,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</InputGroup>
|
||||||
|
</FormControl>
|
||||||
|
<Button
|
||||||
|
loadingText='Logging in...'
|
||||||
|
type='submit'
|
||||||
|
colorScheme='blue'
|
||||||
|
variant='outline'
|
||||||
|
width='full'
|
||||||
|
mt={4}>
|
||||||
|
Log in
|
||||||
|
</Button>
|
||||||
|
</form>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default observer(AuthForm)
|
||||||
@ -1,11 +1,17 @@
|
|||||||
import { observer } from 'mobx-react';
|
import { observer } from 'mobx-react';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import {
|
||||||
|
Flex,
|
||||||
|
Box,
|
||||||
|
} from '@chakra-ui/react';
|
||||||
|
import { MdSchool } from "react-icons/md";
|
||||||
import Helmet from 'react-helmet';
|
import Helmet from 'react-helmet';
|
||||||
import { useHistory } from 'react-router-dom';
|
import { useHistory } from 'react-router-dom';
|
||||||
import Auth from '../components/Auth/Auth';
|
|
||||||
import { useRootStore } from '../hooks/useRootStore';
|
import { useRootStore } from '../hooks/useRootStore';
|
||||||
import { IPageProps } from '../interfaces';
|
import { IPageProps } from '../interfaces';
|
||||||
|
|
||||||
|
import AuthForm from '../components/Auth/AuthForm';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Auth page
|
* Auth page
|
||||||
*/
|
*/
|
||||||
@ -22,7 +28,24 @@ const AuthPage: React.FC<IPageProps> = () => {
|
|||||||
<Helmet>
|
<Helmet>
|
||||||
<title>Auth</title>
|
<title>Auth</title>
|
||||||
</Helmet>
|
</Helmet>
|
||||||
<Auth />
|
<Flex minHeight='100vh' align='center' justifyContent='center'>
|
||||||
|
<Box
|
||||||
|
p={8}
|
||||||
|
my={40}
|
||||||
|
width='full'
|
||||||
|
maxWidth='450px'
|
||||||
|
borderWidth={1}
|
||||||
|
borderRadius={8}>
|
||||||
|
<Box textAlign='center'>
|
||||||
|
<Flex justifyContent='center'>
|
||||||
|
<MdSchool fill='blue' size='64px' />
|
||||||
|
</Flex>
|
||||||
|
</Box>
|
||||||
|
<Box my='30px'>
|
||||||
|
<AuthForm />
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
</Flex>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -7,12 +7,13 @@ import {
|
|||||||
BreadcrumbLink,
|
BreadcrumbLink,
|
||||||
Grid,
|
Grid,
|
||||||
} from '@chakra-ui/react';
|
} from '@chakra-ui/react';
|
||||||
|
|
||||||
import { IPageProps } from '../interfaces';
|
import { IPageProps } from '../interfaces';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Main page
|
* Main page
|
||||||
*/
|
*/
|
||||||
const MainPage: React.FC<IPageProps> = ({ title, history }) => {
|
const MainPage: React.FC<IPageProps> = ({ title }) => {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Breadcrumb fontWeight='medium' fontSize='sm'>
|
<Breadcrumb fontWeight='medium' fontSize='sm'>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user