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

boat listing and creation form,
reservation in progress, deleted *.spec.ts files

mateuszsudra пре 2 година
родитељ
комит
5400955655
52 измењених фајлова са 1096 додато и 361 уклоњено
  1. 2 1
      .gitignore
  2. 18 0
      boat-reservation-logic/src/main/java/pl/sudra/configuration/CorsConfig.java
  3. 102 0
      boat-reservation-logic/src/main/java/pl/sudra/configuration/SpringConfiguration.java
  4. 3 1
      boat-reservation-logic/src/main/java/pl/sudra/configuration/SpringInit.java
  5. 25 34
      boat-reservation-logic/src/main/java/pl/sudra/controller/BoatController.java
  6. 30 0
      boat-reservation-logic/src/main/java/pl/sudra/controller/ReservationController.java
  7. 27 1
      boat-reservation-logic/src/main/java/pl/sudra/domain/Boat.java
  8. 70 2
      boat-reservation-logic/src/main/java/pl/sudra/domain/Reservation.java
  9. 1 1
      boat-reservation-logic/src/main/java/pl/sudra/repository/ReservationRepository.java
  10. 5 5
      boat-reservation-logic/src/main/java/pl/sudra/service/BoatService.java
  11. 31 32
      boat-reservation-logic/src/main/java/pl/sudra/service/BoatServiceImpl.java
  12. 20 0
      boat-reservation-logic/src/main/java/pl/sudra/service/ReservationService.java
  13. 78 0
      boat-reservation-logic/src/main/java/pl/sudra/service/ReservationServiceImpl.java
  14. 0 0
      boat-reservation-view/src/app/add-boat-component/add-boat-component.component.css
  15. 0 3
      boat-reservation-view/src/app/add-boat-component/add-boat-component.component.html
  16. 0 21
      boat-reservation-view/src/app/add-boat-component/add-boat-component.component.spec.ts
  17. 0 10
      boat-reservation-view/src/app/add-boat-component/add-boat-component.component.ts
  18. 32 0
      boat-reservation-view/src/app/add-boat-component/add-boat.component.css
  19. 22 0
      boat-reservation-view/src/app/add-boat-component/add-boat.component.html
  20. 25 0
      boat-reservation-view/src/app/add-boat-component/add-boat.component.ts
  21. 2 1
      boat-reservation-view/src/app/app.component.css
  22. 0 27
      boat-reservation-view/src/app/app.component.html
  23. 0 27
      boat-reservation-view/src/app/app.component.spec.ts
  24. 12 8
      boat-reservation-view/src/app/app.module.ts
  25. 107 0
      boat-reservation-view/src/app/boats-component/boats-view.component.css
  26. 31 0
      boat-reservation-view/src/app/boats-component/boats-view.component.html
  27. 31 0
      boat-reservation-view/src/app/boats-component/boats-view.component.ts
  28. 38 0
      boat-reservation-view/src/app/boats-service/boats.service.ts
  29. 0 0
      boat-reservation-view/src/app/boats-view/boats-view.component.css
  30. 0 4
      boat-reservation-view/src/app/boats-view/boats-view.component.html
  31. 0 21
      boat-reservation-view/src/app/boats-view/boats-view.component.spec.ts
  32. 0 11
      boat-reservation-view/src/app/boats-view/boats-view.component.ts
  33. 13 0
      boat-reservation-view/src/app/domain/boat.ts
  34. 17 0
      boat-reservation-view/src/app/domain/reservation.ts
  35. 0 21
      boat-reservation-view/src/app/home-view/home-view.component.spec.ts
  36. 0 21
      boat-reservation-view/src/app/login-view/login-view.component.spec.ts
  37. 0 21
      boat-reservation-view/src/app/map-view/map-view.component.spec.ts
  38. 8 0
      boat-reservation-view/src/app/navbar/navbar.component.css
  39. 0 21
      boat-reservation-view/src/app/navbar/navbar.component.spec.ts
  40. 0 21
      boat-reservation-view/src/app/page-not-found/page-not-found.component.spec.ts
  41. 32 0
      boat-reservation-view/src/app/register-view/register-view.component.css
  42. 22 1
      boat-reservation-view/src/app/register-view/register-view.component.html
  43. 0 21
      boat-reservation-view/src/app/register-view/register-view.component.spec.ts
  44. 15 1
      boat-reservation-view/src/app/register-view/register-view.component.ts
  45. 40 0
      boat-reservation-view/src/app/reservation-service/reservation.service.ts
  46. 101 0
      boat-reservation-view/src/app/reservation-view/reservation-view.component.css
  47. 77 1
      boat-reservation-view/src/app/reservation-view/reservation-view.component.html
  48. 0 21
      boat-reservation-view/src/app/reservation-view/reservation-view.component.spec.ts
  49. 48 1
      boat-reservation-view/src/app/reservation-view/reservation-view.component.ts
  50. BIN
      boat-reservation-view/src/assets/leisure.png
  51. 5 0
      boat-reservation-view/src/styles.css
  52. 6 0
      package-lock.json

+ 2 - 1
.gitignore

@@ -1,3 +1,4 @@
 /out/
 /.idea/
-*/.vscode/
+*/.vscode/
+*.spec.ts

+ 18 - 0
boat-reservation-logic/src/main/java/pl/sudra/configuration/CorsConfig.java

@@ -0,0 +1,18 @@
+package pl.sudra.configuration;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.config.annotation.CorsRegistry;
+import org.springframework.web.servlet.config.annotation.EnableWebMvc;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+
+@Configuration
+@EnableWebMvc
+public class CorsConfig implements WebMvcConfigurer {
+    @Override
+    public void addCorsMappings(CorsRegistry registry) {
+        registry.addMapping("/**")
+                .allowedOrigins("http://localhost:1410") // Adjust with your Angular frontend URL
+                .allowedMethods("GET", "POST", "PUT", "DELETE")
+                .allowedHeaders("*");
+    }
+}

+ 102 - 0
boat-reservation-logic/src/main/java/pl/sudra/configuration/SpringConfiguration.java

