diff --git a/Lab5/data.json b/Lab5/data.json index 50b2e59..fb53e45 100644 --- a/Lab5/data.json +++ b/Lab5/data.json @@ -4,7 +4,7 @@ "id": 0, "login": "dyctator", "password": "12345", - "role": "user" + "role": "admin" }, { "login": "user", diff --git a/Lab5/src/App.jsx b/Lab5/src/App.jsx index 5369184..33446e0 100644 --- a/Lab5/src/App.jsx +++ b/Lab5/src/App.jsx @@ -5,17 +5,20 @@ import { Outlet } from 'react-router-dom'; import { CartProvider } from './components/cart/CartContext.jsx'; import Footer from './components/footer/Footer.jsx'; import Navigation from './components/navigation/Navigation.jsx'; +import { AuthProvider } from './components/logins/login/context/AuthContext.jsx'; const App = ({ routes }) => { return ( - - - - - - - - + + + + + + + + + + ); }; diff --git a/Lab5/src/components/lines/News/UpdateNews.jsx b/Lab5/src/components/lines/News/UpdateNews.jsx index 7277b60..fcb2a09 100644 --- a/Lab5/src/components/lines/News/UpdateNews.jsx +++ b/Lab5/src/components/lines/News/UpdateNews.jsx @@ -1,5 +1,5 @@ import { useSearchParams } from 'react-router-dom'; -import { useState, useEffect } from 'react'; +import { useState, useEffect, useContext } from 'react'; import PropTypes from 'prop-types'; import { Button, Container, @@ -13,10 +13,17 @@ import useLinesFormModal from '../hooks/LinesFormModalHook'; import LinesItemForm from '../form/LinesItemForm.jsx'; import useLines from '../hooks/LinesHook'; import Input from '../../input/Input.jsx'; +import { AuthContext } from '../../logins/login/context/AuthContext.jsx'; // linesChangeHandle изменять состояние => при вызове изменения linesChangeHandle // должно все перерисовываться const UpdateNews = () => { + const { state, dispatch } = useContext(AuthContext); + + let obj = null; + if (state.user !== null) { + [obj] = state.user; + } const [searchParams, setSearchParams] = useSearchParams(); const [searchValue, setSearchValue] = useState(searchParams.get('q') || ''); @@ -44,7 +51,26 @@ const UpdateNews = () => { return ( <> - + {obj === null || obj.role === 'user' ? ( + <> + + Новости + + setSearchValue(e.target.value)} + type='text' required /> + + + { + lines.map((item) => { + return ; + })} + + > + ) : ( + <> + Новости setSearchValue(e.target.value)} @@ -72,6 +98,8 @@ const UpdateNews = () => { title='Редактирование'> + > + )} > ); @@ -79,6 +107,7 @@ const UpdateNews = () => { UpdateNews.propTypes = { item: PropTypes.object, + role: PropTypes.string, }; export default UpdateNews; diff --git a/Lab5/src/components/logins/hooks/EntrysDataHook.js b/Lab5/src/components/logins/hooks/EntrysDataHook.js index 7ae495f..abfc5c9 100644 --- a/Lab5/src/components/logins/hooks/EntrysDataHook.js +++ b/Lab5/src/components/logins/hooks/EntrysDataHook.js @@ -1,14 +1,10 @@ import { useEffect, useState } from 'react'; import EntrysDataApiService from '../service/EntrysDataApiService'; -const useEntrysData = (login, password) => { +const useEntrysData = (login, password, expand) => { const [entrys, setEntrys] = useState([]); const getEntrysData = async () => { - let expand = `?login=${login}&password=${password}`; - if (password === '') { - expand = `?login=${login}`; - } const data = await EntrysDataApiService.getAll(expand); setEntrys(data ?? []); }; diff --git a/Lab5/src/components/logins/hooks/Reducer.js b/Lab5/src/components/logins/hooks/Reducer.js new file mode 100644 index 0000000..e69de29 diff --git a/Lab5/src/components/logins/login/Entry.jsx b/Lab5/src/components/logins/login/Entry/Entry.jsx similarity index 60% rename from Lab5/src/components/logins/login/Entry.jsx rename to Lab5/src/components/logins/login/Entry/Entry.jsx index 826d47d..32e7cbc 100644 --- a/Lab5/src/components/logins/login/Entry.jsx +++ b/Lab5/src/components/logins/login/Entry/Entry.jsx @@ -1,16 +1,19 @@ -import { useState } from 'react'; +import { useContext, useState } from 'react'; +import PropTypes from 'prop-types'; import { Link } from 'react-router-dom'; import toast from 'react-hot-toast'; import { Button, Form } from 'react-bootstrap'; -import Input from '../../input/Input.jsx'; -import useEntrysData from '../hooks/EntrysDataHook'; +import Input from '../../../input/Input.jsx'; +import useEntrysData from '../../hooks/EntrysDataHook'; +import { AuthContext } from '../context/AuthContext.jsx'; const Entry = () => { const [validated, setValidated] = useState(false); const [login, setLogin] = useState(''); const [password, setPassword] = useState(''); - const isLoginValid = (value) => /^[a-zA-Z]+$/.test(value); - const { entrys } = useEntrysData(login, password); + const isLoginValid = (value) => /^[a-zA-Z0-9]+$/.test(value); + const { entrys } = useEntrysData(login, password, `?login=${login}&password=${password}`); + const { state, dispatch } = useContext(AuthContext); const handleSubmit = (event) => { const form = event.currentTarget; @@ -21,8 +24,12 @@ const Entry = () => { if (entrys.length === 0) { toast.error('Аккаунт не найден'); } else { - setValidated(true); - toast.success('Был произведён вход'); + setValidated(true); + dispatch({ + type: 'LOGIN', + payload: entrys, + }); + toast.success(`Был произведён вход: ${login}`); } } else { toast.error('Логин должен быть введён латинскими символами'); @@ -31,15 +38,24 @@ const Entry = () => { setValidated(true); }; + const handleLogOut = () => { + dispatch({ + type: 'LOGOUT', + payload: entrys, + }); + }; + return ( Личный кабинет - - Вход - + {state.user === null ? ( + <> + + Вход + Логин setLogin(e.target.value)} @@ -50,9 +66,22 @@ const Entry = () => { Войти Регистрация + > + ) : ( + <> + Welcome, {state.user.map((item) => item.login)} + + Выйти + + > + )} ); }; +Entry.propTypes = { + item: PropTypes.object, + }; + export default Entry; diff --git a/Lab5/src/components/logins/login/Registration.jsx b/Lab5/src/components/logins/login/Registration.jsx index 903b868..08e1c21 100644 --- a/Lab5/src/components/logins/login/Registration.jsx +++ b/Lab5/src/components/logins/login/Registration.jsx @@ -10,8 +10,8 @@ const Entry = () => { const [validated, setValidated] = useState(false); const [login, setLogin] = useState(''); const [password, setPassword] = useState(''); - const isLoginValid = (value) => /^[a-zA-Z]+$/.test(value); - const { entrys } = useEntrysData(login, ''); + const isLoginValid = (value) => /^[a-zA-Z0-9]+$/.test(value); + const { entrys } = useEntrysData(login, password, `?login=${login}`); const { UseHandleSubmit, UseHandleChange } = useEntrysItemForm(); diff --git a/Lab5/src/components/logins/login/context/AuthContext.jsx b/Lab5/src/components/logins/login/context/AuthContext.jsx new file mode 100644 index 0000000..cc6712e --- /dev/null +++ b/Lab5/src/components/logins/login/context/AuthContext.jsx @@ -0,0 +1,66 @@ +import { createContext, useReducer, useEffect } from 'react'; +import PropTypes from 'prop-types'; + +// Функция для сохранения состояния user в localStorage +const saveToLocalstorage = (user) => { + if (user) { + localStorage.setItem('authState', JSON.stringify(user)); + } else { + localStorage.removeItem('authState'); + } +}; + +// Функция для восстановления состояния user из localStorage +const getInitialState = () => { + const userStorage = localStorage.getItem('authState'); + if (userStorage) { + return { user: JSON.parse(userStorage) }; + } + return { user: null }; +}; + +const AuthReducer = (state, action) => { + switch (action.type) { + case 'LOGIN': + saveToLocalstorage(action.payload); + return { + ...state, + user: action.payload, + }; + case 'LOGOUT': + saveToLocalstorage(null); + return { + ...state, + user: null, + }; + default: + return state; + } +}; + +export const AuthContext = createContext(); + +export const AuthProvider = ({ children }) => { + const [state, dispatch] = useReducer(AuthReducer, getInitialState, getInitialState); + + // При инициализации компонента проверим localStorage + useEffect(() => { + const user = localStorage.getItem('authState'); + if (user) { + dispatch({ + type: 'LOGIN', + payload: JSON.parse(user), + }); + } + }, []); + + return ( + + {children} + + ); +}; + +AuthProvider.propTypes = { + children: PropTypes.node.isRequired, +}; diff --git a/Lab5/src/main.jsx b/Lab5/src/main.jsx index e5c0281..7149512 100644 --- a/Lab5/src/main.jsx +++ b/Lab5/src/main.jsx @@ -32,7 +32,7 @@ const routes = [ { path: '/page4', element: , - title: 'Вход', + title: 'Личный кабинет', }, { path: '/page5', diff --git a/Lab5/src/pages/Page4.jsx b/Lab5/src/pages/Page4.jsx index 8358431..064f3b2 100644 --- a/Lab5/src/pages/Page4.jsx +++ b/Lab5/src/pages/Page4.jsx @@ -1,4 +1,4 @@ -import Entry from '../components/logins/login/Entry.jsx'; +import Entry from '../components/logins/login/Entry/Entry.jsx'; const Page4 = () => { return (
Welcome, {state.user.map((item) => item.login)}