diff --git a/build.gradle b/build.gradle
index 7e8766c..b374d68 100644
--- a/build.gradle
+++ b/build.gradle
@@ -19,11 +19,16 @@ jar {
dependencies {
implementation(project(':front'))
+ annotationProcessor "org.springframework.boot:spring-boot-configuration-processor"
+
implementation 'org.springframework.boot:spring-boot-starter-web'
+ implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'com.h2database:h2:2.1.210'
implementation 'org.springframework.boot:spring-boot-starter-validation'
implementation group: 'org.springdoc', name: 'springdoc-openapi-ui', version: '1.6.5'
- implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
+
+ implementation 'org.springframework.boot:spring-boot-starter-security'
+ implementation 'com.auth0:java-jwt:4.4.0'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
implementation 'org.hibernate.validator:hibernate-validator'
diff --git a/front/src/App.js b/front/src/App.js
index 173405f..5c161f9 100644
--- a/front/src/App.js
+++ b/front/src/App.js
@@ -1,4 +1,4 @@
-import { useRoutes, Outlet, BrowserRouter } from 'react-router-dom'
+import {BrowserRouter, Route, Routes} from 'react-router-dom'
import Films from './pages/Films'
import FilmPage from './pages/FilmPage'
import Header from './pages/components/Header'
@@ -7,39 +7,40 @@ import SearchSame from './pages/SearchSame'
import Registration from './pages/Registration'
import Sessions from './pages/Sessions'
import Orders from './pages/Orders'
-
-function Router(props) {
- return useRoutes(props.rootRoute);
-}
+import Users from "./pages/Users";
+import PrivateRoutes from "./pages/components/PrivateRoutes";
export default function App() {
- const routes = [
- { index: true, element: },
- { path: '/films', element: , label: 'Главная' },
- { path: '/registration', element: , label: 'Регистрация' },
- { path: '/sessions', element: , label: 'Сеансы' },
- { path: '/orders', element: , label: 'Заказы' },
- { path: '/films/:id', element: },
- { path: '/search-same/:request', element: }
- ];
- const links = routes.filter(route => route.hasOwnProperty('label'));
- const rootRoute = [
- { path: '/', element: render(links), children: routes }
- ];
+ const links = [
+ {path: 'films', label: 'Главная', userAccess: 'NONE'},
+ {path: 'registration', label: 'Регистрация', userAccess: 'NONE'},
+ {path: 'entry', label: 'Вход', userAccess: 'NONE'},
+ {path: 'users', label: 'Пользователи', userAccess: 'ADMIN'},
+ {path: 'sessions', label: 'Сеансы', userAccess: 'NONE'},
+ {path: 'orders', label: 'Заказы', userAccess: 'USER'}
+ ];
- function render(links) {
return (
- <>
-
-
-
- >
+ <>
+
+
+
+ } path='/'/>
+ } path='/films'/>
+ } path='/films:id'/>
+ } path='/search-same/:request'/>
+ } path="/registration"/>
+ } path="/entry"/>
+ } path="/sessions"/>
+ }>
+ } path="/orders"/>
+
+ }>
+ } path="/users"/>
+
+
+
+
+ >
);
- }
-
- return (
-
-
-
- );
}
\ No newline at end of file
diff --git a/front/src/pages/Films.jsx b/front/src/pages/Films.jsx
index 996c341..ddcef40 100644
--- a/front/src/pages/Films.jsx
+++ b/front/src/pages/Films.jsx
@@ -1,5 +1,5 @@
-import { React, useState, useEffect } from 'react'
-import { useNavigate } from 'react-router-dom'
+import {React, useState, useEffect} from 'react'
+import {useNavigate} from 'react-router-dom'
import FilmItem from './components/FilmItem'
import ContentBlock from './components/ContentBlock'
import ModalEdit from './components/ModalEdit'
@@ -20,26 +20,51 @@ export default function Films() {
const [filmNameEdit, setFilmNameEdit] = useState('');
// хук для запоминания индекса элемента, вызвавшего модальное окно
const [currEditItem, setCurrEditItem] = useState(0);
-
- // фильмы, страны, жанры
+ const getTokenForHeader = function () {
+ return "Bearer " + localStorage.getItem("token");
+ }
+ async function getAll(elem) {
+ const requestParams = {
+ method: "GET"
+ };
+ const requestUrl = `http://localhost:8080/${elem}`
+ const response = await fetch(requestUrl, requestParams)
+ return await response.json()
+ }
+ // фильмы
useEffect(() => {
- Service.readAll('cinema')
+ getAll('cinema')
.then(data => setItems(data));
}, []);
- function handleDeleteFilm(id) {
+ async function handleDeleteFilm(id) {
console.info('Try to remove item');
- Service.delete(`cinema/${id}`)
+ const requestParams = {
+ method: "DELETE",
+ headers: {
+ "Authorization": getTokenForHeader(),
+ "Content-Type": "application/json"
+ }
+ };
+ const response = await fetch(`http://localhost:8080/cinema/${id}`, requestParams)
+ await response.json()
.then(() => {
setItems(items.filter(elem => elem.id !== id))
console.log("Removed")
});
- };
+ }
- function handleEditFilm(id) {
+ async function handleEditFilm(id) {
console.info(`Start edit script`);
-
- Service.read(`cinema/${id}`)
+ const requestParams = {
+ method: "GET",
+ headers: {
+ "Authorization": getTokenForHeader(),
+ }
+ };
+ const requestUrl = `http://localhost:8080/cinema/${id}`
+ const response = await fetch(requestUrl, requestParams)
+ return await response.json()
.then(function (data) {
setFilmNameEdit(data.name);
setCurrEditItem(data.id);
@@ -49,12 +74,20 @@ export default function Films() {
};
// принимаем событие от кнопки "добавить"
- const handleSubmitCreate = (e) => {
+ const handleSubmitCreate = async (e) => {
e.preventDefault(); // страница перестает перезагружаться
const itemObject = new CinemaDto(selectedImage, filmName);
console.info('Try to add item');
-
- Service.create('cinema', itemObject)
+ const requestParams = {
+ method: "POST",
+ headers: {
+ "Authorization": getTokenForHeader(),
+ "Content-Type": "application/json"
+ },
+ body: JSON.stringify(itemObject)
+ };
+ await fetch(`http://localhost:8080/cinema`, requestParams)
+ .then((response) => response.json())
.then((data) => {
setItems([...items, data]);
@@ -66,14 +99,23 @@ export default function Films() {
throw "Can't add item";
});
};
-
// принимаем событие от кнопки "сохранить изменения"
- const handleSubmitEdit = (e, id) => {
+ const handleSubmitEdit = async (e, id) => {
console.info('Start synchronize edit');
e.preventDefault(); // страница перестает перезагружаться
const itemObject = new CinemaDto(selectedImage, filmNameEdit, id);
- Service.update("cinema/" + id, itemObject)
+ const requestParams = {
+ method: "PUT",
+ headers: {
+ "Authorization": getTokenForHeader(),
+ "Content-Type": "application/json"
+ },
+ body: JSON.stringify(itemObject)
+ };
+ const requestUrl = `http://localhost:8080/cinema/${id}`
+ const response = await fetch(requestUrl, requestParams)
+ await response.json()
.then((data) => {
setItems(
items.map(item =>
@@ -95,83 +137,88 @@ export default function Films() {
fileReader.onloadend = () => (
setSelectedImage(fileReader.result)
)
+
function changePicture(e) {
e.preventDefault();
const file = e.target.files[0]
fileReader.readAsDataURL(file)
}
- function handleAddFilmToWillSee(data) {
- const elem = CinemaDto.createFrom(data)
- Service.create('willSee/', data)
- }
-
- // форма для добавления данных
- const Form = (
-
- )
-
const Content = (
- {Form}
-
+ {(localStorage.getItem("role") === 'ADMIN') &&
+
}
+
- {items.map((item) =>
- navigate(`/films/${index}`)}
- />
- )}
+ {items.map((item) =>
+ navigate(`/films/${index}`)}
+ />
+ )}
-
- }
+
);
return (
-
-
+
+
)
}
diff --git a/front/src/pages/Orders.jsx b/front/src/pages/Orders.jsx
index e83d407..024d198 100644
--- a/front/src/pages/Orders.jsx
+++ b/front/src/pages/Orders.jsx
@@ -1,4 +1,4 @@
-import { React, useState, useEffect } from 'react'
+import {useEffect, useState} from 'react'
import ContentBlock from './components/ContentBlock'
import Service from './services/Service';
import ModalEdit from './components/ModalEdit';
@@ -12,33 +12,37 @@ export default function Orders() {
const [currEditItem, setCurrEditItem] = useState(0);
// для выпадающих значений
const [customerName, setCustomerName] = useState('');
- const [customer, setCustomer] = useState([]);
const [sessionName, setSessionName] = useState('');
const [count, setCount] = useState(1);
const [session, setSession] = useState([]);
const [orderSessions, setOrderSessions] = useState([]);
useEffect(() => {
- getAll('customer').then((data) => setCustomer(data))
+ const user = localStorage.getItem('user')
+ setCustomerName(user)
getAll('session').then((data) => setSession(data))
- getAll('order').then((data) => setUsers(data))
+ getAll(`customer?login=${user}`).then((data) => setUsers(data.orders))
}, [])
+ const getTokenForHeader = function () {
+ return "Bearer " + localStorage.getItem("token");
+ }
async function getAll(elem) {
+ const requestParams = {
+ method: "GET",
+ headers: {
+ "Authorization": getTokenForHeader(),
+ }
+ };
const requestUrl = `http://localhost:8080/${elem}`
- const response = await fetch(requestUrl)
- const result = await response.json()
- return result
+ const response = await fetch(requestUrl, requestParams)
+ return await response.json()
}
function handleSubmit(e) {
e.preventDefault();
- if (customer.length <= 0) {
- throw 'Form not submit'
- }
handleSubmitCreate(e)
console.log('Form submit')
- setCustomer('')
}
// принимаем событие от кнопки "добавить"
@@ -49,13 +53,13 @@ export default function Orders() {
const requestParams = {
method: "POST",
headers: {
+ "Authorization": getTokenForHeader(),
"Content-Type": "application/json"
}
};
- await fetch(`http://localhost:8080/order?customer=${customerName}`, requestParams)
- .then((data) => {
- getCustomerOrders(customerName)
- getAll('customer').then((data) => setCustomer(data))
+ await fetch(`http://localhost:8080/order/${customerName}`, requestParams)
+ .then(() => {
+ getAll(`customer?login=${customerName}`).then((data) => setUsers(data.orders))
})
.catch(function (error) {
console.error('Error:', error);
@@ -65,15 +69,14 @@ export default function Orders() {
function handleEdit(id) {
console.info(`Start edit script`);
-
- Service.read(`order/${id}`)
+ getAll(`order/${id}`)
.then(function (data) {
setCurrEditItem(data.id);
setOrderSessions(data.sessions)
setModalTable(true)
console.info('End edit script');
})
- };
+ }
const handleSubmitAdd = async (e, id) => {
console.info('Start add session');
@@ -81,6 +84,7 @@ export default function Orders() {
const requestParams = {
method: "PUT",
headers: {
+ "Authorization": getTokenForHeader(),
"Content-Type": "application/json"
}
};
@@ -103,6 +107,7 @@ export default function Orders() {
const requestParams = {
method: "PUT",
headers: {
+ "Authorization": getTokenForHeader(),
"Content-Type": "application/json"
}
};
@@ -118,22 +123,21 @@ export default function Orders() {
});
};
- function handleDelete(id) {
+ async function handleDelete(id) {
console.info('Try to remove item');
- Service.delete(`order/${id}`)
+ const requestParams = {
+ method: "DELETE",
+ headers: {
+ "Authorization": getTokenForHeader(),
+ "Content-Type": "application/json"
+ }
+ };
+ const response = await fetch(`http://localhost:8080/order/${id}`, requestParams)
+ await response.json()
.then(() => {
setUsers(users.filter(elem => elem.id !== id))
console.log("Removed")
});
- };
-
- async function getCustomerOrders(id) {
- Service.read(`customer/${id}`)
- .then(function (data) {
- setUsers(data.orders);
- console.info('End');
- })
- .catch(e => { console.log('Error get orders') })
}
async function handleDeleteOrderSession(e, id, sessionId) {
@@ -141,6 +145,7 @@ export default function Orders() {
const requestParams = {
method: "PUT",
headers: {
+ "Authorization": getTokenForHeader(),
"Content-Type": "application/json"
}
};
@@ -158,15 +163,6 @@ export default function Orders() {
const Content = (
<>
-