This commit is contained in:
shadowik 2023-05-01 03:54:58 +04:00
parent 32895a211f
commit 6636d6ed4e
19 changed files with 602 additions and 38 deletions

View File

@ -18,6 +18,13 @@ jar {
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
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.npm:bootstrap:5.3.0-alpha2'
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'
@ -25,9 +32,7 @@ dependencies {
implementation 'org.hibernate.validator:hibernate-validator'
implementation 'org.springdoc:springdoc-openapi-ui:1.6.5'
implementation 'org.projectlombok:lombok:1.18.22'
testImplementation 'org.springframework.boot:spring-boot-starter-test'

View File

@ -12,6 +12,7 @@ import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebConfiguration implements WebMvcConfigurer {
public static final String REST_API = "/api";
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**").allowedMethods("*");
@ -22,9 +23,6 @@ public class WebConfiguration implements WebMvcConfigurer {
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

View File

@ -1,5 +1,6 @@
package com.example.demo.master;
import com.example.demo.WebConfiguration;
import com.example.demo.order.OrderService;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
@ -13,11 +14,11 @@ import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
@RequestMapping("/master")
@RequestMapping(WebConfiguration.REST_API + "/master")
public class MasterController {
private final MasterService masterService;
private final OrderService orderService;
private Long currentMasterId = 0L;
public MasterController(MasterService masterService, OrderService orderService) {
this.masterService = masterService;
@ -26,14 +27,14 @@ public class MasterController {
@GetMapping("/")
public MasterDto getCurrentMaster() {
return new MasterDto(masterService.findMaster(currentMasterId));
return new MasterDto(masterService.findMaster(masterService.getCurrentMasterId()));
}
@GetMapping("/{email}/{password}")
public MasterDto getCurrentMaster(@PathVariable("email") String email,
@PathVariable("password") String password) {
var master = new MasterDto(masterService.findMaster(email, password));
currentMasterId = master.getId();
masterService.setCurrentMasterId(master.getId());
return master;
}
@PostMapping("/")
@ -42,29 +43,29 @@ public class MasterController {
@RequestParam("email") String email,
@RequestParam("password") String password) {
MasterDto master = new MasterDto(masterService.addMaster(firstName, lastName, email, password));
currentMasterId = master.getId();
orderService.addOrder(currentMasterId);
masterService.setCurrentMasterId(master.getId());
orderService.addOrder(master.getId());
return master;
}
@PatchMapping("/{id}")
public MasterDto updateMaster(@PathVariable Long id,
@RequestParam("firstName") String firstName,
@PatchMapping("/")
public MasterDto updateMaster(@RequestParam("firstName") String firstName,
@RequestParam("lastName") String lastName,
@RequestParam("email") String email,
@RequestParam("password") String password) {
return new MasterDto(masterService.updateMaster(id, firstName, lastName, email, password));
return new MasterDto(masterService.updateMaster(masterService.getCurrentMasterId(),
firstName, lastName, email, password));
}
@DeleteMapping("/{id}")
@DeleteMapping("/")
public MasterDto deleteMaster(@PathVariable Long id) {
return new MasterDto(masterService.deleteMaster(id));
return new MasterDto(masterService.deleteMaster(masterService.getCurrentMasterId()));
}
@PostMapping("/log_out")
public void logOut() {
currentMasterId = 0L;
masterService.setCurrentMasterId(0L);
}
}

View File

@ -0,0 +1,84 @@
package com.example.demo.master;
import com.example.demo.order.OrderService;
import com.example.demo.product.ProductDto;
import com.example.demo.product.ProductService;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
@Controller
@RequestMapping("/master")
public class MasterMvcController {
private final MasterService masterService;
private final OrderService orderService;
public MasterMvcController(MasterService masterService, OrderService orderService) {
this.masterService = masterService;
this.orderService = orderService;
}
@GetMapping("/login")
public String loginPage(Model model) {
if (masterService.getCurrentMasterId() != 0) {
return "redirect:/product";
}
model.addAttribute("user", new Master());
return "Login";
}
@PostMapping("/login")
public String login(@ModelAttribute Master user) {
var master = new MasterDto(masterService.findMaster(user.getEmail(), user.getPassword()));
masterService.setCurrentMasterId(master.getId());
return "redirect:/product/my_products";
}
@GetMapping("")
public String getUserPage(Model model) {
if (masterService.getCurrentMasterId() != 0) {
model.addAttribute("user", masterService.findMaster(masterService.getCurrentMasterId()));
} else {
return "redirect:/master/register";
}
return "UserPage";
}
@PostMapping(value = "", params = "action=update")
public String updateUserPage(@ModelAttribute Master user) {
if (masterService.getCurrentMasterId() == 0) {
return "redirect:/master";
}
masterService.updateMaster(
masterService.getCurrentMasterId(),
user.getFirstName(),
user.getLastName(),
user.getEmail(),
user.getPassword());
return "redirect:/product";
}
@PostMapping(value = "", params = "action=log_out")
public String logOut() {
masterService.setCurrentMasterId(0L);
return "redirect:/product";
}
@GetMapping("/register")
public String registerPage(Model model) {
model.addAttribute("user", new Master());
return "UserPage";
}
@PostMapping(value = "/register", params = "action=register")
public String register(@ModelAttribute Master user) {
MasterDto master = new MasterDto(masterService.addMaster(
user.getFirstName(),
user.getLastName(),
user.getEmail(),
user.getPassword()));
masterService.setCurrentMasterId(master.getId());
orderService.addOrder(master.getId());
return "redirect:/product/my_products";
}
}

View File

@ -1,5 +1,6 @@
package com.example.demo.master;
import com.example.demo.order.Order;
import com.example.demo.order.OrderController;
import com.example.demo.order.OrderService;
import com.example.demo.util.validation.ValidatorUtil;
@ -16,6 +17,8 @@ public class MasterService {
private final ValidatorUtil validatorUtil;
private Long currentMasterId = 0L;
public MasterService(MasterRepository masterRepository, ValidatorUtil validatorUtil) {
this.masterRepository = masterRepository;
this.validatorUtil = validatorUtil;
@ -34,6 +37,7 @@ public class MasterService {
return mater.orElseThrow(() -> new MasterNotFoundException(id));
}
@Transactional(readOnly = true)
public Master findMaster(String email, String password) {
final Optional<Master> master = masterRepository.findByEmail(email);
@ -72,6 +76,14 @@ public class MasterService {
masterRepository.deleteAll();
}
@Transactional
public Long getCurrentMasterId (){
return currentMasterId;
}
@Transactional
public void setCurrentMasterId(Long masterId) {
currentMasterId = masterId;
}
}

View File

@ -1,5 +1,7 @@
package com.example.demo.order;
import com.example.demo.WebConfiguration;
import com.example.demo.master.MasterService;
import com.example.demo.product.Product;
import com.example.demo.product.ProductDto;
import com.example.demo.product.ProductService;
@ -10,12 +12,14 @@ import java.util.ArrayList;
import java.util.List;
@RestController
@RequestMapping("/order")
@RequestMapping(WebConfiguration.REST_API + "/order")
public class OrderController {
private final OrderService orderService;
private final MasterService masterService;
public OrderController(OrderService orderService) {
public OrderController(OrderService orderService, MasterService masterService) {
this.orderService = orderService;
this.masterService = masterService;
}
@GetMapping("/{id}")
@ -23,9 +27,9 @@ public class OrderController {
return new OrderDto(orderService.findOrder(id));
}
@DeleteMapping("/{id}")
public void buyProducts(@PathVariable Long id) {
orderService.buyProducts(id);
@DeleteMapping("/")
public void buyProducts() {
orderService.buyProducts(masterService.getCurrentMasterId());
}
@GetMapping("/")
@ -38,16 +42,14 @@ public class OrderController {
return new OrderDto(orderService.addOrder(masterId));
}
@PostMapping("{id}/{product}")
public void addProduct(@PathVariable("id") Long id,
@PathVariable("product") Long productId) {
orderService.addProduct(id, productId);
@PostMapping("/{product}")
public void addProduct(@PathVariable("product") Long productId) {
orderService.addProduct(masterService.getCurrentMasterId(), productId);
}
@DeleteMapping("{id}/{product}")
public void deleteProduct(@PathVariable("id") Long id,
@PathVariable("product") Long productId) {
orderService.deleteProduct(id, productId);
@DeleteMapping("{product}")
public void deleteProduct(@PathVariable("product") Long productId) {
orderService.deleteProduct(masterService.getCurrentMasterId(), productId);
}
@DeleteMapping("/")
public void deleteOrders() {

View File

@ -0,0 +1,49 @@
package com.example.demo.order;
import com.example.demo.master.MasterService;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.concurrent.atomic.AtomicInteger;
@Controller
@RequestMapping("/order")
public class OrderMvcController {
private final MasterService masterService;
private final OrderService orderService;
public OrderMvcController(MasterService masterService, OrderService orderService) {
this.masterService = masterService;
this.orderService = orderService;
}
@GetMapping("")
public String getOrder(Model model) {
if (masterService.getCurrentMasterId() == 0) {
return "redirect:/master/login";
}
model.addAttribute("user", masterService.findMaster(masterService.getCurrentMasterId()));
model.addAttribute("order", orderService.findOrder(masterService.getCurrentMasterId()));
AtomicInteger fullCost = new AtomicInteger();
orderService.findOrder(masterService.getCurrentMasterId()).getProducts().forEach(
item -> fullCost.addAndGet(item.getCost()));
model.addAttribute("fullCost", fullCost);
return "OrderPage";
}
@PostMapping(value = "", params = "action=delete")
public String deleteProduct(@RequestParam(value = "id", required = true) Long id) {
orderService.deleteProduct(masterService.getCurrentMasterId(), id);
return "redirect:/order";
}
@PostMapping(value = "", params = "action=buy")
public String buyProducts() {
orderService.buyProducts(masterService.getCurrentMasterId());
return "redirect:/product";
}
}

View File

@ -42,7 +42,8 @@ public class OrderService {
@Transactional
public void addProduct(Long masterId, Long productId) {
final Order order = orderRepository.findByMaster(masterRepository.findById(masterId).orElseThrow(() -> new MasterNotFoundException(masterId))).orElseThrow(() -> new OrderNotFoundException(masterId));
final Order order = orderRepository.findByMaster(masterRepository.findById(masterId).orElseThrow(
() -> new MasterNotFoundException(masterId))).orElseThrow(() -> new OrderNotFoundException(masterId));
final Product product = productRepository.findById(productId).orElseThrow(() ->
new ProductNotFoundException(productId));
order.addProduct(product);
@ -54,7 +55,8 @@ public class OrderService {
@Transactional
public void buyProducts(Long masterId) {
final Order order = orderRepository.findByMaster(masterRepository.findById(masterId).orElseThrow(() -> new MasterNotFoundException(masterId))).orElseThrow(() -> new OrderNotFoundException(masterId));
final Order order = orderRepository.findByMaster(masterRepository.findById(masterId).orElseThrow(
() -> new MasterNotFoundException(masterId))).orElseThrow(() -> new OrderNotFoundException(masterId));
var products = new ArrayList<Product>(order.getProducts());
for (var item: products) {
item.setAvailable(Status.Bought);
@ -66,7 +68,8 @@ public class OrderService {
@Transactional
public void deleteProduct(Long masterId, Long productId) {
final Order order = orderRepository.findByMaster(masterRepository.findById(masterId).orElseThrow(() -> new MasterNotFoundException(masterId))).orElseThrow(() -> new OrderNotFoundException(masterId));
final Order order = orderRepository.findByMaster(masterRepository.findById(masterId).orElseThrow(
() -> new MasterNotFoundException(masterId))).orElseThrow(() -> new OrderNotFoundException(masterId));
final Product product = productRepository.findById(productId).orElseThrow(() ->
new ProductNotFoundException(productId));
order.removeProduct(product);
@ -78,7 +81,9 @@ public class OrderService {
@Transactional()
public Order findOrder(Long masterId) {
final Order order = orderRepository.findByMaster(masterRepository.findById(masterId).orElseThrow(() -> new MasterNotFoundException(masterId))).orElseThrow(() -> new OrderNotFoundException(masterId));
final Order order = orderRepository.findByMaster(masterRepository.findById(masterId).
orElseThrow(() -> new MasterNotFoundException(masterId))).orElseThrow(
() -> new OrderNotFoundException(masterId));
return order;
}

View File

@ -73,7 +73,7 @@ public class Product {
public String toString() {
return "Product {" +
"id=" + id +
", firstName='" + name + '\'' +
", name='" + name + '\'' +
", cost='" + cost.toString() + '\'' +
", master='" + master.toString() + '\'' +
'}';

View File

@ -1,5 +1,6 @@
package com.example.demo.product;
import com.example.demo.WebConfiguration;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
@ -12,7 +13,7 @@ import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
@RequestMapping("/product")
@RequestMapping(WebConfiguration.REST_API + "/product")
public class ProductController {
private final ProductService productService;

View File

@ -0,0 +1,102 @@
package com.example.demo.product;
import com.example.demo.master.Master;
import com.example.demo.master.MasterService;
import com.example.demo.order.OrderService;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
@Controller
@RequestMapping("/product")
public class ProductMvcController {
private final ProductService productService;
private final MasterService masterService;
private final OrderService orderService;
public ProductMvcController(MasterService masterService,
ProductService productService,
OrderService orderService) {
this.masterService = masterService;
this.productService = productService;
this.orderService = orderService;
}
@GetMapping("")
public String getProducts(Model model) {
if (masterService.getCurrentMasterId() != 0) {
Master user = masterService.findMaster(masterService.getCurrentMasterId());
model.addAttribute("user", user);
}
else {
model.addAttribute("user", new Master());
}
model.addAttribute("products", productService.findAllProducts()
.stream().map(ProductDto::new).toList());
return "Products";
}
@PostMapping("")
public String addProductToOrder(@RequestParam(value = "id", required = true) Long id) {
if (masterService.getCurrentMasterId() == 0) {
return "redirect:/master/login";
}
orderService.addProduct(masterService.getCurrentMasterId(), id);
return "redirect:/product";
}
@GetMapping("/my_products")
public String getMasterProduct(Model model) {
if (masterService.getCurrentMasterId() == 0) {
return "redirect:/product";
}
model.addAttribute("user",
masterService.findMaster(masterService.getCurrentMasterId()));
model.addAttribute("products",
productService.findProducts(masterService.getCurrentMasterId()).stream().map(ProductDto::new).toList());
return "UserProducts";
}
@GetMapping("/create_product")
public String createProductPage(Model model) {
if (masterService.getCurrentMasterId() == 0) {
return "redirect:/product";
}
model.addAttribute("user", masterService.findMaster(masterService.getCurrentMasterId()));
model.addAttribute("product", new Product());
model.addAttribute("buttonText", "Create");
return "ProductCreate";
}
@PostMapping("/create_product")
public String createProduct(@ModelAttribute Product product) {
productService.addProduct(
product.getName(),
product.getCost(),
masterService.getCurrentMasterId()
);
return "redirect:/product/my_products";
}
@GetMapping("/update_product/{id}")
public String updateProductPage(Model model, @PathVariable("id") Long id) {
if (masterService.getCurrentMasterId() == 0) {
return "redirect:/product";
}
model.addAttribute("user", masterService.findMaster(masterService.getCurrentMasterId()));
model.addAttribute("product", productService.findProduct(id));
model.addAttribute("buttonText", "Update");
return "ProductCreate";
}
@PostMapping("/update_product/{id}")
public String createProduct(@ModelAttribute Product product, @PathVariable("id") Long id) {
productService.updateProduct(
id,
product.getName(),
product.getCost()
);
return "redirect:/product/my_products";
}
}

View File

@ -0,0 +1,25 @@
body {
background: #f54d9a;
}
.logo {
background: #FF9CCE;
}
main {
padding: 2%;
margin: 10% 5%;
}
main img {
width: 100%;
object-fit: cover;
}
form {
padding: 1%;
}
.product-div {
background: #e874ac;
}

View File

@ -0,0 +1,37 @@
<!DOCTYPE html>
<html lang="en" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="/style.css"/>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha3/dist/css/bootstrap.min.css"
rel="stylesheet" integrity="sha384-KK94CHFLLe+nY2dmCWGMq91rCGa5gtU4mk92HdvYe+M/SXH301p5ILy+dN9+nJOZ"
crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.7/dist/umd/popper.min.js"
integrity="sha384-zYPOMqeu1DAVkHiLqWBUTcbYfZ8osu1Nd6Z89ify25QV9guujx43ITvfi12/QExE"
crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha3/dist/js/bootstrap.min.js"
integrity="sha384-Y4oOpwW3duJdCWv5ly8SCFYWqFDsfob/3GkgExXKV4idmbt98QcxXYs9UoXAB7BZ"
crossorigin="anonymous"></script>
</head>
<body>
<header class="logo d-flex flex-wrap align-items-center justify-content-center
justify-content-md-between py-3 mb-4 border-bottom" th:fragment="header">
<a href="/" class="d-flex align-items-center col-md-3 mb-2 mb-md-0 text-dark text-decoration-none">
<svg class="bi me-2" width="40" height="32" role="img" aria-label="Bootstrap"><use xlink:href="#bootstrap"></use></svg>
</a>
<ul class="nav col-12 col-md-auto mb-2 justify-content-center mb-md-0">
<li th:if="${user.firstName != null}"><a href="/product/my_products" class="nav-link px-2 link-dark">My Products</a></li>
<li><a href="/product" class="nav-link px-2 link-dark">Products</a></li>
</ul>
<div th:if="${user.firstName != null}" class="col-md-3 text-end">
<a href="/order" class="btn btn-outline-primary me-2">Shop List</a>
<a href="/master" class="nav-link px-2 link-dark" th:text="${user.firstName + ' ' + user.lastName}">User Name</a>
</div>
<div th:unless="${user.firstName != null}" class="col-md-3 text-end">
<a href="/master/login" class="btn btn-outline-primary me-2">Login</a>
<a href="/master" class="btn btn-primary">Register</a>
</div>
</header>
</body>
</html>

View File

@ -0,0 +1,38 @@
<!DOCTYPE html>
<html lang="en" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
<head>
<meta charset="UTF-8">
<title>Login</title>
<link rel="stylesheet" href="/style.css"/>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha3/dist/css/bootstrap.min.css"
rel="stylesheet" integrity="sha384-KK94CHFLLe+nY2dmCWGMq91rCGa5gtU4mk92HdvYe+M/SXH301p5ILy+dN9+nJOZ"
crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.7/dist/umd/popper.min.js"
integrity="sha384-zYPOMqeu1DAVkHiLqWBUTcbYfZ8osu1Nd6Z89ify25QV9guujx43ITvfi12/QExE"
crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha3/dist/js/bootstrap.min.js"
integrity="sha384-Y4oOpwW3duJdCWv5ly8SCFYWqFDsfob/3GkgExXKV4idmbt98QcxXYs9UoXAB7BZ"
crossorigin="anonymous"></script>
</head>
<body style="background: #f54d9a">
<header th:insert="~{Header :: header}"></header>
<form method="post" th:object="${user}">
<div class="container">
<div class="row gy-5 p-2">
<input type="email" name="email" class="form-control"
id="email" placeholder="Email" th:field="*{email}">
</div>
<div class="row gy-5 p-2">
<input type="password" name="password" class="form-control"
id="password" placeholder="Password" th:field="*{password}">
</div>
<div class="row gy-5">
<button type="submit" class="btn btn-primary">Sing In</button>
</div>
<div class="row gy-5 ">
<a href="/master/register" class="btn btn-primary">Register</a>
</div>
</div>
</form>
</body>
</html>

View File

@ -0,0 +1,48 @@
<!DOCTYPE html>
<html lang="en" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
<head>
<meta charset="UTF-8">
<title>Login</title>
<link rel="stylesheet" href="/style.css"/>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha3/dist/css/bootstrap.min.css"
rel="stylesheet" integrity="sha384-KK94CHFLLe+nY2dmCWGMq91rCGa5gtU4mk92HdvYe+M/SXH301p5ILy+dN9+nJOZ"
crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.7/dist/umd/popper.min.js"
integrity="sha384-zYPOMqeu1DAVkHiLqWBUTcbYfZ8osu1Nd6Z89ify25QV9guujx43ITvfi12/QExE"
crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha3/dist/js/bootstrap.min.js"
integrity="sha384-Y4oOpwW3duJdCWv5ly8SCFYWqFDsfob/3GkgExXKV4idmbt98QcxXYs9UoXAB7BZ"
crossorigin="anonymous"></script>
</head>
<body style="background: #f54d9a">
<header th:insert="~{Header :: header}"></header>
<div>
<h1 class="text-center">Order</h1>
<form method="post" th:object="${order}">
<div class="container">
<div th:each="product : ${order.products}" class="row product-div p-2 m-2">
<input type="hidden" name="id_item" th:name="id" th:value="${product.id}">
<div class="col">
<h2 th:text="${product.name}"></h2>
</div>
<div class="col">
<h3 th:text="${product.cost} + '$'"></h3>
</div>
<div class="col">
<button name="action" value="delete" class="btn btn-primary w-100 h-100 text-lg-center">Delete</button>
</div>
</div>
<div class="row">
<div class="col">
<h2 th:text="${fullCost} + '$'"></h2>
</div>
<div class="col">
<h3><button name="action" value="buy" class="btn btn-primary w-100">Buy</button>
</h3>
</div>
</div>
</div>
</form>
</div>
</body>
</html>

View File

@ -0,0 +1,27 @@
<!DOCTYPE html>
<html lang="en" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
<head>
<meta charset="UTF-8">
<title>Login</title>
<link rel="stylesheet" href="/style.css"/>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha3/dist/css/bootstrap.min.css"
rel="stylesheet" integrity="sha384-KK94CHFLLe+nY2dmCWGMq91rCGa5gtU4mk92HdvYe+M/SXH301p5ILy+dN9+nJOZ"
crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.7/dist/umd/popper.min.js"
integrity="sha384-zYPOMqeu1DAVkHiLqWBUTcbYfZ8osu1Nd6Z89ify25QV9guujx43ITvfi12/QExE"
crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha3/dist/js/bootstrap.min.js"
integrity="sha384-Y4oOpwW3duJdCWv5ly8SCFYWqFDsfob/3GkgExXKV4idmbt98QcxXYs9UoXAB7BZ"
crossorigin="anonymous"></script>
</head>
<body style="background: #f54d9a">
<header th:insert="~{Header :: header}"></header>
<div>
<form method="post" th:object="${product}">
<input type="text" th:field="*{name}" th:value="${product.getName()}" name="name" class="form-control" id="name">
<input type="number" th:field="*{cost}" th:value="${product.getCost()}" name="cost" class="form-control" id="cost">
<button type="submit" class="btn btn-primary" th:text="${buttonText}">Add</button>
</form>
</div>
</body>
</html>

View File

@ -0,0 +1,38 @@
<!DOCTYPE html>
<html lang="en" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="/style.css"/>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha3/dist/css/bootstrap.min.css"
rel="stylesheet" integrity="sha384-KK94CHFLLe+nY2dmCWGMq91rCGa5gtU4mk92HdvYe+M/SXH301p5ILy+dN9+nJOZ"
crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.7/dist/umd/popper.min.js"
integrity="sha384-zYPOMqeu1DAVkHiLqWBUTcbYfZ8osu1Nd6Z89ify25QV9guujx43ITvfi12/QExE"
crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha3/dist/js/bootstrap.min.js"
integrity="sha384-Y4oOpwW3duJdCWv5ly8SCFYWqFDsfob/3GkgExXKV4idmbt98QcxXYs9UoXAB7BZ"
crossorigin="anonymous"></script>
</head>
<body style="background: #f54d9a">
<header th:insert="~{Header :: header}"></header>
<div class="container">
<div th:each="item : ${products}" class="row product-div p-2 m-2">
<form method="post" th:object="${item}" >
<input type="hidden" th:name="id" th:value="${item.getId()}">
<div class="col">
<h2 th:text="${item.getName()}" th:name="*{name}"></h2>
</div>
<div class="col">
<h3 th:text="${item.getCost()} + '$'" th:name="*{cost}"></h3>
</div>
<div class="col">
<button type="submit" class="btn btn-primary w-100">Buy</button>
</div>
</form>
</div>
</div>
</body>
</html>

View File

@ -0,0 +1,55 @@
<!DOCTYPE html>
<html lang="en" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="/style.css"/>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha3/dist/css/bootstrap.min.css"
rel="stylesheet" integrity="sha384-KK94CHFLLe+nY2dmCWGMq91rCGa5gtU4mk92HdvYe+M/SXH301p5ILy+dN9+nJOZ"
crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.7/dist/umd/popper.min.js"
integrity="sha384-zYPOMqeu1DAVkHiLqWBUTcbYfZ8osu1Nd6Z89ify25QV9guujx43ITvfi12/QExE"
crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha3/dist/js/bootstrap.min.js"
integrity="sha384-Y4oOpwW3duJdCWv5ly8SCFYWqFDsfob/3GkgExXKV4idmbt98QcxXYs9UoXAB7BZ"
crossorigin="anonymous"></script>
</head>
<body style="background: #f54d9a">
<header th:insert="~{Header :: header}"></header>
<form method="post" th:object="${user}">
<div class="container">
<div class="row gy-5 p-2">
<input type="text" name="name" class="form-control"
id="name" placeholder="Name" th:value="${user.firstName}" th:field="*{firstName}">
</div>
<div class="row gy-5 p-2">
<input type="text" name="surname" class="form-control"
id="surname" placeholder="Surname" th:value="${user.lastName}" th:field="*{lastName}">
</div>
<div class="row gy-5 p-2">
<input type="email" name="email" class="form-control"
id="email" placeholder="Email" th:value="${user.email}" th:field="*{email}">
</div>
<div class="row gy-5 p-2">
<input type="password" name="password" class="form-control"
id="password" placeholder="Password" th:value="${user.password}" th:field="*{password}">
</div>
<div th:if='${user.firstName != null}' class="row align-items-start">
<div class="col">
<button name="action" class="btn btn-primary w-100" value="update">Update</button>
</div>
<div class="col">
<button name="action" th:onclick="/master/log_out"
class="btn btn-primary w-100" value="log_out">Log Out</button>
</div>
</div>
<div th:unless='${user.firstName != null}' class="row gy-5">
<button name="action" value="register" class="btn btn-primary w-100">Register</button>
</div>
<div th:unless='${user.firstName != null}' class="row align-items-start">
<a href="/sing_in" class="btn btn-primary">Sing In</a>
</div>
</div>
</form>
</body>
</html>

View File

@ -0,0 +1,37 @@
<!DOCTYPE html>
<html lang="en" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="/style.css"/>
<a></a>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha3/dist/css/bootstrap.min.css"
rel="stylesheet" integrity="sha384-KK94CHFLLe+nY2dmCWGMq91rCGa5gtU4mk92HdvYe+M/SXH301p5ILy+dN9+nJOZ"
crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.7/dist/umd/popper.min.js"
integrity="sha384-zYPOMqeu1DAVkHiLqWBUTcbYfZ8osu1Nd6Z89ify25QV9guujx43ITvfi12/QExE"
crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha3/dist/js/bootstrap.min.js"
integrity="sha384-Y4oOpwW3duJdCWv5ly8SCFYWqFDsfob/3GkgExXKV4idmbt98QcxXYs9UoXAB7BZ"
crossorigin="anonymous"></script>
</head>
<body style="background: #f54d9a">
<header th:insert="~{Header :: header}"></header>
<div class="container">
<div class="row align-content-center">
<a href="/product/create_product" class="btn btn-primary w-100 h-100 text-lg-center">Create</a>
</div>
<div th:each="item : ${products}" class="row product-div p-2 m-2">
<div class="col">
<h2 th:text="${item.name}"></h2>
</div>
<div class="col">
<h3 th:text="${item.cost} + '$'"></h3>
</div>
<div class="col">
<a th:href="'/product/update_product/' + ${{item.id}}" class="btn btn-primary w-100 h-100 text-lg-center">Edit</a>
</div>
</div>
</div>
</body>
</html>