diff --git a/front/.env b/front/.env
new file mode 100644
index 0000000..e69de29
diff --git a/front/Dockerfile b/front/Dockerfile
index d9052db..4ecf20d 100644
--- a/front/Dockerfile
+++ b/front/Dockerfile
@@ -1,5 +1,3 @@
FROM nginx:1.16.0-alpine
-COPY default.conf /etc/nginx/conf.d
-COPY build /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
\ No newline at end of file
diff --git a/front/package.json b/front/package.json
index 27949b9..1034a42 100644
--- a/front/package.json
+++ b/front/package.json
@@ -41,7 +41,7 @@
},
"scripts": {
"start": "react-scripts start",
- "build": "CI=false && react-scripts build",
+ "build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
diff --git a/front/src/app/layout/PublicLayout.js b/front/src/app/layout/PublicLayout.js
index 74aa4f6..3d3a1d9 100644
--- a/front/src/app/layout/PublicLayout.js
+++ b/front/src/app/layout/PublicLayout.js
@@ -41,9 +41,6 @@ export function PublicLayout({ children }) {
Добро пожаловать в бар
-
- Самый большой выбор честно спизженных коктейлей
-
{
api().get(requests.bar.ingredientList)
@@ -77,6 +76,14 @@ export function IngredientsPage() {
const handleOpenModal = (i) => {
selectIngredient(i)
}
+ const handleDelete = (id) => {
+ const newState = ingredients.filter((ingredient) => ingredient.id !== id);
+ setIngredients(newState)
+
+ api().delete(`${requests.bar.ingredient}/${id}`)
+ .then((r) => createSuccess("Ингредиент удален"))
+ .catch(() => createError("Ошибка удаления ингредиента. Перезагрузите страницу"))
+ }
return (
@@ -136,7 +143,7 @@ export function IngredientsPage() {
{/*Загрузчик*/}
{/*Модальное окно информации об ингредиенте*/}
-
+
)
}
\ No newline at end of file
diff --git a/front/src/components/Ingredients/IngredientAlert.js b/front/src/components/Ingredients/IngredientAlert.js
new file mode 100644
index 0000000..0f78ba4
--- /dev/null
+++ b/front/src/components/Ingredients/IngredientAlert.js
@@ -0,0 +1,39 @@
+import * as React from 'react';
+import Button from '@mui/material/Button';
+import Dialog from '@mui/material/Dialog';
+import DialogActions from '@mui/material/DialogActions';
+import DialogContent from '@mui/material/DialogContent';
+import DialogContentText from '@mui/material/DialogContentText';
+import DialogTitle from '@mui/material/DialogTitle';
+
+export function IngredientAlert({open, handleClose, handleDelete, id, handleCloseParent}) {
+ return (
+
+
+
+ );
+}
\ No newline at end of file
diff --git a/front/src/components/Ingredients/IngredientInfoModal.js b/front/src/components/Ingredients/IngredientInfoModal.js
index 103ab14..65c7ec6 100644
--- a/front/src/components/Ingredients/IngredientInfoModal.js
+++ b/front/src/components/Ingredients/IngredientInfoModal.js
@@ -13,11 +13,19 @@ import {requests} from "../../requests";
import {useAlert} from "../../hooks/useAlert";
import ListItem from "@mui/material/ListItem";
import {useSelect} from "../../hooks/useSelect";
+import {IngredientAlert} from "./IngredientAlert";
+import {useUser} from "../../hooks/useUser";
-export function IngredientInfoModal({ingredient}) {
+export function IngredientInfoModal({ingredient, handleDelete}) {
+ const {user} = useUser();
const [cocktails, setCocktails] = useState([]);
const {closeIngredient, getOpenIngredient, selectCocktail} = useSelect();
const {createError} = useAlert();
+ const [open, setOpen] = React.useState(false);
+
+ const handleClose = () => {
+ setOpen(false);
+ };
useEffect(() => {
if(!ingredient) {
@@ -72,8 +80,10 @@ export function IngredientInfoModal({ingredient}) {
)}
-
+ {user.role !== 'USER' && }
+
+
);
}
\ No newline at end of file
diff --git a/front/src/components/cocktails/Cocktail.js b/front/src/components/cocktails/Cocktail.js
index ec82a54..6289f6a 100644
--- a/front/src/components/cocktails/Cocktail.js
+++ b/front/src/components/cocktails/Cocktail.js
@@ -12,6 +12,7 @@ import DeleteIcon from '@mui/icons-material/Delete';
import LocalBarIcon from '@mui/icons-material/LocalBar';
import {paths} from "../../path";
import {useAlert} from "../../hooks/useAlert";
+import {useUser} from "../../hooks/useUser";
function renderFavouriteBadge(handleFavourite, row) {
const childIcon = row.rating.favourite ? : ;
@@ -35,6 +36,7 @@ function renderRating(handleChangeRating, row) {
export function Cocktail({row, handleFavourite, handleChangeRating, handleSelect, deleteHandler}) {
const {notImplement} = useAlert();
+ const {user} = useUser();
return (
@@ -63,12 +65,17 @@ export function Cocktail({row, handleFavourite, handleChangeRating, handleSelect
{renderFavouriteBadge(handleFavourite, row)}
{renderRating(handleChangeRating, row)}
-
-
-
- deleteHandler(row)}>
-
-
+ {user.role !== 'USER' &&
+ <>
+
+
+
+ deleteHandler(row)}>
+
+
+ >
+
+ }
{row.name}
diff --git a/front/src/components/core/UserPopover.js b/front/src/components/core/UserPopover.js
index a0b2805..8c271c9 100644
--- a/front/src/components/core/UserPopover.js
+++ b/front/src/components/core/UserPopover.js
@@ -86,7 +86,6 @@ function userDescriptor(user, session) {
<>
{user.name + " " + user.lastName}
{user.id}
- {`Бар ${open}`}
>
);
}
diff --git a/front/src/lib/clients/api.js b/front/src/lib/clients/api.js
index 7952708..d7c859a 100644
--- a/front/src/lib/clients/api.js
+++ b/front/src/lib/clients/api.js
@@ -1,9 +1,9 @@
import axios from "axios";
import {tokenUtil} from "../TokenUtil";
-// const host = "localhost:8080"; //дебаг вместе с беком
+const host = "localhost:8080"; //дебаг вместе с беком
// const host = "192.168.1.100:8091"; //дебаг фронта
-const host = "bar.kayashov.keenetic.pro"; //прод
+// const host = "bar.kayashov.keenetic.pro"; //прод
export const api = () => {
const result = axios;
result.defaults.baseURL = `${window.location.protocol}//${host}/`;
diff --git a/src/main/java/ru/kayashov/bar/controller/BarController.java b/src/main/java/ru/kayashov/bar/controller/BarController.java
index 15a091c..d8edcad 100644
--- a/src/main/java/ru/kayashov/bar/controller/BarController.java
+++ b/src/main/java/ru/kayashov/bar/controller/BarController.java
@@ -79,9 +79,7 @@ public class BarController {
@GetMapping("/getMe")
public VisitorResponseDto getMe() {
Visitor visitor = visitorService.getCurrentVisitor();
- String role;
- role = UserRole.ADMIN.toString();
- VisitorResponseDto dto = VisitorResponseDto.mapToDto(visitor, true, role, true);
+ VisitorResponseDto dto = VisitorResponseDto.mapToDto(visitor, true, visitor.getRole().toString(), true);
log.info("Запрос информации о пользователе: {}-{} {}, вошел в бар",
dto.getId(),
dto.getName().strip(),
diff --git a/src/main/java/ru/kayashov/bar/controller/IngredientController.java b/src/main/java/ru/kayashov/bar/controller/IngredientController.java
index 786cf4f..47f1b38 100644
--- a/src/main/java/ru/kayashov/bar/controller/IngredientController.java
+++ b/src/main/java/ru/kayashov/bar/controller/IngredientController.java
@@ -6,6 +6,7 @@ import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PatchMapping;
+import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
@@ -64,6 +65,11 @@ public class IngredientController {
ingredientService.changeBarIngredient(id, false);
}
+ @DeleteMapping("/{id}")
+ public void removeIngredient(@PathVariable Long id) {
+ ingredientService.removeIngredient(id);
+ }
+
@PutMapping
public void putIngredient(@RequestParam Long id) {
ingredientService.changeBarIngredient(id, true);
diff --git a/src/main/java/ru/kayashov/bar/model/entity/IngredientEntity.java b/src/main/java/ru/kayashov/bar/model/entity/IngredientEntity.java
index 9e46e77..f866d79 100644
--- a/src/main/java/ru/kayashov/bar/model/entity/IngredientEntity.java
+++ b/src/main/java/ru/kayashov/bar/model/entity/IngredientEntity.java
@@ -6,6 +6,7 @@ import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
+import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
@@ -43,7 +44,7 @@ public class IngredientEntity {
@JoinColumn(name = "type")
private TypeEntity type;
- @ManyToMany
+ @ManyToMany(cascade = CascadeType.REMOVE)
@JoinTable(
name = "bar_ingredient",
joinColumns = @JoinColumn(name = "ingredient"),
diff --git a/src/main/java/ru/kayashov/bar/model/entity/Visitor.java b/src/main/java/ru/kayashov/bar/model/entity/Visitor.java
index 1519670..f81b82b 100644
--- a/src/main/java/ru/kayashov/bar/model/entity/Visitor.java
+++ b/src/main/java/ru/kayashov/bar/model/entity/Visitor.java
@@ -7,6 +7,8 @@ import org.springframework.security.core.userdetails.UserDetails;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
+import javax.persistence.EnumType;
+import javax.persistence.Enumerated;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import java.time.LocalDateTime;
@@ -21,6 +23,8 @@ public class Visitor implements UserDetails {
private Long id;
private String name;
private String lastName;
+ @Enumerated(EnumType.STRING)
+ private UserRole role;
private Integer code;
private String login;
private String password;
@@ -28,7 +32,8 @@ public class Visitor implements UserDetails {
@Override
public Collection extends GrantedAuthority> getAuthorities() {
- return UserRole.ADMIN.getAuthorities();
+ return role.getAuthorities();
+// return UserRole.ADMIN.getAuthorities();
// return residents.stream()
// .filter(BarResident::getActive)
// .map(BarResident::getRole)
diff --git a/src/main/java/ru/kayashov/bar/service/IngredientService.java b/src/main/java/ru/kayashov/bar/service/IngredientService.java
index 9a9263e..77e77f3 100644
--- a/src/main/java/ru/kayashov/bar/service/IngredientService.java
+++ b/src/main/java/ru/kayashov/bar/service/IngredientService.java
@@ -3,14 +3,20 @@ package ru.kayashov.bar.service;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
import ru.kayashov.bar.controller.dto.ingredient.IngredientResponseDto;
import ru.kayashov.bar.controller.dto.ingredient.IngredientSimpleResponseDto;
import ru.kayashov.bar.mapper.IngredientMapper;
+import ru.kayashov.bar.model.Ingredient;
import ru.kayashov.bar.model.entity.BarEntity;
+import ru.kayashov.bar.model.entity.CocktailEntity;
import ru.kayashov.bar.model.entity.IngredientEntity;
+import ru.kayashov.bar.model.entity.ReceiptEntity;
import ru.kayashov.bar.model.entity.TypeEntity;
import ru.kayashov.bar.repository.BarEntityRepository;
+import ru.kayashov.bar.repository.CocktailRepository;
import ru.kayashov.bar.repository.IngredientRepository;
+import ru.kayashov.bar.repository.ReceiptRepository;
import ru.kayashov.bar.repository.TypeRepository;
import java.util.ArrayList;
@@ -26,6 +32,8 @@ public class IngredientService {
private final IngredientMapper mapper;
private final BarEntityRepository barEntityRepository;
private final IngredientRepository ingredientRepository;
+ private final ReceiptRepository receiptRepository;
+ private final CocktailRepository cocktailRepository;
private TypeEntity findTypeByName(String name) {
return typeRepository.findByName(name)
@@ -86,4 +94,21 @@ public class IngredientService {
repository.save(entity);
return true;
}
+
+ @Transactional
+ public void removeIngredient(Long id) {
+ IngredientEntity ingredient = ingredientRepository.findById(id).orElseThrow();
+
+ List cocktails = ingredient.getReceipts()
+ .stream()
+ .map(ReceiptEntity::getCocktail)
+ .toList();
+
+ receiptRepository.deleteAll(ingredient.getReceipts());
+ cocktailRepository.deleteAll(cocktails);
+
+ log.info("Удалены коктейли {}", cocktails.stream().map(c -> c.getId() + "-" + c.getName()).toList());
+ repository.delete(ingredient);
+ log.info("Удален ингредиент {}-{}", id, ingredient.getName());
+ }
}