Skip to content

Commit

Permalink
add routes auth
Browse files Browse the repository at this point in the history
  • Loading branch information
Tatyana-js committed Dec 25, 2024
1 parent a41e456 commit 796c363
Show file tree
Hide file tree
Showing 12 changed files with 127 additions and 46 deletions.
2 changes: 1 addition & 1 deletion frontend/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@
</head>
<body class="h-100 bg-light">
<div id="root" class="h-100"></div>
<script type="module" src="/src/index.jsx"></script>
<script type="module" src="/src/index.js"></script>
</body>
</html>
14 changes: 9 additions & 5 deletions frontend/src/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import PageNotFound from './pages/PageNotFound.jsx';
import MainPage from './pages/MainPage.jsx';
import LoginPage from './pages/LoginPage.jsx';
import router from './utils/routes.js';
import AuthProvider from './context/AuthProvider.jsx';

const App = () => {
return (
Expand All @@ -16,11 +17,14 @@ const App = () => {
<button type="button" className="btn btn-primary">Выйти</button>
</Container>
</Navbar>
<Routes>
<Route path="*" element={<PageNotFound />} />
<Route path={router.main} element={<MainPage />} />
<Route path={router.login} element={<LoginPage />} />
</Routes>
<AuthProvider>
<Routes>
<Route path={router.main} element={<MainPage />} />
<Route path={router.login} element={<LoginPage />} />
<Route path="*" element={<PageNotFound />} />
</Routes>
</AuthProvider>

</div>
</BrowserRouter>
);
Expand Down
21 changes: 21 additions & 0 deletions frontend/src/context/AuthProvider.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { useState } from 'react';
import AuthContext from '../context/index.jsx';

// eslint-disable-next-line react/prop-types
const AuthProvider = ({ children }) => {
const [loggedIn, setLoggedIn] = useState(false);

const logIn = () => setLoggedIn(true);
const logOut = () => {
localStorage.removeItem('username');
setLoggedIn(false);
};

return (
<AuthContext.Provider value={{ loggedIn, logIn, logOut }}>
{children}
</AuthContext.Provider>
);
};

export default AuthProvider;
5 changes: 5 additions & 0 deletions frontend/src/context/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { createContext } from 'react';

const AuthContext = createContext({});

export default AuthContext;
7 changes: 7 additions & 0 deletions frontend/src/hooks/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { useContext } from 'react';

import authContext from '../context/index.jsx';

const useAuth = () => useContext(authContext);

export default useAuth;
File renamed without changes.
15 changes: 14 additions & 1 deletion frontend/src/locales/ru.js
Original file line number Diff line number Diff line change
@@ -1 +1,14 @@
export default {};
export default {
translation: {
loginForm: {
title: 'Войти',
username: 'Ваш ник',
password: 'Пароль',
span: 'Нет аккаунта?',
signUp: 'Регистрация',
},
// singUpForm: {
// username: ''
// }
}
};
55 changes: 38 additions & 17 deletions frontend/src/pages/LoginPage.jsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,44 @@
import axios from 'axios';
import { useEffect, useRef, useState } from 'react';
import { useLocation, useNavigate } from 'react-router-dom';
import { Container, Row, Col, Card, Form, Button } from 'react-bootstrap';
import { useFormik } from 'formik';
import * as yup from 'yup';
import { useTranslation } from 'react-i18next';
import avatarLogin from '../assets/avatarLogin.jpg';
import useAuth from '../hooks/index.js';
import routes from '../utils/routes.js';


const LoginPage = () => {
const schema = yup.object().shape({
username: yup.string().required(),
password: yup.string().required(),
});
const auth = useAuth();
const { t } = useTranslation();
const [authFailed, setAuthFailed] = useState(false);
const inputEl = useRef(null);
const navigate = useNavigate();

useEffect(() => {
inputEl.current.focus();
}, []);

const formik = useFormik({
initialValues: {
username: '',
password: '',
},
onSubmit: values => {
alert(JSON.stringify(values, null, 2));
validationSchema: userSchema(t),
onSubmit: async (values) => {
setAuthFailed(false);
try {
const res = await axios.post(routes.loginPath(), values);
console.log(res);
localStorage.setItem('token', res.data.token);
auth.logIn();
} catch (err) {
console.log(err);
}
},
});

return (
<Container fluid className="h-100">
<Row className="justify-content-center align-content-center h-100">
Expand All @@ -28,44 +49,44 @@ const LoginPage = () => {
<img src={avatarLogin} className="rounded-circle" alt="Войти" />
</div>
<Form className="col-12 col-md-6 mt-3 mt-md-0" onSubmit={formik.handleSubmit}>
<h1 className="text-center mb-4">Войти</h1>
<h1 className="text-center mb-4">{t('loginForm.title')}</h1>
<fieldset >
<Form.Group className="form-floating mb-3" controlId="username">
<Form.Control
type="text"
autoComplete="username"
required
placeholder="Ваш ник"
placeholder={t('loginForm.username')}
id="username"
onChange={formik.handleChange}
value={formik.values.username}
isInvalid={false}
// ref={inpit}
ref={inpitEl}
/>
<Form.Label>Ваш ник</Form.Label>
<Form.Label>{t('loginForm.username')}</Form.Label>
</Form.Group>
<Form.Group className="form-floating mb-4" controlId="password">
<Form.Control
type="password"
autoComplete="current-password"
required
placeholder="Пароль"
placeholder={t('loginForm.password')}
id="password"
onChange={formik.handleChange}
value={formik.values.password}
isInvalid={false}
// ref={inpit}
ref={inpitEl}
/>
<Form.Label>Пароль</Form.Label>
<Form.Label>{t('loginForm.password')}</Form.Label>
</Form.Group>
<Button type="submit" variant="outline-primary" className="w-100 mb-3">Войти</Button>
<Button type="submit" variant="outline-primary" className="w-100 mb-3">{t('loginForm.title')}</Button>
</fieldset>
</Form>
</Card.Body>
<Card.Footer className="p-4">
<div className="text-center">
<span>Нет аккаунта? </span>
<a href="/signup">Регистрация</a>
<span>{t('loginForm.span')} </span>
<a href="/signup">{t('loginForm.signUp')}</a>
</div>
</Card.Footer>
</Card>
Expand Down
26 changes: 13 additions & 13 deletions frontend/src/store/channelsSlice.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import { createSlice } from '@reduxjs/toolkit';
// import { createSlice } from '@reduxjs/toolkit';

const initialState = {
channels: [],
activeChannel: 1,
};
// const initialState = {
// channels: [],
// activeChannel: 1,
// };

const channelsSlice = createSlice({
name: 'channels',
initialState,
reducers: {
// const channelsSlice = createSlice({
// name: 'channels',
// initialState,
// reducers: {

}
});
// }
// });

export const { actions } = channelsSlice;
export default channelsSlice.reducer;
// export const { actions } = channelsSlice;
// export default channelsSlice.reducer;
14 changes: 7 additions & 7 deletions frontend/src/store/index.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { configureStore } from '@reduxjs/toolkit';
import channelsReducer from './channelsSlice';
// import { configureStore } from '@reduxjs/toolkit';
// import channelsReducer from './channelsSlice';

export default configureStore({
reducer: {
channels: channelsReducer,
}
});
// export default configureStore({
// reducer: {
// channels: channelsReducer,
// }
// });
6 changes: 4 additions & 2 deletions frontend/src/utils/routes.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
const apiPath = '/api/v1';

export default {
login: '/login',
main: '/',
loginPath: () => '/login',
usersPath: () => [apiPath, 'data'].join('/'),
};
8 changes: 8 additions & 0 deletions frontend/src/utils/validate.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { object, string } from 'yup';

const userSchema = (t) => object().shape({
username: string().required(),
password: string().required(),
});

export default userSchema;

0 comments on commit 796c363

Please sign in to comment.