@@ -0,0 +1,102 @@
+package pl.sudra.configuration;
+
+import org.springframework.context.MessageSource;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.support.ReloadableResourceBundleMessageSource;
+import org.springframework.scheduling.annotation.EnableScheduling;
+import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
+import org.springframework.web.servlet.LocaleResolver;
+import org.springframework.web.servlet.config.annotation.EnableWebMvc;
+import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
+import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+import org.springframework.web.servlet.i18n.CookieLocaleResolver;
+import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;
+import org.springframework.web.servlet.view.InternalResourceViewResolver;
+
+import java.time.Duration;
+import java.util.Locale;
+
+
+@Configuration
+@EnableWebMvc
+@EnableScheduling
+@ComponentScan("pl.sudra")
+//@Import({SecurityConfiguration.class})
+public class SpringConfiguration implements WebMvcConfigurer {
+    @Bean
+    public InternalResourceViewResolver viewResolver() {
+        InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
+        viewResolver.setPrefix("/");
+        viewResolver.setSuffix(".jsp");
+        return viewResolver;
+    }
+
+    @Bean
+    public MessageSource messageSource() {
+        ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
+        messageSource.setBasename("/resources/i18n/messages");
+        messageSource.setDefaultEncoding("UTF-8");
+        return messageSource;
+    }
+
+    @Bean
+    public LocaleResolver localeResolver() {
+        CookieLocaleResolver resolver = new CookieLocaleResolver("myLocaleCookie");
+        resolver.setDefaultLocale(new Locale("en"));
+        resolver.setCookieMaxAge(Duration.ofSeconds(4800));
+        return resolver;
+    }
+
+    @Override
+    public void addInterceptors(InterceptorRegistry registry) {
+        LocaleChangeInterceptor interceptor = new LocaleChangeInterceptor();
+        interceptor.setParamName("lang");
+        registry.addInterceptor(interceptor);
+    }
+
+    @Override
+    public void addResourceHandlers(ResourceHandlerRegistry registry) {
+        registry
+                .addResourceHandler("/resources/**")
+                .addResourceLocations("/resources/");
+    }
+
+    @Bean
+    @Override
+    public LocalValidatorFactoryBean getValidator() {
+        LocalValidatorFactoryBean bean = new LocalValidatorFactoryBean();
+        bean.setValidationMessageSource(messageSource());
+        return bean;
+    }
+
+//    @Resource(name = "addressService")
+//    private AddressService addressService;
+//
+//    @Resource(name = "appUserRoleService")
+//    private AppUserRoleService appUserRoleService;
+//
+//    @Override
+//    public void addFormatters(FormatterRegistry formatterRegistry) {
+//        formatterRegistry.addConverter(getMyAddressConverter());
+//        formatterRegistry.addConverter(getMyUserRoleConverter());
+//        formatterRegistry.addConverter(getMyUserRoleListConverter());
+//    }
+
+//    @Bean
+//    public AddressConverter getMyAddressConverter() {
+//        return new AddressConverter(addressService);
+//    }
+//
+//    @Bean
+//    public AppUserRoleConverter getMyUserRoleConverter() {
+//        return new AppUserRoleConverter(appUserRoleService);
+//    }
+//
+//    @Bean
+//    public AppUserRoleListConverter getMyUserRoleListConverter() {
+//        return new AppUserRoleListConverter(appUserRoleService);
+//    }
+}

+ 3 - 1
boat-reservation-logic/src/main/java/pl/sudra/configuration/SpringInit.java

@@ -11,7 +11,9 @@ public class SpringInit extends AbstractAnnotationConfigDispatcherServletInitial
 
     protected Class<?>[] getRootConfigClasses() {
         return new Class[]{
-                HibernatePersistenceConfiguration.class
+                SpringConfiguration.class,
+                HibernatePersistenceConfiguration.class,
+                CorsConfig.class
         };
     }
 

+ 25 - 34
boat-reservation-logic/src/main/java/pl/sudra/controller/BoatController.java

@@ -1,53 +1,44 @@
 package pl.sudra.controller;
 
-import jakarta.servlet.http.HttpServletRequest;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Controller;
-import org.springframework.ui.Model;
-import org.springframework.validation.BindingResult;
-import org.springframework.web.bind.ServletRequestUtils;
+import org.springframework.http.MediaType;
 import org.springframework.web.bind.annotation.*;
 import pl.sudra.domain.Boat;
 import pl.sudra.service.BoatService;
 
