Вроде все работает

This commit is contained in:
Максим Яковлев 2024-05-12 18:20:25 +04:00
parent 386203ef31
commit 1db0e84d89
16 changed files with 291 additions and 86 deletions

Binary file not shown.

108
data.trace.db Normal file
View File

@ -0,0 +1,108 @@
2024-05-12 15:36:55.285977+04:00 database: wrong user or password; user: "SA"
org.h2.message.DbException: Неверное имя пользователя или пароль
Wrong user name or password [28000-224]
at org.h2.message.DbException.get(DbException.java:223)
at org.h2.message.DbException.get(DbException.java:199)
at org.h2.message.DbException.get(DbException.java:188)
at org.h2.engine.Engine.openSession(Engine.java:154)
at org.h2.engine.Engine.openSession(Engine.java:222)
at org.h2.engine.Engine.createSession(Engine.java:201)
at org.h2.engine.SessionRemote.connectEmbeddedOrServer(SessionRemote.java:343)
at org.h2.jdbc.JdbcConnection.<init>(JdbcConnection.java:125)
at org.h2.util.JdbcUtils.getConnection(JdbcUtils.java:288)
at org.h2.server.web.WebServer.getConnection(WebServer.java:811)
at org.h2.server.web.WebApp.login(WebApp.java:1039)
at org.h2.server.web.WebApp.process(WebApp.java:227)
at org.h2.server.web.WebApp.processRequest(WebApp.java:177)
at org.h2.server.web.JakartaWebServlet.doGet(JakartaWebServlet.java:129)
at org.h2.server.web.JakartaWebServlet.doPost(JakartaWebServlet.java:166)
at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:590)
at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:150)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:175)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:150)
at org.springframework.web.filter.CompositeFilter$VirtualFilterChain.doFilter(CompositeFilter.java:108)
at org.springframework.security.web.FilterChainProxy.lambda$doFilterInternal$3(FilterChainProxy.java:231)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:365)
at org.springframework.security.web.access.intercept.AuthorizationFilter.doFilter(AuthorizationFilter.java:100)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374)
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:126)
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:120)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374)
at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:100)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374)
at org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter.doFilter(RememberMeAuthenticationFilter.java:110)
at org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter.doFilter(RememberMeAuthenticationFilter.java:101)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374)
at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:179)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374)
at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374)
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:227)
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:221)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374)
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:107)
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:93)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374)
at org.springframework.web.filter.CorsFilter.doFilterInternal(CorsFilter.java:91)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374)
at org.springframework.security.web.header.HeaderWriterFilter.doHeadersAfter(HeaderWriterFilter.java:90)
at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:75)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374)
at org.springframework.security.web.context.SecurityContextHolderFilter.doFilter(SecurityContextHolderFilter.java:82)
at org.springframework.security.web.context.SecurityContextHolderFilter.doFilter(SecurityContextHolderFilter.java:69)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374)
at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:62)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374)
at org.springframework.security.web.session.DisableEncodeUrlFilter.doFilterInternal(DisableEncodeUrlFilter.java:42)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374)
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:233)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:191)
at org.springframework.web.filter.CompositeFilter$VirtualFilterChain.doFilter(CompositeFilter.java:113)
at org.springframework.web.servlet.handler.HandlerMappingIntrospector.lambda$createCacheFilter$3(HandlerMappingIntrospector.java:195)
at org.springframework.web.filter.CompositeFilter$VirtualFilterChain.doFilter(CompositeFilter.java:113)
at org.springframework.web.filter.CompositeFilter.doFilter(CompositeFilter.java:74)
at org.springframework.security.config.annotation.web.configuration.WebMvcSecurityConfiguration$CompositeFilterChainProxy.doFilter(WebMvcSecurityConfiguration.java:230)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:352)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:268)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:175)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:150)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:175)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:150)
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:175)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:150)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:175)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:150)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:167)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:482)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:115)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:344)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:391)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:896)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1736)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52)
at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63)
at java.base/java.lang.Thread.run(Thread.java:1623)
Caused by: org.h2.jdbc.JdbcSQLInvalidAuthorizationSpecException: Неверное имя пользователя или пароль
Wrong user name or password [28000-224]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:522)
at org.h2.message.DbException.getJdbcSQLException(DbException.java:489)
... 100 more

View File

