готовая лаба 5
This commit is contained in:
parent
658ae323ba
commit
b45991ed26
@ -4,7 +4,7 @@
|
|||||||
"id": 0,
|
"id": 0,
|
||||||
"login": "dyctator",
|
"login": "dyctator",
|
||||||
"password": "12345",
|
"password": "12345",
|
||||||
"role": "user"
|
"role": "admin"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"login": "user",
|
"login": "user",
|
||||||
|
@ -5,9 +5,11 @@ import { Outlet } from 'react-router-dom';
|
|||||||
import { CartProvider } from './components/cart/CartContext.jsx';
|
import { CartProvider } from './components/cart/CartContext.jsx';
|
||||||
import Footer from './components/footer/Footer.jsx';
|
import Footer from './components/footer/Footer.jsx';
|
||||||
import Navigation from './components/navigation/Navigation.jsx';
|
import Navigation from './components/navigation/Navigation.jsx';
|
||||||
|
import { AuthProvider } from './components/logins/login/context/AuthContext.jsx';
|
||||||
|
|
||||||
const App = ({ routes }) => {
|
const App = ({ routes }) => {
|
||||||
return (
|
return (
|
||||||
|
<AuthProvider>
|
||||||
<CartProvider>
|
<CartProvider>
|
||||||
<Navigation routes={routes}></Navigation>
|
<Navigation routes={routes}></Navigation>
|
||||||
<Container className='p-2' as='main' fluid>
|
<Container className='p-2' as='main' fluid>
|
||||||
@ -16,6 +18,7 @@ const App = ({ routes }) => {
|
|||||||
<Footer />
|
<Footer />
|
||||||
<Toaster position='top-center' reverseOrder={true} />
|
<Toaster position='top-center' reverseOrder={true} />
|
||||||
</CartProvider>
|
</CartProvider>
|
||||||
|
</AuthProvider>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { useSearchParams } from 'react-router-dom';
|
import { useSearchParams } from 'react-router-dom';
|
||||||
import { useState, useEffect } from 'react';
|
import { useState, useEffect, useContext } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import {
|
import {
|
||||||
Button, Container,
|
Button, Container,
|
||||||
@ -13,10 +13,17 @@ import useLinesFormModal from '../hooks/LinesFormModalHook';
|
|||||||
import LinesItemForm from '../form/LinesItemForm.jsx';
|
import LinesItemForm from '../form/LinesItemForm.jsx';
|
||||||
import useLines from '../hooks/LinesHook';
|
import useLines from '../hooks/LinesHook';
|
||||||
import Input from '../../input/Input.jsx';
|
import Input from '../../input/Input.jsx';
|
||||||
|
import { AuthContext } from '../../logins/login/context/AuthContext.jsx';
|
||||||
// linesChangeHandle изменять состояние => при вызове изменения linesChangeHandle
|
// linesChangeHandle изменять состояние => при вызове изменения linesChangeHandle
|
||||||
// должно все перерисовываться
|
// должно все перерисовываться
|
||||||
|
|
||||||
const UpdateNews = () => {
|
const UpdateNews = () => {
|
||||||
|
const { state, dispatch } = useContext(AuthContext);
|
||||||
|
|
||||||
|
let obj = null;
|
||||||
|
if (state.user !== null) {
|
||||||
|
[obj] = state.user;
|
||||||
|
}
|
||||||
const [searchParams, setSearchParams] = useSearchParams();
|
const [searchParams, setSearchParams] = useSearchParams();
|
||||||
|
|
||||||
const [searchValue, setSearchValue] = useState(searchParams.get('q') || '');
|
const [searchValue, setSearchValue] = useState(searchParams.get('q') || '');
|
||||||
@ -44,6 +51,25 @@ const UpdateNews = () => {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Container className="col text-center">
|
<Container className="col text-center">
|
||||||
|
{obj === null || obj.role === 'user' ? (
|
||||||
|
<>
|
||||||
|
<span className="mainSt">
|
||||||
|
<b>Новости</b>
|
||||||
|
</span>
|
||||||
|
<Input name='search' value = {searchValue} onChange={(e) => setSearchValue(e.target.value)}
|
||||||
|
type='text' required />
|
||||||
|
|
||||||
|
<div className="mainDiv row">
|
||||||
|
{
|
||||||
|
lines.map((item) => {
|
||||||
|
return <UpdateNew key={item.id}
|
||||||
|
item={item}
|
||||||
|
/>;
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
<span className="mainSt">
|
<span className="mainSt">
|
||||||
<b>Новости</b>
|
<b>Новости</b>
|
||||||
</span>
|
</span>
|
||||||
@ -72,6 +98,8 @@ const UpdateNews = () => {
|
|||||||
title='Редактирование'>
|
title='Редактирование'>
|
||||||
<LinesItemForm item={currentItem} handleChange={handleItemChange} />
|
<LinesItemForm item={currentItem} handleChange={handleItemChange} />
|
||||||
</ModalForm>
|
</ModalForm>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
</Container>
|
</Container>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
@ -79,6 +107,7 @@ const UpdateNews = () => {
|
|||||||
|
|
||||||
UpdateNews.propTypes = {
|
UpdateNews.propTypes = {
|
||||||
item: PropTypes.object,
|
item: PropTypes.object,
|
||||||
|
role: PropTypes.string,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default UpdateNews;
|
export default UpdateNews;
|
||||||
|
@ -1,14 +1,10 @@
|
|||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import EntrysDataApiService from '../service/EntrysDataApiService';
|
import EntrysDataApiService from '../service/EntrysDataApiService';
|
||||||
|
|
||||||
const useEntrysData = (login, password) => {
|
const useEntrysData = (login, password, expand) => {
|
||||||
const [entrys, setEntrys] = useState([]);
|
const [entrys, setEntrys] = useState([]);
|
||||||
|
|
||||||
const getEntrysData = async () => {
|
const getEntrysData = async () => {
|
||||||
let expand = `?login=${login}&password=${password}`;
|
|
||||||
if (password === '') {
|
|
||||||
expand = `?login=${login}`;
|
|
||||||
}
|
|
||||||
const data = await EntrysDataApiService.getAll(expand);
|
const data = await EntrysDataApiService.getAll(expand);
|
||||||
setEntrys(data ?? []);
|
setEntrys(data ?? []);
|
||||||
};
|
};
|
||||||
|
0
Lab5/src/components/logins/hooks/Reducer.js
Normal file
0
Lab5/src/components/logins/hooks/Reducer.js
Normal file
@ -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 { Link } from 'react-router-dom';
|
||||||
import toast from 'react-hot-toast';
|
import toast from 'react-hot-toast';
|
||||||
import { Button, Form } from 'react-bootstrap';
|
import { Button, Form } from 'react-bootstrap';
|
||||||
import Input from '../../input/Input.jsx';
|
import Input from '../../../input/Input.jsx';
|
||||||
import useEntrysData from '../hooks/EntrysDataHook';
|
import useEntrysData from '../../hooks/EntrysDataHook';
|
||||||
|
import { AuthContext } from '../context/AuthContext.jsx';
|
||||||
|
|
||||||
const Entry = () => {
|
const Entry = () => {
|
||||||
const [validated, setValidated] = useState(false);
|
const [validated, setValidated] = useState(false);
|
||||||
const [login, setLogin] = useState('');
|
const [login, setLogin] = useState('');
|
||||||
const [password, setPassword] = useState('');
|
const [password, setPassword] = useState('');
|
||||||
const isLoginValid = (value) => /^[a-zA-Z]+$/.test(value);
|
const isLoginValid = (value) => /^[a-zA-Z0-9]+$/.test(value);
|
||||||
const { entrys } = useEntrysData(login, password);
|
const { entrys } = useEntrysData(login, password, `?login=${login}&password=${password}`);
|
||||||
|
const { state, dispatch } = useContext(AuthContext);
|
||||||
|
|
||||||
const handleSubmit = (event) => {
|
const handleSubmit = (event) => {
|
||||||
const form = event.currentTarget;
|
const form = event.currentTarget;
|
||||||
@ -22,7 +25,11 @@ const Entry = () => {
|
|||||||
toast.error('Аккаунт не найден');
|
toast.error('Аккаунт не найден');
|
||||||
} else {
|
} else {
|
||||||
setValidated(true);
|
setValidated(true);
|
||||||
toast.success('Был произведён вход');
|
dispatch({
|
||||||
|
type: 'LOGIN',
|
||||||
|
payload: entrys,
|
||||||
|
});
|
||||||
|
toast.success(`Был произведён вход: ${login}`);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
toast.error('Логин должен быть введён латинскими символами');
|
toast.error('Логин должен быть введён латинскими символами');
|
||||||
@ -31,12 +38,21 @@ const Entry = () => {
|
|||||||
setValidated(true);
|
setValidated(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleLogOut = () => {
|
||||||
|
dispatch({
|
||||||
|
type: 'LOGOUT',
|
||||||
|
payload: entrys,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<main className="container-fluid text-center">
|
<main className="container-fluid text-center">
|
||||||
<span className="mainSt">
|
<span className="mainSt">
|
||||||
<b>Личный кабинет</b>
|
<b>Личный кабинет</b>
|
||||||
</span>
|
</span>
|
||||||
<div className="rectpage4 d-flex row justify-content-center">
|
<div className="rectpage4 d-flex row justify-content-center">
|
||||||
|
{state.user === null ? (
|
||||||
|
<>
|
||||||
<span className="EntrysSt">
|
<span className="EntrysSt">
|
||||||
<b>Вход</b>
|
<b>Вход</b>
|
||||||
</span>
|
</span>
|
||||||
@ -50,9 +66,22 @@ const Entry = () => {
|
|||||||
<Button className="btn btn-primary w-auto" type="submit" >Войти</Button>
|
<Button className="btn btn-primary w-auto" type="submit" >Войти</Button>
|
||||||
<Button as={Link} to='/registrPage' variant = "danger" className="btn btn-primary w-auto" >Регистрация</Button>
|
<Button as={Link} to='/registrPage' variant = "danger" className="btn btn-primary w-auto" >Регистрация</Button>
|
||||||
</Form>
|
</Form>
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<p className = 'EntrysSt'>Welcome, {state.user.map((item) => item.login)}</p>
|
||||||
|
<Button className="btn btn-primary w-25 h-25" variant = "danger" onClick = {handleLogOut}>
|
||||||
|
Выйти
|
||||||
|
</Button>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Entry.propTypes = {
|
||||||
|
item: PropTypes.object,
|
||||||
|
};
|
||||||
|
|
||||||
export default Entry;
|
export default Entry;
|
@ -10,8 +10,8 @@ const Entry = () => {
|
|||||||
const [validated, setValidated] = useState(false);
|
const [validated, setValidated] = useState(false);
|
||||||
const [login, setLogin] = useState('');
|
const [login, setLogin] = useState('');
|
||||||
const [password, setPassword] = useState('');
|
const [password, setPassword] = useState('');
|
||||||
const isLoginValid = (value) => /^[a-zA-Z]+$/.test(value);
|
const isLoginValid = (value) => /^[a-zA-Z0-9]+$/.test(value);
|
||||||
const { entrys } = useEntrysData(login, '');
|
const { entrys } = useEntrysData(login, password, `?login=${login}`);
|
||||||
|
|
||||||
const { UseHandleSubmit, UseHandleChange } = useEntrysItemForm();
|
const { UseHandleSubmit, UseHandleChange } = useEntrysItemForm();
|
||||||
|
|
||||||
|
66
Lab5/src/components/logins/login/context/AuthContext.jsx
Normal file
66
Lab5/src/components/logins/login/context/AuthContext.jsx
Normal file
@ -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 (
|
||||||
|
<AuthContext.Provider value={{ state, dispatch }}>
|
||||||
|
{children}
|
||||||
|
</AuthContext.Provider>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
AuthProvider.propTypes = {
|
||||||
|
children: PropTypes.node.isRequired,
|
||||||
|
};
|
@ -32,7 +32,7 @@ const routes = [
|
|||||||
{
|
{
|
||||||
path: '/page4',
|
path: '/page4',
|
||||||
element: <Page4 />,
|
element: <Page4 />,
|
||||||
title: 'Вход',
|
title: 'Личный кабинет',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/page5',
|
path: '/page5',
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import Entry from '../components/logins/login/Entry.jsx';
|
import Entry from '../components/logins/login/Entry/Entry.jsx';
|
||||||
|
|
||||||
const Page4 = () => {
|
const Page4 = () => {
|
||||||
return (
|
return (
|
||||||
|
Loading…
Reference in New Issue
Block a user