-@Controller
-@SessionAttributes
+import java.util.List;
+
+@RestController
+@CrossOrigin(origins = "http://localhost:1410")
 public class BoatController {
 
-    private BoatService boatService;
+    private final BoatService boatService;
 
     @Autowired
     public BoatController(BoatService boatService) {
         this.boatService = boatService;
     }
 
-//    @RequestMapping("/getAllBoats")
-//    public String listAddresses(Model model, HttpServletRequest request) {
-//
-//        int addressId = ServletRequestUtils.getIntParameter(request, "addressId" , -1);
-//
-//        if (addressId > 0)
-//            model.addAttribute("address", addressService.getAddress(addressId));
-//        else
-//            model.addAttribute("address", new Address());
-//
-//        model.addAttribute("addressList", addressService.listAddress());
-//
-//        return "address";
-//    }
+    @RequestMapping(
+            value = "/getAllBoats",
+            method = RequestMethod.GET,
+            produces = MediaType.APPLICATION_JSON_VALUE)
+    public List<Boat> listAddresses() {
+        System.out.println("Getting Boats");
+        return boatService.getBoats();
+    }
 
-    @RequestMapping(value = "/addBoat", method = RequestMethod.POST)
-    public void addBoat(@ModelAttribute("boat") Boat boat) {
-        if (boat.getId()==0)
-            boatService.addBoat(boat);
-        else
-            boatService.editBoat(boat);
+//    test request
+    @RequestMapping(value = "/hello", method = RequestMethod.GET)
+    public String sayHello() {
+        System.out.println("Greetings!");
+        return "Hello";
     }
 
-//    @RequestMapping("/deleteAddress/{addressId}")
-//    public String deleteAddress(@PathVariable("addressId") Integer addressId) {
-//        addressService.removeAddress(addressId);
-//
-//        return "redirect:/addresses";
-//    }
+    @RequestMapping(value = "/addBoat", method = RequestMethod.POST)
+    public boolean addBoat(@RequestBody Boat boat) {
+        System.out.println(boat.toString());
+        boatService.addBoat(boat);
+        return true;
+    }
 }

+ 30 - 0
boat-reservation-logic/src/main/java/pl/sudra/controller/ReservationController.java

@@ -1,4 +1,34 @@
 package pl.sudra.controller;
 
+import org.springframework.http.MediaType;
+import org.springframework.web.bind.annotation.*;
+import pl.sudra.domain.Reservation;
+import pl.sudra.service.ReservationService;
+
+@RestController
+@CrossOrigin(origins = "http://localhost:1410")
 public class ReservationController {
+    private final ReservationService reservationService;
+
+    public ReservationController(ReservationService reservationService) {
+        this.reservationService = reservationService;
+    }
+
+    @RequestMapping(
+            value = "/generateReservations",
+            method = RequestMethod.GET,
+            produces = MediaType.APPLICATION_JSON_VALUE)
+    public void generateReservations(@RequestParam("n") int n) {
+        System.out.println("Generation of reservations");
+        this.reservationService.generateReservations(n);
+    }
+
+    @RequestMapping(
+            value = "/createReservation",
+            method = RequestMethod.POST,
+            produces = MediaType.APPLICATION_JSON_VALUE)
+    public void createReservation(@RequestBody Reservation reservation) {
+        System.out.println("Creating reservation");
+        this.reservationService.addReservation(reservation);
+    }
 }

+ 27 - 1
boat-reservation-logic/src/main/java/pl/sudra/domain/Boat.java

@@ -1,17 +1,27 @@
 package pl.sudra.domain;
 
 import jakarta.persistence.Entity;
+import jakarta.persistence.GeneratedValue;
+import jakarta.persistence.GenerationType;
 import jakarta.persistence.Id;
-import jakarta.persistence.criteria.CriteriaBuilder;
+import jakarta.validation.constraints.NotNull;
 
 @Entity
 public class Boat {
     @Id
+    @GeneratedValue(strategy = GenerationType.AUTO)
     private Long id;
+    @NotNull
     private String name;
+    @NotNull
     private Integer capacity;
+    @NotNull
     private Float cost;
 
+    public Boat() {
+
+    }
+
     public Long getId() {
         return id;
     }
@@ -43,4 +53,20 @@ public class Boat {
     public void setCost(Float cost) {
         this.cost = cost;
     }
+
+    @Override
+    public String toString() {
+        return "Boat{" +
+                "name='" + name + '\'' +
+                ", capacity=" + capacity +
+                ", cost=" + cost +
+                '}';
+    }
+
+    public Boat(Long id, String name, Integer capacity, Float cost) {
+        this.id = id;
+        this.name = name;
+        this.capacity = capacity;
+        this.cost = cost;
+    }
 }

+ 70 - 2
boat-reservation-logic/src/main/java/pl/sudra/domain/Reservation.java

@@ -1,17 +1,85 @@
 package pl.sudra.domain;
 
 import jakarta.persistence.Entity;
+import jakarta.persistence.GeneratedValue;
+import jakarta.persistence.GenerationType;
 import jakarta.persistence.Id;
+import jakarta.validation.constraints.NotNull;
 
 import java.util.Date;
 
 @Entity
 public class Reservation {
     @Id
+    @GeneratedValue(strategy = GenerationType.AUTO)
     private Long id;
+    @NotNull
     private Long user_id;
+    @NotNull
     private Long boat_id;
-    private Date from_date;
-    private Date to_date;
+    @NotNull
+    private Date date;
+    @NotNull
+    private byte start_hour;
+    @NotNull
+    private byte end_hour;
 
+    public Reservation(Long user_id, Long boat_id, Date date, byte start_hour, byte end_hour) {
+        this.user_id = user_id;
+        this.boat_id = boat_id;
+        this.date = date;
+        this.start_hour = start_hour;
+        this.end_hour = end_hour;
+    }
+
+    public Reservation() {
+    }
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public Long getUser_id() {
+        return user_id;
+    }
+
+    public void setUser_id(Long user_id) {
+        this.user_id = user_id;
+    }
+
+    public Long getBoat_id() {
+        return boat_id;
+    }
+
+    public void setBoat_id(Long boat_id) {
+        this.boat_id = boat_id;
+    }
+
+    public Date getDate() {
+        return date;
+    }
+
+    public void setDate(Date date) {
+        this.date = date;
+    }
+
+    public byte getStart_hour() {
+        return start_hour;
+    }
+
+    public void setStart_hour(byte start_hour) {
+        this.start_hour = start_hour;
+    }
+
+    public byte getEnd_hour() {
+        return end_hour;
+    }
+
+    public void setEnd_hour(byte end_hour) {
+        this.end_hour = end_hour;
+    }
 }

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

@@ -8,5 +8,5 @@ import pl.sudra.domain.Reservation;
 @Transactional
 @Repository
 public interface ReservationRepository extends JpaRepository<Reservation, Long> {
-    Reservation findBoatById(long id);
+    Reservation findReservationById(long id);
 }

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

@@ -6,10 +6,10 @@ import java.util.List;
 
 public interface BoatService {
 
-	public void addBoat(Boat boat);
-	public void editBoat(Boat boat);
-	public List<Boat> listBoats();
-	public void removeBoat(long id);
-	public Boat getBoat(long id);
+	void addBoat(Boat boat);
+	void editBoat(Boat boat);
+	List<Boat> getBoats();
+	void removeBoat(long id);
+	Boat getBoat(long id);
 	
 }

+ 31 - 32
boat-reservation-logic/src/main/java/pl/sudra/service/BoatServiceImpl.java

@@ -11,37 +11,36 @@ import java.util.List;
 @Service("boatService")
 @Transactional
 public class BoatServiceImpl implements BoatService {
-
-	private BoatRepository boatRepository;
-
-	@Autowired
-	public BoatServiceImpl(BoatRepository boatRepository) {
-		this.boatRepository = boatRepository;
-	}
-	
-	@Transactional
-	public void addBoat(Boat boat) {
-		boatRepository.save(boat);
-	}
-	
-	@Transactional
-	public void editBoat(Boat boat) {
-		boatRepository.save(boat);
-	}
-
-	@Transactional
-	public List<Boat> listBoats() {
-		return boatRepository.findAll();
-	}
-
-	@Transactional
-	public void removeBoat(long id) {
-		boatRepository.deleteById(id);
-	}
-	
-	@Transactional
-	public Boat getBoat(long id) {
-		return boatRepository.findBoatById(id);
-	}
+    private final BoatRepository boatRepository;
+
+    @Autowired
+    public BoatServiceImpl(BoatRepository boatRepository) {
+        this.boatRepository = boatRepository;
+    }
+
+    @Transactional
+    public void addBoat(Boat boat) {
+        boatRepository.save(boat);
+    }
+
+    @Transactional
+    public void editBoat(Boat boat) {
+        boatRepository.save(boat);
+    }
+
+    @Transactional
+    public List<Boat> getBoats() {
+        return boatRepository.findAll();
+    }
+
+    @Transactional
+    public void removeBoat(long id) {
+        boatRepository.deleteById(id);
+    }
+
+    @Transactional
+    public Boat getBoat(long id) {
+        return boatRepository.findBoatById(id);
+    }
 }
 

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

@@ -0,0 +1,20 @@
+package pl.sudra.service;
+
+import pl.sudra.domain.Reservation;
+
+import java.util.List;
+
+public interface ReservationService {
+
+    void addReservation(Reservation reservation);
+
+    void editReservation(Reservation reservation);
+
+    List<Reservation> getReservations();
+
+    void removeReservation(long id);
+
+    Reservation getReservation(long id);
+
+    void generateReservations(int n);
+}

+ 78 - 0
boat-reservation-logic/src/main/java/pl/sudra/service/ReservationServiceImpl.java

@@ -0,0 +1,78 @@
+package pl.sudra.service;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import pl.sudra.domain.Reservation;
+import pl.sudra.repository.ReservationRepository;
+
+import java.time.ZoneId;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.List;
+import java.util.Random;
+
+@Service("reservationService")
+@Transactional
+public class ReservationServiceImpl implements ReservationService {
+    private final ReservationRepository reservationRepository;
+
+    @Autowired
+    public ReservationServiceImpl(ReservationRepository reservationRepository) {
+        this.reservationRepository = reservationRepository;
+    }
+
+    @Override
+    public void addReservation(Reservation reservation) {
+        this.reservationRepository.save(reservation);
+    }
+
+    @Override
+    public void editReservation(Reservation reservation) {
+        this.reservationRepository.save(reservation);
+    }
+
+    @Override
+    public List<Reservation> getReservations() {
+        return this.reservationRepository.findAll();
+    }
+
+    @Override
+    public void removeReservation(long id) {
+        this.reservationRepository.deleteById(id);
+    }
+
+    @Override
+    public Reservation getReservation(long id) {
+        return this.reservationRepository.findReservationById(id);
+    }
+
+    @Override
+    public void generateReservations(int n) {
+        Date today = new Date();
+
+        System.out.println("n: " + n);
+
+        Random random = new Random();
+
+        Calendar calendar = Calendar.getInstance();
+
+        for (int i = 0; i < n; i++) {
+            byte start_hour = (byte) (random.nextInt(23 - 7) + 7);
+            byte end_hour = (byte) (random.nextInt(24 - start_hour + 1) + start_hour + 1);
+
+            calendar.setTime(today);
+            calendar.add(Calendar.DAY_OF_YEAR, -1 + i);
+
+            this.reservationRepository.save(
+                    new Reservation(
+                            (long) i,
+                            (long) (i % 2),
+                            calendar.getTime(),
+                            start_hour, end_hour
+                    )
+            );
+        }
+    }
+}
+

+ 0 - 0
boat-reservation-view/src/app/add-boat-component/add-boat-component.component.css


+ 0 - 3
boat-reservation-view/src/app/add-boat-component/add-boat-component.component.html

@@ -1,3 +0,0 @@
-<form>
-  
-</form>

+ 0 - 21
boat-reservation-view/src/app/add-boat-component/add-boat-component.component.spec.ts

@@ -1,21 +0,0 @@
-import { ComponentFixture, TestBed } from '@angular/core/testing';
-
-import { AddBoatComponentComponent } from './add-boat-component.component';
-
-describe('AddBoatComponentComponent', () => {
-  let component: AddBoatComponentComponent;
-  let fixture: ComponentFixture<AddBoatComponentComponent>;
-
-  beforeEach(() => {
-    TestBed.configureTestingModule({
-      declarations: [AddBoatComponentComponent]
-    });
-    fixture = TestBed.createComponent(AddBoatComponentComponent);
-    component = fixture.componentInstance;
-    fixture.detectChanges();
-  });
-
-  it('should create', () => {
-    expect(component).toBeTruthy();
-  });
-});

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

@@ -1,10 +0,0 @@
-import { Component } from '@angular/core';
-
-@Component({
-  selector: 'app-add-boat-component',
-  templateUrl: './add-boat-component.component.html',
-  styleUrls: ['./add-boat-component.component.css']
-})
-export class AddBoatComponentComponent {
-
-}

+ 32 - 0
boat-reservation-view/src/app/add-boat-component/add-boat.component.css

@@ -0,0 +1,32 @@
+form {
+  width: 300px;
+  margin: 0 auto;
+}
+
+label {
+  display: block;
+  margin-bottom: 8px;
+}
+
+input[type="text"],
+input[type="number"],
+textarea {
+  width: 100%;
+  padding: 8px;
+  margin-bottom: 16px;
+  border: 1px solid #ccc;
+  border-radius: 4px;
+}
+
+input[type="submit"] {
+  background-color: #4caf50;
+  color: #fff;
+  padding: 10px 16px;
+  border: none;
+  border-radius: 4px;
+  cursor: pointer;
+}
+
+input[type="submit"]:hover {
+  background-color: #45a049;
+}

+ 22 - 0
boat-reservation-view/src/app/add-boat-component/add-boat.component.html

@@ -0,0 +1,22 @@
+<div style="text-align: center;">
+  <h2>REGISTER NEW BOAT</h2>
+</div>
+<form (submit)="addBoat()" #myForm="ngForm">
+  <label for="name">Name:</label>
+  <input type="text"
+         id="name"
+         name="name" [(ngModel)]="formData.name" required>
+
+  <label for="capacity">Capacity:</label>
+  <input type="number"
+         id="capacity"
+         name="capacity" [(ngModel)]="formData.capacity" required>
+
+  <label for="cost">Cost:</label>
+  <input type="number"
+         id="cost"
+         name="cost" [(ngModel)]="formData.cost" required>
+
+  <input type="submit" value="Submit">
+</form>
+

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

@@ -0,0 +1,25 @@
+import {Component} from '@angular/core';
+import {BoatsService} from "../boats-service/boats.service";
+
+@Component({
+  selector: 'app-add-boat-component',
+  templateUrl: './add-boat.component.html',
+  styleUrls: ['./add-boat.component.css']
+})
+export class AddBoatComponent {
+  formData: any = {};
+
+  constructor(private boatService: BoatsService) {
+  }
+
+  addBoat() {
+    let boat_info  = {
+      "name": this.formData.name,
+      "capacity": this.formData.capacity,
+      "cost": this.formData.cost,
+    }
+
+    this.boatService.addBoat(boat_info)
+  }
+
+}

+ 2 - 1
boat-reservation-view/src/app/app.component.css

@@ -36,11 +36,12 @@ body {
 }
 
 .main {
+  overflow: auto;
   background-color: darksalmon;
   margin-left: 15%;
   margin-right: 15%;
   margin-top: 4em;
-  height: calc(100% - 4em);
+  /*height: calc(100% - 4em);*/
   /*position: absolute;*/
   box-shadow: -5px 0 20px rgba(0, 0, 0, 0.4), 5px 0 20px rgba(0, 0, 0, 0.4);
 

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

@@ -4,34 +4,7 @@
 </div>
 <div class="background">
   <div class="main">
-<!--    <nav>-->
-<!--      <a class="button"-->
-<!--         routerLink="/"-->
-<!--         routerLinkActive="activebutton"-->
-<!--         i18n="button_home_page">-->
-<!--        Home Page-->
-<!--      </a> |-->
-<!--      <a class="button"-->
-<!--         routerLink="/boats"-->
-<!--         routerLinkActive="activebutton"-->
-<!--         i18n="button_see_boats">-->
-<!--        See our boats-->
-<!--      </a>-->
-<!--    </nav>-->
-
-    <h4 i18n="greeting">Welcome on our website!</h4>
-
-    <br/><br/><br/>
-
     <router-outlet></router-outlet>
-
-    <!--<ul>-->
-    <!--  <li *ngFor="let locale of localesList">-->
-    <!--    <a href="/{{locale.code}}/">-->
-    <!--      {{locale.label}}-->
-    <!--    </a>-->
-    <!--  </li>-->
-    <!--</ul>-->
   </div>
 </div>
 </body>

+ 0 - 27
boat-reservation-view/src/app/app.component.spec.ts

@@ -1,27 +0,0 @@
-import { TestBed } from '@angular/core/testing';
-import { AppComponent } from './app.component';
-
-describe('AppComponent', () => {
-  beforeEach(() => TestBed.configureTestingModule({
-    declarations: [AppComponent]
-  }));
-
-  it('should create the app', () => {
-    const fixture = TestBed.createComponent(AppComponent);
-    const app = fixture.componentInstance;
-    expect(app).toBeTruthy();
-  });
-
-  it(`should have as title 'boat-reservation-view'`, () => {
-    const fixture = TestBed.createComponent(AppComponent);
-    const app = fixture.componentInstance;
-    expect(app.title).toEqual('boat-reservation-view');
-  });
-
-  it('should render title', () => {
-    const fixture = TestBed.createComponent(AppComponent);
-    fixture.detectChanges();
-    const compiled = fixture.nativeElement as HTMLElement;
-    expect(compiled.querySelector('.content span')?.textContent).toContain('boat-reservation-view app is running!');
-  });
-});

+ 12 - 8
boat-reservation-view/src/app/app.module.ts

@@ -3,18 +3,19 @@ import {BrowserModule} from '@angular/platform-browser';
 
 import {RouterModule} from '@angular/router';
 import {AppComponent} from "./app.component";
-import {BoatsViewComponent} from "./boats-view/boats-view.component";
+import {BoatsViewComponent} from "./boats-component/boats-view.component";
 import {PageNotFoundComponent} from './page-not-found/page-not-found.component';
 import {HomeViewComponent} from './home-view/home-view.component';
 import {TranslatePipe} from './translate/translate.pipe';
 import {TranslateService} from "./translate/translate.service";
 import {HttpClientModule} from "@angular/common/http";
-import { NavbarComponent } from './navbar/navbar.component';
-import { LoginViewComponent } from './login-view/login-view.component';
-import { RegisterViewComponent } from './register-view/register-view.component';
-import { ReservationViewComponent } from './reservation-view/reservation-view.component';
-import { MapViewComponent } from './map-view/map-view.component';
-import { AddBoatComponentComponent } from './add-boat-component/add-boat-component.component';
+import {NavbarComponent} from './navbar/navbar.component';
+import {LoginViewComponent} from './login-view/login-view.component';
+import {RegisterViewComponent} from './register-view/register-view.component';
+import {ReservationViewComponent} from './reservation-view/reservation-view.component';
+import {MapViewComponent} from './map-view/map-view.component';
+import {AddBoatComponent} from './add-boat-component/add-boat.component';
+import {FormsModule, ReactiveFormsModule} from "@angular/forms";
 
 export function setupTranslateServiceFactory(
   service: TranslateService): Function {
@@ -33,7 +34,7 @@ export function setupTranslateServiceFactory(
     RegisterViewComponent,
     ReservationViewComponent,
     MapViewComponent,
-    AddBoatComponentComponent
+    AddBoatComponent
   ],
   imports: [
     BrowserModule,
@@ -44,8 +45,11 @@ export function setupTranslateServiceFactory(
       {path: 'register', component: RegisterViewComponent},
       {path: 'map', component: MapViewComponent},
       {path: 'reservation', component: ReservationViewComponent},
+      {path: 'add-boat', component: AddBoatComponent},
       {path: '**', component: PageNotFoundComponent},
     ]),
+    ReactiveFormsModule,
+    FormsModule,
     HttpClientModule
   ],
   providers: [TranslateService,

+ 107 - 0
boat-reservation-view/src/app/boats-component/boats-view.component.css

@@ -0,0 +1,107 @@
+.boat-list {
+  display: flex;
+  flex-wrap: wrap;
+  justify-content: space-between;
+}
+
+.boat-list-item {
+  width: 100%;
+  padding: 20px;
+  border: 1px solid #ccc;
+  border-radius: 6px;
+  margin: 1% 4% 5px;
+  background-color: #fff;
+  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
+}
+
+.boat-list-item:hover {
+  box-shadow: 0 8px 16px 0 rgba(0, 0, 0, 0.2);
+}
+
+.boat-list-item h3 {
+  font-size: 18px;
+  margin-bottom: 10px;
+}
+
+.boat-list-item p {
+  /*font-size: 14px;*/
+  color: #555;
+  margin-bottom: 10px;
+}
+
+.boat-list-item a {
+  text-decoration: none;
+  color: #007bff;
+}
+
+.item-name {
+  font-style: normal;
+  font-weight: bold;
+  font-family: Georgia, serif;
+}
+
+/*.item-name:before {*/
+/*  content: "boat name: ";*/
+/*  margin-right: 2px;*/
+/*  font-style: normal;*/
+/*  font-weight: normal;*/
+/*}*/
+
+.item-capacity {
+
+}
+
+.item-capacity:before {
+  content: "Max people capacity: ";
+  margin-right: 2px;
+  font-style: normal;
+}
+
+.item-cost {
+  font-size: 24px;
+  font-weight: bold;
+  color: #333;
+  font-style: normal;
+}
+
+.item-cost:before {
+  content: "cost per hour:   €";
+  margin-right: 2px;
+  font-style: normal;
+  font-size: 18px;
+  font-weight: normal;
+}
+
+.item-cost:after {
+  content: "EUR";
+  font-size: 12px;
+  color: #999;
+  margin-left: 2px;
+}
+
+img {
+  width: 30%;
+  display: inline-block;
+  vertical-align: middle;
+}
+
+td {
+  text-align: center;
+  vertical-align: middle;
+}
+
+a {
+  text-decoration: underline;
+  text-align: center;
+  vertical-align: middle;
+  justify-content: center;
+}
+
+a:hover {
+  cursor: pointer;
+}
+
+h2 {
+  font-family: Courier New, monospace;
+  font-weight: bold;
+}

+ 31 - 0
boat-reservation-view/src/app/boats-component/boats-view.component.html

@@ -0,0 +1,31 @@
+<!--<p>boats-view works!</p>-->
+<div style="text-align: center;">
+  <h2>OUR BOATS</h2>
+</div>
+<div class="boat-list">
+
+  <div class="boat-list-item" *ngFor="let item of boats">
+    <table>
+      <tr>
+        <td>
+          <img src="../../assets/leisure.png">
+        </td>
+        <td>
+          <h3 class="item-name">{{item.name}}</h3>
+          <p class="item-capacity">{{item.capacity}}</p>
+          <p class="item-cost">{{item.cost}}</p>
+        </td>
+      </tr>
+    </table>
+  </div>
+</div>
+
+<br>
+<div style="text-align: center">
+  <a class="navbar-button"
+     routerLink="/add-boat"
+     routerLinkActive="activebutton">
+    ADD NEW BOAT
+  </a>
+</div>
+<br>

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

@@ -0,0 +1,31 @@
+import {Component} from '@angular/core';
+import {BoatsService} from "../boats-service/boats.service";
+import {Boat} from "../domain/boat";
+
+@Component({
+  selector: 'app-boats-component',
+  templateUrl: './boats-view.component.html',
+  styleUrls: ['./boats-view.component.css']
+})
+export class BoatsViewComponent {
+
+  boats: Boat[] = [];
+
+  constructor(private boatService: BoatsService) {
+  }
+
+  async ngOnInit() {
+    const items = this.boatService.getBoats().subscribe(
+      (response) => {
+        this.boats = response;
+        this.boats.forEach(item => {
+          item.cost = parseFloat(item.cost).toFixed(2)
+        })
+      },
+      (error) => {
+        // Handle any errors
+        console.error(error);
+      }
+    );
+  }
+}

+ 38 - 0
boat-reservation-view/src/app/boats-service/boats.service.ts

@@ -0,0 +1,38 @@
+import {Injectable} from '@angular/core';
+import {Boat} from "../domain/boat";
+import {HttpClient, HttpHeaders} from "@angular/common/http";
+import {Observable} from "rxjs";
+
+@Injectable({
+  providedIn: 'root'
+})
+export class BoatsService {
+
+  constructor(private http: HttpClient) {
+  }
+
+  getBoats(): Observable<Boat[]> {
+    const url = 'http://localhost:2137/getAllBoats';
+
+    return this.http.get<Boat[]>(url);
+  }
+
+  addBoat(boat_info: object): void {
+    const url = 'http://localhost:2137/addBoat';
+
+    const headers = new HttpHeaders()
+      .set('Content-Type', 'application/json');
+
+    this.http.post(url, boat_info, {headers}).subscribe(
+      (response) => {
+        console.log('POST request successful', response);
+      },
+      (error) => {
+        console.error('Error making POST request:', error);
+      });
+  }
+
+  clearBoat() {
+
+  }
+}

+ 0 - 0
boat-reservation-view/src/app/boats-view/boats-view.component.css


+ 0 - 4
boat-reservation-view/src/app/boats-view/boats-view.component.html

@@ -1,4 +0,0 @@
-<!--<p>boats-view works!</p>-->
-Boat A<br>
-Boat B<br>
-Boat C<br>

+ 0 - 21
boat-reservation-view/src/app/boats-view/boats-view.component.spec.ts

@@ -1,21 +0,0 @@
-import { ComponentFixture, TestBed } from '@angular/core/testing';
-
-import { BoatsViewComponent } from './boats-view.component';
-
-describe('BoatsViewComponent', () => {
-  let component: BoatsViewComponent;
-  let fixture: ComponentFixture<BoatsViewComponent>;
-
-  beforeEach(() => {
-    TestBed.configureTestingModule({
-      declarations: [BoatsViewComponent]
-    });
-    fixture = TestBed.createComponent(BoatsViewComponent);
-    component = fixture.componentInstance;
-    fixture.detectChanges();
-  });
-
-  it('should create', () => {
-    expect(component).toBeTruthy();
-  });
-});

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

@@ -1,11 +0,0 @@
-import {Component} from '@angular/core';
-
-@Component({
-  selector: 'app-boats-view',
-  templateUrl: './boats-view.component.html',
-  styleUrls: ['./boats-view.component.css']
-})
-export class BoatsViewComponent {
-  constructor() {
-  }
-}

+ 13 - 0
boat-reservation-view/src/app/domain/boat.ts

@@ -0,0 +1,13 @@
+export class Boat {
+  id = ''
+  name = ''
+  capacity = ''
+  cost = ''
+
+  constructor(id: string, name: string, capacity: string, cost: string) {
+    this.id = id;
+    this.name = name;
+    this.capacity = capacity;
+    this.cost = cost;
+  }
+}

+ 17 - 0
boat-reservation-view/src/app/domain/reservation.ts

@@ -0,0 +1,17 @@
+export class Reservation {
+  id = ''
+  client_id = ''
+  boat_id = ''
+  date = ''
+  start_hour = ''
+  end_hour = ''
+
+  constructor(id: string, client_id: string, boat_id: string, date: string, start_hour: string, end_hour: string) {
+    this.id = id;
+    this.client_id = client_id;
+    this.boat_id = boat_id;
+    this.date = date;
+    this.start_hour = start_hour;
+    this.end_hour = end_hour;
+  }
+}

+ 0 - 21
boat-reservation-view/src/app/home-view/home-view.component.spec.ts

@@ -1,21 +0,0 @@
-import { ComponentFixture, TestBed } from '@angular/core/testing';
-
-import { HomeViewComponent } from './home-view.component';
-
-describe('HomeViewComponent', () => {
-  let component: HomeViewComponent;
-  let fixture: ComponentFixture<HomeViewComponent>;
-
-  beforeEach(() => {
-    TestBed.configureTestingModule({
-      declarations: [HomeViewComponent]
-    });
-    fixture = TestBed.createComponent(HomeViewComponent);
-    component = fixture.componentInstance;
-    fixture.detectChanges();
-  });
-
-  it('should create', () => {
-    expect(component).toBeTruthy();
-  });
-});

+ 0 - 21
boat-reservation-view/src/app/login-view/login-view.component.spec.ts

@@ -1,21 +0,0 @@
-import { ComponentFixture, TestBed } from '@angular/core/testing';
-
-import { LoginViewComponent } from './login-view.component';
-
-describe('LoginViewComponent', () => {
-  let component: LoginViewComponent;
-  let fixture: ComponentFixture<LoginViewComponent>;
-
-  beforeEach(() => {
-    TestBed.configureTestingModule({
-      declarations: [LoginViewComponent]
-    });
-    fixture = TestBed.createComponent(LoginViewComponent);
-    component = fixture.componentInstance;
-    fixture.detectChanges();
-  });
-
-  it('should create', () => {
-    expect(component).toBeTruthy();
-  });
-});

+ 0 - 21
boat-reservation-view/src/app/map-view/map-view.component.spec.ts

@@ -1,21 +0,0 @@
-import { ComponentFixture, TestBed } from '@angular/core/testing';
-
-import { MapViewComponent } from './map-view.component';
-
-describe('MapViewComponent', () => {
-  let component: MapViewComponent;
-  let fixture: ComponentFixture<MapViewComponent>;
-
-  beforeEach(() => {
-    TestBed.configureTestingModule({
-      declarations: [MapViewComponent]
-    });
-    fixture = TestBed.createComponent(MapViewComponent);
-    component = fixture.componentInstance;
-    fixture.detectChanges();
-  });
-
-  it('should create', () => {
-    expect(component).toBeTruthy();
-  });
-});

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

@@ -15,9 +15,17 @@ th, td {
   text-align: left;
 }
 
+td {
+  width: fit-content;
+}
+
 td:not(:first-child) {
   border: 1px solid rgba(0, 0, 0, 0);
   padding: 4px;
   text-align: center;
   width: fit-content;
 }
+
+a:hover {
+   cursor: pointer;
+ }

+ 0 - 21
boat-reservation-view/src/app/navbar/navbar.component.spec.ts

@@ -1,21 +0,0 @@
-import { ComponentFixture, TestBed } from '@angular/core/testing';
-
-import { NavbarComponent } from './navbar.component';
-
-describe('NavbarComponent', () => {
-  let component: NavbarComponent;
-  let fixture: ComponentFixture<NavbarComponent>;
-
-  beforeEach(() => {
-    TestBed.configureTestingModule({
-      declarations: [NavbarComponent]
-    });
-    fixture = TestBed.createComponent(NavbarComponent);
-    component = fixture.componentInstance;
-    fixture.detectChanges();
-  });
-
-  it('should create', () => {
-    expect(component).toBeTruthy();
-  });
-});

+ 0 - 21
boat-reservation-view/src/app/page-not-found/page-not-found.component.spec.ts

@@ -1,21 +0,0 @@
-import { ComponentFixture, TestBed } from '@angular/core/testing';
-
-import { PageNotFoundComponent } from './page-not-found.component';
-
-describe('PageNotFoundComponent', () => {
-  let component: PageNotFoundComponent;
-  let fixture: ComponentFixture<PageNotFoundComponent>;
-
-  beforeEach(() => {
-    TestBed.configureTestingModule({
-      declarations: [PageNotFoundComponent]
-    });
-    fixture = TestBed.createComponent(PageNotFoundComponent);
-    component = fixture.componentInstance;
-    fixture.detectChanges();
-  });
-
-  it('should create', () => {
-    expect(component).toBeTruthy();
-  });
-});

+ 32 - 0
boat-reservation-view/src/app/register-view/register-view.component.css

@@ -0,0 +1,32 @@
+form {
+  width: 300px;
+  margin: 0 auto;
+}
+
+label {
+  display: block;
+  margin-bottom: 8px;
+}
+
+input[type="text"],
+input[type="number"],
+textarea {
+  width: 100%;
+  padding: 8px;
+  margin-bottom: 16px;
+  border: 1px solid #ccc;
+  border-radius: 4px;
+}
+
+input[type="submit"] {
+  background-color: #4caf50;
+  color: #fff;
+  padding: 10px 16px;
+  border: none;
+  border-radius: 4px;
+  cursor: pointer;
+}
+
+input[type="submit"]:hover {
+  background-color: #45a049;
+}

+ 22 - 1
boat-reservation-view/src/app/register-view/register-view.component.html

@@ -1 +1,22 @@
-REGISTER FORM
+<div style="text-align: center;">
+  <h2>REGISTER NEW BOAT</h2>
+</div>
+<form (submit)="addBoat()" #myForm="ngForm">
+  <label for="name">Name:</label>
+  <input type="text"
+         id="name"
+         name="name" [(ngModel)]="formData.name" required>
+
+  <label for="capacity">Capacity:</label>
+  <input type="number"
+         id="capacity"
+         name="capacity" [(ngModel)]="formData.capacity" required>
+
+  <label for="cost">Cost:</label>
+  <input type="number"
+         id="cost"
+         name="cost" [(ngModel)]="formData.cost" required>
+
+  <input type="submit" value="Submit">
+</form>
+

+ 0 - 21
boat-reservation-view/src/app/register-view/register-view.component.spec.ts

@@ -1,21 +0,0 @@
-import { ComponentFixture, TestBed } from '@angular/core/testing';
-
-import { RegisterViewComponent } from './register-view.component';
-
-describe('RegisterViewComponent', () => {
-  let component: RegisterViewComponent;
-  let fixture: ComponentFixture<RegisterViewComponent>;
-
-  beforeEach(() => {
-    TestBed.configureTestingModule({
-      declarations: [RegisterViewComponent]
-    });
-    fixture = TestBed.createComponent(RegisterViewComponent);
-    component = fixture.componentInstance;
-    fixture.detectChanges();
-  });
-
-  it('should create', () => {
-    expect(component).toBeTruthy();
-  });
-});

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

@@ -1,4 +1,5 @@
-import { Component } from '@angular/core';
+import {Component} from '@angular/core';
+import {BoatsService} from "../boats-service/boats.service";
 
 @Component({
   selector: 'app-register-view',
@@ -6,5 +7,18 @@ import { Component } from '@angular/core';
   styleUrls: ['./register-view.component.css']
 })
 export class RegisterViewComponent {
+  formData: any = {};
 
+  constructor(private boatService: BoatsService) {
+  }
+
+  addBoat() {
+    let boat_info  = {
+      "name": this.formData.name,
+      "capacity": this.formData.capacity,
+      "cost": this.formData.cost,
+    }
+
+    this.boatService.addBoat(boat_info)
+  }
 }

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

@@ -0,0 +1,40 @@
+import { Injectable } from '@angular/core';
+import {HttpClient, HttpHeaders} from "@angular/common/http";
+import {Observable} from "rxjs";
+import {Reservation} from "../domain/reservation";
+
+@Injectable({
+  providedIn: 'root'
+})
+export class ReservationService {
+
+  constructor(private http: HttpClient) {
+  }
+
+  getReservations(): Observable<Reservation[]> {
+    const url = 'http://localhost:2137/getAllBoats';
+
+    return this.http.get<Reservation[]>(url);
+  }
+
+  createReservarion(reservation_info: object): any {
+    const url = 'http://localhost:2137/createReservation';
+
+    const headers = new HttpHeaders()
+      .set('Content-Type', 'application/json');
+
+    this.http.post(url, reservation_info, {headers}).subscribe(
+      (response) => {
+        console.log('POST request successful', response);
+        return response;
+      },
+      (error) => {
+        console.error('Error making POST request:', error);
+        return error;
+      });
+  }
+
+  clearBoat() {
+
+  }
+}

+ 101 - 0
boat-reservation-view/src/app/reservation-view/reservation-view.component.css

@@ -0,0 +1,101 @@
+form {
+  width: 300px;
+  margin: 0 auto;
+}
+
+label {
+  display: block;
+  margin-bottom: 8px;
+}
+
+input[type="text"],
+input[type="number"],
+textarea {
+  width: 100%;
+  padding: 8px;
+  margin-bottom: 16px;
+  border: 1px solid #ccc;
+  border-radius: 4px;
+}
+
+input[type="submit"] {
+  background-color: #4caf50;
+  color: #fff;
+  padding: 10px 16px;
+  border: none;
+  border-radius: 4px;
+  cursor: pointer;
+  width: 70%;
+  align-self: center;
+}
+
+input[type="submit"]:hover {
+  background-color: #45a049;
+}
+
+#boat_label:after {
+  content: " (name | capacity | cost/hour)";
+  color: gray;
+  font-size: 80%;
+}
+
+select {
+  width: 100%;
+  padding: 8px;
+  margin-bottom: 16px;
+  border: 1px solid #ccc;
+  border-radius: 4px;
+}
+
+select option {
+  background-color: #fff;
+  color: #333;
+  font-size: 14px;
+}
+
+select:focus {
+  outline: none;
+  border-color: blue;
+}
+
+.date-picker {
+  position: relative;
+  display: inline-block;
+}
+
+#from_date::before, #to_date::before {
+  content: '\f073'; /* FontAwesome calendar icon */
+  font-family: "Font Awesome 5 Free";
+  font-weight: 900;
+  position: absolute;
+  right: 8px;
+  top: 50%;
+  transform: translateY(-50%);
+}
+
+input[id="from_date"], input[id="to_date"] {
+  width: 100%;
+  padding-right: 24px; /* Make room for the calendar icon */
+  appearance: none;
+  -webkit-appearance: none;
+  border: 1px solid #ccc;
+  border-radius: 4px;
+  height: 30px;
+  font-size: 14px;
+  padding: 4px 8px;
+}
+
+/* Additional styling for the calendar icon */
+#from_date #to_date::-webkit-calendar-picker-indicator {
+  opacity: 0; /* Hide the default arrow icon in WebKit browsers */
+  position: absolute;
+  right: 0;
+  top: 0;
+  bottom: 0;
+  width: 24px;
+  cursor: pointer;
+}
+
+select[id="from_date"], select[id="to_date"] {
+  width: fit-content;
+}

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

@@ -1 +1,77 @@
-<p>reservation-view works!</p>
+<div style="text-align: center;">
+  <h2>MAKE RESERVATION</h2>
+</div>
+<form (submit)="makeReservation()" #myForm="ngForm">
+  <label id="boat_label" for="boat" style="font-family: Courier New, monospace;">Boat:</label>
+  <select name="_boats" id="boat" [(ngModel)]="selectedBoat">
+    <option *ngFor="let boat of boats_labels">{{ boat.label.toString() }}</option>
+  </select>
+  <br>
+
+  <h2 style="text-align: center">DATE</h2>
+  <div style="text-align: center">
+    <input type="date"
+           id="from_date"
+           name="cost" [(ngModel)]="date" required
+           style="width: 80%">
+  </div>
+
+  <h2 style="text-align: center">TIME</h2>
+  <table style="width: 100%">
+    <tr>
+      <td style="width: 30%; text-align: center">
+        <label for="from_hour" style="font-family: Courier New, monospace;">START</label>
+      </td>
+      <td style="width: 70%;display:inline-block;">
+        <select id="from_hour" style="width:100%; box-sizing: border-box;" [(ngModel)]="formData.fromHour">
+          <option>7:00</option>
+          <option>8:00</option>
+          <option>9:00</option>
+          <option>10:00</option>
+          <option>11:00</option>
+          <option>12:00</option>
+          <option>13:00</option>
+          <option>14:00</option>
+          <option>15:00</option>
+          <option>16:00</option>
+          <option>17:00</option>
+          <option>18:00</option>
+          <option>19:00</option>
+          <option>20:00</option>
+          <option>21:00</option>
+          <option>22:00</option>
+        </select>
+      </td>
+    </tr>
+    <tr>
+      <td style="width: 30%; text-align: center">
+        <label for="to_hour" style="font-family: Courier New, monospace;">END</label>
+      </td>
+      <td style="width: 70%;display:inline-block;">
+        <select id="to_hour" style="width:100%; box-sizing: border-box;" [(ngModel)]="formData.toHour">
+          <option>8:00</option>
+          <option>9:00</option>
+          <option>10:00</option>
+          <option>11:00</option>
+          <option>12:00</option>
+          <option>13:00</option>
+          <option>14:00</option>
+          <option>15:00</option>
+          <option>16:00</option>
+          <option>17:00</option>
+          <option>18:00</option>
+          <option>19:00</option>
+          <option>20:00</option>
+          <option>21:00</option>
+          <option>22:00</option>
+          <option>23:00</option>
+        </select>
+      </td>
+    </tr>
+  </table>
+
+  <div style="text-align: center;">
+    <input type="submit" value="Submit">
+  </div>
+  <br>
+</form>

+ 0 - 21
boat-reservation-view/src/app/reservation-view/reservation-view.component.spec.ts

@@ -1,21 +0,0 @@
-import { ComponentFixture, TestBed } from '@angular/core/testing';
-
-import { ReservationViewComponent } from './reservation-view.component';
-
-describe('ReservationViewComponent', () => {
-  let component: ReservationViewComponent;
-  let fixture: ComponentFixture<ReservationViewComponent>;
-
-  beforeEach(() => {
-    TestBed.configureTestingModule({
-      declarations: [ReservationViewComponent]
-    });
-    fixture = TestBed.createComponent(ReservationViewComponent);
-    component = fixture.componentInstance;
-    fixture.detectChanges();
-  });
-
-  it('should create', () => {
-    expect(component).toBeTruthy();
-  });
-});

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

@@ -1,4 +1,6 @@
-import { Component } from '@angular/core';
+import {Component} from '@angular/core';
+import {BoatsService} from "../boats-service/boats.service";
+import {ReservationService} from "../reservation-service/reservation.service";
 
 @Component({
   selector: 'app-reservation-view',
@@ -7,4 +9,49 @@ import { Component } from '@angular/core';
 })
 export class ReservationViewComponent {
 
+
+  boats_labels: any[] = [];
+
+  formData: any = {};
+  boat: any;
+  date: any;
+  fromHour: any;
+  toHour: any;
+  selectedBoat: string = '';
+
+
+  constructor(private boatService: BoatsService,
+              private reservationService: ReservationService) {
+  }
+
+  makeReservation() {
+    let reservation_info = {
+      "Boat": this.formData.boat,
+      "fromDate": this.date,
+      "fromHour": this.fromHour,
+      "toHour": this.toHour
+    }
+    console.log("reservation_info: ", reservation_info)
+    console.log("boats_labels: ", this.boats_labels)
+    console.log("Form: ", this.selectedBoat)
+    console.log(this.date)
+    this.reservationService.createReservarion(reservation_info)
+  }
+
+  async ngOnInit() {
+    const items = this.boatService.getBoats().subscribe(
+      (response) => {
+        this.boats_labels = response.map(val => ({
+          "id": val.id,
+          "label": val.name + "\t|\t" + val.capacity + "\t|\t" + parseFloat(val.cost).toFixed(2)
+        }));
+      },
+      (error) => {
+        // Handle any errors
+        console.error(error);
+      }
+    );
+    console.log()
+  }
+
 }

BIN
boat-reservation-view/src/assets/leisure.png


+ 5 - 0
boat-reservation-view/src/styles.css

@@ -59,3 +59,8 @@ a {
   font-family: Courier New, monospace;
   font-weight: bold;
 }
+
+h2 {
+  font-family: Courier New, monospace;
+  font-weight: bold;
+}

+ 6 - 0
package-lock.json

@@ -0,0 +1,6 @@
+{
+  "name": "oslo_boating_project",
+  "lockfileVersion": 3,
+  "requires": true,
+  "packages": {}
+}