@ -6,21 +6,24 @@ import java.util.Map;
import org.modelmapper.ModelMapper;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import com.example.demo.core.api.PageAttributesMapper;
import com.example.demo.core.configuration.Constants;
import com.example.demo.games.model.GameEntity;
import com.example.demo.games.service.GameService;
import com.example.demo.genres.api.GenreDto;
import com.example.demo.genres.model.GenreEntity;
import com.example.demo.genres.service.GenreService;
import com.example.demo.types.api.TypeDto;
import com.example.demo.types.model.TypeEntity;
import com.example.demo.types.service.TypeService;
import jakarta.validation.Valid;
@ -60,6 +63,14 @@ public class GameController {
return dto;
}
private TypeDto toTypeDto(TypeEntity entity) {
return modelMapper.map(entity, TypeDto.class);
}
private GenreDto toGenreDto(GenreEntity entity) {
return modelMapper.map(entity, GenreDto.class);
}
private GameEntity toEntity(GameDto dto) {
// return modelMapper.map(dto, GameEntity.class);
final GameEntity entity = modelMapper.map(dto, GameEntity.class);
@ -83,23 +94,75 @@ public class GameController {
return GAME_VIEW;
}
@GetMapping("/{id}")
public GameDto get(@PathVariable(name = "id") Long id) {
return toDto(gameService.get(id));
@GetMapping("/edit/")
public String create(
@RequestParam(name = PAGE_ATTRIBUTE, defaultValue = "0") int page,
Model model) {
model.addAttribute(GAME_ATTRIBUTE, new GameDto());
model.addAttribute("types", typeService.getAll().stream().map(this::toTypeDto).toList());
model.addAttribute("genresCheck", genreService.getAll().stream().map(this::toGenreDto).toList());
model.addAttribute(PAGE_ATTRIBUTE, page);
return GAME_EDIT_VIEW;
}
@PostMapping
public GameDto create(@RequestBody @Valid GameDto dto) {
return toDto(gameService.create(toEntity(dto)));
@PostMapping("/edit/")
public String create(
@RequestParam(name = PAGE_ATTRIBUTE, defaultValue = "0") int page,
@ModelAttribute(name = GAME_ATTRIBUTE) @Valid GameDto game,
BindingResult bindingResult,
Model model,
RedirectAttributes redirectAttributes) {
if (bindingResult.hasErrors()) {
model.addAttribute(PAGE_ATTRIBUTE, page);
return GAME_EDIT_VIEW;
}
redirectAttributes.addAttribute(PAGE_ATTRIBUTE, page);
gameService.create(toEntity(game));
return Constants.REDIRECT_VIEW + URL;
}
@PutMapping("/{id}")
public GameDto update(@PathVariable(name = "id") Long id, @RequestBody GameDto dto) {
return toDto(gameService.update(id, toEntity(dto)));
@GetMapping("/edit/{id}")
public String update(
@PathVariable(name = "id") Long id,
@RequestParam(name = PAGE_ATTRIBUTE, defaultValue = "0") int page,
Model model) {
if (id <= 0) {
throw new IllegalArgumentException();
}
model.addAttribute(GAME_ATTRIBUTE, toDto(gameService.get(id)));
model.addAttribute(PAGE_ATTRIBUTE, page);
model.addAttribute("types", typeService.getAll().stream().map(this::toTypeDto).toList());
model.addAttribute("genresCheck", genreService.getAll().stream().map(this::toGenreDto).toList());
return GAME_EDIT_VIEW;
}
@DeleteMapping("/{id}")
public GameDto delete(@PathVariable(name = "id") Long id) {
return toDto(gameService.delete(id));
@PostMapping("/edit/{id}")
public String update(
@PathVariable(name = "id") Long id,
@RequestParam(name = PAGE_ATTRIBUTE, defaultValue = "0") int page,
@ModelAttribute(name = GAME_ATTRIBUTE) @Valid GameDto game,
BindingResult bindingResult,
Model model,
RedirectAttributes redirectAttributes) {
if (bindingResult.hasErrors()) {
model.addAttribute(PAGE_ATTRIBUTE, page);
return GAME_EDIT_VIEW;
}
if (id <= 0) {
throw new IllegalArgumentException();
}
redirectAttributes.addAttribute(PAGE_ATTRIBUTE, page);
gameService.update(id, toEntity(game));
return Constants.REDIRECT_VIEW + URL;
}
@PostMapping("/delete/{id}")
public String delete(
@PathVariable(name = "id") Long id,
@RequestParam(name = PAGE_ATTRIBUTE, defaultValue = "0") int page,
RedirectAttributes redirectAttributes) {
redirectAttributes.addAttribute(PAGE_ATTRIBUTE, page);
gameService.delete(id);
return Constants.REDIRECT_VIEW + URL;
}
}

View File

@ -15,7 +15,7 @@ public class GameDto {
@NotNull
private final List<Long> genres = new ArrayList<>();
@NotNull
@Min(1)
@Min(100)
private Double price;
@NotBlank
private String name;

View File

@ -12,12 +12,12 @@ import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToMany;
import jakarta.persistence.OneToOne;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
@Entity
@Table(name = "games")
public class GameEntity extends BaseEntity{
public class GameEntity extends BaseEntity {
@Column(nullable = false)
private String name;
@Column(nullable = false)
@ -27,14 +27,14 @@ public class GameEntity extends BaseEntity{
@ManyToMany()
@Column(unique = false)
private final List<GenreEntity> genres = new ArrayList<>();
@OneToOne
@ManyToOne
@JoinColumn(name = "typeId", nullable = false, unique = false)
private TypeEntity type;
public GameEntity(){
public GameEntity() {
}
public GameEntity(TypeEntity type, String name, Double price, String description, List<GenreEntity> genres){
public GameEntity(TypeEntity type, String name, Double price, String description, List<GenreEntity> genres) {
this.type = type;
this.name = name;
this.price = price;
@ -43,56 +43,60 @@ public class GameEntity extends BaseEntity{
this.genres.addAll(genres);
}
public TypeEntity getType(){
public TypeEntity getType() {
return type;
}
public void setType(TypeEntity type){
public void setType(TypeEntity type) {
this.type = type;
}
public Double getPrice(){
public Double getPrice() {
return price;
}
public void setPrice(Double price){
public void setPrice(Double price) {
this.price = price;
}
public String getName(){
public String getName() {
return name;
}
public void setName(String name){
public void setName(String name) {
this.name = name;
}
public String getDescription(){
public String getDescription() {
return description;
}
public void setDescription(String description){
public void setDescription(String description) {
this.description = description;
}
public List<GenreEntity> getGenres(){
public List<GenreEntity> getGenres() {
return genres;
}
public void setGenres(GenreEntity genre){
public void setGenres(GenreEntity genre) {
this.genres.add(genre);
}
public void delGenres() {
this.genres.clear();
}
@Override
public int hashCode() {
return Objects.hash(id, type, price, genres, description, name);
}
@Override
public boolean equals(Object obj){
if(this == obj)
public boolean equals(Object obj) {
if (this == obj)
return true;
if(obj == null || getClass() != obj.getClass())
if (obj == null || getClass() != obj.getClass())
return false;
final GameEntity other = (GameEntity) obj;
return Objects.equals(other.getId(), id)

View File

@ -86,9 +86,12 @@ public class GameService {
existEntity.setDescription(entity.getDescription());
existEntity.setType(entity.getType());
var genres = entity.getGenres();
if (genres.size() != 0) {
existEntity.delGenres();
for (var genre : genres) {
existEntity.setGenres(genre);
}
}
return repository.save(existEntity);
}

View File

@ -1,30 +1,27 @@
package com.example.demo.genres.api;
import com.fasterxml.jackson.annotation.JsonProperty;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Size;
public class GenreDto {
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
private Long id;
@NotBlank
@Size(min = 1, max = 50)
private String name;
public Long getId(){
public Long getId() {
return id;
}
public void setId(Long id){
public void setId(Long id) {
this.id = id;
}
public String getName(){
public String getName() {
return name;
}
public void setName(String name){
public void setName(String name) {
this.name = name;
}
}

View File

@ -15,6 +15,7 @@ public interface OrderRepository
extends CrudRepository<OrderEntity, Long>, PagingAndSortingRepository<OrderEntity, Long> {
Optional<OrderEntity> findOneByUserIdAndId(long userId, long id);
@Query("select o from OrderEntity o join fetch o.games where o.user.id = ?1")
List<OrderEntity> findByUserId(long userId);
@Query("select o from OrderEntity o join fetch o.games where o.user.id = ?1")

View File

@ -1,7 +1,6 @@
package com.example.demo.orders.service;
import java.util.List;
import java.util.stream.StreamSupport;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;

View File

@ -2,9 +2,7 @@ package com.example.demo.users.api;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;
import org.modelmapper.ModelMapper;
@ -43,7 +41,6 @@ public class UserCartController {
private final GameService gameService;
private final OrderService orderService;
private final SessionCart cart;
private final ModelMapper modelMapper;
public UserCartController(
GameService gameService,
@ -53,7 +50,6 @@ public class UserCartController {
this.gameService = gameService;
this.orderService = orderService;
this.cart = cart;
this.modelMapper = modelMapper;
}
private GameDto toGameDto(GameEntity entity) {

View File

@ -5,7 +5,10 @@ import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import com.example.demo.core.api.PageAttributesMapper;
import com.example.demo.core.configuration.Constants;
@ -24,13 +27,9 @@ public class UserProfileController {
private static final String PROFILE_VIEW = "profile";
private static final String PAGE_ATTRIBUTE = "page";
private static final String TYPEID_ATTRIBUTE = "gameId";
private static final String PROFILE_ATTRIBUTE = "profile";
private final OrderService orderService;
private final GameService gameService;
private final UserService userService;
private final ModelMapper modelMapper;
public UserProfileController(
OrderService orderService,
@ -39,8 +38,6 @@ public class UserProfileController {
ModelMapper modelMapper) {
this.orderService = orderService;
this.gameService = gameService;
this.userService = userService;
this.modelMapper = modelMapper;
}
private OrderDto toDto(OrderEntity entity) {
@ -64,12 +61,10 @@ public class UserProfileController {
@GetMapping
public String getProfile(
@RequestParam(name = PAGE_ATTRIBUTE, defaultValue = "0") int page,
@RequestParam(name = TYPEID_ATTRIBUTE, defaultValue = "0") int typeId,
Model model,
@AuthenticationPrincipal UserPrincipal principal) {
final long userId = principal.getId();
model.addAttribute(PAGE_ATTRIBUTE, page);
model.addAttribute(TYPEID_ATTRIBUTE, typeId);
model.addAllAttributes(PageAttributesMapper.toAttributes(
orderService.getAll(userId, page, Constants.DEFAULT_PAGE_SIZE),
this::toDto));
@ -79,4 +74,15 @@ public class UserProfileController {
.toList());
return PROFILE_VIEW;
}
@PostMapping("/delete/{id}")
public String deleteOrder(
@PathVariable(name = "id") Long id,
@RequestParam(name = PAGE_ATTRIBUTE, defaultValue = "0") int page,
RedirectAttributes redirectAttributes,
@AuthenticationPrincipal UserPrincipal principal) {
redirectAttributes.addAttribute(PAGE_ATTRIBUTE, page);
orderService.delete(principal.getId(), id);
return Constants.REDIRECT_VIEW + "/";
}
}

View File

@ -17,12 +17,15 @@
</button>
</form>
</div>
<div class="card col-12 col-md-8 col-lg-6 align-items-center" th:each="cartItem : ${cart}">
<div class="card col-12 col-md-8 col-lg-6 w-25 align-items-center" th:each="cartItem : ${cart}">
<div class="card-body col-12 p-2 d-flex flex-row align-items-center justify-content-center">
<div class="col-9">
[[${cartItem.gameName}]]
<div class="col-5">
Название: [[${cartItem.gameName}]]
</div>
<div class="col-7">
Цена: [[${cartItem.Price}]]
</div>
</div>
</div>
<div class=" mb-2 col-12 col-md-8 col-lg-6 d-flex justify-content-end">

View File

@ -47,8 +47,6 @@
</a>
<a class="nav-link" href="/h2-console/" target="_blank">Консоль H2</a>
</th:block>
<a class="nav-link" href="/123" target="_blank">Ошибка 1</a>
<a class="nav-link" href="/admin/123" target="_blank">Ошибка 2</a>
</ul>
<ul class="navbar-nav" th:if="${not #strings.isEmpty(userName)}">
<form th:action="@{/logout}" method="post">

View File

@ -7,7 +7,7 @@
<body>
<main layout:fragment="content">
<form action="#" th:action="@{/admin/game/edit/{id}(id=${type.id})}" th:object="${type}" method="post">
<form action="#" th:action="@{/admin/game/edit/{id}(id=${game.id})}" th:object="${game}" method="post">
<div class="mb-3">
<label for="id" class="form-label">ID</label>
<input type="text" th:value="*{id}" id="id" class="form-control" readonly disabled>
@ -18,16 +18,37 @@
<div th:if="${#fields.hasErrors('name')}" th:errors="*{name}" class="invalid-feedback"></div>
</div>
<div class="mb-2">
<label for="type" class="form-label">Тип</label>
<select th:field="*{type}" id="type" class="form-select">
<label for="typeId" class="form-label">Тип</label>
<select th:field="*{typeId}" id="typeId" class="form-select">
<option selected value="">Укажите тип</option>
<option th:each="type : ${types}" th:value="${type.id}">[[${type.name}]]</option>
</select>
<div th:if="${#fields.hasErrors('type')}" th:errors="*{type}" class="invalid-feedback"></div>
</div>
<div class="mb-2">
<label class="form-label">Жанр</label>
<div class="form-check" th:each="genre : ${genresCheck}">
<input class="form-check-input" th:field="*{genres}" th:value="${genre.id}" type="checkbox"
th:for="${id}">
<label class="form-check-label" th:field="*{genres}" for="" th:for="${id}">
[[${genre.name}]]
</label>
</div>
</div>
<div class="mb-3">
<label for="price" class="form-label">Цена</label>
<input type="number" th:field="*{price}" id="price" class="form-control">
<div th:if="${#fields.hasErrors('price')}" th:errors="*{price}" class="invalid-feedback"></div>
</div>
<div class="mb-3">
<label for="description" class="form-label">Описание</label>
<textarea type="textarea" rows="5" cols="80" th:field="*{description}" id="description"
class="form-control"></textarea>
<div th:if="${#fields.hasErrors('description')}" th:errors="*{description}" class="invalid-feedback">
</div>
</div>
<div class="mb-3 d-flex flex-row">
<button class="btn btn-primary me-2 button-fixed-width" type="submit">Сохранить</button>
<a class="btn btn-secondary button-fixed-width" href="/admin/type">Отмена</a>
<a class="btn btn-secondary button-fixed-width" href="/admin/game">Отмена</a>
</div>
</form>
</main>

View File

@ -2,7 +2,7 @@
<html xmlns:th="http://www.thymeleaf.org">
<body>
<th:block th:fragment="orders (items, totalPages, currentPage), games (items, totalPages, currentPage)">
<th:block th:fragment="orders (items, totalPages, currentPage, games)">
<th:block th:switch="${items.size()}">
<h2 th:case="0">Данные отсутствуют</h2>
<th:block th:case="*">
@ -26,11 +26,18 @@
<tr>
<th scope="col" class="w-10"></th>
<th scope="col" class="w-auto">Название игры</th>
<th scope="col" class="w-10">Цена</th>
</tr>
</thead>
<tbody>
<tr th:each="game : ${order.games}">
<th scope="row" th:text="${game}"></th>
<tr th:each="gameId : ${order.games}">
<th:block th:each="game : ${games}">
<th:block th:if="${gameId} eq ${game.id}">
<th scope="row" th:text="${gameId}"></th>
<th scope="row" th:text="${game.name}"></th>
<th scope="row" th:text="${game.price}"></th>
</th:block>
</th:block>
</tr>
</tbody>
</table>
@ -38,7 +45,6 @@
<td>
<form th:action="@{/delete/{id}(id=${order.id})}" method="post">
<input type="hidden" th:name="page" th:value="${page}">
<input type="hidden" th:name="typeId" th:value="${typeId}">
<button type="submit" class="btn btn-link button-link"
onclick="return confirm('Вы уверены?')">Удалить</button>
</form>

View File

@ -16,7 +16,7 @@
<div class="tab-content mt-2">
<div class="tab-pane container active" id="orders">
<th:block
th:replace="~{ orders :: orders (items=${items}, totalPages=${totalPages}, currentPage=${currentPage})}" />
th:replace="~{ orders :: orders (items=${items}, totalPages=${totalPages}, currentPage=${currentPage}, games=${games})}" />
</div>
</div>
</main>