|
1 | | -import { useFormik /*, ErrorMessage*/ } from 'formik'; |
2 | | -import { Form, Button } from 'react-bootstrap'; |
| 1 | +import { useState } from 'react'; |
| 2 | +import { useFormik } from 'formik'; |
| 3 | +import axios from 'axios'; |
| 4 | +import { Form, Button, Container, Col, Card, Row } from 'react-bootstrap'; |
| 5 | +import { useNavigate } from 'react-router-dom'; |
| 6 | +import { useDispatch } from 'react-redux'; |
| 7 | + |
| 8 | +import { login } from '../features/auth/authSlice'; |
| 9 | + |
| 10 | +import logInImage from '../assets/avatar-DIE1AEpS.jpg'; |
3 | 11 |
|
4 | 12 | const Login = () => { |
| 13 | + const navigate = useNavigate(); |
| 14 | + const dispatch = useDispatch(); |
| 15 | + const [authError, setAuthError] = useState(null); |
| 16 | + const [submitted, setSubmitted] = useState(false); |
| 17 | + |
5 | 18 | const formik = useFormik({ |
6 | 19 | initialValues: { |
7 | | - nickname: '', |
| 20 | + username: '', |
8 | 21 | password: '', |
9 | 22 | }, |
10 | 23 | validate: (values) => { |
11 | 24 | const errors = {}; |
12 | 25 |
|
13 | | - if (!values.nickname) { |
14 | | - errors.nickname = 'Обязательное поле'; |
15 | | - } else if (values.nickname.length < 3) { |
16 | | - errors.nickname = 'Ник должен содержать минимум 3 символа'; |
| 26 | + if (!values.username) { |
| 27 | + errors.username = 'Обязательное поле'; |
| 28 | + } else if (values.username.length < 3) { |
| 29 | + errors.username = 'Ник должен содержать минимум 3 символа'; |
17 | 30 | } |
18 | 31 |
|
19 | 32 | if (!values.password) { |
20 | 33 | errors.password = 'Обязательное поле'; |
21 | | - } else if (values.password.length < 6) { |
22 | | - errors.password = 'Пароль должен содержать минимум 6 символов'; |
| 34 | + } else if (values.password.length < 5) { |
| 35 | + errors.password = 'Пароль должен содержать минимум 5 символов'; |
23 | 36 | } |
24 | 37 | return errors; |
25 | 38 | }, |
26 | | - onSubmit: (values) => { |
27 | | - console.log(JSON.stringify(values, null, 2)); |
| 39 | + onSubmit: async (values) => { |
| 40 | + try { |
| 41 | + const response = await axios.post('/api/v1/login', values); |
| 42 | + dispatch(login({ user: values.username, token: response.data.token })); |
| 43 | + navigate('/'); |
| 44 | + setSubmitted(false); |
| 45 | + } catch (error) { |
| 46 | + console.error('Ошибка авторизации', error); |
| 47 | + setAuthError('Неверное имя пользователя или пароль'); |
| 48 | + setSubmitted(true); |
| 49 | + } |
28 | 50 | }, |
29 | 51 | }); |
30 | 52 | return ( |
31 | | - <Form onSubmit={formik.handleSubmit}> |
32 | | - <Form.Group className="mb-3" controlId="nickname"> |
33 | | - <Form.Label>Ваш ник</Form.Label> |
34 | | - <Form.Control |
35 | | - type="text" |
36 | | - placeholder="Введите ваш ник" |
37 | | - {...formik.getFieldProps('nickname')} |
38 | | - isInvalid={formik.touched.nickname && !!formik.errors.nickname} |
39 | | - /> |
40 | | - <Form.Control.Feedback type="invalid"> |
41 | | - {formik.errors.nickname} |
42 | | - </Form.Control.Feedback> |
43 | | - </Form.Group> |
44 | | - |
45 | | - <Form.Group className="mb-3" controlId="password"> |
46 | | - <Form.Label>Пароль</Form.Label> |
47 | | - <Form.Control |
48 | | - type="password" |
49 | | - placeholder="Введите пароль" |
50 | | - {...formik.getFieldProps('password')} |
51 | | - isInvalid={formik.touched.password && !!formik.errors.password} |
52 | | - /> |
53 | | - <Form.Control.Feedback type="invalid"> |
54 | | - {formik.errors.password} |
55 | | - </Form.Control.Feedback> |
56 | | - </Form.Group> |
| 53 | + <Container className="h-100 d-flex flex-column"> |
| 54 | + <Row className="justify-content-center align-content-center flex-grow-1"> |
| 55 | + <Col md={8} xxl={6}> |
| 56 | + <Card className="shadow-sm"> |
| 57 | + <Card.Body className="row p-5"> |
| 58 | + {/* <Row className="align-items-center"> */} |
| 59 | + <Col |
| 60 | + md={6} |
| 61 | + className="d-flex align-items-center justify-content-center" |
| 62 | + > |
| 63 | + <img |
| 64 | + src={logInImage} |
| 65 | + alt="Log in" |
| 66 | + className="img-fluid rounded-circle" |
| 67 | + /> |
| 68 | + </Col> |
| 69 | + <Form |
| 70 | + onSubmit={formik.handleSubmit} |
| 71 | + className="col-12 col-md-6 mt-3 mt-md-0" |
| 72 | + > |
| 73 | + <h1 className="text-center mb-4">Войти</h1> |
| 74 | + <Form.Floating className="mb-3"> |
| 75 | + <Form.Control |
| 76 | + type="text" |
| 77 | + placeholder="Ваш ник" |
| 78 | + {...formik.getFieldProps('username')} |
| 79 | + isInvalid={submitted && !!formik.errors.username} |
| 80 | + /> |
| 81 | + <Form.Label>Ваш ник</Form.Label> |
| 82 | + <Form.Control.Feedback type="invalid"> |
| 83 | + {formik.errors.username} |
| 84 | + </Form.Control.Feedback> |
| 85 | + </Form.Floating> |
57 | 86 |
|
58 | | - <Button variant="primary" type="submit"> |
59 | | - Войти |
60 | | - </Button> |
61 | | - </Form> |
62 | | - // <form onSubmit={formik.handleSubmit}> |
63 | | - // <label htmlFor="Nickname">Ваш ник</label> |
64 | | - // <input |
65 | | - // id="nickname" |
66 | | - // name="nickname" |
67 | | - // type="text" |
68 | | - // onChange={formik.handleChange} |
69 | | - // value={formik.values.nickname} |
70 | | - // /> |
71 | | - // <label htmlFor="password">Пароль</label> |
72 | | - // <input |
73 | | - // type="password" |
74 | | - // name="password" |
75 | | - // onChange={formik.handleChange} |
76 | | - // value={formik.values.password} |
77 | | - // /> |
78 | | - // {/* <ErrorMessage |
79 | | - // component="div" |
80 | | - // name="nickname" |
81 | | - // className="invalid-feedback" |
82 | | - // /> |
83 | | - // <ErrorMessage |
84 | | - // component="div" |
85 | | - // name="password" |
86 | | - // className="invalid-feedback" |
87 | | - // /> */} |
| 87 | + <Form.Floating className="mb-4"> |
| 88 | + <Form.Control |
| 89 | + type="password" |
| 90 | + placeholder="Пароль" |
| 91 | + {...formik.getFieldProps('password')} |
| 92 | + isInvalid={submitted && !!formik.errors.password} |
| 93 | + /> |
| 94 | + <Form.Label>Пароль</Form.Label> |
| 95 | + <Form.Control.Feedback type="invalid"> |
| 96 | + {formik.errors.password} |
| 97 | + </Form.Control.Feedback> |
| 98 | + </Form.Floating> |
88 | 99 |
|
89 | | - // <button type="submit">Submit</button> |
90 | | - // </form> |
| 100 | + <Button |
| 101 | + variant="outline-primary" |
| 102 | + type="submit" |
| 103 | + className="w-100 mb-3" |
| 104 | + > |
| 105 | + Войти |
| 106 | + </Button> |
| 107 | + {authError && ( |
| 108 | + <div className="text-danger mt-3 text-center"> |
| 109 | + {authError} |
| 110 | + </div> |
| 111 | + )} |
| 112 | + </Form> |
| 113 | + {/* </Row> */} |
| 114 | + </Card.Body> |
| 115 | + <Card.Footer className="card_footer text-center p-4"> |
| 116 | + Нет аккаунта? <a href="#">Регистрация</a> |
| 117 | + </Card.Footer> |
| 118 | + </Card> |
| 119 | + </Col> |
| 120 | + </Row> |
| 121 | + </Container> |
91 | 122 | ); |
92 | 123 | }; |
93 | 124 |
|
|
0 commit comments