Преглед изворни кода

names update, simple email work, profile page modification

mateuszsudra пре 2 година
родитељ
комит
b49e28938d
29 измењених фајлова са 531 додато и 111 уклоњено
  1. 59 18
      boat-reservation-logic/pom.xml
  2. 32 32
      boat-reservation-logic/src/main/java/pl/sudra/configuration/EmailManagerConfiguration.java
  3. 29 0
      boat-reservation-logic/src/main/java/pl/sudra/controller/BillController.java
  4. 10 1
      boat-reservation-logic/src/main/java/pl/sudra/controller/BoatController.java
  5. 10 1
      boat-reservation-logic/src/main/java/pl/sudra/controller/ReservationController.java
  6. 10 1
      boat-reservation-logic/src/main/java/pl/sudra/controller/UserController.java
  7. 4 2
      boat-reservation-logic/src/main/java/pl/sudra/domain/Bill.java
  8. 9 7
      boat-reservation-logic/src/main/java/pl/sudra/domain/Reservation.java
  9. 4 1
      boat-reservation-logic/src/main/java/pl/sudra/repository/ReservationRepository.java
  10. 5 1
      boat-reservation-logic/src/main/java/pl/sudra/securityController/CustomInterceptor.java
  11. 8 8
      boat-reservation-logic/src/main/java/pl/sudra/securityController/SecurityController.java
  12. 25 22
      boat-reservation-logic/src/main/java/pl/sudra/service/EmailServiceImpl.java
  13. 5 0
      boat-reservation-logic/src/main/java/pl/sudra/service/ReservationService.java
  14. 66 4
      boat-reservation-logic/src/main/java/pl/sudra/service/ReservationServiceImpl.java
  15. 1 0
      boat-reservation-logic/src/main/java/pl/sudra/service/UserService.java
  16. 2 2
      boat-reservation-view/src/app/add-boat-component/add-boat.component.ts
  17. 1 1
      boat-reservation-view/src/app/admin-panel/admin-panel.component.ts
  18. 5 2
      boat-reservation-view/src/app/app.module.ts
  19. 2 2
      boat-reservation-view/src/app/boats-component/boats-view.component.ts
  20. 6 1
      boat-reservation-view/src/app/login-view/login-view.component.html
  21. 8 0
      boat-reservation-view/src/app/navbar/navbar.component.html
  22. 45 0
      boat-reservation-view/src/app/profile-page/profile-page.component.css
  23. 74 0
      boat-reservation-view/src/app/profile-page/profile-page.component.html
  24. 75 0
      boat-reservation-view/src/app/profile-page/profile-page.component.ts
  25. 2 2
      boat-reservation-view/src/app/register-view/register-view.component.ts
  26. 2 2
      boat-reservation-view/src/app/reservation-view/reservation-view.component.ts
  27. 12 1
      boat-reservation-view/src/app/services/boat.service.ts
  28. 10 0
      boat-reservation-view/src/app/services/reservation.service.ts
  29. 10 0
      boat-reservation-view/src/app/services/user.service.ts

+ 59 - 18
boat-reservation-logic/pom.xml

@@ -109,22 +109,63 @@
             <artifactId>jakarta.json</artifactId>
             <version>2.0.1</version>
         </dependency>
+<!--&lt;!&ndash;        test&ndash;&gt;-->
+<!--        <dependency>-->
+<!--            <groupId>org.springframework.boot</groupId>-->
+<!--            <artifactId>spring-boot-starter-mail</artifactId>-->
+<!--            <version>2.2.6.RELEASE</version>-->
+<!--        </dependency>-->
+<!--        <dependency>-->
+<!--            <groupId>com.sun.mail</groupId>-->
+<!--            <artifactId>jakarta.mail</artifactId>-->
+<!--            <version>1.6.5</version>-->
+<!--        </dependency>-->
+<!--        <dependency>-->
+<!--            <groupId>org.springframework</groupId>-->
+<!--            <artifactId>spring-context-support</artifactId>-->
+<!--            <version>5.2.5.RELEASE</version>-->
+<!--        </dependency>-->
+<!--        <dependency>-->
+<!--            <groupId>org.springframework.boot</groupId>-->
+<!--            <artifactId>spring-boot-starter-mail</artifactId>-->
+<!--            <version>2.2.6.RELEASE</version>-->
+<!--        </dependency>-->
+
+
+
         <!-- for sending emails -->
         <dependency>
             <groupId>org.springframework</groupId>
             <artifactId>spring-context-support</artifactId>
             <version>6.0.7</version>
         </dependency>
