почти все
This commit is contained in:
parent
63dcaa4d7a
commit
2d2394bce5
24
build.gradle
24
build.gradle
@ -12,22 +12,24 @@ repositories {
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
jar {
|
||||
enabled = false
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(project(':front'))
|
||||
|
||||
implementation 'org.springframework.boot:spring-boot-starter-web'
|
||||
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-thymeleaf'
|
||||
implementation 'org.springframework.boot:spring-boot-devtools'
|
||||
implementation 'nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect'
|
||||
|
||||
implementation 'org.webjars:bootstrap:5.1.3'
|
||||
implementation 'org.webjars:jquery:3.6.0'
|
||||
implementation 'org.webjars:font-awesome:6.1.0'
|
||||
|
||||
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
|
||||
implementation 'com.h2database:h2:2.1.210'
|
||||
|
||||
implementation 'org.hibernate.validator:hibernate-validator'
|
||||
|
||||
implementation 'org.springdoc:springdoc-openapi-ui:1.6.5'
|
||||
|
||||
testImplementation 'org.springframework.boot:spring-boot-starter-test'
|
||||
implementation 'org.hibernate.validator:hibernate-validator'
|
||||
implementation 'org.springdoc:springdoc-openapi-ui:1.6.5'
|
||||
}
|
||||
|
||||
tasks.named('test') {
|
||||
|
@ -1,35 +1,19 @@
|
||||
package com.labwork1.app;
|
||||
|
||||
import org.springframework.boot.web.server.ErrorPage;
|
||||
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
|
||||
import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.web.servlet.config.annotation.CorsRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.ViewControllerRegistration;
|
||||
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
import org.springframework.web.servlet.config.annotation.*;
|
||||
|
||||
@Configuration
|
||||
public class WebConfiguration implements WebMvcConfigurer {
|
||||
public static final String REST_API = "/api";
|
||||
|
||||
@Override
|
||||
public void addViewControllers(ViewControllerRegistry registry) {
|
||||
WebMvcConfigurer.super.addViewControllers(registry);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addCorsMappings(CorsRegistry registry) {
|
||||
registry.addMapping("/**").allowedMethods("*");
|
||||
}
|
||||
@Override
|
||||
public void addViewControllers(ViewControllerRegistry registry) {
|
||||
ViewControllerRegistration registration = registry.addViewController("/notFound");
|
||||
registration.setViewName("forward:/index.html");
|
||||
registration.setStatusCode(HttpStatus.OK);
|
||||
|
||||
// Alternative way (404 error hits the console):
|
||||
// > registry.addViewController("/notFound").setViewName("forward:/index.html");
|
||||
}
|
||||
|
||||
@Bean
|
||||
public WebServerFactoryCustomizer<ConfigurableServletWebServerFactory> containerCustomizer() {
|
||||
return container -> {
|
||||
container.addErrorPages(new ErrorPage(HttpStatus.NOT_FOUND, "/notFound"));
|
||||
};
|
||||
}
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
package com.labwork1.app.student.controller;
|
||||
|
||||
import com.labwork1.app.WebConfiguration;
|
||||
import com.labwork1.app.student.service.CinemaService;
|
||||
import jakarta.validation.Valid;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
@ -7,7 +8,7 @@ import org.springframework.web.bind.annotation.*;
|
||||
import java.util.List;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/cinema")
|
||||
@RequestMapping(WebConfiguration.REST_API + "/cinema")
|
||||
public class CinemaController {
|
||||
private final CinemaService cinemaService;
|
||||
|
||||
|
@ -18,6 +18,18 @@ public class CinemaDto {
|
||||
this.image = new String(cinema.getImage(), StandardCharsets.UTF_8);
|
||||
}
|
||||
|
||||
public void setId(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public void setImage(String image) {
|
||||
this.image = image;
|
||||
}
|
||||
|
||||
public String getImage() {
|
||||
return image;
|
||||
}
|
||||
|
@ -0,0 +1,81 @@
|
||||
package com.labwork1.app.student.controller;
|
||||
|
||||
import com.labwork1.app.student.service.CinemaService;
|
||||
import jakarta.validation.Valid;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.validation.BindingResult;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Base64;
|
||||
import java.util.List;
|
||||
|
||||
@Controller
|
||||
@RequestMapping("/cinema")
|
||||
public class CinemaMvcController {
|
||||
private final CinemaService cinemaService;
|
||||
|
||||
public CinemaMvcController(CinemaService cinemaService) {
|
||||
this.cinemaService = cinemaService;
|
||||
}
|
||||
|
||||
@GetMapping
|
||||
public String getCinemas(Model model) {
|
||||
model.addAttribute("cinemas",
|
||||
cinemaService.findAllCinemas().stream()
|
||||
.map(CinemaDto::new)
|
||||
.toList());
|
||||
return "cinema";
|
||||
}
|
||||
|
||||
@GetMapping(value = {"/edit", "/edit/{id}"})
|
||||
public String editCinema(@PathVariable(required = false) Long id,
|
||||
Model model) {
|
||||
if (id == null || id <= 0) {
|
||||
model.addAttribute("cinemaDto", new CinemaDto());
|
||||
} else {
|
||||
model.addAttribute("cinemaId", id);
|
||||
model.addAttribute("cinemaDto", new CinemaDto(cinemaService.findCinema(id)));
|
||||
}
|
||||
return "cinema-edit";
|
||||
}
|
||||
|
||||
@GetMapping (value = "/search/")
|
||||
public String searchCinema(@RequestParam String request,
|
||||
Model model) {
|
||||
List<CinemaDto> cinemas = cinemaService.findAllCinemas(request)
|
||||
.stream().map(CinemaDto::new).toList();
|
||||
model.addAttribute("cinemas", cinemas);
|
||||
return "cinema";
|
||||
}
|
||||
|
||||
@PostMapping(value = {"/", "/{id}"})
|
||||
public String saveCinema(@PathVariable(required = false) Long id,
|
||||
@RequestParam("multipartFile") MultipartFile multipartFile,
|
||||
@ModelAttribute @Valid CinemaDto cinemaDto,
|
||||
BindingResult bindingResult,
|
||||
Model model) throws IOException {
|
||||
if (bindingResult.hasErrors()) {
|
||||
model.addAttribute("errors", bindingResult.getAllErrors());
|
||||
return "cinema-edit";
|
||||
}
|
||||
if (id == null || id <= 0) {
|
||||
cinemaDto.setImage("data:image/jpeg;base64," + Base64.getEncoder().encodeToString(multipartFile.getBytes()));
|
||||
cinemaService.addCinema(cinemaDto);
|
||||
} else {
|
||||
cinemaDto.setId(id);
|
||||
cinemaDto.setImage("data:image/jpeg;base64," + Base64.getEncoder().encodeToString(multipartFile.getBytes()));
|
||||
cinemaService.updateCinema(cinemaDto);
|
||||
}
|
||||
return "redirect:/cinema";
|
||||
}
|
||||
|
||||
@PostMapping("/delete/{id}")
|
||||
public String deleteCinema(@PathVariable Long id) {
|
||||
cinemaService.deleteCinema(id);
|
||||
return "redirect:/cinema";
|
||||
}
|
||||
|
||||
}
|
@ -1,12 +1,13 @@
|
||||
package com.labwork1.app.student.controller;
|
||||
|
||||
import com.labwork1.app.WebConfiguration;
|
||||
import com.labwork1.app.student.service.CustomerService;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/customer")
|
||||
@RequestMapping(WebConfiguration.REST_API + "/customer")
|
||||
public class CustomerController {
|
||||
private final CustomerService customerService;
|
||||
|
||||
|
@ -27,6 +27,22 @@ public class CustomerDto {
|
||||
}
|
||||
}
|
||||
|
||||
public void setId(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public void setLogin(String login) {
|
||||
this.login = login;
|
||||
}
|
||||
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
public void setOrders(List<OrderDto> orders) {
|
||||
this.orders = orders;
|
||||
}
|
||||
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
@ -0,0 +1,64 @@
|
||||
package com.labwork1.app.student.controller;
|
||||
|
||||
import com.labwork1.app.student.service.CustomerService;
|
||||
import jakarta.validation.Valid;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.validation.BindingResult;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
@Controller
|
||||
@RequestMapping("/customer")
|
||||
public class CustomerMvcController {
|
||||
private final CustomerService customerService;
|
||||
|
||||
public CustomerMvcController(CustomerService customerService) {
|
||||
this.customerService = customerService;
|
||||
}
|
||||
|
||||
@GetMapping
|
||||
public String getCustomers(Model model) {
|
||||
model.addAttribute("customers",
|
||||
customerService.findAllCustomers().stream()
|
||||
.map(CustomerDto::new)
|
||||
.toList());
|
||||
return "customer";
|
||||
}
|
||||
|
||||
@GetMapping(value = {"/edit", "/edit/{id}"})
|
||||
public String editCustomer(@PathVariable(required = false) Long id,
|
||||
Model model) {
|
||||
if (id == null || id <= 0) {
|
||||
model.addAttribute("customerDto", new CustomerDto());
|
||||
} else {
|
||||
model.addAttribute("customerId", id);
|
||||
model.addAttribute("customerDto", new CustomerDto(customerService.findCustomer(id)));
|
||||
}
|
||||
return "customer-edit";
|
||||
}
|
||||
|
||||
@PostMapping(value = {"/", "/{id}"})
|
||||
public String saveCustomer(@PathVariable(required = false) Long id,
|
||||
@ModelAttribute @Valid CustomerDto customerDto,
|
||||
BindingResult bindingResult,
|
||||
Model model) {
|
||||
if (bindingResult.hasErrors()) {
|
||||
model.addAttribute("errors", bindingResult.getAllErrors());
|
||||
return "customer-edit";
|
||||
}
|
||||
if (id == null || id <= 0) {
|
||||
customerService.addCustomer(customerDto.getLogin(), customerDto.getPassword());
|
||||
} else {
|
||||
customerDto.setId(id);
|
||||
customerService.updateCustomer(id, customerDto.getLogin(), customerDto.getPassword());
|
||||
}
|
||||
return "redirect:/customer";
|
||||
}
|
||||
|
||||
@PostMapping("/delete/{id}")
|
||||
public String deleteCustomer(@PathVariable Long id) {
|
||||
customerService.deleteCustomer(id);
|
||||
return "redirect:/customer";
|
||||
}
|
||||
|
||||
}
|
@ -1,12 +1,13 @@
|
||||
package com.labwork1.app.student.controller;
|
||||
|
||||
import com.labwork1.app.WebConfiguration;
|
||||
import com.labwork1.app.student.service.OrderService;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/order")
|
||||
@RequestMapping(WebConfiguration.REST_API + "/order")
|
||||
public class OrderController {
|
||||
private final OrderService orderService;
|
||||
|
||||
|
@ -10,6 +10,7 @@ import java.util.List;
|
||||
public class OrderDto {
|
||||
private long id;
|
||||
private Date dateOfPurchase;
|
||||
private Long customerId;
|
||||
private String customer;
|
||||
private List<OrderSessionDto> sessions;
|
||||
|
||||
@ -19,6 +20,7 @@ public class OrderDto {
|
||||
public OrderDto(Order order) {
|
||||
this.id = order.getId();
|
||||
this.dateOfPurchase = order.getDateOfPurchase();
|
||||
this.customerId = order.getCustomer().getId();
|
||||
this.customer = order.getCustomer().getLogin();
|
||||
if (order.getSessions() != null && order.getSessions().size() > 0)
|
||||
this.sessions = order.getSessions()
|
||||
@ -27,6 +29,30 @@ public class OrderDto {
|
||||
x.getId().getOrderId(), x.getCount())).toList();
|
||||
}
|
||||
|
||||
public Long getCustomerId() {
|
||||
return customerId;
|
||||
}
|
||||
|
||||
public void setCustomerId(Long customerId) {
|
||||
this.customerId = customerId;
|
||||
}
|
||||
|
||||
public void setId(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public void setDateOfPurchase(Date dateOfPurchase) {
|
||||
this.dateOfPurchase = dateOfPurchase;
|
||||
}
|
||||
|
||||
public void setCustomer(String customer) {
|
||||
this.customer = customer;
|
||||
}
|
||||
|
||||
public void setSessions(List<OrderSessionDto> sessions) {
|
||||
this.sessions = sessions;
|
||||
}
|
||||
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
@ -0,0 +1,99 @@
|
||||
package com.labwork1.app.student.controller;
|
||||
|
||||
import com.labwork1.app.student.service.CustomerService;
|
||||
import com.labwork1.app.student.service.OrderService;
|
||||
import com.labwork1.app.student.service.SessionService;
|
||||
import jakarta.validation.Valid;
|
||||
import org.slf4j.event.KeyValuePair;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.validation.BindingResult;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Controller
|
||||
@RequestMapping("/order")
|
||||
public class OrderMvcController {
|
||||
private final OrderService orderService;
|
||||
private final SessionService sessionService;
|
||||
private final CustomerService customerService;
|
||||
|
||||
public OrderMvcController(OrderService orderService, SessionService sessionService, CustomerService customerService) {
|
||||
this.orderService = orderService;
|
||||
this.sessionService = sessionService;
|
||||
this.customerService = customerService;
|
||||
}
|
||||
|
||||
@GetMapping
|
||||
public String getOrders(Model model) {
|
||||
model.addAttribute("orders",
|
||||
orderService.findAllOrders().stream()
|
||||
.map(OrderDto::new)
|
||||
.toList());
|
||||
return "order";
|
||||
}
|
||||
|
||||
@GetMapping(value = {"/edit", "/edit/{id}"})
|
||||
public String editOrder(@PathVariable(required = false) Long id,
|
||||
Model model) {
|
||||
if (id == null || id <= 0) {
|
||||
List<CustomerDto> customers = customerService.findAllCustomers().stream()
|
||||
.map(CustomerDto::new)
|
||||
.toList();
|
||||
model.addAttribute("orderDto", new OrderDto());
|
||||
model.addAttribute("customers", customers);
|
||||
|
||||
return "order-edit";
|
||||
} else {
|
||||
List<OrderSessionDto> temp = orderService.findOrder(id).getSessions()
|
||||
.stream().map(x -> new OrderSessionDto(new SessionDto(x.getSession()),
|
||||
x.getOrder().getId(), x.getCount())).toList();
|
||||
List<SessionDto> sessions = sessionService.findAllSessions().stream()
|
||||
.map(SessionDto::new)
|
||||
.toList();
|
||||
HashMap<SessionDto, Integer> orderSessions = new HashMap<>();
|
||||
for (var os : temp) {
|
||||
orderSessions.put(os.getSession(), os.getCount());
|
||||
}
|
||||
model.addAttribute("orderSessions", orderSessions);
|
||||
model.addAttribute("sessions", sessions);
|
||||
model.addAttribute("orderSessionDto", new OrderSessionDto());
|
||||
|
||||
return "ordersession";
|
||||
}
|
||||
}
|
||||
|
||||
@PostMapping(value = "/")
|
||||
public String saveOrder(@ModelAttribute @Valid OrderDto orderDto,
|
||||
BindingResult bindingResult,
|
||||
Model model) {
|
||||
if (bindingResult.hasErrors()) {
|
||||
model.addAttribute("errors", bindingResult.getAllErrors());
|
||||
return "order-edit";
|
||||
}
|
||||
orderService.addOrder(orderDto.getCustomerId());
|
||||
return "redirect:/order";
|
||||
}
|
||||
|
||||
@PostMapping(value = {"/{id}"})
|
||||
public String editOrder(@PathVariable Long id,
|
||||
@RequestParam("session") Long session,
|
||||
@RequestParam(value = "count", required = false) Integer count,
|
||||
Model model) {
|
||||
if (count == null)
|
||||
orderService.deleteSessionInOrder(id, session, Integer.MAX_VALUE);
|
||||
else if (count > 0)
|
||||
orderService.addSession(id, session, count);
|
||||
return "redirect:/order/edit/" + id;
|
||||
}
|
||||
|
||||
@PostMapping("/delete/{id}")
|
||||
public String deleteOrder(@PathVariable Long id) {
|
||||
orderService.deleteOrder(id);
|
||||
return "redirect:/order";
|
||||
}
|
||||
|
||||
}
|
@ -14,6 +14,18 @@ public class OrderSessionDto {
|
||||
this.count = count;
|
||||
}
|
||||
|
||||
public void setSession(SessionDto session) {
|
||||
this.session = session;
|
||||
}
|
||||
|
||||
public void setOrderId(Long orderId) {
|
||||
this.orderId = orderId;
|
||||
}
|
||||
|
||||
public void setCount(Integer count) {
|
||||
this.count = count;
|
||||
}
|
||||
|
||||
public SessionDto getSession() {
|
||||
return session;
|
||||
}
|
||||
|
@ -1,16 +1,19 @@
|
||||
package com.labwork1.app.student.controller;
|
||||
|
||||
import com.labwork1.app.WebConfiguration;
|
||||
import com.labwork1.app.student.service.SessionService;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/session")
|
||||
@RequestMapping(WebConfiguration.REST_API + "/session")
|
||||
public class SessionController {
|
||||
private final SessionService sessionService;
|
||||
|
||||
@ -36,11 +39,11 @@ public class SessionController {
|
||||
@RequestParam("cinemaid") Long cinemaId,
|
||||
@RequestParam("capacity") Integer capacity) throws ParseException {
|
||||
SimpleDateFormat format = new SimpleDateFormat();
|
||||
format.applyPattern("yyyy-MM-dd-HH:ss");
|
||||
format.applyPattern("yyyy-MM-dd-HH:mm");
|
||||
Date docDate = format.parse(timestamp.replace('T', '-'));
|
||||
return new SessionDto(sessionService.findSession(
|
||||
sessionService.addSession(Double.parseDouble(price),
|
||||
new Timestamp(docDate.getTime()), cinemaId, capacity).getId()));
|
||||
LocalDateTime.now(), cinemaId, capacity).getId()));
|
||||
}
|
||||
|
||||
@PutMapping("/{id}")
|
||||
|
@ -1,16 +1,17 @@
|
||||
package com.labwork1.app.student.controller;
|
||||
|
||||
import com.labwork1.app.student.model.Session;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
public class SessionDto {
|
||||
private long id;
|
||||
private Double price;
|
||||
private Timestamp timestamp;
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd'T'HH:mm")
|
||||
private LocalDateTime timestamp;
|
||||
private CinemaDto cinema;
|
||||
private Long capacity;
|
||||
|
||||
private int maxCount;
|
||||
|
||||
public SessionDto() {
|
||||
@ -22,31 +23,56 @@ public class SessionDto {
|
||||
this.timestamp = session.getTimestamp();
|
||||
this.capacity = session.getCapacity();
|
||||
this.maxCount = session.getMaxCount();
|
||||
if (session.getCinema() != null) this.cinema = new CinemaDto(session.getCinema());
|
||||
else this.cinema = null;
|
||||
if (session.getCinema() != null) {
|
||||
this.cinema = new CinemaDto(session.getCinema());
|
||||
} else this.cinema = null;
|
||||
}
|
||||
|
||||
public int getMaxCount() {
|
||||
return maxCount;
|
||||
public CinemaDto getCinema() {
|
||||
return cinema;
|
||||
}
|
||||
|
||||
public void setCinema(CinemaDto cinema) {
|
||||
this.cinema = cinema;
|
||||
}
|
||||
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Double getPrice() {
|
||||
return price;
|
||||
}
|
||||
|
||||
public Timestamp getTimestamp() {
|
||||
public void setPrice(Double price) {
|
||||
this.price = price;
|
||||
}
|
||||
|
||||
public LocalDateTime getTimestamp() {
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
public void setTimestamp(LocalDateTime timestamp) {
|
||||
this.timestamp = timestamp;
|
||||
}
|
||||
|
||||
public Long getCapacity() {
|
||||
return capacity;
|
||||
}
|
||||
|
||||
public CinemaDto getCinema() {
|
||||
return cinema;
|
||||
public void setCapacity(Long capacity) {
|
||||
this.capacity = capacity;
|
||||
}
|
||||
|
||||
public int getMaxCount() {
|
||||
return maxCount;
|
||||
}
|
||||
|
||||
public void setMaxCount(int maxCount) {
|
||||
this.maxCount = maxCount;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,81 @@
|
||||
package com.labwork1.app.student.controller;
|
||||
|
||||
import com.labwork1.app.student.service.CinemaService;
|
||||
import com.labwork1.app.student.service.SessionService;
|
||||
import jakarta.validation.Valid;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.validation.BindingResult;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
@Controller
|
||||
@RequestMapping("/session")
|
||||
public class SessionMvcController {
|
||||
private final SessionService sessionService;
|
||||
private final CinemaService cinemaService;
|
||||
|
||||
public SessionMvcController(SessionService sessionService, CinemaService cinemaService) {
|
||||
this.sessionService = sessionService;
|
||||
this.cinemaService = cinemaService;
|
||||
}
|
||||
|
||||
@GetMapping
|
||||
public String getSessions(Model model) {
|
||||
model.addAttribute("sessions",
|
||||
sessionService.findAllSessions().stream()
|
||||
.map(SessionDto::new)
|
||||
.toList());
|
||||
return "session";
|
||||
}
|
||||
|
||||
@GetMapping(value = {"/edit", "/edit/{id}"})
|
||||
public String editSession(@PathVariable(required = false) Long id,
|
||||
Model model) {
|
||||
if (id == null || id <= 0) {
|
||||
List<CinemaDto> cinemas = cinemaService.findAllCinemas().stream()
|
||||
.map(CinemaDto::new)
|
||||
.toList();
|
||||
model.addAttribute("sessionDto", new SessionDto());
|
||||
model.addAttribute("cinemas", cinemas);
|
||||
} else {
|
||||
model.addAttribute("sessionId", id);
|
||||
model.addAttribute("sessionDto", new SessionDto(sessionService.findSession(id)));
|
||||
}
|
||||
return "session-edit";
|
||||
}
|
||||
|
||||
@PostMapping(value = "/{id}")
|
||||
public String editSession(@PathVariable Long id,
|
||||
@ModelAttribute @Valid SessionDto sessionDto,
|
||||
BindingResult bindingResult,
|
||||
Model model) {
|
||||
if (bindingResult.hasErrors()) {
|
||||
model.addAttribute("errors", bindingResult.getAllErrors());
|
||||
return "session-edit";
|
||||
}
|
||||
sessionService.updateSession(id, sessionDto.getPrice());
|
||||
|
||||
return "redirect:/session";
|
||||
}
|
||||
|
||||
@PostMapping(value = "/")
|
||||
public String saveSession(@RequestParam("price") String price,
|
||||
@RequestParam("timestamp") LocalDateTime timestamp,
|
||||
@RequestParam("cinemaid") Long cinemaId,
|
||||
@RequestParam("maxCount") Integer capacity,
|
||||
Model model) {
|
||||
sessionService.addSession(Double.parseDouble(price), timestamp,
|
||||
cinemaId, capacity);
|
||||
return "redirect:/session";
|
||||
}
|
||||
|
||||
@PostMapping("/delete/{id}")
|
||||
public String deleteSession(@PathVariable Long id) {
|
||||
sessionService.deleteSession(id);
|
||||
return "redirect:/session";
|
||||
}
|
||||
|
||||
}
|
@ -2,8 +2,10 @@ package com.labwork1.app.student.model;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
@ -18,7 +20,8 @@ public class Session {
|
||||
@NotNull(message = "timestamp can't be null or empty")
|
||||
@Column
|
||||
@Temporal(TemporalType.TIMESTAMP)
|
||||
private Timestamp timestamp;
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd'T'HH:mm")
|
||||
private LocalDateTime timestamp;
|
||||
@OneToMany(mappedBy = "session", fetch = FetchType.EAGER)
|
||||
private List<OrderSession> orders;
|
||||
@ManyToOne(fetch = FetchType.EAGER)
|
||||
@ -37,7 +40,7 @@ public class Session {
|
||||
return maxCount;
|
||||
}
|
||||
|
||||
public Session(Double price, Timestamp timestamp, Integer maxCount) {
|
||||
public Session(Double price, LocalDateTime timestamp, Integer maxCount) {
|
||||
this.price = price;
|
||||
this.timestamp = timestamp;
|
||||
this.maxCount = maxCount;
|
||||
@ -125,11 +128,11 @@ public class Session {
|
||||
this.price = price;
|
||||
}
|
||||
|
||||
public Timestamp getTimestamp() {
|
||||
public LocalDateTime getTimestamp() {
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
public void setTimestamp(Timestamp timestamp) {
|
||||
public void setTimestamp(LocalDateTime timestamp) {
|
||||
this.timestamp = timestamp;
|
||||
}
|
||||
|
||||
|
@ -8,6 +8,7 @@ import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
@Service
|
||||
@ -23,7 +24,7 @@ public class SessionService {
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public Session addSession(Double price, Timestamp date, Long cinemaId, Integer capacity) {
|
||||
public Session addSession(Double price, LocalDateTime date, Long cinemaId, Integer capacity) {
|
||||
final Session session = new Session(price, date, capacity);
|
||||
final Cinema cinema = cinemaService.findCinema(cinemaId);
|
||||
session.setCinema(cinema);
|
||||
|
112
src/main/resources/public/css/style.css
Normal file
112
src/main/resources/public/css/style.css
Normal file
@ -0,0 +1,112 @@
|
||||
html,
|
||||
body {
|
||||
background: #2b2d33;
|
||||
}
|
||||
.green-mark {
|
||||
background-color: #38a65d;
|
||||
}
|
||||
.willSee {
|
||||
background-color: #38a65d;
|
||||
}
|
||||
.delete {
|
||||
background-color: #e94049;
|
||||
}
|
||||
.icon {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
}
|
||||
hr {
|
||||
height: 2px !important;
|
||||
}
|
||||
.description {
|
||||
color: #8f9398;
|
||||
}
|
||||
.editIcon {
|
||||
height: 2.5vh;
|
||||
}
|
||||
.posterChoiceToTaste {
|
||||
width: 290px;
|
||||
height: 437px;
|
||||
}
|
||||
.posterFilmPage{
|
||||
width: 290px;
|
||||
height: 437px;
|
||||
}
|
||||
a {
|
||||
text-decoration: none;
|
||||
}
|
||||
a:hover {
|
||||
color: white;
|
||||
}
|
||||
|
||||
.current a {
|
||||
color: white;
|
||||
}
|
||||
|
||||
/* for film-page */
|
||||
.table {
|
||||
color: #8f9398;
|
||||
}
|
||||
/* main */
|
||||
@media screen and (max-width: 290px) {
|
||||
.posterItem {
|
||||
display: none !important;
|
||||
}
|
||||
.fs-1 {
|
||||
margin-left: 1em !important;
|
||||
}
|
||||
}
|
||||
|
||||
body {
|
||||
background: #2b2d33;
|
||||
}
|
||||
|
||||
.content {
|
||||
min-height: calc(100vh - 25.1vh);
|
||||
background: #40444d;
|
||||
}
|
||||
|
||||
.content_header {
|
||||
margin: -1.5em -1.5em 0em -1.5em;
|
||||
background-color: #8f9297;
|
||||
}
|
||||
|
||||
.posterItem {
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
margin-top: -10px;
|
||||
}
|
||||
|
||||
form input {
|
||||
max-width: 300px;
|
||||
}
|
||||
|
||||
table tbody tr td {
|
||||
border: 0px !important;
|
||||
}
|
||||
|
||||
footer {
|
||||
flex: 0 0 auto !important;
|
||||
background: #1a1c20;
|
||||
color: #c2c2c2;
|
||||
}
|
||||
|
||||
footer nav {
|
||||
color: #c2c2c2;
|
||||
}
|
||||
|
||||
header {
|
||||
background: #1a1c20;
|
||||
}
|
||||
|
||||
header a {
|
||||
color: #c2c2c2;
|
||||
}
|
||||
|
||||
header a:hover {
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.mainInput {
|
||||
max-width: 200px;
|
||||
}
|
4
src/main/resources/public/favicon.svg
Normal file
4
src/main/resources/public/favicon.svg
Normal file
@ -0,0 +1,4 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 448 512"><!--! Font Awesome Pro 6.1.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2022 Fonticons, Inc. -->
|
||||
<path d="M448 48V384c-63.09 22.54-82.34 32-119.5 32c-62.82 0-86.6-32-149.3-32C158.6 384 142.6 387.6 128 392.2v-64C142.6 323.6 158.6 320 179.2 320c62.73 0 86.51 32 149.3 32C348.9 352 364.1 349 384 342.7v-208C364.1 141 348.9 144 328.5 144c-62.82 0-86.6-32-149.3-32C128.4 112 104.3 132.6 64 140.7v307.3C64 465.7 49.67 480 32 480S0 465.7 0 448V63.1C0 46.33 14.33 32 31.1 32S64 46.33 64 63.1V76.66C104.3 68.63 128.4 48 179.2 48c62.73 0 86.51 32 149.3 32C365.7 80 384.9 70.54 448 48z"/>
|
||||
</svg>
|
After Width: | Height: | Size: 727 B |
BIN
src/main/resources/public/search.jpg
Normal file
BIN
src/main/resources/public/search.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.6 KiB |
BIN
src/main/resources/public/vk.jpg
Normal file
BIN
src/main/resources/public/vk.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.2 KiB |
32
src/main/resources/templates/cinema-edit.html
Normal file
32
src/main/resources/templates/cinema-edit.html
Normal file
@ -0,0 +1,32 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en"
|
||||
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
||||
layout:decorate="~{default}">
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
<div layout:fragment="content">
|
||||
<h1>Фильм</h1>
|
||||
<div th:text="${errors}" class="margin-bottom alert-danger"></div>
|
||||
<form action="#" th:action="@{/cinema/{id}(id=${id})}" th:object="${cinemaDto}" enctype="multipart/form-data" method="post">
|
||||
<div class="mb-3">
|
||||
<label for="name" class="form-label">Название</label>
|
||||
<input type="text" class="form-control" id="name" th:field="${cinemaDto.name}" required="true">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="multipartFile" class="form-label">Изображение</label>
|
||||
<input type="file" class="form-control" id="multipartFile" th:name="multipartFile" required="true">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<button type="submit" class="btn btn-primary button-fixed">
|
||||
<span th:if="${id == null}">Добавить</span>
|
||||
<span th:if="${id != null}">Обновить</span>
|
||||
</button>
|
||||
<a class="btn btn-secondary button-fixed" th:href="@{/cinema}">
|
||||
Назад
|
||||
</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
57
src/main/resources/templates/cinema.html
Normal file
57
src/main/resources/templates/cinema.html
Normal file
@ -0,0 +1,57 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en"
|
||||
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
||||
layout:decorate="~{default}">
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
<div layout:fragment="content">
|
||||
<h1>Фильмы</h1>
|
||||
<div class="d-flex justify-content-end">
|
||||
<a class="btn btn-success button-fixed"
|
||||
th:href="@{/cinema/edit}">
|
||||
<i class="fa-solid fa-plus"></i>
|
||||
</a>
|
||||
</div>
|
||||
<form action="#" th:action="@{/cinema/search/}">
|
||||
<input class="form-control mainInput" type="text" name="request" search="true" rounded="true" required="true" />
|
||||
<button class="border border-0 p-0 ms-2" type="submit"><img class="icon" src="/search.jpg" alt="Поиск" /></button>
|
||||
</form>
|
||||
<hr class="border border-0 bg-black" />
|
||||
<table class="table" id="tbl-items">
|
||||
<tbody>
|
||||
<tr th:each="cinema, iterator: ${cinemas}">
|
||||
<td>
|
||||
<img class="posterItem me-3" th:src="${cinema.image}" alt="${cinema.name}" align="left"/>
|
||||
<div class="d-flex flex-row flex-wrap flex-grow-1 align-items-center">
|
||||
<div class="pt-3 description d-flex flex-column justify-content-start align-items-center mb-3 fs-6 fw-bold">
|
||||
<p class="text-start description">
|
||||
<a class="text-white fs-5 fw-bold pt-3" th:text="${cinema.name}"></a>
|
||||
</p>
|
||||
</div>
|
||||
<div id="rightPanel" class="d-flex flex-wrap justify-content-end text-white fw-bold fs-4 flex-grow-1">
|
||||
<div class="rounded p-1 mx-2 green-mark">9.2</div>
|
||||
<div>
|
||||
<a type="button" class="m-1 btn btn-primary" th:href="@{/cinema/edit/{id}(id=${cinema.id})}">
|
||||
<i class="fa fa-pencil"></i>
|
||||
</a>
|
||||
<a type="button" class="m-1 btn btn-danger"
|
||||
th:attr="onclick=|confirm('Удалить запись?') && document.getElementById('remove-${cinema.id}').click()|">
|
||||
<i class="fa fa-trash"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<form th:action="@{/cinema/delete/{id}(id=${cinema.id})}" method="post">
|
||||
<button th:id="'remove-' + ${cinema.id}" type="submit" style="display: none">
|
||||
Удалить
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
<hr class="border border-0 bg-black" />
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
32
src/main/resources/templates/customer-edit.html
Normal file
32
src/main/resources/templates/customer-edit.html
Normal file
@ -0,0 +1,32 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en"
|
||||
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
||||
layout:decorate="~{default}">
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
<div layout:fragment="content">
|
||||
<h1>Пользователь</h1>
|
||||
<div th:text="${errors}" class="margin-bottom alert-danger"></div>
|
||||
<form action="#" th:action="@{/customer/{id}(id=${id})}" th:object="${customerDto}" method="post">
|
||||
<div class="mb-3">
|
||||
<label for="login" class="form-label">Логин</label>
|
||||
<input type="text" class="form-control" id="login" th:field="${customerDto.login}" required="true">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="password" class="form-label">Пароль</label>
|
||||
<input type="text" class="form-control" id="password" th:field="${customerDto.password}" required="true">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<button type="submit" class="btn btn-primary button-fixed">
|
||||
<span th:if="${id == null}">Добавить</span>
|
||||
<span th:if="${id != null}">Обновить</span>
|
||||
</button>
|
||||
<a class="btn btn-secondary button-fixed" th:href="@{/customer}">
|
||||
Назад
|
||||
</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
51
src/main/resources/templates/customer.html
Normal file
51
src/main/resources/templates/customer.html
Normal file
@ -0,0 +1,51 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en"
|
||||
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
||||
layout:decorate="~{default}">
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
<div layout:fragment="content">
|
||||
<h1>Пользователи</h1>
|
||||
<div class="d-flex justify-content-end">
|
||||
<a class="btn btn-success button-fixed"
|
||||
th:href="@{/customer/edit}">
|
||||
<i class="fa-solid fa-plus"></i>
|
||||
</a>
|
||||
</div>
|
||||
<table class="table text-white" id="tbl-items">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">ID</th>
|
||||
<th scope="col">Логин</th>
|
||||
<th scope="col">Пароль</th>
|
||||
<th scope="col"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr th:each="customer, iterator: ${customers}">
|
||||
<td th:text="${customer.id}"/>
|
||||
<td th:text="${customer.login}"/>
|
||||
<td th:text="${customer.password}"/>
|
||||
<td>
|
||||
<div>
|
||||
<a type="button" class="m-1 btn btn-primary" th:href="@{/customer/edit/{id}(id=${customer.id})}">
|
||||
<i class="fa fa-pencil"></i>
|
||||
</a>
|
||||
<a type="button" class="m-1 btn btn-danger"
|
||||
th:attr="onclick=|confirm('Удалить запись?') && document.getElementById('remove-${customer.id}').click()|">
|
||||
<i class="fa fa-trash"></i>
|
||||
</a>
|
||||
</div>
|
||||
<form th:action="@{/customer/delete/{id}(id=${customer.id})}" method="post">
|
||||
<button th:id="'remove-' + ${customer.id}" type="submit" style="display: none">
|
||||
Удалить
|
||||
</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
68
src/main/resources/templates/default.html
Normal file
68
src/main/resources/templates/default.html
Normal file
@ -0,0 +1,68 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ru"
|
||||
xmlns:th="http://www.thymeleaf.org"
|
||||
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
|
||||
<head>
|
||||
<meta charset="UTF-8"/>
|
||||
<title>Киносайт</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
||||
<link rel="icon" href="/favicon.svg">
|
||||
<script type="text/javascript" src="/webjars/bootstrap/5.1.3/js/bootstrap.bundle.min.js"></script>
|
||||
<script type="text/javascript" src="/webjars/jquery/3.6.0/jquery.min.js"></script>
|
||||
<link rel="stylesheet" href="/webjars/bootstrap/5.1.3/css/bootstrap.min.css"/>
|
||||
<link rel="stylesheet" href="/webjars/font-awesome/6.1.0/css/all.min.css"/>
|
||||
<link rel="stylesheet" href="/css/style.css"/>
|
||||
</head>
|
||||
<body class="d-flex flex-column h-100 text-white">
|
||||
<header class="fs-4 fw-bold p-1">
|
||||
<nav class="navbar navbar-expand-lg navbar-dark text-white">
|
||||
<div class="container-fluid">
|
||||
<a class="navbar-brand" href="/">
|
||||
<i class="fa-solid fa-font-awesome"></i>
|
||||
</a>
|
||||
<button class="navbar-toggler" type="button"
|
||||
data-bs-toggle="collapse" data-bs-target="#navbarNav"
|
||||
aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<div class="collapse navbar-collapse menu" id="navbarNav">
|
||||
<ul class="navbar-nav">
|
||||
<a class="nav-link" href="/">Главная</a>
|
||||
<a class="nav-link" href="/cinema">Фильмы</a>
|
||||
<a class="nav-link" href="/customer">Регистрация</a>
|
||||
<a class="nav-link" href="/order">Заказы</a>
|
||||
<a class="nav-link" href="/session">Сеансы</a>
|
||||
<a class="nav-link" href="/h2-console/" target="_blank">Консоль H2</a>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
</header>
|
||||
<div class="container rounded my-5 p-4 content">
|
||||
<div class="content_header rounded-top p-2 mb-2">
|
||||
<h1 class="fs-1 fw-bold text-white ms-5">Киносайт</h1>
|
||||
</div>
|
||||
<div layout:fragment="content">
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
<th:block layout:fragment="scripts">
|
||||
<script>
|
||||
$(function () {
|
||||
var location = window.location.href;
|
||||
var cur_url = '/' + location.split('/').pop();
|
||||
|
||||
$('.menu li').each(function () {
|
||||
var link = $(this).find('a').attr('href');
|
||||
|
||||
if (cur_url == link) {
|
||||
$(this).addClass('current');
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</th:block>
|
||||
<footer class="d-flex align-items-center fw-bold fs-4 p-2 ps-5">2022 г.
|
||||
<nav class="d-flex justify-content-center flex-grow-1"><a href="https://vk.com/id0" target="_blank"><img class="icon" src="/vk.jpg" alt="VK" /></a></nav>
|
||||
</footer>
|
||||
</html>
|
13
src/main/resources/templates/error.html
Normal file
13
src/main/resources/templates/error.html
Normal file
@ -0,0 +1,13 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en"
|
||||
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
||||
layout:decorate="~{default}">
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
<div layout:fragment="content">
|
||||
<div><span th:text="${error}"></span></div>
|
||||
<a href="/">На главную</a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
13
src/main/resources/templates/index.html
Normal file
13
src/main/resources/templates/index.html
Normal file
@ -0,0 +1,13 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en"
|
||||
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
||||
layout:decorate="~{default}">
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
<div layout:fragment="content">
|
||||
<div>It's works!</div>
|
||||
<a href="123">ERROR</a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
57
src/main/resources/templates/order-edit.html
Normal file
57
src/main/resources/templates/order-edit.html
Normal file
@ -0,0 +1,57 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en"
|
||||
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
||||
layout:decorate="~{default}">
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
<div layout:fragment="content">
|
||||
<h1 th:if="${id == null}">Создание заказа</h1>
|
||||
<h1 th:if="${id != null}">Добавление сеансов в заказ</h1>
|
||||
<div th:text="${errors}" class="margin-bottom alert-danger"></div>
|
||||
<form action="#" th:action="@{/order/{id}(id=${id})}" th:object="${orderDto}" method="post" th:if="${id == null}">
|
||||
<div class="mb-3" >
|
||||
<label for="customer" class="form-label">Пользователь</label>
|
||||
<select id="customer" class="form-select" th:field="${orderDto.customerId}" required="true">
|
||||
<option th:each="value: ${customers}"
|
||||
th:value="${value.id}"
|
||||
th:text="${value.login}">
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<button type="submit" class="btn btn-primary button-fixed">
|
||||
<span th:if="${id == null}">Добавить</span>
|
||||
<span th:if="${id != null}">Обновить</span>
|
||||
</button>
|
||||
<a class="btn btn-secondary button-fixed" th:href="@{/order}">
|
||||
Назад
|
||||
</a>
|
||||
</div>
|
||||
</form>
|
||||
<form action="#" th:action="@{/order/{id}(id=${id})}" th:object="${orderSessionDto}" method="post" th:if="${id != null}">
|
||||
<div class="mb-3">
|
||||
<label for="session" class="form-label">Сеанс</label>
|
||||
<select id="session" class="form-select" required="true" th:name="session">
|
||||
<option th:each="value: ${sessions}"
|
||||
th:value="${value.id}"
|
||||
th:text="${value.cinema.name} + ' ' + ${value.timestamp}">
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="mb-3" >
|
||||
<label for="count" class="form-label">Количество</label>
|
||||
<input type="number" class="form-control" min="1" id="count" th:name="count" th:field="${orderSessionDto.count}" required="true">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<button type="submit" class="btn btn-primary button-fixed">
|
||||
<span>Добавить</span>
|
||||
</button>
|
||||
<a class="btn btn-secondary button-fixed" th:href="@{/order}">
|
||||
Назад
|
||||
</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
51
src/main/resources/templates/order.html
Normal file
51
src/main/resources/templates/order.html
Normal file
@ -0,0 +1,51 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en"
|
||||
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
||||
layout:decorate="~{default}">
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
<div layout:fragment="content">
|
||||
<h1>Заказы</h1>
|
||||
<div class="d-flex justify-content-end">
|
||||
<a class="btn btn-success button-fixed"
|
||||
th:href="@{/order/edit}">
|
||||
<i class="fa-solid fa-plus"></i>
|
||||
</a>
|
||||
</div>
|
||||
<table class="table text-white" id="tbl-items">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">ID</th>
|
||||
<th scope="col">Customer</th>
|
||||
<th scope="col">DateOfPurchase</th>
|
||||
<th scope="col"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr th:each="item, iterator: ${orders}">
|
||||
<td th:text="${item.id}"/>
|
||||
<td th:text="${item.customer}"/>
|
||||
<td th:text="${item.dateOfPurchase}"/>
|
||||
<td>
|
||||
<div>
|
||||
<a type="button" class="m-1 btn btn-primary" th:href="@{/order/edit/{id}(id=${item.id})}">
|
||||
<i class="fa fa-pencil"></i>
|
||||
</a>
|
||||
<a type="button" class="m-1 btn btn-danger"
|
||||
th:attr="onclick=|confirm('Удалить запись?') && document.getElementById('remove-${item.id}').click()|">
|
||||
<i class="fa fa-trash"></i>
|
||||
</a>
|
||||
</div>
|
||||
<form th:action="@{/order/delete/{id}(id=${item.id})}" method="post">
|
||||
<button th:id="'remove-' + ${item.id}" type="submit" style="display: none">
|
||||
Удалить
|
||||
</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
69
src/main/resources/templates/ordersession.html
Normal file
69
src/main/resources/templates/ordersession.html
Normal file
@ -0,0 +1,69 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en"
|
||||
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
||||
layout:decorate="~{default}">
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
<div layout:fragment="content">
|
||||
<h1 th:text="'Сеансы заказа ' + ${id}"></h1>
|
||||
<form action="#" th:action="@{/order/{id}(id=${id})}" method="post">
|
||||
<div class="mb-3">
|
||||
<label for="session" class="form-label">Сеанс</label>
|
||||
<select id="session" class="form-select" th:name="session" required="true">
|
||||
<option th:each="value: ${sessions}"
|
||||
th:value="${value.id}"
|
||||
th:text="${value.cinema.name} + ' ' + ${value.timestamp}">
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="count" class="form-label">Количество</label>
|
||||
<input type="number" class="form-control" min="1" id="count" th:name="count" th:field="${orderSessionDto.count}" required="true">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<button type="submit" class="btn btn-primary button-fixed">
|
||||
<span>Добавить</span>
|
||||
</button>
|
||||
<a class="btn btn-secondary button-fixed" th:href="@{/order}">
|
||||
Назад
|
||||
</a>
|
||||
</div>
|
||||
</form>
|
||||
<table class="table text-white" id="tbl-items">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">ID</th>
|
||||
<th scope="col">Price</th>
|
||||
<th scope="col">Cinema</th>
|
||||
<th scope="col">Timestamp</th>
|
||||
<th scope="col">Count</th>
|
||||
<th scope="col"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr th:each="item, iterator: ${orderSessions}">
|
||||
<td th:text="${item.key.id}"/>
|
||||
<td th:text="${item.key.price}"/>
|
||||
<td th:text="${item.key.cinema.name}"/>
|
||||
<td th:text="${item.key.timestamp}"/>
|
||||
<td th:text="${item.value}"/>
|
||||
<td>
|
||||
<div>
|
||||
<a type="button" class="m-1 btn btn-danger"
|
||||
th:attr="onclick=|confirm('Удалить запись?') && document.getElementById('remove-${item.key.id}').click()|">
|
||||
<i class="fa fa-trash"></i>
|
||||
</a>
|
||||
</div>
|
||||
<form th:action="@{'/order/' + ${id} + '?session=' + ${item.key.id}}" method="post">
|
||||
<button th:id="'remove-' + ${item.key.id}" type="submit" style="display: none">
|
||||
Удалить
|
||||
</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
45
src/main/resources/templates/session-edit.html
Normal file
45
src/main/resources/templates/session-edit.html
Normal file
@ -0,0 +1,45 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en"
|
||||
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
||||
layout:decorate="~{default}">
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
<div layout:fragment="content">
|
||||
<h1>Сеанс</h1>
|
||||
<div th:text="${errors}" class="margin-bottom alert-danger"></div>
|
||||
<form action="#" th:action="@{/session/{id}(id=${id})}" th:object="${sessionDto}" method="post">
|
||||
<div class="mb-3">
|
||||
<label for="price" class="form-label">Цена</label>
|
||||
<input type="number" class="form-control" min="1" step="0.01" id="price" th:field="${sessionDto.price}" required="true">
|
||||
</div>
|
||||
<div class="mb-3" th:if="${id == null}">
|
||||
<label for="cinemaid" class="form-label">Фильм</label>
|
||||
<select id="cinemaid" class="form-select" th:name="cinemaid" required="true">
|
||||
<option th:each="value: ${cinemas}"
|
||||
th:value="${value.id}"
|
||||
th:text="${value.name}">
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="mb-3" th:if="${id == null}">
|
||||
<label for="count" class="form-label">Кол-во сеансов</label>
|
||||
<input type="number" class="form-control" min="1" id="count" th:field="${sessionDto.maxCount}" required="true">
|
||||
</div>
|
||||
<div class="mb-3" th:if="${id == null}">
|
||||
<label for="date" class="form-label">Дата</label>
|
||||
<input type="datetime-local" class="form-control" id="date" th:field="${sessionDto.timestamp}" required="true">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<button type="submit" class="btn btn-primary button-fixed">
|
||||
<span th:if="${id == null}">Добавить</span>
|
||||
<span th:if="${id != null}">Обновить</span>
|
||||
</button>
|
||||
<a class="btn btn-secondary button-fixed" th:href="@{/session}">
|
||||
Назад
|
||||
</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
57
src/main/resources/templates/session.html
Normal file
57
src/main/resources/templates/session.html
Normal file
@ -0,0 +1,57 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en"
|
||||
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
||||
layout:decorate="~{default}">
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
<div layout:fragment="content">
|
||||
<h1>Сеансы</h1>
|
||||
<div class="d-flex justify-content-end">
|
||||
<a class="btn btn-success button-fixed"
|
||||
th:href="@{/session/edit}">
|
||||
<i class="fa-solid fa-plus"></i>
|
||||
</a>
|
||||
</div>
|
||||
<table class="table text-white" id="tbl-items">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">ID</th>
|
||||
<th scope="col">Price</th>
|
||||
<th scope="col">Cinema</th>
|
||||
<th scope="col">Timestamp</th>
|
||||
<th scope="col">Capacity</th>
|
||||
<th scope="col">MaxCount</th>
|
||||
<th scope="col"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr th:each="item, iterator: ${sessions}">
|
||||
<td th:text="${item.id}"/>
|
||||
<td th:text="${item.price}"/>
|
||||
<td th:text="${item.cinema.name}"/>
|
||||
<td th:text="${item.timestamp}"/>
|
||||
<td th:text="${item.capacity} == null ? ${item.maxCount} : ${item.maxCount}-${item.capacity}"/>
|
||||
<td th:text="${item.maxCount}"/>
|
||||
<td>
|
||||
<div>
|
||||
<a type="button" class="m-1 btn btn-primary" th:href="@{/session/edit/{id}(id=${item.id})}">
|
||||
<i class="fa fa-pencil"></i>
|
||||
</a>
|
||||
<a type="button" class="m-1 btn btn-danger"
|
||||
th:attr="onclick=|confirm('Удалить запись?') && document.getElementById('remove-${item.id}').click()|">
|
||||
<i class="fa fa-trash"></i>
|
||||
</a>
|
||||
</div>
|
||||
<form th:action="@{/session/delete/{id}(id=${item.id})}" method="post">
|
||||
<button th:id="'remove-' + ${item.id}" type="submit" style="display: none">
|
||||
Удалить
|
||||
</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in New Issue
Block a user