diff --git a/docker-compose.yml b/docker-compose.yml index 3c68ff8..c852ead 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,5 +1,14 @@ version: '3.8' services: + mysqldb: + image: mysql:8.0.21 + ports: + - "3307:3307" + environment: + MYSQL_ROOT_PASSWORD: "root" + MYSQL_DATABASE: "device_shop" + MYSQL_ALLOW_EMPTY_PASSWORD: "yes" + MYSQL_PASSWORD: "root" app: build: context: . @@ -7,19 +16,13 @@ services: ports: - "8081:8081" depends_on: - - localhost - - localhost: - image: mysql:8.0.21 - ports: - - "3306:3306" + mysqldb: + condition: service_completed_successfully environment: - SPRING_DATASOURCE_URL: jdbc:mysql://localhost:3306/device_shop?serverTimezone=UTC - SPRING_DATASOURCE_USERNAME: root - SPRING_DATASOURCE_PASSWORD: root - flyway: - build: - context: . - dockerfile: Dockerfile.flyway - depends_on: - - localhost \ No newline at end of file + SPRING_APPLICATION_JSON: '{ + "spring.datasource.url" : "jdbc:mysql://mysqldb:3307/device_shop?serverTimezone=UTC", + "spring.datasource.username" : "root", + "spring.datasource.password" : "root", + "spring.jpa.properties.hibernate.dialect" : "org.hibernate.dialect.MySQL5Dialect", + "spring.jpa.hibernate.ddl-auto" : "update" + }' \ No newline at end of file diff --git a/src/main/java/com/device/shop/configuration/WebSecurityConfig.java b/src/main/java/com/device/shop/configuration/WebSecurityConfig.java index b6ba623..2d70c99 100644 --- a/src/main/java/com/device/shop/configuration/WebSecurityConfig.java +++ b/src/main/java/com/device/shop/configuration/WebSecurityConfig.java @@ -60,14 +60,33 @@ protected void configure(HttpSecurity http) throws Exception { .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) .and() .authorizeRequests() - .antMatchers("/login", "/v3/api-docs/**", "/swagger-ui/**", "/swagger-ui.html", "/resources/**", "/static/**", "/js/**", "/img/**", "/css/**", "/ui", "/products", "/product/{id}", "/search/{name}", "/create", "/cart/{id}/items", "/{sessionId}", "/cart/items/{id}").permitAll() + .antMatchers("/login", + "/v3/api-docs/**", + "/swagger-ui/**", + "/swagger-ui.html", + "/resources/**", + "/static/**", + "/js/**", + "/img/**", + "/css/**", + "/ui", + "/products", + "/upload", + "/product/{id}", + "/search/{name}", + "/create", + "/cart/{id}/items", + "/{sessionId}", + "/cart/items/{id}", + "/users"/*, + "/product"*/).permitAll() .antMatchers(HttpMethod.POST, "/users").permitAll() .anyRequest().authenticated(); http.addFilterBefore(authenticationJwtTokenFilter(), UsernamePasswordAuthenticationFilter.class); } - @Bean + @Bean public CorsConfigurationSource corsConfigurationSource() { CorsConfiguration configuration = new CorsConfiguration(); diff --git a/src/main/java/com/device/shop/controller/AuthController.java b/src/main/java/com/device/shop/controller/AuthController.java index 3b04528..695dfab 100644 --- a/src/main/java/com/device/shop/controller/AuthController.java +++ b/src/main/java/com/device/shop/controller/AuthController.java @@ -1,6 +1,9 @@ package com.device.shop.controller; import com.device.shop.security.JwtUtils; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import org.springframework.http.ResponseEntity; import org.springframework.security.authentication.AuthenticationManager; @@ -15,17 +18,26 @@ @RestController @AllArgsConstructor public class AuthController { - + private final AuthenticationManager authenticationManager; private final JwtUtils jwtUtils; @PostMapping("/login") - public ResponseEntity authenticateUser(@RequestParam MultiValueMap body) { + public ResponseEntity authenticateUser( + @RequestParam @Parameter( + description = "User's username", + required = true, + content = @Content(schema = @Schema(type = "string")) + ) String username, + @RequestParam @Parameter( + description = "User's password", + required = true, + content = @Content(schema = @Schema(type = "string", format = "password")) + ) String password) { Authentication authentication = authenticationManager - .authenticate(new UsernamePasswordAuthenticationToken(String.valueOf(body.get("username")) - ,String.valueOf(body.get("password")))); + .authenticate(new UsernamePasswordAuthenticationToken(username, password)); SecurityContextHolder.getContext().setAuthentication(authentication); String jwt = jwtUtils.generateJwtToken(authentication); diff --git a/src/main/java/com/device/shop/controller/ProductPhotoController.java b/src/main/java/com/device/shop/controller/ProductPhotoController.java index f614d2e..125045a 100644 --- a/src/main/java/com/device/shop/controller/ProductPhotoController.java +++ b/src/main/java/com/device/shop/controller/ProductPhotoController.java @@ -1,8 +1,10 @@ package com.device.shop.controller; import com.device.shop.service.ProductPhotoService; +import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.security.SecurityRequirement; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.*; @@ -11,7 +13,6 @@ import java.io.IOException; @RestController - public class ProductPhotoController { private final ProductPhotoService productPhotoService; @@ -22,9 +23,9 @@ public ProductPhotoController(ProductPhotoService productPhotoService) { } @SecurityRequirement(name = "bearerAuth") - @PreAuthorize("hasRole('ROLE_ADMIN')") - @PostMapping("/upload") - public ResponseEntity uploadPhoto(@RequestParam("image") MultipartFile image) throws IOException { + //@PreAuthorize("hasRole('ROLE_ADMIN')") + @PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) + public ResponseEntity uploadPhoto(@RequestPart("image") MultipartFile image) throws IOException { Long photoId = productPhotoService.uploadPhoto(image); return ResponseEntity.ok(photoId); } diff --git a/src/main/java/com/device/shop/controller/UserController.java b/src/main/java/com/device/shop/controller/UserController.java index 5172cee..f4779f1 100644 --- a/src/main/java/com/device/shop/controller/UserController.java +++ b/src/main/java/com/device/shop/controller/UserController.java @@ -27,7 +27,7 @@ public class UserController { private final UserService userService; - + @SecurityRequirement(name = "bearerAuth") @PostMapping("/users") public ResponseEntity createUser(@RequestBody UserDTO userDTO) throws BadRequestException { UserDTO savedUserDTO = userService.createUser(userDTO); diff --git a/src/main/java/com/device/shop/entity/CartItem.java b/src/main/java/com/device/shop/entity/CartItem.java index 754f3f8..8b90dad 100644 --- a/src/main/java/com/device/shop/entity/CartItem.java +++ b/src/main/java/com/device/shop/entity/CartItem.java @@ -28,7 +28,7 @@ public class CartItem { @JoinColumn(name = "session_id") ShoppingSession shoppingSession; - @OneToOne + @ManyToOne @JoinColumn(name = "product_id") Product product; diff --git a/src/main/java/com/device/shop/mapper/ProductMapper.java b/src/main/java/com/device/shop/mapper/ProductMapper.java index c511a6a..d3d98a1 100644 --- a/src/main/java/com/device/shop/mapper/ProductMapper.java +++ b/src/main/java/com/device/shop/mapper/ProductMapper.java @@ -22,11 +22,12 @@ public ProductDTO toDTO(Product product) { .deletedAt(product.getDeletedAt()) .discountId(Optional.ofNullable(product.getDiscount()) .map(Discount::getId) - .orElse(null)) - .photoId(product.getProductPhoto().getId()); + .orElse(null)); if (product.getProductPhoto() != null) { - builder.imageData(product.getProductPhoto().getPhotoData()); + builder + .photoId(product.getProductPhoto().getId()) + .imageData(product.getProductPhoto().getPhotoData()); } return builder.build(); @@ -44,5 +45,4 @@ public Product toEntity(ProductDTO productDTO) { .deletedAt(productDTO.getDeletedAt()) .build(); } - } \ No newline at end of file diff --git a/src/main/java/com/device/shop/service/impl/ProductServiceImpl.java b/src/main/java/com/device/shop/service/impl/ProductServiceImpl.java index 7c0a3af..5fe681b 100644 --- a/src/main/java/com/device/shop/service/impl/ProductServiceImpl.java +++ b/src/main/java/com/device/shop/service/impl/ProductServiceImpl.java @@ -107,18 +107,22 @@ public void save(MultipartFile file) throws IOException, BadRequestException { public ResponseEntity addProduct(ProductDTO productDTO) { Product product = productMapper.toEntity(productDTO); - if (productDTO.getPhotoId() != null) { - ProductPhoto productPhoto = productPhotoRepository.findById(productDTO.getPhotoId()) - .orElseThrow(() -> new EntityNotFoundException("Фото з id " + productDTO.getPhotoId() + " не знайдено")); + if (productDTO.getImageData() != null) { + ProductPhoto productPhoto = ProductPhoto.builder() + .photoData(productDTO.getImageData()) + .build(); product.setProductPhoto(productPhoto); } - Discount discount = discountRepository.findById(productDTO.getDiscountId()) - .orElseThrow(() -> new EntityNotFoundException("Discount with id " + productDTO.getDiscountId() + " not found")); - product.setDiscount(discount); + if (productDTO.getDiscountId() != null) { + Discount discount = discountRepository.findById(productDTO.getDiscountId()) + .orElseThrow(() -> new EntityNotFoundException("Discount with id " + productDTO.getDiscountId() + " not found")); + product.setDiscount(discount); + } else { + product.setDiscount(null); + } productRepository.save(product); return ResponseEntity.ok(productMapper.toDTO(product)); } - } \ No newline at end of file diff --git a/src/main/java/com/device/shop/service/impl/UserServiceImpl.java b/src/main/java/com/device/shop/service/impl/UserServiceImpl.java index 6b02701..d6aa8ef 100644 --- a/src/main/java/com/device/shop/service/impl/UserServiceImpl.java +++ b/src/main/java/com/device/shop/service/impl/UserServiceImpl.java @@ -43,13 +43,13 @@ public UserDTO createUser(UserDTO userDTO) throws BadRequestException { user.setPassword(encodedPassword); User savedUser = userRepository.save(user); - //todo move send email via spring AOP and remove flush operation +/* //todo move send email via spring AOP and remove flush operation userRepository.flush(); try { emailService.sendRegistrationEmail(savedUser.getEmail(), savedUser.getName()); } catch (MessagingException e) { - } + }*/ return userMapper.toDTO(savedUser); } @@ -104,7 +104,7 @@ private void validateUserFields(UserDTO userDTO) throws BadRequestException { if (!emailMatcher.matches()) { throw new BadRequestException("Invalid email format"); } - String phoneRegex = "^\\+380\\s\\d{2}\\s\\d{3}\\s\\d{2}\\s\\d{2}$|^\\+380-\\d{2}-\\d{3}-\\d{2}-\\d{2}$"; + String phoneRegex = "^(\\+380\\s\\d{2}\\s\\d{3}\\s\\d{2}\\s\\d{2}|\\+380-\\d{2}-\\d{3}-\\d{2}-\\d{2}|\\+380\\d{9})$"; Pattern phonePattern = Pattern.compile(phoneRegex); Matcher phoneMatcher = phonePattern.matcher(userDTO.getPhone()); if (!phoneMatcher.matches()) { diff --git a/src/main/resources/META-INF/MANIFEST.MF b/src/main/resources/META-INF/MANIFEST.MF new file mode 100644 index 0000000..2307cf4 --- /dev/null +++ b/src/main/resources/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Main-Class: com.device.shop.MyProjectWithSpring2Application + diff --git a/src/main/resources/backup_data_only.sql b/src/main/resources/backup_data_only.sql new file mode 100644 index 0000000..2a59e3e Binary files /dev/null and b/src/main/resources/backup_data_only.sql differ diff --git a/src/main/resources/static/js/Test.js b/src/main/resources/static/js/Test.js new file mode 100644 index 0000000..a74eb6a --- /dev/null +++ b/src/main/resources/static/js/Test.js @@ -0,0 +1,94 @@ +document.addEventListener('DOMContentLoaded', function () { + const form = document.getElementById('productForm'); + const submitButton = document.getElementById('submitButton'); + + submitButton.addEventListener('click', function () { + const formData = { + name: document.getElementById('name').value, + description: document.getElementById('description').value, + sku: document.getElementById('sku').value, + price: parseFloat(document.getElementById('price').value), + quantity: parseInt(document.getElementById('quantity').value), + }; + + // Отримуємо токен з локального сховища + const token = localStorage.getItem('token'); // Перед цим ви маєте зберегти токен в локальному сховищі + + // Перевірка, чи є токен + if (!token) { + console.error('Токен не знайдено'); + return; + } + + // Відправляємо POST-запит на бекенд разом із токеном + fetch('http://localhost:8081/product', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'Authorization': `Bearer ${token}`, // Додаємо токен до заголовків + }, + body: JSON.stringify(formData), + }) + .then(response => response.json()) + .then(data => { + console.log('Дані успішно відправлені на бекенд:', data); + // Додайте код для відображення успішного повідомлення користувачу + }) + .catch(error => { + console.error('Помилка під час відправлення запиту:', error); + // Додайте код для відображення повідомлення про помилку користувачу + }); + }); +}); + + + + + + + +/* + +document.addEventListener('DOMContentLoaded', function () { + const form = document.getElementById('productForm'); + const submitButton = document.getElementById('submitButton'); + + submitButton.addEventListener('click', function () { + const formData = { + name: document.getElementById('name').value, + description: document.getElementById('description').value, + sku: document.getElementById('sku').value, + price: parseFloat(document.getElementById('price').value), + quantity: parseInt(document.getElementById('quantity').value), + }; + + // Отримуємо токен з локального сховища + const token = localStorage.getItem('token'); + + // Відправляємо POST-запит на бекенд з токеном у заголовку + fetch('http://localhost:8081/product', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'Authorization': `Bearer ${token}` // Додаємо токен у заголовок + }, + body: JSON.stringify(formData), + }) + .then(response => response.json()) + .then(data => { + console.log('Дані успішно відправлені на бекенд:', data); + // Додайте код для відображення успішного повідомлення користувачу + }) + .catch(error => { + console.error('Помилка під час відправлення запиту:', error); + // Додайте код для відображення повідомлення про помилку користувачу + }); + }); +}); +*/ + + + + + + diff --git a/src/main/resources/static/js/client.js b/src/main/resources/static/js/client.js index 0da85d5..a901e82 100644 --- a/src/main/resources/static/js/client.js +++ b/src/main/resources/static/js/client.js @@ -1,8 +1,6 @@ -function goToProductsPage() { - window.location.href = 'products.html'; -} -async function login() { + +/*async function login() { const email = document.getElementById('email').value; const password = document.getElementById('password').value; @@ -41,12 +39,74 @@ async function login() { goToProductsPage(); + } catch (error) { + console.error('Помилка входу:', error); + alert('Не вдалось увійти. Перевірте ваші облікові дані та спробуйте знову.'); + } +}*/ + + +async function login() { + const email = document.getElementById('email').value; + const password = document.getElementById('password').value; + + const formData = new URLSearchParams(); + formData.append('username', email); + formData.append('password', password); + + try { + const response = await fetch('http://localhost:8081/login', { + method: 'POST', + headers: { + 'Content-Type': 'application/x-www-form-urlencoded' + }, + body: formData.toString() + }); + + if (!response.ok) { + throw new Error('Не вдалось увійти'); + } + + const accessToken = await response.text(); + console.log(accessToken); + localStorage.setItem('token', accessToken); + + const userResponse = await fetch('http://localhost:8081/users/principal', { + headers: { + Authorization: `Bearer ${accessToken}` + } + }); + + if (userResponse.ok) { + const user = await userResponse.json(); + localStorage.setItem('userId', user.id); + + // Перевірка ролі користувача + if (user.roles.includes('ROLE_USER')) { + // Перекидуємо на сторінку з усіма продуктами + goToProductsPage(); + } else if (user.roles.includes('ROLE_ADMIN')) { + // Перекидуємо на сторінку адміністратора + goAdmin(); + } + } else { + throw new Error('Не вдалось отримати дані користувача'); + } + } catch (error) { console.error('Помилка входу:', error); alert('Не вдалось увійти. Перевірте ваші облікові дані та спробуйте знову.'); } } +function goToProductsPage() { + window.location.href = 'products.html'; +} +function goAdmin() { + window.location.href = 'createProduct.html'; +} + + const registrationForm = document.getElementById('registrationForm'); function register() { diff --git a/src/main/resources/static/js/creatProd.js b/src/main/resources/static/js/creatProd.js new file mode 100644 index 0000000..959ae30 --- /dev/null +++ b/src/main/resources/static/js/creatProd.js @@ -0,0 +1,36 @@ +async function uploadFile() { + const fileInput = document.getElementById('image'); + if (fileInput.files.length === 0) { + alert('Please select a file to upload.'); + return; + } + + const accessToken = localStorage.getItem('token'); + if (!accessToken) { + alert('You need to log in to upload a file.'); + return; + } + + const formData = new FormData(); + formData.append('image', fileInput.files[0]); + + const requestOptions = { + method: 'POST', + headers: { + Authorization: `Bearer ${accessToken}`, + }, + body: formData, + }; + + try { + const response = await fetch('http://localhost:8081/upload', requestOptions); + if (response.ok) { + const { photoId } = await response.json(); + alert('File uploaded successfully.'); + } else { + alert('An error occurred while uploading the file to the server.'); + } + } catch (error) { + console.error('An error has occurred:', error); + } +} diff --git a/src/main/resources/static/js/creatProd_v3.js b/src/main/resources/static/js/creatProd_v3.js new file mode 100644 index 0000000..d4ea988 --- /dev/null +++ b/src/main/resources/static/js/creatProd_v3.js @@ -0,0 +1,104 @@ + +async function uploadFile() { + const fileInput = document.getElementById('image'); + if (fileInput.files.length === 0) { + alert('Please select a file to upload.'); + return; + } + + const accessToken = localStorage.getItem('token'); + if (!accessToken) { + alert('You need to log in to upload a file.'); + return; + } + + const formData = new FormData(); + formData.append('image', fileInput.files[0]); + + const requestOptions = { + method: 'POST', + headers: { + Authorization: `Bearer ${accessToken}`, + }, + body: formData, + }; + + try { + const response = await fetch('http://localhost:8081/upload', requestOptions); + if (response.ok) { + const { photoId } = await response.json(); + alert('File uploaded successfully.'); + } else { + alert('An error occurred while uploading the file to the server.'); + } + } catch (error) { + console.error('An error has occurred:', error); + } +} + +// Відправка даних з форми information: +async function saveProductData() { + const accessToken = localStorage.getItem('token'); + if (!accessToken) { + alert('You need to log in to save product data.'); + return; + } + + // Отримуємо дані з форми + const productName = document.querySelector('.product_name').value; + const productDescription = document.querySelector('.description').value; + const sku = document.querySelector('.sku').value; + const price = parseFloat(document.querySelector('.price').value.replace(',', '.')); + const quantity = parseFloat(document.querySelector('.quantity').value.replace(',', '.')); + + // Перевіряємо, чи всі поля заповнені + if (!productName || !sku || isNaN(price) || isNaN(quantity)) { + alert('Please fill in all required fields with valid data.'); + return; + } + + // Створюємо обєкт + const productData = { + id: productId, + name: productName, + description: productDescription, + sku: sku, + price: price, + createdAt: new Date().toISOString(), + modifiedAt: new Date().toISOString(), + deletedAt: null, + quantity: quantity, + discountId: discountId, + photoId: photoId + }; + + // Створюємо запит + const requestOptions = { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${accessToken}`, + }, + body: JSON.stringify(productData), + }; + + try { + const response = await fetch('http://localhost:8081/product', requestOptions); + if (response.ok) { + alert('Product data saved successfully.'); + } else { + alert('An error occurred while saving product data.'); + } + } catch (error) { + console.error('An error has occurred:', error); + } +} + +// // Додаємо функцію для перетворення коми на крапку в інпутах, які мають містити числівники +// const numberInputs = document.querySelectorAll('input[type="number"]'); + +// numberInputs.forEach(function(input) { +// input.addEventListener('input', function () { +// this.value = this.value.replace(',', '.'); +// }); +// }); diff --git a/src/main/resources/static/js/createProduct.js b/src/main/resources/static/js/createProduct.js new file mode 100644 index 0000000..087478e --- /dev/null +++ b/src/main/resources/static/js/createProduct.js @@ -0,0 +1,245 @@ +/* +window.onload = function() { + +// Додаємо функцію для перетворення коми на крапку в інпутах, кі мають містити числівники + const numberInputs = document.querySelectorAll('input[type="number"]'); + + numberInputs.forEach(function(input) { + input.addEventListener('input', function () { + this.value = this.value.replace(',', '.'); + }); + }); +*/ + +// Передаємо фото-файл на сервер: + +/* + function uploadFile() { + + const accessToken = localStorage.getItem('token'); + + if (!accessToken) { + alert('Для завантаження файлу вам потрібно увійти.'); + return; + } + + const fileInput = document.getElementById('photo'); + if (fileInput.files.length === 0) { + alert('Please select a file to upload.'); + return; + } + + const imegFile = new imegFile(); + imegFile.append('file', fileInput.files[0]); + + const requestOptions = { + method: 'POST', + body: imegFile + }; + + fetch('http://localhost:8081/upload', requestOptions) + .then(response => { + if (response.ok) { + alert('The file was successfully uploaded to the server.'); + } else { + alert('An error occurred while uploading the file to the server.'); + } + }) + .catch(error => { + console.error('An error has occurred:', error); + }); + } + + const uploadButton = document.querySelector('.upload'); + uploadButton.addEventListener('click', uploadFile); +*/ +/* + + +function goToProductsPage() { + // Implement your logic to navigate back to the products page +} + +async function uploadFile() { + const fileInput = document.getElementById('image'); + if (fileInput.files.length === 0) { + alert('Please select a file to upload.'); + return; + } + + const accessToken = localStorage.getItem('token'); + if (!accessToken) { + alert('You need to log in to upload a file.'); + return; + } + + const formData = new FormData(); + formData.append('image', fileInput.files[0]); + + const requestOptions = { + method: 'POST', + headers: { + Authorization: `Bearer ${accessToken}`, + }, + body: formData, + }; + + try { + const response = await fetch('http://localhost:8081/upload', requestOptions); + if (response.ok) { + const { photoId } = await response.json(); + alert('File uploaded successfully.'); + } else { + alert('An error occurred while uploading the file to the server.'); + } + } catch (error) { + console.error('An error has occurred:', error); + } +} + +async function saveProductData() { + const productName = document.querySelector('.product_name').value; + const description = document.querySelector('.description').value; + const sku = document.querySelector('.sku').value; + const price = parseFloat(document.querySelector('.price').value); + const quantity = parseInt(document.querySelector('.quantity').value); + + const productData = { + name: productName, + description: description, + sku: sku, + price: price, + quantity: quantity, + }; + + const accessToken = localStorage.getItem('token'); + if (!accessToken) { + alert('You need to log in to save product data.'); + return; + } + + try { + const productResponse = await fetch('http://localhost:8081/product', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${accessToken}`, + }, + body: JSON.stringify(productData), + }); + + if (productResponse.ok) { + alert('Product data saved successfully.'); + document.getElementById('editSuccess').style.display = 'block'; + } else { + alert('An error occurred while saving product data.'); + } + } catch (error) { + console.error('An error has occurred:', error); + } +} +*/ + + +// function goToProductsPage() { +// window.location.href = 'products.html'; +// } + +// async function login() { +// const email = document.getElementById('email').value; +// const password = document.getElementById('password').value; + +// const formData = new URLSearchParams(); +// formData.append('username', email); +// formData.append('password', password); + +// try { +// const response = await fetch('http://localhost:8081/login', { +// method: 'POST', +// headers: { +// 'Content-Type': 'application/x-www-form-urlencoded' +// }, +// body: formData.toString() +// }); + +// if (!response.ok) { +// throw new Error('Не вдалось увійти'); +// } + +// const accessToken = await response.text(); + +// console.log(accessToken); +// localStorage.setItem('token', accessToken); + +// const userResponse = await fetch('http://localhost:8081/users/principal', { +// headers: { +// Authorization: `Bearer ${accessToken}` +// } +// }); + +// if (userResponse.ok) { +// const user = await userResponse.json(); +// localStorage.setItem('userId', user.id); +// } + +// goToProductsPage(); + +// } catch (error) { +// console.error('Помилка входу:', error); +// alert('Не вдалось увійти. Перевірте ваші облікові дані та спробуйте знову.'); +// } +// } + +// const registrationForm = document.getElementById('registrationForm'); + +// function register() { +// // Отримайте дані з форми реєстрації +// const name = document.getElementById('name').value; +// const surname = document.getElementById('surname').value; +// const phone = document.getElementById('phone').value; +// const email = document.getElementById('regEmail').value; +// const password = document.getElementById('regPassword').value; + +// const user = { +// name, +// surname, +// phone, +// email, +// password +// }; + +// fetch('http://localhost:8081/users', { +// method: 'POST', +// headers: { +// 'Content-Type': 'application/json' +// }, +// body: JSON.stringify(user) +// }) +// .then(response => { +// if (response.ok) { +// return response.json(); +// } else { +// throw new Error('Edit failed'); +// } +// }) +// .then(data => { +// console.log('Edit successful:', data); +// const editSuccess = document.getElementById('editSuccess'); +// editSuccess.style.display = 'block'; +// document.getElementById('editSuccess').reset(); +// }) +// .catch(error => { +// console.error('Edit error:', error); +// }); +// } + +// document.getElementById('loginForm').addEventListener('submit', async (event) => { +// event.preventDefault(); +// login(); +// }); + + +// document.getElementById('registrationForm').addEventListener('submit', async (event) => { +// event.preventDefault(); +// register(); +// }); diff --git a/src/main/resources/templates/Test.html b/src/main/resources/templates/Test.html new file mode 100644 index 0000000..1d1cc4c --- /dev/null +++ b/src/main/resources/templates/Test.html @@ -0,0 +1,64 @@ + + + + + + Форма для відправки товару + + + + + + + +

Додати новий товар

+
+ +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + + + \ No newline at end of file diff --git a/src/main/resources/templates/admin.html b/src/main/resources/templates/admin.html new file mode 100644 index 0000000..4365453 --- /dev/null +++ b/src/main/resources/templates/admin.html @@ -0,0 +1,22 @@ + + + + + Title + + + +
+

Привіт адмін

+
+ + + \ No newline at end of file diff --git a/src/main/resources/templates/createProduct.html b/src/main/resources/templates/createProduct.html new file mode 100644 index 0000000..f53504f --- /dev/null +++ b/src/main/resources/templates/createProduct.html @@ -0,0 +1,204 @@ + + + + + + + + Registration and Login Page + + + + + +
+
+

Creat/edit product

+
+ +
+
+ +
+
+
+ + +
+ +
+
+
+ + +
+ +
+
+

Product Information

+ + + + + + + + + +
+
+ +
+
Data saved successfully +
+
+
+ + + + + + \ No newline at end of file