+<!--        <dependency>-->
+<!--            <groupId>jakarta.mail</groupId>-->
+<!--            <artifactId>jakarta.mail-api</artifactId>-->
+<!--            <version>2.1.1</version>-->
+<!--        </dependency>-->
+<!--        <dependency>-->
+<!--            <groupId>com.sun.mail</groupId>-->
+<!--            <artifactId>jakarta.mail</artifactId>-->
+<!--            <version>2.0.1</version>-->
+<!--        </dependency>-->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-mail</artifactId>
+            <version>3.1.1</version>
+        </dependency>
         <dependency>
             <groupId>jakarta.mail</groupId>
             <artifactId>jakarta.mail-api</artifactId>
-            <version>2.1.1</version>
+            <version>2.1.0</version>
+            <scope>provided</scope>
         </dependency>
         <dependency>
-            <groupId>com.sun.mail</groupId>
+            <groupId>org.eclipse.angus</groupId>
             <artifactId>jakarta.mail</artifactId>
-            <version>2.0.1</version>
+            <version>1.0.0</version>
         </dependency>
+
         <!-- https://mvnrepository.com/artifact/org.springframework.security/spring-security-jwt -->
         <dependency>
             <groupId>org.springframework.security</groupId>
@@ -132,11 +173,11 @@
             <version>1.1.1.RELEASE</version>
         </dependency>
         <!-- https://mvnrepository.com/artifact/org.springframework/spring-context-support -->
-        <dependency>
-            <groupId>org.springframework</groupId>
-            <artifactId>spring-context-support</artifactId>
-            <version>6.0.9</version>
-        </dependency>
+        <!--        <dependency>-->
+        <!--            <groupId>org.springframework</groupId>-->
+        <!--            <artifactId>spring-context-support</artifactId>-->
+        <!--            <version>6.0.9</version>-->
+        <!--        </dependency>-->
         <dependency>
             <groupId>io.jsonwebtoken</groupId>
             <artifactId>jjwt-api</artifactId>
@@ -154,16 +195,16 @@
             <version>0.11.2</version>
             <scope>runtime</scope>
         </dependency>
-<!--        &lt;!&ndash; https://mvnrepository.com/artifact/org.springframework.security/spring-security-web &ndash;&gt;-->
-<!--        <dependency>-->
-<!--            <groupId>org.springframework.security</groupId>-->
-<!--            <artifactId>spring-security-web</artifactId>-->
-<!--            <version>6.1.0</version>-->
-<!--        </dependency>-->
-<!--        <dependency>-->
-<!--            <groupId>org.springframework.boot</groupId>-->
-<!--            <artifactId>spring-boot-starter-security</artifactId>-->
-<!--        </dependency>-->
+        <!--        &lt;!&ndash; https://mvnrepository.com/artifact/org.springframework.security/spring-security-web &ndash;&gt;-->
+        <!--        <dependency>-->
+        <!--            <groupId>org.springframework.security</groupId>-->
+        <!--            <artifactId>spring-security-web</artifactId>-->
+        <!--            <version>6.1.0</version>-->
+        <!--        </dependency>-->
+        <!--        <dependency>-->
+        <!--            <groupId>org.springframework.boot</groupId>-->
+        <!--            <artifactId>spring-boot-starter-security</artifactId>-->
+        <!--        </dependency>-->
 
     </dependencies>
 

+ 32 - 32
boat-reservation-logic/src/main/java/pl/sudra/configuration/EmailManagerConfiguration.java

@@ -1,32 +1,32 @@
-//package pl.sudra.configuration;
-//
-//import org.springframework.context.annotation.Bean;
-//import org.springframework.context.annotation.Configuration;
-//import org.springframework.mail.javamail.JavaMailSender;
-//import org.springframework.mail.javamail.JavaMailSenderImpl;
-//
-//import java.util.Properties;
-//
-//@Configuration
-//public class EmailManagerConfiguration {
-//
-//    @Bean
-//    public JavaMailSender JavaMailSender() {
-//        JavaMailSenderImpl mailSender = new JavaMailSenderImpl();
-//        mailSender.setHost("smtp.gmail.com");
-//        mailSender.setPort(587); //SSL config
-//
-//        mailSender.setUsername("mateusz.sudra.21@gmail.com");
-//        mailSender.setPassword("jupjlcrapzgpxwah");
-//
-//        Properties props = mailSender.getJavaMailProperties();
-//        props.put("mail.transport.protocol", "smtp");
-//        props.put("mail.smtp.auth", "true");
-//        props.put("mail.smtp.starttls.enable", "true");
-//        props.put("mail.debug", "true");
-//        props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
-//
-//        return mailSender;
-//    }
-//}
-//
+package pl.sudra.configuration;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.mail.javamail.JavaMailSender;
+import org.springframework.mail.javamail.JavaMailSenderImpl;
+
+import java.util.Properties;
+
+@Configuration
+public class EmailManagerConfiguration {
+
+    @Bean
+    public JavaMailSender getJavaMailSender() {
+        JavaMailSenderImpl mailSender = new JavaMailSenderImpl();
+        mailSender.setHost("smtp.gmail.com");
+        mailSender.setPort(587); //SSL config
+
+        mailSender.setUsername("mateusz.sudra.21@gmail.com");
+        mailSender.setPassword("jupjlcrapzgpxwah");
+
+        Properties props = mailSender.getJavaMailProperties();
+        props.put("mail.transport.protocol", "smtp");
+        props.put("mail.smtp.auth", "true");
+        props.put("mail.smtp.starttls.enable", "true");
+        props.put("mail.debug", "true");
+        props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
+
+        return mailSender;
+    }
+}
+

