Skip to content

Commit 3285602

Browse files
committed
added Login, PageNotFound & configured routing
1 parent 4f9c174 commit 3285602

File tree

11 files changed

+1024
-58
lines changed

11 files changed

+1024
-58
lines changed

frontend/package-lock.json

Lines changed: 428 additions & 11 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

frontend/package.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,13 @@
1010
"preview": "vite preview"
1111
},
1212
"dependencies": {
13+
"bootstrap": "^5.3.3",
14+
"formik": "^2.4.6",
1315
"react": "^19.0.0",
14-
"react-dom": "^19.0.0"
16+
"react-bootstrap": "^2.10.9",
17+
"react-dom": "^19.0.0",
18+
"react-router-dom": "^7.1.5",
19+
"yup": "^1.6.1"
1520
},
1621
"devDependencies": {
1722
"@eslint/js": "^9.19.0",

frontend/src/App.jsx

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
import { useState } from 'react'
2-
import reactLogo from './assets/react.svg'
3-
import viteLogo from '/vite.svg'
4-
import './App.css'
1+
import { useState } from 'react';
2+
import reactLogo from './assets/react.svg';
3+
import viteLogo from '/vite.svg';
4+
import './App.css';
55

66
function App() {
7-
const [count, setCount] = useState(0)
7+
const [count, setCount] = useState(0);
88

99
return (
1010
<>
@@ -29,7 +29,7 @@ function App() {
2929
Click on the Vite and React logos to learn more
3030
</p>
3131
</>
32-
)
32+
);
3333
}
3434

35-
export default App
35+
export default App;

frontend/src/Components/Login.jsx

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
import { useFormik /*, ErrorMessage*/ } from 'formik';
2+
import { Form, Button } from 'react-bootstrap';
3+
4+
const Login = () => {
5+
const formik = useFormik({
6+
initialValues: {
7+
nickname: '',
8+
password: '',
9+
},
10+
validate: (values) => {
11+
const errors = {};
12+
13+
if (!values.nickname) {
14+
errors.nickname = 'Обязательное поле';
15+
} else if (values.nickname.length < 3) {
16+
errors.nickname = 'Ник должен содержать минимум 3 символа';
17+
}
18+
19+
if (!values.password) {
20+
errors.password = 'Обязательное поле';
21+
} else if (values.password.length < 6) {
22+
errors.password = 'Пароль должен содержать минимум 6 символов';
23+
}
24+
return errors;
25+
},
26+
onSubmit: (values) => {
27+
console.log(JSON.stringify(values, null, 2));
28+
},
29+
});
30+
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>
57+
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+
// /> */}
88+
89+
// <button type="submit">Submit</button>
90+
// </form>
91+
);
92+
};
93+
94+
export default Login;

frontend/src/Components/MainPage.jsx

Whitespace-only changes.
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { Link } from 'react-router-dom';
2+
import { Navbar, Container, Nav } from 'react-bootstrap';
3+
4+
const Navigation = () => {
5+
return (
6+
<Navbar bg="light" expand="lg">
7+
<Container>
8+
<Navbar.Toggle aria-controls="basic-navbar-nav" />
9+
<Navbar.Collapse id="basic-navbar-nav">
10+
<Nav className="me-auto">
11+
<Nav.Link as={Link} to="/">
12+
Home
13+
</Nav.Link>
14+
<Nav.Link as={Link} to="/login">
15+
Log in
16+
</Nav.Link>
17+
</Nav>
18+
</Navbar.Collapse>
19+
</Container>
20+
</Navbar>
21+
);
22+
};
23+
24+
export default Navigation;
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { Link } from 'react-router-dom';
2+
import { Container } from 'react-bootstrap';
3+
import notFoundImage from '/src/assets/404-D_FLHmTM.svg';
4+
5+
const PageNotFound = () => {
6+
return (
7+
<Container className="text-center mt-5">
8+
<img
9+
className="img-fluid"
10+
alt="Страница не найдена"
11+
src={notFoundImage}
12+
style={{ maxWidth: '300px' }}
13+
></img>
14+
<h1 className="h4">Страница не найдена</h1>
15+
<p className="mt-3">
16+
Но вы можете перейти на <Link to="/">главную страницу</Link>
17+
</p>
18+
</Container>
19+
);
20+
};
21+
22+
export default PageNotFound;

frontend/src/assets/404-D_FLHmTM.svg

Lines changed: 1 addition & 0 deletions
Loading

frontend/src/main.jsx

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,22 @@
1-
import { StrictMode } from 'react'
2-
import { createRoot } from 'react-dom/client'
3-
import './index.css'
4-
import App from './App.jsx'
1+
import { StrictMode } from 'react';
2+
import { createRoot } from 'react-dom/client';
3+
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
4+
import 'bootstrap/dist/css/bootstrap.min.css';
5+
import './index.css';
6+
import App from './App.jsx';
7+
import Login from './Components/Login.jsx';
8+
import Navigation from './Components/Navigation.jsx';
9+
import PageNotFound from './Components/PageNotFound.jsx';
510

611
createRoot(document.getElementById('root')).render(
712
<StrictMode>
8-
<App />
9-
</StrictMode>,
10-
)
13+
<Router>
14+
<Navigation />
15+
<Routes>
16+
<Route path="/" element={<App />} />
17+
<Route path="/login" element={<Login />} />
18+
<Route path="*" element={<PageNotFound />} />
19+
</Routes>
20+
</Router>
21+
</StrictMode>
22+
);

0 commit comments

Comments
 (0)