LoginPage.jsx 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. import Avatar from '@mui/material/Avatar';
  2. import Button from '@mui/material/Button';
  3. import CssBaseline from '@mui/material/CssBaseline';
  4. import TextField from '@mui/material/TextField';
  5. import FormControlLabel from '@mui/material/FormControlLabel';
  6. import Checkbox from '@mui/material/Checkbox';
  7. import Link from '@mui/material/Link';
  8. import Grid from '@mui/material/Grid';
  9. import Box from '@mui/material/Box';
  10. import LockOutlinedIcon from '@mui/icons-material/LockOutlined';
  11. import Typography from '@mui/material/Typography';
  12. import Container from '@mui/material/Container';
  13. import { createTheme, ThemeProvider } from '@mui/material/styles';
  14. import { lightGreen } from '@mui/material/colors';
  15. import { categoriesApi, useGetLoginMutation } from '../../store/categoriesApi';
  16. import { useDispatch, useSelector } from 'react-redux';
  17. import { setCredentials } from '../../store/authSlice';
  18. import { Navigate, Link as RoterLink, useNavigate, useLocation } from 'react-router-dom';
  19. import { Alert, Snackbar } from '@mui/material';
  20. import { useState } from 'react';
  21. function jwtDecode(token) {
  22. let result;
  23. try {
  24. let secondPartToken = token.split('.')[1];
  25. result = JSON.parse(atob(secondPartToken));
  26. } catch (e) {
  27. }
  28. return result;
  29. }
  30. const theme = createTheme();
  31. export default function SignIn() {
  32. const navigate = useNavigate()
  33. const location = useLocation()
  34. const fromPage = location.state?.from?.pathname || '/'
  35. console.log(fromPage)
  36. const [open, setOpen] = useState(false);
  37. const handleClose = (event, reason) => {
  38. if (reason === 'clickaway') {
  39. return;
  40. }
  41. setOpen(false);
  42. };
  43. const userAuth = useSelector((state) => state.auth.user)
  44. const dispatch = useDispatch()
  45. const [loginQuery, { isLoading }] = useGetLoginMutation()
  46. const handleSubmit = async (event) => {
  47. event.preventDefault();
  48. const dataForm = new FormData(event.currentTarget);
  49. const { data } = await loginQuery({
  50. login: dataForm.get('email'),
  51. password: dataForm.get('password')
  52. })
  53. if (data) {
  54. const token = data.login
  55. const user = jwtDecode(token)
  56. if (user) {
  57. dispatch(setCredentials({ user, token }))
  58. console.log(user.sub.id)
  59. dispatch( categoriesApi.endpoints.getUserById.initiate(user.sub.id))
  60. navigate(fromPage, {replace: true})
  61. }
  62. else {
  63. setOpen(true)
  64. }
  65. }
  66. };
  67. return (
  68. <>
  69. {userAuth ? <Navigate replace to="/profile" /> :
  70. <>
  71. <Snackbar
  72. open={open}
  73. autoHideDuration={2000}
  74. onClose={handleClose}
  75. message="Note archived"
  76. >
  77. <Alert severity="error">Вы ввели неправильный логин или пароль!</Alert>
  78. </Snackbar>
  79. <ThemeProvider theme={theme}>
  80. <Container component="main" maxWidth="xs">
  81. <CssBaseline />
  82. <Box
  83. sx={{
  84. marginTop: 3,
  85. display: 'flex',
  86. flexDirection: 'column',
  87. alignItems: 'center',
  88. marginBottom: 3,
  89. }}
  90. >
  91. <Avatar sx={{ m: 1, bgcolor: lightGreen[800] }}>
  92. <LockOutlinedIcon />
  93. </Avatar>
  94. <Typography component="h1" variant="h5">
  95. Войти
  96. </Typography>
  97. <Box component="form" onSubmit={handleSubmit} noValidate sx={{ mt: 1 }}>
  98. <TextField
  99. margin="normal"
  100. required
  101. fullWidth
  102. id="email"
  103. label="Email или имя профиля"
  104. name="email"
  105. autoComplete="email"
  106. autoFocus
  107. />
  108. <TextField
  109. margin="normal"
  110. required
  111. fullWidth
  112. name="password"
  113. label="Пароль"
  114. type="password"
  115. id="password"
  116. autoComplete="current-password"
  117. />
  118. <FormControlLabel
  119. control={<Checkbox value="remember" color="primary" />}
  120. label="Запомнить меня"
  121. />
  122. <Button
  123. type="submit"
  124. fullWidth
  125. variant="contained"
  126. sx={{ mt: 3, mb: 2 }}
  127. >
  128. Войти
  129. </Button>
  130. <Grid container>
  131. <Grid item xs>
  132. <Link href="#" variant="body2">
  133. Забыли пароль?
  134. </Link>
  135. </Grid>
  136. <Grid item>
  137. <Link to="/registration" variant="body2" component={RoterLink}>
  138. {"У Вас нет аккаунта? Зарегистрироваться"}
  139. </Link>
  140. </Grid>
  141. </Grid>
  142. </Box>
  143. </Box>
  144. </Container>
  145. </ThemeProvider>
  146. </>
  147. }
  148. </>
  149. );
  150. }