+ 29 - 0
boat-reservation-logic/src/main/java/pl/sudra/controller/BillController.java

@@ -0,0 +1,29 @@
+package pl.sudra.controller;
+
+import org.springframework.data.repository.query.Param;
+import org.springframework.http.MediaType;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import pl.sudra.domain.Bill;
+import pl.sudra.domain.Boat;
+import pl.sudra.service.BillService;
+
+import java.util.List;
+
+public class BillController {
+    private BillService billService;
+
+    public BillController(BillService billService) {
+        this.billService = billService;
+    }
+
+
+    @RequestMapping(
+            value = "/getBill",
+            method = RequestMethod.GET,
+            produces = MediaType.APPLICATION_JSON_VALUE)
+    public Bill getBill(@Param("id") Long id) {
+        System.out.println("Getting Bill");
+        return billService.getBill(id);
+    }
+}

+ 10 - 1
boat-reservation-logic/src/main/java/pl/sudra/controller/BoatController.java

@@ -28,7 +28,7 @@ public class BoatController {
         return boatService.getBoats();
     }
 
-//    test request
+    //    test request
     @RequestMapping(value = "/hello", method = RequestMethod.GET)
     public String sayHello() {
         System.out.println("Greetings!");
@@ -41,4 +41,13 @@ public class BoatController {
         boatService.addBoat(boat);
         return true;
     }
+
+
+    @RequestMapping(
+            value = "/getBoatNameById",
+            method = RequestMethod.GET,
+            produces = MediaType.APPLICATION_JSON_VALUE)
+    public String getBoatNameById(@RequestParam("id") Long id) {
+        return this.boatService.getBoat(id).getName();
+    }
 }

+ 10 - 1
boat-reservation-logic/src/main/java/pl/sudra/controller/ReservationController.java

