diff --git a/.gitignore b/.gitignore index 395db21..d0175a1 100644 --- a/.gitignore +++ b/.gitignore @@ -24,3 +24,5 @@ # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml hs_err_pid* replay_pid* +.env +*.env \ No newline at end of file diff --git a/OrariAperti/backend/.run/Backend.run.xml b/OrariAperti/backend/.run/Backend.run.xml new file mode 100644 index 0000000..ca2e9b0 --- /dev/null +++ b/OrariAperti/backend/.run/Backend.run.xml @@ -0,0 +1,10 @@ + + + + \ No newline at end of file diff --git a/OrariAperti/backend/README.md b/OrariAperti/backend/README.md index fafb84e..ad4691a 100644 --- a/OrariAperti/backend/README.md +++ b/OrariAperti/backend/README.md @@ -15,14 +15,19 @@ OrariAperti is a room reservation system built with Spring Boot and React. ### Backend Development -To run the backend only: +To run the backend: +1. **Copy and Modify the [application.properties](./src/main/resources/application.properties.example)** ```bash -mvn spring-boot:run +mv ./src/main/resources/application.properties.example ./src/main/resources/application.properties ``` -and then: +3. **Build the Application** +```bash +mvn spring-boot:run +``` +3. **Run the Application** ```bash java -jar target/OrariAperti-0.0.1-SNAPSHOT.jar ``` diff --git a/OrariAperti/backend/backend-openapi.yaml b/OrariAperti/backend/backend-openapi.yaml new file mode 100644 index 0000000..ef130b8 --- /dev/null +++ b/OrariAperti/backend/backend-openapi.yaml @@ -0,0 +1,220 @@ +openapi: "3.1.0" +info: + title: "OrariAperti Backend API" + description: "Backend API Description of the OrariAperti application." + version: "1.0.0" +servers: + - url: "http://localhost:8080" + description: "Local server" +paths: + /api/reservation: + get: + summary: "Get reservation by key" + operationId: "getReservationByKey" + parameters: + - name: "publicKey" + in: "header" + required: false + schema: + type: "string" + format: "uuid" + - name: "privateKey" + in: "header" + required: false + schema: + type: "string" + format: "uuid" + responses: + "200": + description: "Reservation found" + content: + application/json: + schema: + type: object + properties: + reservationDetails: + $ref: "#/components/schemas/Reservation" + privateKey: + type: string + format: uuid + publicKey: + type: string + format: uuid + "400": + description: "Bad request" + "404": + description: "Not found" + post: + summary: "Create a new reservation" + operationId: "createReservation" + requestBody: + required: true + content: + application/json: + schema: + $ref: "#/components/schemas/ReservationDTO" + responses: + "200": + description: "Reservation created" + content: + application/json: + schema: + type: object + properties: + reservation: + $ref: "#/components/schemas/Reservation" + privateKey: + type: string + format: uuid + publicKey: + type: string + format: uuid + "400": + description: "Bad request" + /api/reservation/{id}: + put: + summary: "Update a reservation" + operationId: "updateReservation" + parameters: + - name: "id" + in: "path" + required: true + schema: + type: "string" + format: "uuid" + - name: "privateKey" + in: "header" + required: true + schema: + type: "string" + format: "uuid" + requestBody: + required: true + content: + application/json: + schema: + $ref: "#/components/schemas/ReservationDTO" + responses: + "200": + description: "Reservation updated" + content: + application/json: + schema: + $ref: "#/components/schemas/Reservation" + "400": + description: "Bad request" + "401": + description: "Unauthorized" + "404": + description: "Not found" + delete: + summary: "Delete a reservation" + operationId: "deleteReservation" + parameters: + - name: "id" + in: "path" + required: true + schema: + type: "string" + format: "uuid" + - name: "privateKey" + in: "header" + required: true + schema: + type: "string" + format: "uuid" + responses: + "200": + description: "Reservation deleted" + "401": + description: "Unauthorized" + "404": + description: "Not found" + /api/room: + get: + summary: "Get all rooms" + operationId: "getRooms" + responses: + "200": + description: "List of rooms" + content: + application/json: + schema: + type: array + items: + $ref: "#/components/schemas/Room" + "404": + description: "No rooms found" +components: + schemas: + Room: + type: object + properties: + id: + type: string + format: uuid + roomNumber: + type: string + roomFeatures: + type: array + items: + $ref: "#/components/schemas/RoomFeatures" + RoomFeatures: + type: string + enum: + - "Beamer" + - "Water Tap" + - "Whiteboard" + - "Air Conditioning" + - "Projector Screen" + - "Speaker System" + - "Video Conferencing" + - "WiFi" + - "Power Outlets" + - "Natural Light" + - "Soundproofing" + - "Smart Board" + - "Telephone" + - "Coffee Machine" + - "Printer" + - "Lockers" + Reservation: + type: object + properties: + id: + type: string + format: uuid + date: + type: string + format: date + startTime: + type: string + format: partial-time + endTime: + type: string + format: partial-time + room: + $ref: "#/components/schemas/Room" + description: + type: string + participants: + type: string + ReservationDTO: + type: object + properties: + date: + type: string + format: date + startTime: + type: string + format: partial-time + endTime: + type: string + format: partial-time + roomId: + type: string + format: uuid + description: + type: string + participants: + type: string \ No newline at end of file diff --git a/OrariAperti/backend/pom.xml b/OrariAperti/backend/pom.xml index 73fd559..0dfb637 100644 --- a/OrariAperti/backend/pom.xml +++ b/OrariAperti/backend/pom.xml @@ -27,7 +27,7 @@ - 21 + 17 diff --git a/OrariAperti/backend/src/main/java/ims/orariaperti/DTO/ReservationDTO.java b/OrariAperti/backend/src/main/java/ims/orariaperti/DTO/ReservationDTO.java index e191a33..4d3cbec 100644 --- a/OrariAperti/backend/src/main/java/ims/orariaperti/DTO/ReservationDTO.java +++ b/OrariAperti/backend/src/main/java/ims/orariaperti/DTO/ReservationDTO.java @@ -8,18 +8,18 @@ public class ReservationDTO { private LocalDate date; private LocalTime startTime; private LocalTime endTime; - private int room; + private UUID roomId; private String description; private String participants; public ReservationDTO() { } - public ReservationDTO(LocalDate date, LocalTime startTime, LocalTime endTime, int room, String description, String participants) { + public ReservationDTO(LocalDate date, LocalTime startTime, LocalTime endTime, UUID roomId, String description, String participants) { this.date = date; this.startTime = startTime; this.endTime = endTime; - this.room = room; + this.roomId = roomId; this.description = description; this.participants = participants; } @@ -48,12 +48,12 @@ public void setEndTime(LocalTime endTime) { this.endTime = endTime; } - public int getRoom() { - return room; + public UUID getRoomId() { + return roomId; } - public void setRoom(int room) { - this.room = room; + public void setRoomId(UUID roomId) { + this.roomId = roomId; } public String getDescription() { @@ -78,7 +78,7 @@ public String toString() { ", date=" + date + ", startTime=" + startTime + ", endTime=" + endTime + - ", room=" + room + + ", roomId=" + roomId + ", description='" + description + '\'' + ", participants='" + participants + '\'' + '}'; diff --git a/OrariAperti/backend/src/main/java/ims/orariaperti/config/WebConfig.java b/OrariAperti/backend/src/main/java/ims/orariaperti/config/WebConfig.java index c4d8266..2c418f8 100644 --- a/OrariAperti/backend/src/main/java/ims/orariaperti/config/WebConfig.java +++ b/OrariAperti/backend/src/main/java/ims/orariaperti/config/WebConfig.java @@ -1,25 +1,27 @@ package ims.orariaperti.config; +import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Configuration; -import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; -import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; -import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; +import org.springframework.web.servlet.config.annotation.*; @Configuration public class WebConfig implements WebMvcConfigurer { + @Value("${frontend.url}") + private String frontendUrl; + @Override - public void addResourceHandlers(ResourceHandlerRegistry registry) { - // Serve static resources from the react-app directory - registry.addResourceHandler("/**") - .addResourceLocations("classpath:/static/react-app/"); + public void addCorsMappings(CorsRegistry registry) { + registry.addMapping("/**") + .allowedOrigins(frontendUrl, "http://localhost:8080") + .allowedMethods("*") + .allowedHeaders("*"); } - + @Override public void addViewControllers(ViewControllerRegistry registry) { - // Forward requests to the index.html for client-side routing - registry.addViewController("/").setViewName("forward:/index.html"); - registry.addViewController("/{x:[\\w\\-]+}").setViewName("forward:/index.html"); - registry.addViewController("/{x:^(?!api$).*$}/**").setViewName("forward:/index.html"); + registry.addViewController("/").setViewName("redirect:" + frontendUrl); + registry.addViewController("/{x:[\\w\\-]+}").setViewName("redirect:" + frontendUrl); + registry.addViewController("/{x:^(?!api$).*$}/**").setViewName("redirect:" + frontendUrl); } -} \ No newline at end of file +} diff --git a/OrariAperti/backend/src/main/java/ims/orariaperti/controller/ReservationController.java b/OrariAperti/backend/src/main/java/ims/orariaperti/controller/ReservationController.java index e83798a..73faaeb 100644 --- a/OrariAperti/backend/src/main/java/ims/orariaperti/controller/ReservationController.java +++ b/OrariAperti/backend/src/main/java/ims/orariaperti/controller/ReservationController.java @@ -2,48 +2,51 @@ import ims.orariaperti.DTO.ReservationDTO; import ims.orariaperti.entity.Reservation; +import ims.orariaperti.entity.Room; import ims.orariaperti.repository.ReservationRepository; +import ims.orariaperti.repository.RoomRepository; import org.springframework.http.ResponseEntity; -import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.*; +import java.util.Map; import java.util.Optional; import java.util.UUID; @RestController @RequestMapping("/api/reservation") -@Controller public class ReservationController { private final ReservationRepository reservationRepository; + private final RoomRepository roomRepository; - public ReservationController(ReservationRepository reservationRepository) { + public ReservationController(ReservationRepository reservationRepository, RoomRepository roomRepository) { this.reservationRepository = reservationRepository; + this.roomRepository = roomRepository; } @GetMapping - public Object getReservations(@RequestHeader(required = false) UUID publicKey, @RequestHeader(required = false) UUID privateKey) { - if (publicKey == null && privateKey == null) { + public ResponseEntity getReservations(@RequestHeader(required = false) UUID publickey, @RequestHeader(required = false) UUID privatekey) { + if (publickey == null && privatekey == null) { return ResponseEntity.badRequest().build(); } - if (privateKey != null) { - Optional reservationInDB = reservationRepository.findByPrivateKey(privateKey); + if (privatekey != null) { + Optional reservationInDB = reservationRepository.findByPrivateKey(privatekey); if (reservationInDB.isPresent() && reservationInDB.get() instanceof Reservation reservation) { - return ResponseEntity.ok(new Object() { - public final Reservation reservationDetails = reservation; - public final UUID privateKey = reservation.getPrivateKey(); - public final UUID publicKey = reservation.getPublicKey(); - }); + return ResponseEntity.ok(Map.of( + "reservationDetails", reservation, + "privateKey", reservation.getPrivateKey(), + "publicKey", reservation.getPublicKey() + )); } else { return ResponseEntity.notFound().build(); } } else { - Optional reservationInDB = reservationRepository.findByPublicKey(publicKey); + Optional reservationInDB = reservationRepository.findByPublicKey(publickey); if (reservationInDB.isPresent() && reservationInDB.get() instanceof Reservation reservation) { - return ResponseEntity.ok(new Object() { - public final Reservation reservationDetails = reservation; - public final UUID publicKey = reservation.getPublicKey(); - }); + return ResponseEntity.ok(Map.of( + "reservationDetails", reservation, + "publicKey", reservation.getPublicKey() + )); } else { return ResponseEntity.notFound().build(); } @@ -51,35 +54,40 @@ public Object getReservations(@RequestHeader(required = false) UUID publicKey, @ } @PostMapping - public ResponseEntity createReservation(@RequestBody ReservationDTO reservationDTO) { + public ResponseEntity createReservation(@RequestBody ReservationDTO reservationDTO) { try { - if (!reservationDTO.getParticipants().matches("^[A-Za-z\\s]+(,\\s*[A-Za-z\\s]+)*$")) { + if (!reservationDTO.getParticipants().matches("^[A-Za-zÄäÖöÜüßèéêç ]+(, *[A-Za-zÄäÖöÜüßèéêç ]+)*$")) { throw new Exception("Participants field must only contain letters (A-Z, a-z) separated by commas."); } - + Room room = roomRepository.findById(reservationDTO.getRoomId()).orElse(null); + if (room == null) { + throw new Exception("Room not found. Please hard reload the page (ctrl + F5)"); + } for (Reservation reservation : reservationRepository.findAll()) { - boolean isSameRoom = reservation.getRoom() == reservationDTO.getRoom(); + boolean isSameRoom = reservation.getRoom().getId().equals(room.getId()); boolean isSameDate = reservation.getDate().equals(reservationDTO.getDate()); boolean isOverlappingTime = reservationDTO.getStartTime().isBefore(reservation.getEndTime()) && reservationDTO.getEndTime().isAfter(reservation.getStartTime()); - if (isSameRoom && isSameDate && isOverlappingTime) { throw new Exception("Room is already reserved for the given time and the given date."); } } - Reservation reservationInDB = new Reservation(null, reservationDTO.getDate(), reservationDTO.getStartTime(), reservationDTO.getEndTime(), reservationDTO.getRoom(), reservationDTO.getDescription(), reservationDTO.getParticipants(), null, null); + Reservation reservationInDB = new Reservation(null, reservationDTO.getDate(), reservationDTO.getStartTime(), reservationDTO.getEndTime(), room, reservationDTO.getDescription(), reservationDTO.getParticipants(), null, null); reservationRepository.save(reservationInDB); - return ResponseEntity.ok(new Object() { - public final Reservation reservation = reservationInDB; - public final UUID privateKey = reservationInDB.getPrivateKey(); - public final UUID publicKey = reservationInDB.getPublicKey(); - }); + return ResponseEntity.ok(Map.of( + "reservation", reservationInDB, + "privateKey", reservationInDB.getPrivateKey(), + "publicKey", reservationInDB.getPublicKey() + )); } catch (Exception e) { - return ResponseEntity.badRequest().build(); + return ResponseEntity.badRequest().body(e.getMessage()); } } @DeleteMapping("/{id}") - public ResponseEntity deleteReservation(@PathVariable UUID id, @RequestHeader UUID privateKey) { + public ResponseEntity deleteReservation(@PathVariable UUID id, @RequestHeader(required = false) UUID privateKey) { + if (privateKey == null) { + return ResponseEntity.status(401).body("Private key is required for deleting a reservation."); + } Reservation reservation = reservationRepository.getFirstById(id); if (reservation == null) { return ResponseEntity.notFound().build(); @@ -92,7 +100,10 @@ public ResponseEntity deleteReservation(@PathVariable UUID id, @RequestHea } @PutMapping("/{id}") - public ResponseEntity updateReservation(@PathVariable UUID id, @RequestBody ReservationDTO reservationDTO, @RequestHeader UUID privateKey) { + public ResponseEntity updateReservation(@PathVariable UUID id, @RequestBody ReservationDTO reservationDTO, @RequestHeader(required = false) UUID privateKey) { + if (privateKey == null) { + return ResponseEntity.status(401).body("Private key is required for updating a reservation."); + } try { Reservation reservation = reservationRepository.getFirstById(id); if (reservation == null) { @@ -101,27 +112,27 @@ public ResponseEntity updateReservation(@PathVariable UUID id, @Req if (!reservation.getPrivateKey().equals(privateKey)) { return ResponseEntity.status(401).build(); } - if (!reservationDTO.getParticipants().matches("^[A-Za-z\\s]+(,\\s*[A-Za-z\\s]+)*$")) { throw new Exception("Participants field must only contain letters (A-Z, a-z) separated by commas."); } - + Room room = roomRepository.findById(reservationDTO.getRoomId()).orElse(null); + if (room == null) { + throw new Exception("Room not found. Please hard reload the page (ctrl + F5)"); + } for (Reservation currentReservationFromDB : reservationRepository.findAll()) { - boolean isSameRoom = currentReservationFromDB.getRoom() == reservationDTO.getRoom(); + boolean isSameRoom = currentReservationFromDB.getRoom().getId().equals(room.getId()); boolean isSameDate = currentReservationFromDB.getDate().equals(reservationDTO.getDate()); boolean isOverlappingTime = reservationDTO.getStartTime().isBefore(currentReservationFromDB.getEndTime()) && reservationDTO.getEndTime().isAfter(currentReservationFromDB.getStartTime()); - if (isSameRoom && isSameDate && isOverlappingTime && !currentReservationFromDB.getId().equals(id)) { throw new Exception("Room is already reserved for the given time and the given date."); } } - return reservationRepository.findById(id) .map(existingReservation -> { existingReservation.setDate(reservationDTO.getDate()); existingReservation.setStartTime(reservationDTO.getStartTime()); existingReservation.setEndTime(reservationDTO.getEndTime()); - existingReservation.setRoom(reservationDTO.getRoom()); + existingReservation.setRoom(room); existingReservation.setDescription(reservationDTO.getDescription()); existingReservation.setParticipants(reservationDTO.getParticipants()); reservationRepository.save(existingReservation); @@ -129,7 +140,7 @@ public ResponseEntity updateReservation(@PathVariable UUID id, @Req }) .orElse(ResponseEntity.notFound().build()); } catch (Exception e) { - return ResponseEntity.badRequest().build(); + return ResponseEntity.badRequest().body(e.getMessage()); } } diff --git a/OrariAperti/backend/src/main/java/ims/orariaperti/controller/RoomController.java b/OrariAperti/backend/src/main/java/ims/orariaperti/controller/RoomController.java new file mode 100644 index 0000000..1c07b8b --- /dev/null +++ b/OrariAperti/backend/src/main/java/ims/orariaperti/controller/RoomController.java @@ -0,0 +1,46 @@ +package ims.orariaperti.controller; + +import ims.orariaperti.entity.Room; +import ims.orariaperti.entity.Reservation; +import ims.orariaperti.repository.RoomRepository; +import ims.orariaperti.repository.ReservationRepository; +import ims.orariaperti.utilities.RoomFeatures; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Repository; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +@Repository +@RequestMapping("/api/room") +@RestController +public class RoomController { + + private final RoomRepository roomRepository; + + public RoomController(RoomRepository roomRepository) { + this.roomRepository = roomRepository; + } + + @GetMapping + public Object getRooms() { + List roomsInDB = roomRepository.findAll(); + if (!roomsInDB.isEmpty()) { + ArrayList rooms = new ArrayList<>(); + for (Room room : roomsInDB) { + rooms.add(Map.of( + "id", room.getId(), + "roomNumber", room.getRoomNumber(), + "roomFeatures", room.getRoomFeatures().stream().map(RoomFeatures::getFeature).toList() + )); + } + return ResponseEntity.ok(rooms); + } else { + return ResponseEntity.notFound().build(); + } + } +} diff --git a/OrariAperti/backend/src/main/java/ims/orariaperti/entity/Reservation.java b/OrariAperti/backend/src/main/java/ims/orariaperti/entity/Reservation.java index ad163c7..c7bcb55 100644 --- a/OrariAperti/backend/src/main/java/ims/orariaperti/entity/Reservation.java +++ b/OrariAperti/backend/src/main/java/ims/orariaperti/entity/Reservation.java @@ -24,8 +24,9 @@ public class Reservation { @Column(nullable = false) private LocalTime endTime; - @Column(nullable = false) - private int room; + @ManyToOne(fetch = FetchType.EAGER) + @JoinColumn(name = "room_id", nullable = false) + private Room room; @Column(nullable = false, columnDefinition = "VARCHAR(200)") private String description; @@ -44,7 +45,7 @@ public class Reservation { public Reservation() { } - public Reservation(UUID id, LocalDate date, LocalTime startTime, LocalTime endTime, int room, String description, String participants, UUID privateKey, UUID publicKey) { + public Reservation(UUID id, LocalDate date, LocalTime startTime, LocalTime endTime, Room room, String description, String participants, UUID privateKey, UUID publicKey) { this.id = id; this.date = date; this.startTime = startTime; @@ -99,11 +100,11 @@ public void setEndTime(LocalTime endTime) { this.endTime = endTime; } - public int getRoom() { + public Room getRoom() { return room; } - public void setRoom(int room) { + public void setRoom(Room room) { this.room = room; } @@ -146,7 +147,7 @@ public String toString() { ", date=" + date + ", startTime=" + startTime + ", endTime=" + endTime + - ", room=" + room + + ", room=" + (room != null ? room.getId() : null) + ", description='" + description + '\'' + ", participants='" + participants + '\'' + ", privateKey=" + privateKey + diff --git a/OrariAperti/backend/src/main/java/ims/orariaperti/entity/Room.java b/OrariAperti/backend/src/main/java/ims/orariaperti/entity/Room.java new file mode 100644 index 0000000..b0d50c7 --- /dev/null +++ b/OrariAperti/backend/src/main/java/ims/orariaperti/entity/Room.java @@ -0,0 +1,59 @@ +package ims.orariaperti.entity; + +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import ims.orariaperti.serializer.RoomFeaturesSerializer; +import ims.orariaperti.utilities.RoomFeatures; +import jakarta.persistence.*; + +import java.util.ArrayList; +import java.util.UUID; + +@Entity +@Table(name = "rooms") +public class Room { + + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private UUID id; + + /** + * Should contain only the numbers. **without** the "Room {nmr}" Room prefix. + */ + private String roomNumber; + + @JsonSerialize(contentUsing = RoomFeaturesSerializer.class) + private ArrayList roomFeatures; + + public Room() { + } + + public Room(UUID id, String roomNumber, ArrayList roomFeatures) { + this.id = id; + this.roomNumber = roomNumber; + this.roomFeatures = roomFeatures; + } + + public UUID getId() { + return id; + } + + public void setId(UUID id) { + this.id = id; + } + + public String getRoomNumber() { + return roomNumber; + } + + public void setRoomNumber(String roomName) { + this.roomNumber = roomName; + } + + public ArrayList getRoomFeatures() { + return roomFeatures; + } + + public void setRoomFeatures(ArrayList roomFeatures) { + this.roomFeatures = roomFeatures; + } +} diff --git a/OrariAperti/backend/src/main/java/ims/orariaperti/repository/RoomRepository.java b/OrariAperti/backend/src/main/java/ims/orariaperti/repository/RoomRepository.java new file mode 100644 index 0000000..40a44f6 --- /dev/null +++ b/OrariAperti/backend/src/main/java/ims/orariaperti/repository/RoomRepository.java @@ -0,0 +1,8 @@ +package ims.orariaperti.repository; + +import ims.orariaperti.entity.Room; +import org.springframework.data.jpa.repository.JpaRepository; +import java.util.UUID; + +public interface RoomRepository extends JpaRepository { +} diff --git a/OrariAperti/backend/src/main/java/ims/orariaperti/serializer/RoomFeaturesSerializer.java b/OrariAperti/backend/src/main/java/ims/orariaperti/serializer/RoomFeaturesSerializer.java new file mode 100644 index 0000000..a57a99c --- /dev/null +++ b/OrariAperti/backend/src/main/java/ims/orariaperti/serializer/RoomFeaturesSerializer.java @@ -0,0 +1,15 @@ +package ims.orariaperti.serializer; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; +import ims.orariaperti.utilities.RoomFeatures; + +import java.io.IOException; + +public class RoomFeaturesSerializer extends JsonSerializer { + @Override + public void serialize(RoomFeatures value, JsonGenerator gen, SerializerProvider serializers) throws IOException { + gen.writeString(value.getFeature()); + } +} \ No newline at end of file diff --git a/OrariAperti/backend/src/main/java/ims/orariaperti/utilities/RoomFeatures.java b/OrariAperti/backend/src/main/java/ims/orariaperti/utilities/RoomFeatures.java new file mode 100644 index 0000000..ef2fd48 --- /dev/null +++ b/OrariAperti/backend/src/main/java/ims/orariaperti/utilities/RoomFeatures.java @@ -0,0 +1,30 @@ +package ims.orariaperti.utilities; + +public enum RoomFeatures { + BEAMER("Beamer"), + WATER_SOURCE("Water Tap"), + WHITEBOARD("Whiteboard"), + AIR_CONDITIONING("Air Conditioning"), + PROJECTOR_SCREEN("Projector Screen"), + SPEAKER_SYSTEM("Speaker System"), + VIDEO_CONFERENCING("Video Conferencing"), + WIFI("WiFi"), + POWER_OUTLETS("Power Outlets"), + NATURAL_LIGHT("Natural Light"), + SOUNDPROOFING("Soundproofing"), + SMART_BOARD("Smart Board"), + TELEPHONE("Telephone"), + COFFEE_MACHINE("Coffee Machine"), + PRINTER("Printer"), + LOCKERS("Lockers"); + + private final String feature; + + RoomFeatures(String name) { + this.feature = name; + } + + public String getFeature() { + return feature; + } +} \ No newline at end of file diff --git a/OrariAperti/backend/src/main/java/ims/orariaperti/utilities/Seeder.java b/OrariAperti/backend/src/main/java/ims/orariaperti/utilities/Seeder.java index 564fbeb..9d873a9 100644 --- a/OrariAperti/backend/src/main/java/ims/orariaperti/utilities/Seeder.java +++ b/OrariAperti/backend/src/main/java/ims/orariaperti/utilities/Seeder.java @@ -1,52 +1,116 @@ package ims.orariaperti.utilities; import ims.orariaperti.entity.Reservation; +import ims.orariaperti.entity.Room; import ims.orariaperti.repository.ReservationRepository; +import ims.orariaperti.repository.RoomRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.CommandLineRunner; import org.springframework.stereotype.Component; import java.time.LocalDate; import java.time.LocalTime; +import java.util.ArrayList; +import java.util.Arrays; import java.util.UUID; @Component public class Seeder implements CommandLineRunner { private final ReservationRepository reservationRepository; + private final RoomRepository roomRepository; @Autowired - public Seeder(ReservationRepository reservationRepository) { + public Seeder(ReservationRepository reservationRepository, RoomRepository roomRepository) { this.reservationRepository = reservationRepository; + this.roomRepository = roomRepository; } @Override public void run(String... args) { - if (reservationRepository.count() == 0) { - reservationRepository.save(new Reservation( - null, - LocalDate.now(), - LocalTime.of(9, 0), - LocalTime.of(10, 0), - 101, - "Team Meeting", - "Chandra,Johnson", - UUID.randomUUID(), - UUID.randomUUID() - )); - reservationRepository.save(new Reservation( - null, - LocalDate.now(), - LocalTime.of(11, 0), - LocalTime.of(12, 0), - 102, - "Project Discussion", - "Natalia,Fluury", - UUID.randomUUID(), - UUID.randomUUID() - )); + if (roomRepository.count() == 0) { + Room room101 = roomRepository.save(new Room(null, "101", new ArrayList<>(Arrays.asList(RoomFeatures.BEAMER, RoomFeatures.WHITEBOARD)))); + Room room102 = roomRepository.save(new Room(null, "102", new ArrayList<>(Arrays.asList(RoomFeatures.BEAMER, RoomFeatures.WHITEBOARD)))); + @SuppressWarnings("unused") + Room room201 = roomRepository.save(new Room(null, "201", new ArrayList<>(Arrays.asList(RoomFeatures.BEAMER, RoomFeatures.WATER_SOURCE)))); + @SuppressWarnings("unused") + Room room103 = roomRepository.save(new Room(null, "103", new ArrayList<>(Arrays.asList(RoomFeatures.WHITEBOARD, RoomFeatures.WIFI)))); + @SuppressWarnings("unused") + Room room104 = roomRepository.save(new Room(null, "104", new ArrayList<>(Arrays.asList(RoomFeatures.BEAMER, RoomFeatures.AIR_CONDITIONING)))); + @SuppressWarnings("unused") + Room room105 = roomRepository.save(new Room(null, "105", new ArrayList<>(Arrays.asList(RoomFeatures.BEAMER, RoomFeatures.POWER_OUTLETS)))); + @SuppressWarnings("unused") + Room room110 = roomRepository.save(new Room(null, "110", new ArrayList<>(Arrays.asList(RoomFeatures.WHITEBOARD, RoomFeatures.NATURAL_LIGHT)))); + @SuppressWarnings("unused") + Room room120 = roomRepository.save(new Room(null, "120", new ArrayList<>(Arrays.asList(RoomFeatures.BEAMER, RoomFeatures.SOUNDPROOFING)))); + @SuppressWarnings("unused") + Room room130 = roomRepository.save(new Room(null, "130", new ArrayList<>(Arrays.asList(RoomFeatures.BEAMER, RoomFeatures.SMART_BOARD, RoomFeatures.WIFI)))); + @SuppressWarnings("unused") + Room room140 = roomRepository.save(new Room(null, "140", new ArrayList<>(Arrays.asList(RoomFeatures.BEAMER, RoomFeatures.WHITEBOARD, RoomFeatures.POWER_OUTLETS)))); + @SuppressWarnings("unused") + Room room150 = roomRepository.save(new Room(null, "150", new ArrayList<>(Arrays.asList(RoomFeatures.BEAMER, RoomFeatures.LOCKERS)))); + @SuppressWarnings("unused") + Room room201_2 = roomRepository.save(new Room(null, "201", new ArrayList<>(Arrays.asList(RoomFeatures.BEAMER, RoomFeatures.WATER_SOURCE)))); + @SuppressWarnings("unused") + Room room202 = roomRepository.save(new Room(null, "202", new ArrayList<>(Arrays.asList(RoomFeatures.BEAMER, RoomFeatures.WHITEBOARD, RoomFeatures.AIR_CONDITIONING)))); + @SuppressWarnings("unused") + Room room210 = roomRepository.save(new Room(null, "210", new ArrayList<>(Arrays.asList(RoomFeatures.BEAMER, RoomFeatures.PROJECTOR_SCREEN)))); + @SuppressWarnings("unused") + Room room220 = roomRepository.save(new Room(null, "220", new ArrayList<>(Arrays.asList(RoomFeatures.BEAMER, RoomFeatures.SPEAKER_SYSTEM)))); + @SuppressWarnings("unused") + Room room230 = roomRepository.save(new Room(null, "230", new ArrayList<>(Arrays.asList(RoomFeatures.BEAMER, RoomFeatures.VIDEO_CONFERENCING, RoomFeatures.WIFI)))); + @SuppressWarnings("unused") + Room room240 = roomRepository.save(new Room(null, "240", new ArrayList<>(Arrays.asList(RoomFeatures.BEAMER, RoomFeatures.POWER_OUTLETS, RoomFeatures.NATURAL_LIGHT)))); + @SuppressWarnings("unused") + Room room250 = roomRepository.save(new Room(null, "250", new ArrayList<>(Arrays.asList(RoomFeatures.BEAMER, RoomFeatures.SMART_BOARD)))); + @SuppressWarnings("unused") + Room room301 = roomRepository.save(new Room(null, "301", new ArrayList<>(Arrays.asList(RoomFeatures.BEAMER, RoomFeatures.WHITEBOARD, RoomFeatures.TELEPHONE)))); + @SuppressWarnings("unused") + Room room310 = roomRepository.save(new Room(null, "310", new ArrayList<>(Arrays.asList(RoomFeatures.BEAMER, RoomFeatures.COFFEE_MACHINE)))); + @SuppressWarnings("unused") + Room room320 = roomRepository.save(new Room(null, "320", new ArrayList<>(Arrays.asList(RoomFeatures.BEAMER, RoomFeatures.PRINTER)))); + @SuppressWarnings("unused") + Room room330 = roomRepository.save(new Room(null, "330", new ArrayList<>(Arrays.asList(RoomFeatures.BEAMER, RoomFeatures.LOCKERS, RoomFeatures.WIFI)))); + @SuppressWarnings("unused") + Room room340 = roomRepository.save(new Room(null, "340", new ArrayList<>(Arrays.asList(RoomFeatures.BEAMER, RoomFeatures.WHITEBOARD, RoomFeatures.AIR_CONDITIONING, RoomFeatures.POWER_OUTLETS)))); + System.out.println("Sample Rooms have been added to the database."); - System.out.println("Sample Reservations have been added to the database."); + if (reservationRepository.count() == 0) { + reservationRepository.save(new Reservation( + null, + LocalDate.now(), + LocalTime.of(9, 0), + LocalTime.of(10, 0), + room101, + "Team Meeting", + "Tom, Johnson", + UUID.randomUUID(), + UUID.randomUUID() + )); + reservationRepository.save(new Reservation( + null, + LocalDate.now(), + LocalTime.of(11, 0), + LocalTime.of(12, 0), + room102, + "Project Discussion", + "Mac, Fluury", + UUID.randomUUID(), + UUID.randomUUID() + )); + reservationRepository.save(new Reservation( + null, + LocalDate.now(), + LocalTime.of(11, 0), + LocalTime.of(12, 0), + room102, + "Project Feedback", + "Pluh, Tompson", + UUID.randomUUID(), + UUID.randomUUID() + )); + System.out.println("Sample Reservations have been added to the database."); + } } } -} \ No newline at end of file +} diff --git a/OrariAperti/backend/src/main/resources/application.properties.example b/OrariAperti/backend/src/main/resources/application.properties.example index 44afada..5aa0b85 100644 --- a/OrariAperti/backend/src/main/resources/application.properties.example +++ b/OrariAperti/backend/src/main/resources/application.properties.example @@ -10,3 +10,6 @@ spring.jpa.hibernate.ddl-auto=update spring.jpa.show-sql=true spring.jpa.properties.hibernate.format_sql=true spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQLDialect + +# CORS and Redirect Configuration +frontend.url=http://localhost:3000 diff --git a/OrariAperti/frontend/.env.example b/OrariAperti/frontend/.env.example new file mode 100644 index 0000000..6a2c6d9 --- /dev/null +++ b/OrariAperti/frontend/.env.example @@ -0,0 +1 @@ +VITE_APP_BACKEND_URL=http://localhost:8080 # Might change depending on your backend configuration \ No newline at end of file diff --git a/OrariAperti/frontend/.gitignore b/OrariAperti/frontend/.gitignore index a547bf3..d730797 100644 --- a/OrariAperti/frontend/.gitignore +++ b/OrariAperti/frontend/.gitignore @@ -22,3 +22,4 @@ dist-ssr *.njsproj *.sln *.sw? +*.env diff --git a/.run/dev.run.xml b/OrariAperti/frontend/.run/Frontend.run.xml similarity index 58% rename from .run/dev.run.xml rename to OrariAperti/frontend/.run/Frontend.run.xml index fba0858..af1dea6 100644 --- a/.run/dev.run.xml +++ b/OrariAperti/frontend/.run/Frontend.run.xml @@ -1,6 +1,6 @@ - - + +