@@ -53,7 +53,7 @@ public class ReservationController {
 //        bill.setStatus(false);
         Bill bill = new Bill(
                 reservation,
-                "WAITING_FOR_PAYMENT",
+                "Pending",
                 new java.sql.Date(System.currentTimeMillis()),
                 this.boatService.getBoat(reservation.getBoatId()).getCost()
                         * (reservation.getEndHour() - reservation.getStartHour()));
@@ -75,6 +75,15 @@ public class ReservationController {
         return this.reservationService.findReservations(boat_id, date);
     }
 
+    @RequestMapping(
+            value = "/findReservationsOfUserId",
+            method = RequestMethod.GET,
+            produces = MediaType.APPLICATION_JSON_VALUE)
+    public List<Reservation> findReservationsOfUsername(@RequestParam("user_id") Long user_id) {
+        System.out.println("Looking for reservations");
+        return this.reservationService.findReservationsByUserId(user_id);
+    }
+
 //    @RequestMapping(
 //            value = "/getReservation",
 //            method = RequestMethod.GET,

+ 10 - 1
boat-reservation-logic/src/main/java/pl/sudra/controller/UserController.java

@@ -10,6 +10,7 @@ import pl.sudra.domain.User;
 import pl.sudra.service.UserService;
 
 import java.util.List;
+import java.util.Optional;
 
 @RestController
 @CrossOrigin(origins = "http://localhost:1410")
@@ -24,10 +25,18 @@ public class UserController {
             value = "/getAllUsers",
             method = RequestMethod.GET,
             produces = MediaType.APPLICATION_JSON_VALUE)
-    public List<User> generateReservations() {
+    public List<User> getAllUsers() {
         return this.userService.getAll();
     }
 
+    @RequestMapping(
+            value = "/getUser",
+            method = RequestMethod.GET,
+            produces = MediaType.APPLICATION_JSON_VALUE)
+    public User getUser(@Param("username") String username) {
+        return this.userService.findByUsername(username).get();
+    }
+
     @RequestMapping(
             value = "/updateUser",
             method = RequestMethod.GET,

+ 4 - 2
boat-reservation-logic/src/main/java/pl/sudra/domain/Bill.java

@@ -1,5 +1,6 @@
 package pl.sudra.domain;
 
+import com.fasterxml.jackson.annotation.JsonIgnore;
 import jakarta.persistence.*;
 import jakarta.validation.constraints.NotNull;
 
@@ -11,11 +12,12 @@ public class Bill {
     @GeneratedValue(strategy = GenerationType.AUTO)
     long id;
 
-    @OneToOne(mappedBy = "bill")
+    @OneToOne(mappedBy = "bill", fetch = FetchType.LAZY)
+    @JsonIgnore
     private Reservation reservation;
 
     @NotNull
-    String status; // WAITING_FOR_PAYMENT, PAYMENT_MADE, CLOSED, CANCELLED
+    String status; // Pending, Confirmed, Active, Completed, Cancelled
     @NotNull
     Date issueDate;
     @NotNull

+ 9 - 7
boat-reservation-logic/src/main/java/pl/sudra/domain/Reservation.java

@@ -1,6 +1,6 @@
 package pl.sudra.domain;
 
-import com.fasterxml.jackson.annotation.JsonBackReference;
+import com.fasterxml.jackson.annotation.JsonIgnore;
 import jakarta.persistence.*;
 import jakarta.validation.constraints.NotNull;
 
@@ -17,7 +17,7 @@ public class Reservation {
 //    @JoinColumn(name = "user_id")
 //    @JsonBackReference
     @NotNull
-    private Long user_id;
+    private Long userId;
     @NotNull
     private Long boatId;
     @NotNull
@@ -27,15 +27,17 @@ public class Reservation {
     @NotNull
     private byte endHour;
 
-    @OneToOne(cascade = CascadeType.ALL)
-    @JoinColumn(name = "bill_id")
+    @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
+    @JoinColumn(name = "billId")
+//    @JsonIgnore
+//    @MapsId
     private Bill bill;
 
     @Override
     public String toString() {
         return "Reservation{" +
                 "id=" + id +
-                ", user=" + user_id +
+                ", user=" + userId +
                 ", boatId=" + boatId +
                 ", date=" + date +
                 ", startHour=" + startHour +
@@ -64,11 +66,11 @@ public class Reservation {
     }
 
     public Long getUserId() {
-        return user_id;
+        return userId;
     }
 
     public void setUserId(Long user_id) {
-        this.user_id = user_id;
+        this.userId = user_id;
     }
 
     public Long getBoatId() {

+ 4 - 1
boat-reservation-logic/src/main/java/pl/sudra/repository/ReservationRepository.java

@@ -1,6 +1,7 @@
 package pl.sudra.repository;
 
 import jakarta.transaction.Transactional;
+import org.springframework.data.jpa.repository.EntityGraph;
 import org.springframework.data.jpa.repository.JpaRepository;
 import org.springframework.data.jpa.repository.Query;
 import org.springframework.data.repository.query.Param;
@@ -16,7 +17,9 @@ public interface ReservationRepository extends JpaRepository<Reservation, Long>
     Reservation findReservationById(long id);
 
     List<Reservation> findAllByBoatIdAndDate(long id, Date date);
-    @Query(value = "SELECT * FROM reservation r WHERE r.boatid = :boatId AND r.date = :date", nativeQuery = true)
+    @EntityGraph(attributePaths = "bill")
+    @Query("SELECT r FROM Reservation r WHERE r.boatId = :boatId AND r.date = :date")
     List<Reservation> findReservationsByBoatIdAndDate(@Param("boatId") Long boatId, @Param("date") Date date);
 
+    List<Reservation> findReservationsByUserId(Long userId);
 }

+ 5 - 1
boat-reservation-logic/src/main/java/pl/sudra/securityController/CustomInterceptor.java

@@ -21,7 +21,11 @@ public class CustomInterceptor implements HandlerInterceptor {
     );
     List<String> customer_and_above = List.of(
             "/createReservation",
-            "/findReservations"
+            "/findReservations",
+            "/getUser",
+            "/findReservationsOfUserId",
+            "/getBoatNameById",
+            "/getBill"
     );
     List<String> manager_and_above = Stream.concat(customer_and_above.stream(),
                     List.of(

+ 8 - 8
boat-reservation-logic/src/main/java/pl/sudra/securityController/SecurityController.java

@@ -26,14 +26,14 @@ import org.springframework.context.support.DefaultMessageSourceResolvable;
 public class SecurityController {
     private final UserService userService;
     private final RoleService roleService;
-//    private final EmailService emailService;
-
+    private final EmailService emailService;
+    @Autowired
     private PasswordEncoder passwordEncoder;
 
-    public SecurityController(UserService userService, RoleService roleService) {
+    public SecurityController(UserService userService, RoleService roleService, EmailService emailService) {
         this.userService = userService;
         this.roleService = roleService;
-//        this.emailService = emailService;
+        this.emailService = emailService;
     }
 
     @RequestMapping(
@@ -88,10 +88,10 @@ public class SecurityController {
 
         this.userService.registerUser(user);
 
-//        this.emailService.sendMail(
-//                user.getEmail(),
-//                "Welcome in our app!",
-//                "Account Created");
+        this.emailService.sendMail(
+                user.getEmail(),
+                "Welcome in our app!",
+                "Account Created");
 
         return ResponseEntity
                 .status(HttpStatus.OK)

+ 25 - 22
boat-reservation-logic/src/main/java/pl/sudra/service/EmailServiceImpl.java

@@ -1,22 +1,25 @@
-//package pl.sudra.service;
-//
-//import org.springframework.beans.factory.annotation.Autowired;
-//import org.springframework.mail.MailException;
-//import org.springframework.mail.SimpleMailMessage;
-//import org.springframework.mail.javamail.JavaMailSender;
-//import org.springframework.stereotype.Service;
-//
-//@Service
-//public class EmailServiceImpl implements EmailService {
-//    @Autowired
-//    private JavaMailSender javaMailSender;
-//
-//    public void sendMail(String receiver, String content, String subject) throws MailException {
-//        SimpleMailMessage mail = new SimpleMailMessage();
-//        mail.setFrom("EmailAuthor-SpringApplication");
-//        mail.setTo(receiver);
-//        mail.setSubject(subject);
-//        mail.setText(content);
-//        javaMailSender.send(mail);
-//    }
-//}
+package pl.sudra.service;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.mail.MailException;
+import org.springframework.mail.SimpleMailMessage;
+import org.springframework.mail.javamail.JavaMailSender;
+import org.springframework.stereotype.Service;
+
+@Service
+public class EmailServiceImpl implements EmailService {
+
+    @Autowired
+    private JavaMailSender javaMailSender;
+
+    public void sendMail(String receiver, String content, String subject) throws MailException {
+        SimpleMailMessage mail = new SimpleMailMessage();
+        mail.setFrom("EmailAuthor-SpringApplication"); // you may specify the name of the "from" field
+        mail.setTo(receiver);
+        mail.setSubject(subject);
+        mail.setText(content);
+        javaMailSender.send(mail);
+    }
+
+}
+

+ 5 - 0
boat-reservation-logic/src/main/java/pl/sudra/service/ReservationService.java

@@ -20,5 +20,10 @@ public interface ReservationService {
     void generateReservations(int n);
 
     List<Reservation> findReservations(long boat_id, Date date);
+
     Reservation findById(long id);
+
+
+    List<Reservation> findReservationsByUserId(Long user_id);
+    void updateBill();
 }

+ 66 - 4
boat-reservation-logic/src/main/java/pl/sudra/service/ReservationServiceImpl.java

@@ -1,25 +1,33 @@
 package pl.sudra.service;
 
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
+import pl.sudra.domain.Bill;
 import pl.sudra.domain.Reservation;
+import pl.sudra.repository.BillRepository;
 import pl.sudra.repository.ReservationRepository;
 
-import java.time.LocalDate;
-import java.util.Calendar;
 import java.sql.Date;
+import java.text.SimpleDateFormat;
+import java.time.LocalDate;
+import java.time.LocalTime;
+import java.time.format.DateTimeFormatter;
+import java.time.temporal.ChronoUnit;
 import java.util.List;
-import java.util.Random;
+import java.util.Objects;
 
 @Service("reservationService")
 @Transactional
 public class ReservationServiceImpl implements ReservationService {
     private final ReservationRepository reservationRepository;
+    private final BillRepository billRepository;
 
     @Autowired
-    public ReservationServiceImpl(ReservationRepository reservationRepository) {
+    public ReservationServiceImpl(ReservationRepository reservationRepository, BillRepository billRepository) {
         this.reservationRepository = reservationRepository;
+        this.billRepository = billRepository;
     }
 
     @Override
@@ -91,5 +99,59 @@ public class ReservationServiceImpl implements ReservationService {
     public Reservation findById(long id) {
         return this.reservationRepository.findById(id).get();
     }
+
+    @Override
+    public List<Reservation> findReservationsByUserId(Long user_id) {
+        return this.reservationRepository.findReservationsByUserId(user_id);
+    }
+
+    // every hour at 0 minutes
+//    @Scheduled(cron = "0 0 * * * *")
+    @Scheduled(cron = "0 * * * * *")
+    public void updateBill() {
+        java.util.Date currentDate = new java.util.Date();
+        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
+        String formattedDate = dateFormat.format(currentDate);
+        LocalTime date_now = LocalTime.now();
+        int hour_now = date_now.getHour();
+//        System.out.println("Updating reservation's Bill: ");
+//        System.out.println("Date: " + formattedDate);
+//        System.out.println("Hour: " + hour_now);
+        List<Reservation> reservations = reservationRepository.findAll();
+        reservations.forEach(reservation -> {
+//            System.out.println("Hour: " + hour_now);
+//            System.out.println("Start: " + reservation.getStartHour());
+//            System.out.println("End: " + reservation.getEndHour());
+//            System.out.println("Date: " + reservation.getDate().toString());
+//            System.out.println("Status: " + reservation.getBill().getStatus());
+
+            if (formattedDate.equals(reservation.getDate().toString()) &&
+                    hour_now == reservation.getStartHour() &&
+                    Objects.equals(reservation.getBill().getStatus(), "Confirmed")) {
+                System.out.println("Conf -> Act");
+                reservation.getBill().setStatus("Active");
+                reservationRepository.saveAndFlush(reservation);
+            } else if (hour_now == reservation.getEndHour() &&
+                    Objects.equals(reservation.getBill().getStatus(), "Active")) {
+                System.out.println("Act -> Comp");
+                reservation.getBill().setStatus("Completed");
+                reservationRepository.saveAndFlush(reservation);
+            }
+
+//            LocalDate date1 = LocalDate.parse(bill.getIssueDate().toString());
+//            LocalDate date2 = LocalDate.parse(LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")).toString());
+//
+//            System.out.println(date1.toString() + ">" + date2.toString());
+//
+//            if (ChronoUnit.DAYS.between(
+//                    LocalDate.parse(bill.getIssueDate().toString()),
+//                    LocalDate.parse(LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")).toString())) > 30
+//                    && date1.isBefore(date2)) {
+//                bill.setStatus("CANCELLED");
+//                billRepository.saveAndFlush(bill);
+//                System.out.println(bill.getId());
+//            }
+        });
+    }
 }
 

+ 1 - 0
boat-reservation-logic/src/main/java/pl/sudra/service/UserService.java

@@ -15,6 +15,7 @@ public interface UserService {
     Optional<User> findByUsername(String username);
 
     List<User> getAll();
+
     void updateUserRole(Long id, String roles);
 
     void deleteUser(Long id);

+ 2 - 2
boat-reservation-view/src/app/add-boat-component/add-boat.component.ts

@@ -1,5 +1,5 @@
 import {Component} from '@angular/core';
-import {BoatsService} from "../services/boats.service";
+import {BoatService} from "../services/boat.service";
 
 @Component({
   selector: 'app-add-boat-component',
@@ -9,7 +9,7 @@ import {BoatsService} from "../services/boats.service";
 export class AddBoatComponent {
   formData: any = {};
 
-  constructor(private boatService: BoatsService) {
+  constructor(private boatService: BoatService) {
   }
 
   addBoat() {

+ 1 - 1
boat-reservation-view/src/app/admin-panel/admin-panel.component.ts

@@ -1,5 +1,5 @@
 import {Component} from '@angular/core';
-import {BoatsService} from "../services/boats.service";
+import {BoatService} from "../services/boat.service";
 import {UserService} from "../services/user.service";
 import {User} from "../domain/user";
 

+ 5 - 2
boat-reservation-view/src/app/app.module.ts

@@ -20,6 +20,7 @@ import {NotFoundComponent} from './not-found/not-found.component';
 import {RecaptchaModule} from "ng-recaptcha";
 import { AdminPanelComponent } from './admin-panel/admin-panel.component';
 import { ManagerPanelComponent } from './manager-panel/manager-panel.component';
+import { ProfilePageComponent } from './profile-page/profile-page.component';
 
 export function setupTranslateServiceFactory(
   service: TranslateService): Function {
@@ -37,7 +38,8 @@ export function setRoutes() {
   if (roles) {
     if (roles.includes("CLIENT")) {
       routes.push(
-        {path: 'reservation', component: ReservationViewComponent}
+        {path: 'reservation', component: ReservationViewComponent},
+        {path: 'profile', component: ProfilePageComponent}
       );
     }
     if (roles.includes("MANAGER")) {
@@ -73,7 +75,8 @@ export function setRoutes() {
     AddBoatComponent,
     NotFoundComponent,
     AdminPanelComponent,
-    ManagerPanelComponent
+    ManagerPanelComponent,
+    ProfilePageComponent
   ],
   imports: [
     BrowserModule,

+ 2 - 2
boat-reservation-view/src/app/boats-component/boats-view.component.ts

@@ -1,5 +1,5 @@
 import {Component} from '@angular/core';
-import {BoatsService} from "../services/boats.service";
+import {BoatService} from "../services/boat.service";
 import {Boat} from "../domain/boat";
 
 @Component({
@@ -11,7 +11,7 @@ export class BoatsViewComponent {
 
   boats: Boat[] = [];
 
-  constructor(private boatService: BoatsService) {
+  constructor(private boatService: BoatService) {
   }
 
   async ngOnInit() {

+ 6 - 1
boat-reservation-view/src/app/login-view/login-view.component.html

@@ -29,6 +29,11 @@
   </form>
   <br>
   <p>Don't have an account?</p>
-  <input class="enabled" type="submit" value="REGISTER HERE" routerLink="/register" routerLinkActive="activebutton">
+  <input class="enabled"
+         type="submit"
+         value="REGISTER HERE"
+         routerLink="/register"
+         routerLinkActive="activebutton"
+         style="width: 210px">
   <br><br>
 </div>

+ 8 - 0
boat-reservation-view/src/app/navbar/navbar.component.html

@@ -38,6 +38,14 @@
         RESERVATION
       </a>
     </div>
+    <div class="navbar-button"
+         routerLink="/profile"
+         routerLinkActive="activebutton"
+         *ngIf="isManager">
+      <a>
+        PROFILE PAGE
+      </a>
+    </div>
     <div class="navbar-button"
          routerLink="/login"
          routerLinkActive="activebutton"

+ 45 - 0
boat-reservation-view/src/app/profile-page/profile-page.component.css

@@ -0,0 +1,45 @@
+table {
+  border-collapse: collapse;
+  width: 100%;
+  background-color: white;
+}
+
+th, td {
+  border: 1px solid black;
+  padding: 8px;
+}
+
+div {
+  text-align: center;
+  font-family: Courier New, monospace;
+}
+
+.action-cell {
+  display: flex;
+  justify-content: space-evenly;
+}
+
+.button {
+  padding: 6px 10px;
+  text-decoration: none;
+  border: none;
+  border-radius: 4px;
+  cursor: pointer;
+  font-weight: bold;
+  transition: background-color 0.3s ease;
+}
+
+.button.change-role {
+  background-color: #4CAF50;
+  color: white;
+}
+
+.button.delete {
+  background-color: #f44336;
+  color: white;
+}
+
+.button:hover {
+  background-color: #555;
+}
+

+ 74 - 0
boat-reservation-view/src/app/profile-page/profile-page.component.html

@@ -0,0 +1,74 @@
+<div>
+  <br>
+  <table>
+    <tr>
+      <th>ID</th>
+      <th>Username</th>
+      <th>Email</th>
+      <th>Roles</th>
+      <th>Actions</th>
+    </tr>
+    <tr>
+      <td>{{user_info.id}}</td>
+      <td>{{user_info.username}}</td>
+      <td>{{user_info.email}}</td>
+      <td>{{user_info.roles}}</td>
+      <td>
+        <button class="button change-role"
+                (click)="sendEmail()"
+                style="margin-left:2px; margin-right: 2px">Send Billing on Email
+        </button>
+        <button class="button change-role"
+                (click)="deleteAccount()"
+                style="margin-left:2px; margin-right: 2px">Delete User
+        </button>
+      </td>
+    </tr>
+  </table>
+
+  <br>
+  <div><b>Reservations</b></div>
+  <br>
+
+  <table>
+    <tr>
+      <th>ID</th>
+      <th>Boat</th>
+      <th>Date</th>
+      <th>From</th>
+      <th>To</th>
+      <th>Cost</th>
+      <th>Status</th>
+      <th>Actions</th>
+    </tr>
+
+    <tr *ngFor="let res of reservations_info">
+      <td>{{res.id}}</td>
+      <td *ngIf="isANumber(res.boatId)">⏳⌛</td>
+      <td *ngIf="!isANumber(res.boatId)">{{res.boatId}}</td>
+      <td>{{res.date}}</td>
+      <td>{{res.startHour}}:00</td>
+      <td>{{res.endHour}}:00</td>
+      <td>{{res.bill.totalCost}}</td>
+      <td>{{res.bill.status}}</td>
+      <td>
+        <button
+          *ngIf="res.bill.status === 'Pending'"
+          class="button change-role"
+          (click)="confirmReservation(res.bill.id)"
+          style="margin-left:2px; margin-right: 2px">
+          Confirm
+        </button>
+        <button
+          *ngIf="res.bill.status !== 'Cancelled' && res.bill.status !== 'Completed' && res.bill.status !== 'Active'"
+          class="button change-role"
+          (click)="cancelReservation(res.bill.id)"
+          style="margin-left:2px; margin-right: 2px">
+          Cancel
+        </button>
+      </td>
+    </tr>
+  </table>
+  <br>
+
+</div>

+ 75 - 0
boat-reservation-view/src/app/profile-page/profile-page.component.ts

@@ -0,0 +1,75 @@
+import {Component} from '@angular/core';
+import {UserService} from "../services/user.service";
+import {ReservationService} from "../services/reservation.service";
+import {BoatService} from "../services/boat.service";
+
+@Component({
+  selector: 'app-profile-page',
+  templateUrl: './profile-page.component.html',
+  styleUrls: ['./profile-page.component.css']
+})
+export class ProfilePageComponent {
+  user_info: any;
+  reservations_info: any[] = [];
+  bills_info: any[] = [];
+
+  // statusOrder = ['Pending', 'Confirmed', 'Active', 'Completed', 'Cancelled'];
+
+  compareFn = (a: any, b: any): number => {
+    // Sort by date
+    const dateComparison = a.date.localeCompare(b.date);
+    if (dateComparison !== 0) {
+      return dateComparison;
+    }
+
+    // Sort by hour
+    return a.startHour - b.startHour;
+  };
+
+  constructor(private userService: UserService,
+              private reservationService: ReservationService,
+              private boatService: BoatService) {
+    this.userService.getUser(sessionStorage.getItem("username")!).subscribe(
+      user => {
+        this.user_info = user
+        this.reservationService.findReservationsByUserId(user.id!).subscribe(
+          reservations => {
+            this.reservations_info = reservations.map(r => {
+              r.date = new Date(r.date).toISOString().split("T")[0]
+              return r;
+            });
+            this.boatService.getBoats().subscribe(
+              boats => {
+                console.log(boats)
+                this.reservations_info.map(r => {
+                  r.boatId = boats.find(b => b.id == r.boatId)!.name
+                })
+                this.reservations_info.sort(this.compareFn)
+              }
+            )
+            console.log(reservations[0])
+          }
+        )
+      })
+  }
+
+  isANumber(value: any): boolean {
+    return typeof value === 'number'
+  }
+
+  deleteAccount() {
+    this.userService.deleteUser(this.user_info.id)
+  }
+
+  sendEmail() {
+    console.log("email")
+  }
+
+  confirmReservation(id: number) {
+    console.log(id)
+  }
+
+  cancelReservation(id: number) {
+    console.log(id)
+  }
+}

+ 2 - 2
boat-reservation-view/src/app/register-view/register-view.component.ts

@@ -1,5 +1,5 @@
 import {Component} from '@angular/core';
-import {BoatsService} from "../services/boats.service";
+import {BoatService} from "../services/boat.service";
 import {AuthService} from "../services/auth.service";
 import {FormBuilder, FormControl, FormGroup, Validators} from "@angular/forms";
 import {delay} from "rxjs";
@@ -27,7 +27,7 @@ export class RegisterViewComponent {
 
   resolved(captchaResponse: string) {
     console.log(`Resolved captcha with response: ${captchaResponse}`);
-    this.isCaptchaResolved = true;
+    this.isCaptchaResolved = captchaResponse !== null;
   }
 
   registerUser() {

+ 2 - 2
boat-reservation-view/src/app/reservation-view/reservation-view.component.ts

@@ -1,5 +1,5 @@
 import {Component} from '@angular/core';
-import {BoatsService} from "../services/boats.service";
+import {BoatService} from "../services/boat.service";
 import {ReservationService} from "../services/reservation.service";
 
 @Component({
@@ -21,7 +21,7 @@ export class ReservationViewComponent {
   reservedHours: any[] = [];
 
 
-  constructor(private boatService: BoatsService,
+  constructor(private boatService: BoatService,
               private reservationService: ReservationService) {
     const today = new Date();
     this.date = today.toISOString().split('T')[0];

+ 12 - 1
boat-reservation-view/src/app/services/boats.service.ts → boat-reservation-view/src/app/services/boat.service.ts

@@ -2,11 +2,12 @@ import {Injectable} from '@angular/core';
 import {Boat} from "../domain/boat";
 import {HttpClient, HttpHeaders} from "@angular/common/http";
 import {Observable} from "rxjs";
+import {User} from "../domain/user";
 
 @Injectable({
   providedIn: 'root'
 })
-export class BoatsService {
+export class BoatService {
 
   constructor(private http: HttpClient) {
   }
@@ -33,6 +34,16 @@ export class BoatsService {
       });
   }
 
+  getBoatName(id: number): Observable<string> {
+    const url = 'http://localhost:2137/getBoatNameById?id=' + id;
+
+    const headers = new HttpHeaders()
+      .set('Content-Type', 'application/json')
+      .set('Authorization', sessionStorage.getItem("jwtToken")!);
+
+    return this.http.get<string>(url, {headers})
+  }
+
   clearBoat() {
 
   }

+ 10 - 0
boat-reservation-view/src/app/services/reservation.service.ts

@@ -27,6 +27,16 @@ export class ReservationService {
     return this.http.get<Reservation[]>(url, {headers});
   }
 
+  findReservationsByUserId(user_id: number): Observable<Reservation[]> {
+    const url = 'http://localhost:2137/findReservationsOfUserId?user_id=' + user_id;
+
+    const headers = new HttpHeaders()
+      .set('Content-Type', 'application/json')
+      .set('Authorization', sessionStorage.getItem("jwtToken")!);
+
+    return this.http.get<Reservation[]>(url, {headers});
+  }
+
   createReservation(reservation_info: object): any {
     const url = 'http://localhost:2137/createReservation';
 

+ 10 - 0
boat-reservation-view/src/app/services/user.service.ts

@@ -40,4 +40,14 @@ export class UserService {
 
     this.http.delete(url, {headers}).subscribe()
   }
+
+  getUser(username: string) {
+    const url = 'http://localhost:2137/getUser?username=' + username;
+
+    const headers = new HttpHeaders()
+      .set('Content-Type', 'application/json')
+      .set('Authorization', sessionStorage.getItem("jwtToken")!);
+
+    return this.http.get<User>(url, {headers})
+  }
 }