diff --git a/.idea/.gitignore b/.idea/.gitignore
deleted file mode 100644
index 13566b8..0000000
--- a/.idea/.gitignore
+++ /dev/null
@@ -1,8 +0,0 @@
-# Default ignored files
-/shelf/
-/workspace.xml
-# Editor-based HTTP Client requests
-/httpRequests/
-# Datasource local storage ignored files
-/dataSources/
-/dataSources.local.xml
diff --git a/.idea/artifacts/Bookings_jar.xml b/.idea/artifacts/Bookings_jar.xml
new file mode 100644
index 0000000..d46bedf
--- /dev/null
+++ b/.idea/artifacts/Bookings_jar.xml
@@ -0,0 +1,23 @@
+
+
+ $PROJECT_DIR$/out/artifacts/Bookings_jar
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml
deleted file mode 100644
index 1bec35e..0000000
--- a/.idea/codeStyles/Project.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml
deleted file mode 100644
index 79ee123..0000000
--- a/.idea/codeStyles/codeStyleConfig.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/dataSources.local.xml b/.idea/dataSources.local.xml
new file mode 100644
index 0000000..7a15961
--- /dev/null
+++ b/.idea/dataSources.local.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+ "
+
+
+ no-auth
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/dataSources.xml b/.idea/dataSources.xml
new file mode 100644
index 0000000..be8638c
--- /dev/null
+++ b/.idea/dataSources.xml
@@ -0,0 +1,17 @@
+
+
+
+
+ sqlite.xerial
+ true
+ org.sqlite.JDBC
+ jdbc:sqlite:C:\Users\mario\IdeaProjects\Bookings\assets\database\bookings.db
+ $ProjectFileDir$
+
+
+ file://$APPLICATION_CONFIG_DIR$/jdbc-drivers/Xerial SQLiteJDBC/3.39.2/sqlite-jdbc-3.39.2.jar
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/dataSources/0ae1950a-c940-4c90-bdb8-2907a895397f.xml b/.idea/dataSources/0ae1950a-c940-4c90-bdb8-2907a895397f.xml
new file mode 100644
index 0000000..008fe62
--- /dev/null
+++ b/.idea/dataSources/0ae1950a-c940-4c90-bdb8-2907a895397f.xml
@@ -0,0 +1,1488 @@
+
+
+
+
+ 3.39.2
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1
+ 1
+
+
+ 1
+ 1
+
+
+ 1
+ 1
+
+
+ 1
+ 1
+
+
+ 1
+ 1
+
+
+ 1
+ 1
+
+
+ 1
+ 1
+
+
+ 1
+ 1
+
+
+ 1
+ 1
+
+
+ 1
+ 1
+
+
+ 1
+ 1
+
+
+ 1
+ 1
+
+
+ 1
+ 1
+
+
+ 1
+ 1
+
+
+ 1
+ 1
+
+
+ 1
+ 1
+
+
+ window
+
+
+ 1
+ 1
+
+
+ 1
+ 1
+
+
+ window
+
+
+ 1
+ 1
+
+
+
+
+ 1
+
+
+ 1
+
+
+ 1
+
+
+
+ 1
+
+
+ 1
+
+
+ window
+
+
+ 1
+
+
+ window
+
+
+ 1
+
+
+
+ 1
+
+
+ 1
+
+
+ 1
+
+
+ 1
+
+
+
+
+ 1
+
+
+ window
+
+
+ 1
+
+
+ 1
+
+
+ window
+
+
+ window
+
+
+ 1
+
+
+ 1
+
+
+ 1
+
+
+ window
+
+
+
+ 1
+
+
+ window
+
+
+ 1
+
+
+ 1
+
+
+ 1
+
+
+ 1
+
+
+ 1
+
+
+
+ 1
+ window
+
+
+ window
+
+
+ 1
+
+
+ 1
+ window
+
+
+ 1
+
+
+ 1
+
+
+
+ 1
+
+
+ window
+
+
+ window
+
+
+
+ 1
+
+
+ 1
+
+
+ window
+
+
+
+
+
+ 1
+
+
+ 1
+
+
+ 1
+
+
+ 1
+
+
+
+ window
+
+
+ 1
+
+
+ 1
+
+
+ window
+
+
+ 1
+
+
+
+
+ window
+
+
+ 1
+
+
+ window
+
+
+ window
+
+
+ window
+
+
+ 1
+
+
+ 1
+
+
+ window
+
+
+ 1
+
+
+ 1
+
+
+ aggregate
+
+
+ aggregate
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ aggregate
+
+
+
+ aggregate
+
+
+
+
+
+
+
+
+ aggregate
+
+
+
+
+
+
+
+
+
+
+
+
+ aggregate
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1
+
+
+ R
+
+
+ R
+
+
+ R
+
+
+ R
+
+
+ R
+
+
+ R
+
+
+ R
+
+
+ R
+
+
+ R
+
+
+ R
+
+
+ R
+
+
+ R
+
+
+ R
+
+
+ R
+
+
+ R
+
+
+ R
+
+
+ R
+
+
+ 1
+
+
+ 2
+
+
+ 3
+
+
+ R
+
+
+ R
+
+
+ R
+
+
+ 1
+
+
+ 2
+
+
+ 3
+
+
+ R
+
+
+ R
+
+
+ 1
+
+
+ 2
+
+
+ 3
+
+
+ R
+
+
+ 1
+
+
+ 2
+
+
+ R
+
+
+ R
+
+
+ R
+
+
+ R
+
+
+ 1
+
+
+ 2
+
+
+ R
+
+
+ R
+
+
+ R
+
+
+ 1
+
+
+ 2
+
+
+ R
+
+
+ 1
+
+
+ 2
+
+
+ R
+
+
+ 1
+
+
+ R
+
+
+ 1
+
+
+ 2
+
+
+ R
+
+
+ 1
+
+
+ R
+
+
+ 1
+
+
+ R
+
+
+ 1
+
+
+ R
+
+
+ 1
+
+
+ 2
+
+
+ R
+
+
+ 1
+
+
+ 2
+
+
+ R
+
+
+ R
+
+
+ 1
+
+
+ R
+
+
+ 1
+
+
+ 2
+
+
+ R
+
+
+ 1
+
+
+ R
+
+
+ 1
+
+
+ R
+
+
+ 1
+
+
+ 2
+
+
+ R
+
+
+ 1
+
+
+ R
+
+
+ R
+
+
+ 1
+
+
+ R
+
+
+ 1
+
+
+ 2
+
+
+ R
+
+
+ 1
+
+
+ 2
+
+
+ R
+
+
+ 1
+
+
+ 2
+
+
+ R
+
+
+ R
+
+
+ 1
+
+
+ 2
+
+
+ R
+
+
+ 1
+
+
+ R
+
+
+ 1
+
+
+ 2
+
+
+ 3
+
+
+ R
+
+
+ 1
+
+
+ 2
+
+
+ 3
+
+
+ R
+
+
+ 1
+
+
+ R
+
+
+ 1
+
+
+ R
+
+
+ 1
+
+
+ R
+
+
+ 1
+
+
+ 2
+
+
+ R
+
+
+ 1
+
+
+ R
+
+
+ 1
+
+
+ R
+
+
+ 1
+
+
+ R
+
+
+ 1
+
+
+ 2
+
+
+ R
+
+
+ 1
+
+
+ 2
+
+
+ R
+
+
+ 1
+
+
+ 2
+
+
+ 3
+
+
+ R
+
+
+ 1
+
+
+ R
+
+
+ 1
+
+
+ R
+
+
+ R
+
+
+ R
+
+
+ R
+
+
+ 1
+
+
+ 2
+
+
+ R
+
+
+ 1
+
+
+ R
+
+
+ 1
+
+
+ R
+
+
+ R
+
+
+ R
+
+
+ R
+
+
+ 1
+
+
+ 2
+
+
+ R
+
+
+ 1
+
+
+ R
+
+
+ 1
+
+
+ R
+
+
+ 1
+
+
+ 2
+
+
+ 3
+
+
+ R
+
+
+ R
+
+
+ R
+
+
+ 1
+
+
+ 2
+
+
+ R
+
+
+ 1
+
+
+ R
+
+
+ R
+
+
+ 1
+
+
+ 2
+
+
+ R
+
+
+ R
+
+
+ R
+
+
+ 1
+
+
+ 2
+
+
+ R
+
+
+ 1
+
+
+ 2
+
+
+ 3
+
+
+ R
+
+
+ 1
+
+
+ R
+
+
+ 1
+
+
+ R
+
+
+ 1
+
+
+ 2
+
+
+ R
+
+
+ 1
+
+
+ R
+
+
+ 1
+
+
+ 2
+
+
+ R
+
+
+ 1
+
+
+ R
+
+
+ 1
+
+
+ R
+
+
+ 1
+
+
+ R
+
+
+ 1
+
+
+ R
+
+
+ 1
+
+
+ R
+
+
+ 1
+
+
+ 2
+
+
+ R
+
+
+ 1
+
+
+ 2
+
+
+ R
+
+
+ 1
+
+
+ 2
+
+
+ R
+
+
+ 1
+
+
+ 2
+
+
+ R
+
+
+ 1
+
+
+ 2
+
+
+ R
+
+
+ 1
+
+
+ 2
+
+
+ R
+
+
+ 1
+
+
+ 2
+
+
+ R
+
+
+ R
+
+
+ 1
+
+
+ R
+
+
+ 1
+
+
+ R
+
+
+ 1
+
+
+ R
+
+
+ 1
+
+
+ R
+
+
+ 1
+
+
+ R
+
+
+ 1
+
+
+ R
+
+
+ 1
+
+
+ 2
+
+
+ R
+
+
+ 1
+
+
+ R
+
+
+ 1
+
+
+ R
+
+
+ 1
+
+
+ R
+
+
+ 1
+
+
+ 2
+
+
+ R
+
+
+ 1
+
+
+ R
+
+
+ 1
+
+
+ 2
+
+
+ R
+
+
+ 1
+
+
+ R
+
+
+ 1
+
+
+ R
+
+
+ 1
+
+
+ R
+
+
+ 1
+
+
+ R
+
+
+ 1
+
+
+ R
+
+
+ 1
+
+
+ R
+
+
+ 1
+
+
+ R
+
+
+ 1
+
+
+ 2
+
+
+ R
+
+
+ 1
+
+
+ R
+
+
+ 1
+
+
+ R
+
+
+ 1
+
+
+ R
+
+
+ 1
+
+
+ R
+
+
+ 1
+
+
+ R
+
+
+ R
+
+
+ 1
+
+
+ R
+
+
+ 1
+
+
+ R
+
+
+ 1
+
+
+ R
+
+
+ 1
+
+
+ R
+
+
+ 1
+
+
+ R
+
+
+ 1
+
+
+ R
+
+
+ 1
+
+
+ R
+
+
+ 1
+
+
+ 2
+
+
+ R
+
+
+ 1
+
+
+ R
+
+
+ 1
+
+
+ R
+
+
+ 1
+
+
+ 2
+
+
+ R
+
+
+ 1
+
+
+ 2
+
+
+ R
+
+
+ 1
+
+
+ R
+
+
+ 1
+
+
+ R
+
+
+ 1
+
+
+ R
+
+
+ 1
+
+
+
+
+
+
+
+
+
+ 1
+ INTEGER|0s
+ 1
+
+
+ INTEGER|0s
+ 1
+ 2
+
+
+ TEXT|0s
+ 1
+ 3
+
+
+ TEXT|0s
+ 1
+ 4
+
+
+ TEXT|0s
+ 1
+ 5
+
+
+ TEXT|0s
+ 1
+ 6
+
+
+ TEXT|0s
+ 1
+ 7
+
+
+ INTEGER|0s
+ 1
+ 8
+
+
+ id
+ 1
+
+
+ TEXT|0s
+ 1
+
+
+ TEXT|0s
+ 1
+ 2
+
+
+ TEXT|0s
+ 1
+ 3
+
+
+ name
+ 1
+ 1
+
+
+ name
+ 1
+ sqlite_autoindex_guests_1
+
+
+ 1
+ INTEGER|0s
+ 1
+
+
+ TEXT|0s
+ 1
+ 2
+
+
+ id
+ 1
+
+
+ TEXT|0s
+ 1
+
+
+ TEXT|0s
+ 2
+
+
+ name
+ 1
+ 1
+
+
+ name
+ 1
+ sqlite_autoindex_settings_1
+
+
+ TEXT|0s
+ 1
+
+
+ TEXT|0s
+ 2
+
+
+ TEXT|0s
+ 3
+
+
+ INT|0s
+ 4
+
+
+ TEXT|0s
+ 5
+
+
+ 1
+
+
+ 2
+
+
+ TEXT|0s
+ 1
+
+
+ TEXT|0s
+ 1
+ 2
+
+
+ INTEGER|0s
+ 1
+ 3
+
+
+ INTEGER|0s
+ 1
+ 4
+
+
+ INTEGER|0s
+ 1
+ 5
+
+
+ username
+ 1
+ 1
+
+
+ username
+ 1
+ sqlite_autoindex_users_1
+
+
+
\ No newline at end of file
diff --git a/.idea/encodings.xml b/.idea/encodings.xml
index 9462bc8..aa00ffa 100644
--- a/.idea/encodings.xml
+++ b/.idea/encodings.xml
@@ -1,9 +1,7 @@
-
-
-
+
\ No newline at end of file
diff --git a/.idea/kotlinc.xml b/.idea/kotlinc.xml
deleted file mode 100644
index 4251b72..0000000
--- a/.idea/kotlinc.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
index 0ff3673..0abcc97 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -1,14 +1,12 @@
+
-
-
-
+
\ No newline at end of file
diff --git a/.idea/workspace.xml b/.idea/workspace.xml
new file mode 100644
index 0000000..74c0acf
--- /dev/null
+++ b/.idea/workspace.xml
@@ -0,0 +1,204 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1673473439642
+
+
+ 1673473439642
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/assets/database/bookings.db b/assets/database/bookings.db
new file mode 100644
index 0000000..d992bf9
Binary files /dev/null and b/assets/database/bookings.db differ
diff --git a/pom.xml b/pom.xml
index c4ae276..cdf759a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -11,11 +11,31 @@
UTF-8
- 5.9.0
- 1.7.22
+ 5.9.2
+
+ org.apache.pdfbox
+ pdfbox
+ 2.0.27
+
+
+ org.controlsfx
+ controlsfx
+ 11.1.2
+
+
+ org.xerial
+ sqlite-jdbc
+ 3.40.0.0
+
+
+ org.openjfx
+ javafx-media
+ 19
+
+
org.openjfx
javafx-controls
@@ -39,15 +59,9 @@
${junit.version}
test
-
- org.jetbrains.kotlin
- kotlin-stdlib-jdk8
- ${kotlin.version}
-
- ${project.basedir}/src/main/kotlin
org.apache.maven.plugins
@@ -79,30 +93,6 @@
-
- org.jetbrains.kotlin
- kotlin-maven-plugin
- ${kotlin.version}
-
-
- compile
- process-sources
-
- compile
-
-
-
- test-compile
- test-compile
-
- test-compile
-
-
-
-
- 11
-
-
\ No newline at end of file
diff --git a/src/main/java/com/github/mariosplen/bookings/Bookings.java b/src/main/java/com/github/mariosplen/bookings/Bookings.java
new file mode 100644
index 0000000..f2f2cd7
--- /dev/null
+++ b/src/main/java/com/github/mariosplen/bookings/Bookings.java
@@ -0,0 +1,20 @@
+package com.github.mariosplen.bookings;
+
+import com.github.mariosplen.bookings.util.Nav;
+import javafx.application.Application;
+import javafx.stage.Stage;
+
+import java.io.IOException;
+
+public class Bookings extends Application {
+
+ public static void main(String[] args) {
+ launch();
+ }
+
+ @Override
+ public void start(Stage stage) throws IOException {
+ Nav.toLoading(stage);
+ }
+}
+
diff --git a/src/main/java/com/github/mariosplen/bookings/Main.java b/src/main/java/com/github/mariosplen/bookings/Main.java
new file mode 100644
index 0000000..1a0375b
--- /dev/null
+++ b/src/main/java/com/github/mariosplen/bookings/Main.java
@@ -0,0 +1,8 @@
+package com.github.mariosplen.bookings;
+
+
+public class Main {
+ public static void main(String[] args) {
+ Bookings.main(args);
+ }
+}
diff --git a/src/main/java/com/github/mariosplen/bookings/controllers/MainView.java b/src/main/java/com/github/mariosplen/bookings/controllers/MainView.java
new file mode 100644
index 0000000..5845bb1
--- /dev/null
+++ b/src/main/java/com/github/mariosplen/bookings/controllers/MainView.java
@@ -0,0 +1,67 @@
+package com.github.mariosplen.bookings.controllers;
+
+
+import com.github.mariosplen.bookings.models.User;
+import com.github.mariosplen.bookings.util.Nav;
+import javafx.application.Platform;
+import javafx.fxml.FXML;
+import javafx.fxml.Initializable;
+import javafx.scene.Node;
+import javafx.scene.control.Button;
+import javafx.scene.layout.BorderPane;
+import javafx.scene.layout.HBox;
+import javafx.scene.text.Text;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.ResourceBundle;
+
+public class MainView implements Initializable {
+ private final User user;
+ public HBox mainViewUsernameHBox;
+ public Text mainViewUsername;
+ public BorderPane contentPane;
+
+
+ @FXML
+ private Button backBtn;
+
+
+ public MainView(User user, Node content) {
+ this.user = user;
+ Platform.runLater(() -> contentPane.setCenter(content));
+
+
+ }
+
+ public Button getBackBtn() {
+ return backBtn;
+ }
+
+ @Override
+ public void initialize(URL url, ResourceBundle resourceBundle) {
+
+ if (user != null) {
+ mainViewUsername.setText(user.username().toUpperCase());
+ backBtn.setOnAction(event -> {
+ try {
+ Nav.toHome();
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ });
+ } else {
+ mainViewUsernameHBox.setVisible(false);
+ backBtn.setOnAction(event -> {
+ try {
+ Nav.user = null;
+ Nav.toLogin();
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ });
+ }
+ }
+
+
+}
diff --git a/src/main/java/com/github/mariosplen/bookings/controllers/books/BooksView.java b/src/main/java/com/github/mariosplen/bookings/controllers/books/BooksView.java
new file mode 100644
index 0000000..e33e70d
--- /dev/null
+++ b/src/main/java/com/github/mariosplen/bookings/controllers/books/BooksView.java
@@ -0,0 +1,141 @@
+package com.github.mariosplen.bookings.controllers.books;
+
+
+import com.github.mariosplen.bookings.models.Book;
+import com.github.mariosplen.bookings.models.BookDAO;
+import com.github.mariosplen.bookings.models.Guest;
+import com.github.mariosplen.bookings.models.GuestDAO;
+import com.github.mariosplen.bookings.util.ReceiptGenerator;
+import javafx.beans.property.SimpleIntegerProperty;
+import javafx.beans.property.SimpleObjectProperty;
+import javafx.beans.property.SimpleStringProperty;
+import javafx.collections.ObservableList;
+import javafx.fxml.FXML;
+import javafx.fxml.Initializable;
+import javafx.scene.control.Button;
+import javafx.scene.control.TableCell;
+import javafx.scene.control.TableColumn;
+import javafx.scene.control.TableView;
+
+import java.io.IOException;
+import java.net.URL;
+import java.sql.SQLException;
+import java.util.Objects;
+import java.util.ResourceBundle;
+
+public class BooksView implements Initializable {
+
+
+ @FXML
+ ObservableList books;
+ @FXML
+ private TableView bookTableView;
+ @FXML
+ private TableColumn
+ saveButtonColumn,
+ deleteButtonColumn;
+ @FXML
+ private TableColumn
+ room_id,
+ nights,
+ price;
+ @FXML
+ private TableColumn
+ check_in,
+ check_out,
+ guest_name,
+ room_category,
+ date;
+
+
+ private void tableViewValues() throws SQLException, ClassNotFoundException {
+ ObservableList roomObservableList = BookDAO.getBooks();
+ saveButtonColumn.setCellValueFactory(param -> new SimpleObjectProperty<>(new Button("Save")));
+ saveButtonColumn.setCellFactory(param -> new TableCell<>() {
+ final Button button = new Button("Save");
+
+ @Override
+ protected void updateItem(Button item, boolean empty) {
+ button.getStyleClass().add("verySmallBtn");
+ super.updateItem(item, empty);
+ if (empty) {
+ setGraphic(null);
+ } else {
+ button.setOnAction(event -> {
+ Book book = getTableView().getItems().get(getIndex());
+ try {
+ ReceiptGenerator receiptGenerator = new ReceiptGenerator();
+ receiptGenerator.genReceipt(GuestDAO.getGuests().stream()
+ .map(Guest::name)
+ .filter(name -> Objects.equals(name, book.guestName()))
+ .findFirst()
+ .orElse(null),
+ book.checkIn(),
+ book.checkOut(),
+ book.totalPrice()
+ );
+ } catch (IOException | SQLException | ClassNotFoundException e) {
+ throw new RuntimeException(e);
+ }
+ });
+ setGraphic(button);
+ }
+ }
+ });
+ deleteButtonColumn.setCellFactory(param -> new TableCell<>() {
+ final Button button = new Button("Delete");
+
+
+ @Override
+ protected void updateItem(Button item, boolean empty) {
+ button.getStyleClass().add("verySmallRedBtn");
+ super.updateItem(item, empty);
+ if (empty) {
+ setGraphic(null);
+ } else {
+ button.setOnAction(event -> {
+ Book book = getTableView().getItems().get(getIndex());
+ try {
+
+ // Delete the book from the database using the BookDAO class
+ BookDAO.deleteBook(book.id());
+ // Remove the book from the table's data
+ books.remove(book);
+ } catch (SQLException | ClassNotFoundException e) {
+ throw new RuntimeException(e);
+ }
+ try {
+ tableViewValues();
+ } catch (SQLException | ClassNotFoundException e) {
+ throw new RuntimeException(e);
+ }
+ });
+ setGraphic(button);
+ }
+ }
+ });
+
+ guest_name.setCellValueFactory(p -> new SimpleStringProperty(p.getValue().guestName()));
+ room_id.setCellValueFactory(p -> new SimpleIntegerProperty(p.getValue().roomId()));
+ check_in.setCellValueFactory(p -> new SimpleStringProperty(p.getValue().checkIn().toString()));
+ check_out.setCellValueFactory(p -> new SimpleStringProperty(p.getValue().checkOut().toString()));
+ date.setCellValueFactory(p -> new SimpleStringProperty(p.getValue().date().toString()));
+ room_category.setCellValueFactory(p -> new SimpleStringProperty(p.getValue().roomCategory()));
+ price.setCellValueFactory(p -> new SimpleIntegerProperty(p.getValue().totalPrice()));
+ nights.setCellValueFactory(p -> new SimpleIntegerProperty(p.getValue().checkIn().until(p.getValue().checkOut()).getDays()));
+
+ bookTableView.setItems(roomObservableList);
+ }
+
+
+ @Override
+ public void initialize(URL url, ResourceBundle resourceBundle) {
+
+ try {
+ books = BookDAO.getBooks();
+ tableViewValues();
+ } catch (SQLException | ClassNotFoundException e) {
+ throw new RuntimeException(e);
+ }
+ }
+}
diff --git a/src/main/java/com/github/mariosplen/bookings/controllers/calendar/CalendarView.java b/src/main/java/com/github/mariosplen/bookings/controllers/calendar/CalendarView.java
new file mode 100644
index 0000000..f211a4a
--- /dev/null
+++ b/src/main/java/com/github/mariosplen/bookings/controllers/calendar/CalendarView.java
@@ -0,0 +1,160 @@
+package com.github.mariosplen.bookings.controllers.calendar;
+
+
+import com.github.mariosplen.bookings.models.BookDAO;
+import com.github.mariosplen.bookings.models.Room;
+import com.github.mariosplen.bookings.models.RoomDAO;
+import javafx.fxml.FXML;
+import javafx.fxml.Initializable;
+import javafx.geometry.Insets;
+import javafx.scene.control.DatePicker;
+import javafx.scene.control.Label;
+import javafx.scene.control.Tooltip;
+import javafx.scene.layout.BorderPane;
+import javafx.scene.layout.GridPane;
+
+import java.net.URL;
+import java.sql.SQLException;
+import java.time.LocalDate;
+import java.time.YearMonth;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.ResourceBundle;
+
+public class CalendarView implements Initializable {
+ Map> roomBookDates;
+ @FXML
+ private GridPane gridPane;
+ @FXML
+ private DatePicker fromDP;
+ @FXML
+ private DatePicker toDP;
+ private LocalDate fromDate;
+ private List rooms;
+
+ // Initializes the calendar view when it is loaded
+ @Override
+ public void initialize(URL url, ResourceBundle resourceBundle) {
+ // Get rooms from database
+ try {
+ rooms = RoomDAO.getRooms();
+ } catch (SQLException | ClassNotFoundException e) {
+ throw new RuntimeException(e);
+ }
+
+ // Set default dates for the from and to date pickers
+ fromDP.setValue(YearMonth.now().atDay(1));
+ toDP.setValue(YearMonth.now().atEndOfMonth());
+
+
+ setCalendarData();
+
+ }
+
+ @FXML
+ private void setCalendarData() {
+
+ gridPane.getChildren().clear();
+
+ // Get values from the datePickers
+ fromDate = fromDP.getValue();
+ LocalDate toDate = toDP.getValue();
+
+ // Get a list of all the dates between the start and end dates
+ List allDates = new ArrayList<>(fromDate.datesUntil(toDate).toList());
+
+ // Set the calendar tag
+ Label roomTag = new Label("Room");
+ roomTag.getStyleClass().add("calendarCellTagWhite");
+ roomTag.setPadding(new Insets(2));
+ gridPane.add(roomTag, 0, 0);
+
+ // Set the rooms in the calendar grid
+ for (int i = 0; i < rooms.size(); i++) {
+ Label roomIdText = new Label(String.valueOf(rooms.get(i).id()));
+ roomIdText.getStyleClass().add("calendarCellTagBlack");
+ BorderPane centered = new BorderPane();
+ centered.setCenter(roomIdText);
+ gridPane.addRow(i + 1, centered);
+ }
+
+
+ // Set the dates in the calendar grid
+ for (int i = 0; i < allDates.size(); i++) {
+ Label dateText = new Label(allDates.get(i).toString());
+ dateText.getStyleClass().add("calendarCellTagWhite");
+ dateText.setPadding(new Insets(2, 8, 2, 8));
+ BorderPane centered = new BorderPane();
+ centered.setCenter(dateText);
+ gridPane.addColumn(i + 1, centered);
+ }
+
+
+ // Get a map of room bookings, with the room id as the key and a list of booked dates as the value
+ try {
+ roomBookDates = BookDAO.getRoomBookDates();
+ } catch (SQLException | ClassNotFoundException e) {
+ throw new RuntimeException(e);
+ }
+
+ // Fill gridPane with available ColoredItems
+ for (int r = 0; r < rooms.size(); r++) {
+ for (int c = 0; c < allDates.size(); c++) {
+ ColoredItem box = new ColoredItem();
+ BorderPane centered = new BorderPane();
+ centered.setCenter(box);
+ gridPane.add(centered, c + 1, r + 1);
+ }
+ }
+
+
+ roomBookDates.forEach((integer, localDates) -> {
+ for (int i = 0; i < rooms.size(); i++) {
+ if (String.valueOf(rooms.get(i).id()).equals(String.valueOf(integer))) {
+ for (LocalDate date : localDates) {
+ for (int j = 0; j < allDates.size(); j++) {
+ if (allDates.get(j).equals(date)) {
+ int finalI = i;
+ int finalJ = j;
+ gridPane.getChildren().forEach(node -> {
+ if (GridPane.getColumnIndex(node) == (finalJ + 1) && GridPane.getRowIndex(node) == (finalI + 1)) {
+ node.setDisable(true);
+ Tooltip.install(node, new Tooltip("Book_id = " + integer));
+ }
+ });
+ }
+ }
+
+ }
+ }
+ }
+
+ });
+ }
+
+ public void onNextMonthClk() {
+ LocalDate initial = fromDate.plusMonths(1);
+
+ LocalDate nextStartOfMonth = initial.withDayOfMonth(1);
+ LocalDate nextEndOfMonth =
+ initial.withDayOfMonth(initial.getMonth().length(initial.isLeapYear()));
+
+ fromDP.setValue(nextStartOfMonth);
+ toDP.setValue(nextEndOfMonth);
+ setCalendarData();
+ }
+
+ public void onPrevMonthClk() {
+
+ LocalDate initial = fromDate.minusMonths(1);
+
+ LocalDate prevStartOfMonth = initial.withDayOfMonth(1);
+ LocalDate prevEndOfMonth =
+ initial.withDayOfMonth(initial.getMonth().length(initial.isLeapYear()));
+
+ fromDP.setValue(prevStartOfMonth);
+ toDP.setValue(prevEndOfMonth);
+ setCalendarData();
+ }
+}
diff --git a/src/main/java/com/github/mariosplen/bookings/controllers/calendar/ColoredItem.java b/src/main/java/com/github/mariosplen/bookings/controllers/calendar/ColoredItem.java
new file mode 100644
index 0000000..a3a3828
--- /dev/null
+++ b/src/main/java/com/github/mariosplen/bookings/controllers/calendar/ColoredItem.java
@@ -0,0 +1,15 @@
+package com.github.mariosplen.bookings.controllers.calendar;
+
+import javafx.scene.shape.Rectangle;
+
+public class ColoredItem extends Rectangle {
+
+
+ public ColoredItem() {
+ setWidth(127);
+ setHeight(30);
+ getStyleClass().add("calendarCell");
+
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/github/mariosplen/bookings/controllers/guests/GuestsView.java b/src/main/java/com/github/mariosplen/bookings/controllers/guests/GuestsView.java
new file mode 100644
index 0000000..2c50df5
--- /dev/null
+++ b/src/main/java/com/github/mariosplen/bookings/controllers/guests/GuestsView.java
@@ -0,0 +1,99 @@
+package com.github.mariosplen.bookings.controllers.guests;
+
+
+import com.github.mariosplen.bookings.models.Guest;
+import com.github.mariosplen.bookings.models.GuestDAO;
+import javafx.collections.FXCollections;
+import javafx.event.ActionEvent;
+import javafx.fxml.FXML;
+import javafx.fxml.Initializable;
+import javafx.scene.control.Button;
+import javafx.scene.control.Label;
+import javafx.scene.control.TextField;
+import org.controlsfx.control.SearchableComboBox;
+
+import java.net.URL;
+import java.sql.SQLException;
+import java.util.List;
+import java.util.Map;
+import java.util.ResourceBundle;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+public class GuestsView implements Initializable {
+ @FXML
+ private Label msg;
+ @FXML
+ private Button selectedBtn;
+ @FXML
+ private TextField selectedTF;
+ private Guest guest;
+ @FXML
+ private SearchableComboBox usersSearchBox;
+ private String selectedInfoToEdit;
+ private Map guestMap;
+
+ @Override
+ public void initialize(URL url, ResourceBundle resourceBundle) {
+ // Load the list of guests from the database
+ try {
+ List guestList = GuestDAO.getGuests();
+ guestMap = guestList.stream().collect(Collectors.toMap(Guest::name, Function.identity()));
+ } catch (SQLException | ClassNotFoundException e) {
+ throw new RuntimeException(e);
+ }
+
+ // Populate the searchable combo box with the names of the guests
+ usersSearchBox.setItems(FXCollections.observableArrayList(guestMap.keySet()));
+ }
+
+ public void clickedEditSelector(ActionEvent actionEvent) {
+ msg.setVisible(false);
+ // Get the text of the button that was clicked
+ selectedInfoToEdit = ((Button) actionEvent.getSource()).getText();
+ // Set the text of the selected button to the selected info to edit
+ selectedBtn.setText(selectedInfoToEdit);
+ // Find the selected guest based on the selected name in the combo box
+ guest = guestMap.get(usersSearchBox.getValue());
+
+ if (selectedInfoToEdit != null) {
+ // Enable editing for the selected text field
+ selectedTF.setEditable(true);
+ }
+
+ if (guest != null) {
+ // Set the text of the selected text field to the selected info for the guest
+ assert selectedInfoToEdit != null;
+ selectedTF.setText(selectedInfoToEdit);
+ }
+ }
+
+ public void selectedNewUserClicked() {
+ msg.setVisible(false);
+ // Find the selected guest based on the selected name in the combo box
+ guest = guestMap.get(usersSearchBox.getValue());
+
+ if (guest != null && selectedInfoToEdit != null) {
+ // Set the text of the selected text field to the selected info for the guest
+ selectedTF.setText(selectedInfoToEdit);
+ }
+ }
+
+
+ public void onSaveClicked() throws SQLException, ClassNotFoundException {
+ String databasePar = selectedInfoToEdit;
+ msg.setVisible(false);
+ if (databasePar != null) {
+
+ GuestDAO.updateData(guest.name(), databasePar, selectedTF.getText());
+
+ // Refresh the list of guests from the database
+ guestMap = GuestDAO.getGuests().stream().collect(Collectors.toMap(Guest::name, Function.identity()));
+
+ // Update the items in the combo box to reflect the updated list of guests
+ usersSearchBox.setItems(FXCollections.observableArrayList(guestMap.keySet()));
+ msg.setVisible(true);
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/github/mariosplen/bookings/controllers/home/HomeView.java b/src/main/java/com/github/mariosplen/bookings/controllers/home/HomeView.java
new file mode 100644
index 0000000..e370140
--- /dev/null
+++ b/src/main/java/com/github/mariosplen/bookings/controllers/home/HomeView.java
@@ -0,0 +1,96 @@
+package com.github.mariosplen.bookings.controllers.home;
+
+
+import com.github.mariosplen.bookings.util.Nav;
+import javafx.fxml.FXML;
+import javafx.fxml.Initializable;
+import javafx.scene.control.Button;
+import javafx.scene.layout.HBox;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.ResourceBundle;
+
+
+public class HomeView implements Initializable {
+
+
+ @FXML
+ private Button newGuestBtn, calendarBtn, guestsButton, usersButton, checkInBtn, booksBtn;
+ @FXML
+ private HBox logoutButton;
+
+
+ public void refresh() {
+ if (Nav.user.canManageGuests()) {
+ guestsButton.setDisable(false);
+ }
+ if (Nav.user.canManageUsers()) {
+ usersButton.setDisable(false);
+ }
+ if (Nav.user.canDoBasic()) {
+ checkInBtn.setDisable(false);
+ newGuestBtn.setDisable(false);
+ calendarBtn.setDisable(false);
+ booksBtn.setDisable(false);
+ }
+ }
+
+
+ @Override
+ public void initialize(URL url, ResourceBundle resourceBundle) {
+ refresh();
+
+ newGuestBtn.setOnAction(actionEvent -> {
+ try {
+ Nav.toNewGuest();
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ });
+ calendarBtn.setOnAction(actionEvent -> {
+ try {
+ Nav.toCalendar();
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ });
+ guestsButton.setOnAction(actionEvent -> {
+ try {
+ Nav.toGuests();
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ });
+ usersButton.setOnAction(actionEvent -> {
+ try {
+ Nav.toUsers();
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ });
+ logoutButton.setOnMouseClicked(mouseEvent -> {
+ try {
+ Nav.toLogin();
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ });
+ checkInBtn.setOnAction(actionEvent -> {
+ try {
+ Nav.toReservation();
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ });
+ booksBtn.setOnAction(actionEvent -> {
+ try {
+
+ Nav.toBooks();
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ });
+
+ }
+}
diff --git a/src/main/java/com/github/mariosplen/bookings/controllers/loading/LoadingView.java b/src/main/java/com/github/mariosplen/bookings/controllers/loading/LoadingView.java
new file mode 100644
index 0000000..a447add
--- /dev/null
+++ b/src/main/java/com/github/mariosplen/bookings/controllers/loading/LoadingView.java
@@ -0,0 +1,96 @@
+package com.github.mariosplen.bookings.controllers.loading;
+
+import com.github.mariosplen.bookings.util.Nav;
+import javafx.animation.PauseTransition;
+import javafx.animation.ScaleTransition;
+import javafx.animation.SequentialTransition;
+import javafx.animation.TranslateTransition;
+import javafx.fxml.FXML;
+import javafx.fxml.Initializable;
+import javafx.scene.media.Media;
+import javafx.scene.media.MediaPlayer;
+import javafx.scene.media.MediaView;
+import javafx.scene.text.Text;
+import javafx.util.Duration;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.Objects;
+import java.util.ResourceBundle;
+
+public class LoadingView implements Initializable {
+ @FXML
+ private Text shadow1, shadow2, title;
+ @FXML
+ private MediaView intro;
+
+
+ @Override
+ public void initialize(URL url, ResourceBundle resourceBundle) {
+
+ // Start the animations
+ playAnimations();
+
+ // Animations end at approximately 7.5 seconds, then continue
+ PauseTransition delay = new PauseTransition(Duration.seconds(7.5));
+ delay.setOnFinished((ActionEvent) -> {
+ try {
+ goToSignIn();
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ });
+ delay.play();
+ }
+
+ private void goToSignIn() throws IOException {
+
+ Nav.toLogin();
+
+ }
+
+ private void playAnimations() {
+ // Instant Scale down
+ ScaleTransition scaleDown = new ScaleTransition(Duration.millis(0.1), title);
+ scaleDown.setToX(0);
+ scaleDown.setToY(0);
+
+ // Scale up
+ ScaleTransition scaleUp = new ScaleTransition(Duration.seconds(2), title);
+ scaleUp.setByX(1f);
+ scaleUp.setByY(1f);
+
+ // Slide up
+ TranslateTransition slideUp = new TranslateTransition(Duration.seconds(1), title);
+ slideUp.setByY(-211);
+
+ // Fade in the shadows
+ TranslateTransition firstShadow = new TranslateTransition(Duration.seconds(0.1), shadow1);
+ firstShadow.setByY(+25);
+ TranslateTransition secondShadow = new TranslateTransition(Duration.seconds(0.1), shadow2);
+ secondShadow.setByY(+50);
+
+ // Play the transitions in sequence
+ SequentialTransition sequentialTransition = new SequentialTransition();
+ sequentialTransition.getChildren().addAll(scaleDown, scaleUp, slideUp);
+ sequentialTransition.setOnFinished(actionEvent -> {
+ shadow1.setVisible(true);
+ shadow2.setVisible(true);
+ firstShadow.play();
+ secondShadow.play();
+ });
+ // Set up the intro video
+ MediaPlayer player = new MediaPlayer(new Media(Objects.requireNonNull(getClass().getResource("/com/github/mariosplen/bookings/media/intro/intro.mp4")).toExternalForm()));
+
+ player.setAutoPlay(true);
+
+
+ intro.setMediaPlayer(player);
+
+ // Show the title when the video ends
+ player.setOnEndOfMedia(() -> {
+ title.setVisible(true);
+ sequentialTransition.play();
+ });
+ }
+}
diff --git a/src/main/java/com/github/mariosplen/bookings/controllers/login/LoginView.java b/src/main/java/com/github/mariosplen/bookings/controllers/login/LoginView.java
new file mode 100644
index 0000000..65b7b51
--- /dev/null
+++ b/src/main/java/com/github/mariosplen/bookings/controllers/login/LoginView.java
@@ -0,0 +1,52 @@
+package com.github.mariosplen.bookings.controllers.login;
+
+import com.github.mariosplen.bookings.models.User;
+import com.github.mariosplen.bookings.models.UserDAO;
+import com.github.mariosplen.bookings.util.Nav;
+import javafx.fxml.FXML;
+import javafx.scene.control.PasswordField;
+import javafx.scene.control.TextField;
+import javafx.scene.text.Text;
+
+import java.io.IOException;
+import java.sql.SQLException;
+
+public class LoginView {
+ @FXML
+ private PasswordField passwordTF;
+ @FXML
+ private TextField usernameTF;
+ @FXML
+ private Text errorMsg;
+
+
+ @FXML
+ private void onLoginBtnClicked() throws SQLException, ClassNotFoundException, IOException {
+
+ // Try to log the user in
+ User user = UserDAO.login(usernameTF.getText(), passwordTF.getText());
+
+ // If the login fails, display an error message
+ if (user == null) {
+ errorMsg.setVisible(true);
+ return;
+ }
+ Nav.user = user;
+ Nav.toHome();
+
+
+ }
+
+ @FXML
+ private void onForgotPassHLClicked() throws IOException {
+ Nav.toRecovery();
+ }
+
+
+ @FXML
+ private void onRegisterHLClicked() throws IOException {
+ Nav.toRegister();
+ }
+
+
+}
diff --git a/src/main/java/com/github/mariosplen/bookings/controllers/new_guest/NewGuestView.java b/src/main/java/com/github/mariosplen/bookings/controllers/new_guest/NewGuestView.java
new file mode 100644
index 0000000..922f8fa
--- /dev/null
+++ b/src/main/java/com/github/mariosplen/bookings/controllers/new_guest/NewGuestView.java
@@ -0,0 +1,30 @@
+package com.github.mariosplen.bookings.controllers.new_guest;
+
+import com.github.mariosplen.bookings.models.GuestDAO;
+import javafx.fxml.FXML;
+import javafx.scene.control.TextField;
+import javafx.scene.text.Text;
+
+import java.sql.SQLException;
+
+public class NewGuestView {
+ @FXML
+ private TextField nameTF, phoneTF, emailTF;
+ @FXML
+ private Text errorMsg;
+
+ public void onSaveClicked() throws SQLException, ClassNotFoundException {
+ errorMsg.setText("");
+ if (nameTF.getText().isBlank() || phoneTF.getText().isBlank() || emailTF.getText().isBlank()) {
+ errorMsg.setText("Wrong Parameters");
+ return;
+ }
+
+
+ GuestDAO.addGuest(nameTF.getText(), phoneTF.getText(), emailTF.getText());
+ errorMsg.setText("New Guest Added!");
+ nameTF.setText("");
+ phoneTF.setText("");
+ emailTF.setText("");
+ }
+}
diff --git a/src/main/java/com/github/mariosplen/bookings/controllers/recovery/RecoverView.java b/src/main/java/com/github/mariosplen/bookings/controllers/recovery/RecoverView.java
new file mode 100644
index 0000000..4c31ec1
--- /dev/null
+++ b/src/main/java/com/github/mariosplen/bookings/controllers/recovery/RecoverView.java
@@ -0,0 +1,51 @@
+package com.github.mariosplen.bookings.controllers.recovery;
+
+import com.github.mariosplen.bookings.models.SettingsDAO;
+import com.github.mariosplen.bookings.models.User;
+import com.github.mariosplen.bookings.models.UserDAO;
+import com.github.mariosplen.bookings.util.Nav;
+import javafx.fxml.FXML;
+import javafx.scene.control.Label;
+import javafx.scene.control.PasswordField;
+import javafx.scene.control.TextField;
+import javafx.scene.text.Text;
+
+import java.io.IOException;
+import java.sql.SQLException;
+
+public class RecoverView {
+
+ @FXML
+ private Text showPasswordTxt;
+ @FXML
+ private Label errorMsg;
+ @FXML
+ private PasswordField hotelKey;
+ @FXML
+ private TextField usernameTF;
+
+
+ public void onBackButtonClicked() throws IOException {
+ Nav.toLogin();
+ }
+
+ public void onShowBtnClicked() throws SQLException, ClassNotFoundException {
+ errorMsg.setVisible(false);
+ showPasswordTxt.setVisible(false);
+
+ // Check if hotel key is correct
+ if (hotelKey.getText().equals(SettingsDAO.getHotelKey())) {
+ // Check if user exists
+ for (User user : UserDAO.getUsers()) {
+ if (user.username().equals(usernameTF.getText())) {
+ errorMsg.setVisible(false);
+ showPasswordTxt.setText(showPasswordTxt.getText() + user.password());
+ showPasswordTxt.setVisible(true);
+ return;
+ }
+ }
+ }
+ // If hotel key is incorrect or user does not exist, show error message
+ errorMsg.setVisible(true);
+ }
+}
diff --git a/src/main/java/com/github/mariosplen/bookings/controllers/register/RegisterView.java b/src/main/java/com/github/mariosplen/bookings/controllers/register/RegisterView.java
new file mode 100644
index 0000000..f5506ef
--- /dev/null
+++ b/src/main/java/com/github/mariosplen/bookings/controllers/register/RegisterView.java
@@ -0,0 +1,65 @@
+package com.github.mariosplen.bookings.controllers.register;
+
+import com.github.mariosplen.bookings.models.SettingsDAO;
+import com.github.mariosplen.bookings.models.User;
+import com.github.mariosplen.bookings.models.UserDAO;
+import com.github.mariosplen.bookings.util.Nav;
+import javafx.fxml.FXML;
+import javafx.scene.control.CheckBox;
+import javafx.scene.control.PasswordField;
+import javafx.scene.control.TextField;
+import javafx.scene.text.Text;
+
+import java.io.IOException;
+import java.sql.SQLException;
+
+public class RegisterView {
+ @FXML
+ private Text errorMsg;
+ @FXML
+ private PasswordField hotelKeyTF, passwordTF;
+ @FXML
+ private TextField usernameTF;
+ @FXML
+ private CheckBox editUsersCB;
+ @FXML
+ private CheckBox editGuestsCB;
+ @FXML
+ private CheckBox basicCB;
+
+
+ @FXML
+ private void onRegisterBtnClicked() throws IOException, SQLException, ClassNotFoundException {
+
+ errorMsg.setVisible(false);
+
+ // Check if username, password, and hotel key are not blank
+ // Check if hotel key is correct
+ if (usernameTF.getText().isBlank() || passwordTF.getText().isBlank() || !hotelKeyTF.getText().equals(SettingsDAO.getHotelKey())) {
+ errorMsg.setText("Please enter a username, password, and hotel key (ask the owner for the hotel key)");
+ errorMsg.setVisible(true);
+ return;
+ }
+
+ // Check if username is already taken
+ for (User user : UserDAO.getUsers()) {
+ if (user.username().equals(usernameTF.getText())) {
+ errorMsg.setText("A user with this username already exists");
+ errorMsg.setVisible(true);
+ return;
+ }
+ }
+
+ // If no errors, add new user to the database
+ if (!errorMsg.isVisible()) {
+ UserDAO.addUser(
+ usernameTF.getText(),
+ passwordTF.getText(),
+ basicCB.isSelected(),
+ editGuestsCB.isSelected(),
+ editUsersCB.isSelected()
+ );
+ Nav.toLogin();
+ }
+ }
+}
diff --git a/src/main/java/com/github/mariosplen/bookings/controllers/reservation/ReservationDetailsView.java b/src/main/java/com/github/mariosplen/bookings/controllers/reservation/ReservationDetailsView.java
new file mode 100644
index 0000000..762ba93
--- /dev/null
+++ b/src/main/java/com/github/mariosplen/bookings/controllers/reservation/ReservationDetailsView.java
@@ -0,0 +1,121 @@
+package com.github.mariosplen.bookings.controllers.reservation;
+
+
+import com.github.mariosplen.bookings.models.Book;
+import com.github.mariosplen.bookings.models.BookDAO;
+import com.github.mariosplen.bookings.models.Guest;
+import com.github.mariosplen.bookings.models.GuestDAO;
+import com.github.mariosplen.bookings.util.Nav;
+import com.github.mariosplen.bookings.util.Views;
+import javafx.application.Platform;
+import javafx.collections.FXCollections;
+import javafx.fxml.FXML;
+import javafx.fxml.FXMLLoader;
+import javafx.scene.Scene;
+import javafx.scene.control.TextField;
+import javafx.scene.text.Text;
+import javafx.stage.Stage;
+import org.controlsfx.control.SearchableComboBox;
+
+import java.io.IOException;
+import java.sql.SQLException;
+import java.time.LocalDate;
+import java.util.List;
+import java.util.stream.Collectors;
+
+public class ReservationDetailsView {
+ private final int numberOfNights;
+ private final int roomId;
+ private final LocalDate checkInDate;
+ private final LocalDate checkOutDate;
+ @FXML
+ private Text roomIDText, categoryText, numberOfNightsText, finalPriceText, errorMsg;
+ @FXML
+ private TextField doorPrice;
+
+ @FXML
+ private SearchableComboBox usersSearchBox;
+ private int totalPrice;
+
+
+ public ReservationDetailsView(Book tempBook) throws SQLException, ClassNotFoundException {
+ roomId = tempBook.roomId();
+ checkInDate = tempBook.checkIn();
+ checkOutDate = tempBook.checkOut();
+
+ numberOfNights = checkInDate.until(checkOutDate).getDays();
+
+
+ Platform.runLater(() -> {
+
+ try {
+ setUsersInBox();
+ } catch (SQLException | ClassNotFoundException e) {
+ throw new RuntimeException(e);
+ }
+
+ numberOfNightsText.setText("Number of nights: " + numberOfNights);
+ roomIDText.setText("room ID: " + roomId);
+
+ categoryText.setText(tempBook.roomCategory());
+
+
+ });
+ }
+
+ @FXML
+ private void refresh() {
+ totalPrice = numberOfNights * Integer.parseInt(doorPrice.getText());
+ finalPriceText.setText("$ " + totalPrice);
+ }
+
+ private void setUsersInBox() throws SQLException, ClassNotFoundException {
+ List guestList = GuestDAO.getGuests();
+ usersSearchBox.setItems(
+ FXCollections.observableArrayList(guestList.stream().map(Guest::name).collect(Collectors.toList()))
+ );
+ }
+
+
+ public void onAddGuestBtnClicked() throws IOException {
+ FXMLLoader loader = new FXMLLoader(getClass().getResource(Views.NEW_GUEST));
+ Stage popUpStage = new Stage();
+ loader.load();
+ Scene scene = new Scene(loader.getRoot());
+ popUpStage.setScene(scene);
+ popUpStage.show();
+ popUpStage.setOnCloseRequest(windowEvent -> {
+ try {
+ setUsersInBox();
+ } catch (SQLException | ClassNotFoundException e) {
+ throw new RuntimeException(e);
+ }
+ });
+ }
+
+
+ public void onSubmitClicked() throws IOException, SQLException, ClassNotFoundException {
+ errorMsg.setVisible(false);
+ if (usersSearchBox.getValue() == null || totalPrice == 0) {
+ errorMsg.setText("Please enter correct parameters!");
+ errorMsg.setVisible(true);
+ return;
+ }
+
+ BookDAO.addBook(
+ roomId,
+ categoryText.getText(),
+ usersSearchBox.getValue(),
+ checkInDate,
+ checkOutDate,
+ LocalDate.now(),
+ totalPrice
+ );
+
+ Nav.toHome();
+ }
+}
+
+
+
+
diff --git a/src/main/java/com/github/mariosplen/bookings/controllers/reservation/ReservationView.java b/src/main/java/com/github/mariosplen/bookings/controllers/reservation/ReservationView.java
new file mode 100644
index 0000000..2857e57
--- /dev/null
+++ b/src/main/java/com/github/mariosplen/bookings/controllers/reservation/ReservationView.java
@@ -0,0 +1,145 @@
+package com.github.mariosplen.bookings.controllers.reservation;
+
+
+import com.github.mariosplen.bookings.models.Book;
+import com.github.mariosplen.bookings.models.Room;
+import com.github.mariosplen.bookings.models.RoomDAO;
+import com.github.mariosplen.bookings.util.Nav;
+import javafx.fxml.FXML;
+import javafx.fxml.Initializable;
+import javafx.scene.control.*;
+
+import java.io.IOException;
+import java.net.URL;
+import java.sql.SQLException;
+import java.time.LocalDate;
+import java.util.List;
+import java.util.ResourceBundle;
+
+public class ReservationView implements Initializable {
+ public ChoiceBox categoryChoiceBox;
+ @FXML
+ private Label errorLabel;
+ @FXML
+ private Button continueButton;
+ @FXML
+ private DatePicker checkInDP, checkOutDP;
+ private Book tempBook;
+
+ private List availableRooms;
+
+
+ @Override
+ public void initialize(URL url, ResourceBundle resourceBundle) {
+
+ continueButton.setOnAction(actionEvent -> {
+ try {
+ Nav.toResDetails(tempBook);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ });
+
+ setDatePickers();
+
+ // Populate the categoryChoiceBox with category names from the database
+ fillCategoryChoiceBox();
+ }
+
+
+ public void checkAvailabilityClicked() throws SQLException, ClassNotFoundException {
+ if (availableRooms != null) {
+ availableRooms.clear();
+ }
+
+ // Hide the continue button and error label initially
+ continueButton.setVisible(false);
+ errorLabel.setVisible(false);
+
+ // Check that the check-in and check-out dates are not null
+ if (checkInDP.getValue() == null || checkOutDP.getValue() == null) {
+ errorLabel.setVisible(true);
+ errorLabel.setText("Error please enter valid parameters");
+ return;
+ }
+
+ // Get the selected category name
+ String cat;
+ if (categoryChoiceBox.getValue().equals("Single")) {
+ cat = "Single";
+ } else if (categoryChoiceBox.getValue().equals("Twin")) {
+ cat = "Twin";
+ } else if (categoryChoiceBox.getValue().equals("Double")) {
+ cat = "Double";
+ } else {
+ // If the selected category is not recognized, show an error message
+ errorLabel.setVisible(true);
+ errorLabel.setText("Error please enter valid parameters");
+ return;
+ }
+ // Get a list of available rooms that match the selected category and date range
+ availableRooms = RoomDAO.getAvailableForDate(checkInDP.getValue(), checkOutDP.getValue(), cat);
+
+ if (availableRooms.size() > 0) {
+ // If at least one room is available, show the room's ID and enable the continue button
+ errorLabel.setText(String.format("Room Found with id: %s", availableRooms.get(0).id()));
+ Room foundRoom = availableRooms.get(0);
+ errorLabel.setVisible(true);
+ tempBook = new Book(
+ -1,
+ foundRoom.id(),
+ categoryChoiceBox.getValue(),
+ null,
+ checkInDP.getValue(),
+ checkOutDP.getValue(),
+ null,
+ 0
+ );
+
+
+ continueButton.setVisible(true);
+ } else {
+ // If no rooms are available, show an error message
+ errorLabel.setVisible(true);
+ errorLabel.setText("No rooms found!");
+ }
+ }
+
+
+ private void fillCategoryChoiceBox() {
+ categoryChoiceBox.getItems().addAll(
+ "Double", "Single", "Twin"
+ );
+ }
+
+ private void setDatePickers() {
+ // Set the minimum date for check-in to be today
+ LocalDate start = LocalDate.now();
+
+ // Disable check-in dates that are before today or after the check-out date
+ checkInDP.setDayCellFactory(d -> new DateCell() {
+ @Override
+ public void updateItem(LocalDate item, boolean empty) {
+ super.updateItem(item, empty);
+ try {
+ setDisable(item.isBefore(start) || item.isAfter(checkOutDP.getValue().minusDays(1)));
+ } catch (Exception e) {
+ setDisable(item.isBefore(start));
+ }
+ }
+ });
+
+ // Disable check-out dates that are before the check-in date
+ checkOutDP.setDayCellFactory(d -> new DateCell() {
+ @Override
+ public void updateItem(LocalDate item, boolean empty) {
+ super.updateItem(item, empty);
+ try {
+ setDisable(item.isBefore(checkInDP.getValue().plusDays(1)));
+ } catch (Exception e) {
+ setDisable(item.isBefore(LocalDate.now().plusDays(1)));
+ }
+ }
+ });
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/github/mariosplen/bookings/controllers/users/UserItem.java b/src/main/java/com/github/mariosplen/bookings/controllers/users/UserItem.java
new file mode 100644
index 0000000..f1ad64e
--- /dev/null
+++ b/src/main/java/com/github/mariosplen/bookings/controllers/users/UserItem.java
@@ -0,0 +1,162 @@
+package com.github.mariosplen.bookings.controllers.users;
+
+import com.github.mariosplen.bookings.models.UserDAO;
+import com.github.mariosplen.bookings.util.Nav;
+import com.github.mariosplen.bookings.util.Views;
+import javafx.event.ActionEvent;
+import javafx.fxml.FXMLLoader;
+import javafx.fxml.Initializable;
+import javafx.geometry.Insets;
+import javafx.geometry.Pos;
+import javafx.scene.Parent;
+import javafx.scene.Scene;
+import javafx.scene.control.Button;
+import javafx.scene.control.Label;
+import javafx.scene.control.PasswordField;
+import javafx.scene.control.Tooltip;
+import javafx.scene.input.MouseEvent;
+import javafx.scene.layout.BorderPane;
+import javafx.scene.layout.HBox;
+import javafx.scene.layout.VBox;
+import javafx.scene.shape.Rectangle;
+import javafx.scene.text.Text;
+import javafx.stage.Stage;
+import javafx.stage.Window;
+import javafx.util.Duration;
+
+import java.io.IOException;
+import java.net.URL;
+import java.sql.SQLException;
+import java.util.ResourceBundle;
+
+public class UserItem implements Initializable {
+ public Rectangle basicPerm;
+ public Rectangle manageGuests;
+ public Rectangle manageUsers;
+ public Text nameTxt;
+
+ public void onChangePassBtnClicked(ActionEvent actionEvent) {
+
+ // Finds current username by going backwards to the node tree
+ String username = (
+ ((Text)
+ ((Button) actionEvent.getSource())
+ .getParent().getChildrenUnmodifiable().get(3))
+ .getText()
+ );
+
+ BorderPane borderPane = new BorderPane();
+ Scene scene = new Scene(borderPane);
+ Stage stage = new Stage();
+ stage.setScene(scene);
+ stage.setTitle("Change Password of User: " + username);
+ Label enterPass = new Label("Enter new Password");
+ PasswordField passwordField = new PasswordField();
+ passwordField.setStyle("-fx-background-color: #C6B3EF;\n" +
+ " -fx-background-radius: 3;");
+ Button save = new Button("Save");
+ save.setStyle("""
+ -fx-background-color: #5100FC;
+ -fx-text-fill: #FFFFFF;
+ -fx-background-radius: 6;
+ -fx-font-size: 20;
+ -fx-font-weight: bold;
+ -fx-border-radius: 6;
+ -fx-border-color: #000000;
+ -fx-border-width: 1;
+ -fx-padding: 14;""");
+ enterPass.setStyle("-fx-font-size: 32; -fx-font-weight: bold;");
+ VBox vBox = new VBox(enterPass, passwordField, save);
+ vBox.setSpacing(20);
+ vBox.setPadding(new Insets(40));
+ vBox.setAlignment(Pos.CENTER);
+ borderPane.setCenter(vBox);
+ stage.show();
+ save.setOnAction(actionEvent1 -> {
+ try {
+ UserDAO.changePass(username, passwordField.getText());
+ } catch (SQLException | ClassNotFoundException e) {
+ throw new RuntimeException(e);
+ }
+ stage.close();
+ });
+
+ }
+
+ @Override
+ public void initialize(URL url, ResourceBundle resourceBundle) {
+ Tooltip basic = new Tooltip("Basic Functionality");
+ basic.setShowDelay(Duration.ZERO);
+ Tooltip.install(basicPerm, basic);
+ Tooltip guestsManage = new Tooltip("Edit Guests");
+ guestsManage.setShowDelay(Duration.ZERO);
+ Tooltip.install(manageGuests, guestsManage);
+ Tooltip usersManage = new Tooltip("Edit Users");
+ usersManage.setShowDelay(Duration.ZERO);
+ Tooltip.install(manageUsers, usersManage);
+
+ }
+
+ public void onDeleteBtnClicked(ActionEvent actionEvent) throws SQLException, ClassNotFoundException {
+ String username = (
+ ((Text)
+ ((Button) actionEvent.getSource())
+ .getParent().getChildrenUnmodifiable().get(3))
+ .getText()
+ );
+ UserDAO.deleteUser(username);
+ refreshView();
+
+ }
+
+ private void refreshView() throws SQLException, ClassNotFoundException {
+ // Refresh mainPane by re-creating loader
+ Window.getWindows().forEach(window -> {
+ Parent p = window.getScene().getRoot();
+ // if it has mainPane that means that it's the main Screen
+ if (p.lookup("#contentPane") != null) {
+ FXMLLoader loader = new FXMLLoader(getClass().getResource(Views.USERS));
+ try {
+ ((BorderPane) (p.lookup("#contentPane"))).setCenter(loader.load());
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ });
+
+ Nav.user = UserDAO.login(Nav.user.username(), Nav.user.password());
+ }
+
+ public void onPermManageUsersClicked(MouseEvent mouseEvent) throws SQLException, ClassNotFoundException {
+
+ String username = handleRectangleClick(mouseEvent);
+ UserDAO.switchPerm(username, "manage_users");
+ refreshView();
+ }
+
+ public void onPermManageGuestsClicked(MouseEvent mouseEvent) throws SQLException, ClassNotFoundException {
+ String username = handleRectangleClick(mouseEvent);
+ UserDAO.switchPerm(username, "manage_guests");
+ refreshView();
+ }
+
+
+ public void onPermBasicClicked(MouseEvent mouseEvent) throws SQLException, ClassNotFoundException {
+ String username = handleRectangleClick(mouseEvent);
+ UserDAO.switchPerm(username, "basic_functions");
+ refreshView();
+ }
+
+ private String handleRectangleClick(MouseEvent event) {
+ // Get the rectangle that was clicked
+ Rectangle rectangle = (Rectangle) event.getSource();
+
+ // Get the HBox containing the rectangle
+ HBox hBox = (HBox) rectangle.getParent();
+
+ // Get the HBox containing the HBoxes
+ HBox allHBoxes = (HBox) hBox.getParent();
+
+ return ((Text) allHBoxes.getChildren().get(3)).getText();
+ }
+}
diff --git a/src/main/java/com/github/mariosplen/bookings/controllers/users/UsersView.java b/src/main/java/com/github/mariosplen/bookings/controllers/users/UsersView.java
new file mode 100644
index 0000000..8a9ce33
--- /dev/null
+++ b/src/main/java/com/github/mariosplen/bookings/controllers/users/UsersView.java
@@ -0,0 +1,47 @@
+package com.github.mariosplen.bookings.controllers.users;
+
+
+import com.github.mariosplen.bookings.models.UserDAO;
+import com.github.mariosplen.bookings.util.Views;
+import javafx.fxml.FXMLLoader;
+import javafx.fxml.Initializable;
+import javafx.scene.layout.VBox;
+import javafx.scene.paint.Color;
+
+import java.io.IOException;
+import java.net.URL;
+import java.sql.SQLException;
+import java.util.ResourceBundle;
+
+public class UsersView implements Initializable {
+ public VBox usersVBox;
+
+ @Override
+ public void initialize(URL url, ResourceBundle resourceBundle) {
+ try {
+ UserDAO.getUsers().forEach(user -> {
+ FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource(Views.USER_ITEM));
+
+ try {
+ usersVBox.getChildren().add(fxmlLoader.load());
+ UserItem userItem = fxmlLoader.getController();
+ if (user.canManageUsers()) {
+ userItem.manageUsers.setFill(Color.web("0x5100FC", 1));
+ }
+ if (user.canDoBasic()) {
+ userItem.basicPerm.setFill(Color.web("0x5100FC", 1));
+ }
+ if (user.canManageGuests()) {
+ userItem.manageGuests.setFill(Color.web("0x5100FC", 1));
+ }
+ userItem.nameTxt.setText(user.username());
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ });
+ } catch (SQLException | ClassNotFoundException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+}
diff --git a/src/main/java/com/github/mariosplen/bookings/models/Book.java b/src/main/java/com/github/mariosplen/bookings/models/Book.java
new file mode 100644
index 0000000..9d68fb9
--- /dev/null
+++ b/src/main/java/com/github/mariosplen/bookings/models/Book.java
@@ -0,0 +1,15 @@
+package com.github.mariosplen.bookings.models;
+
+import java.time.LocalDate;
+
+public record Book(
+ int id,
+ int roomId,
+ String roomCategory,
+ String guestName,
+ LocalDate checkIn,
+ LocalDate checkOut,
+ LocalDate date,
+ int totalPrice
+) {
+}
diff --git a/src/main/java/com/github/mariosplen/bookings/models/BookDAO.java b/src/main/java/com/github/mariosplen/bookings/models/BookDAO.java
new file mode 100644
index 0000000..a0e04ed
--- /dev/null
+++ b/src/main/java/com/github/mariosplen/bookings/models/BookDAO.java
@@ -0,0 +1,105 @@
+package com.github.mariosplen.bookings.models;
+
+import com.github.mariosplen.bookings.util.DBManager;
+import javafx.collections.FXCollections;
+import javafx.collections.ObservableList;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.time.LocalDate;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class BookDAO {
+
+ public static Map> getRoomBookDates() throws SQLException, ClassNotFoundException {
+ String query = "SELECT room_id, check_in, check_out FROM books;";
+
+ ResultSet rs = DBManager.dbExecuteQuery(query);
+
+ Map> roomBookDates = new HashMap<>();
+ while (rs.next()) {
+ LocalDate from = LocalDate.parse(rs.getString("check_in"));
+ LocalDate to = LocalDate.parse(rs.getString("check_out"));
+ List dates = new ArrayList<>(from.datesUntil(to).toList());
+ dates.add(to);
+
+
+ if (roomBookDates.containsKey(rs.getInt("room_id"))) {
+ roomBookDates.get(rs.getInt("room_id")).addAll(dates);
+ } else {
+ roomBookDates.put(rs.getInt("room_id"), dates);
+ }
+
+
+ }
+ rs.close();
+ return roomBookDates;
+ }
+
+
+ public static void addBook(
+ int roomId,
+ String roomCategory,
+ String guestName,
+ LocalDate checkIn,
+ LocalDate checkOut,
+ LocalDate date,
+ int totalPrice
+ ) throws SQLException, ClassNotFoundException {
+ String query = """
+ INSERT INTO books(room_id, room_category, guest_name, check_in, check_out, date, total_price)
+ VALUES(?, ?, ?, ?, ?, ?, ?)
+ """;
+ DBManager.dbExecuteUpdate(query,
+ roomId,
+ roomCategory,
+ guestName,
+ checkIn,
+ checkOut,
+ date,
+ totalPrice
+ );
+
+ }
+
+ public static ObservableList getBooks() throws SQLException, ClassNotFoundException {
+ String query = "SELECT * FROM books;";
+ ResultSet rs = DBManager.dbExecuteQuery(query);
+ ObservableList books = getBooksFromRS(rs);
+ rs.close();
+
+ return books;
+ }
+
+ public static Book getBookFromRs(ResultSet rs) throws SQLException {
+ return new Book(
+ rs.getInt("id"),
+ rs.getInt("room_id"),
+ rs.getString("room_category"),
+ rs.getString("guest_name"),
+ LocalDate.parse(rs.getString("check_in")),
+ LocalDate.parse(rs.getString("check_out")),
+ LocalDate.parse(rs.getString("date")),
+ rs.getInt("total_price")
+ );
+
+ }
+
+ public static ObservableList getBooksFromRS(ResultSet rs) throws SQLException {
+ ObservableList books = FXCollections.observableArrayList();
+ while (rs.next()) {
+ books.add(getBookFromRs(rs));
+ }
+ return books;
+ }
+
+ public static void deleteBook(int id) throws SQLException, ClassNotFoundException {
+ String query = "DELETE FROM books WHERE id = ? ";
+ DBManager.dbExecuteUpdate(query, id);
+
+ }
+}
+
diff --git a/src/main/java/com/github/mariosplen/bookings/models/Guest.java b/src/main/java/com/github/mariosplen/bookings/models/Guest.java
new file mode 100644
index 0000000..3c45451
--- /dev/null
+++ b/src/main/java/com/github/mariosplen/bookings/models/Guest.java
@@ -0,0 +1,8 @@
+package com.github.mariosplen.bookings.models;
+
+public record Guest(
+ String name,
+ String phone,
+ String email
+) {
+}
diff --git a/src/main/java/com/github/mariosplen/bookings/models/GuestDAO.java b/src/main/java/com/github/mariosplen/bookings/models/GuestDAO.java
new file mode 100644
index 0000000..8b78e04
--- /dev/null
+++ b/src/main/java/com/github/mariosplen/bookings/models/GuestDAO.java
@@ -0,0 +1,58 @@
+package com.github.mariosplen.bookings.models;
+
+
+import com.github.mariosplen.bookings.util.DBManager;
+import javafx.collections.FXCollections;
+import javafx.collections.ObservableList;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+public class GuestDAO {
+
+ public static ObservableList getGuests() throws SQLException, ClassNotFoundException {
+ String query = "SELECT * FROM guests";
+ ResultSet rs = DBManager.dbExecuteQuery(query);
+
+ ObservableList guests = getGuestsFromRs(rs);
+ rs.close();
+ return guests;
+ }
+
+
+ public static Guest getGuestFromRs(ResultSet rs) throws SQLException {
+ return new Guest(
+ rs.getString("name"),
+ rs.getString("phone"),
+ rs.getString("email"));
+ }
+
+ public static ObservableList getGuestsFromRs(ResultSet rs) throws SQLException {
+ ObservableList guests = FXCollections.observableArrayList();
+ while (rs.next()) {
+ guests.add(getGuestFromRs(rs));
+ }
+ return guests;
+ }
+
+
+ public static void addGuest(String name, String phone, String email) throws SQLException, ClassNotFoundException {
+ String query = """
+ INSERT INTO guests(name, phone, email)
+ VALUES(?,?,?)
+ """;
+ DBManager.dbExecuteUpdate(query, name, phone, email);
+
+ }
+
+ public static void updateData(String name, String perm, String value) throws SQLException, ClassNotFoundException {
+
+ String query = """
+ UPDATE guests SET '%s' = ?
+ WHERE name = ?
+ """.formatted(perm);
+ DBManager.dbExecuteUpdate(query, value, name);
+
+ }
+
+}
diff --git a/src/main/java/com/github/mariosplen/bookings/models/Room.java b/src/main/java/com/github/mariosplen/bookings/models/Room.java
new file mode 100644
index 0000000..2c500f9
--- /dev/null
+++ b/src/main/java/com/github/mariosplen/bookings/models/Room.java
@@ -0,0 +1,7 @@
+package com.github.mariosplen.bookings.models;
+
+public record Room(
+ int id,
+ String category
+) {
+}
diff --git a/src/main/java/com/github/mariosplen/bookings/models/RoomDAO.java b/src/main/java/com/github/mariosplen/bookings/models/RoomDAO.java
new file mode 100644
index 0000000..f530287
--- /dev/null
+++ b/src/main/java/com/github/mariosplen/bookings/models/RoomDAO.java
@@ -0,0 +1,70 @@
+package com.github.mariosplen.bookings.models;
+
+
+import com.github.mariosplen.bookings.util.DBManager;
+import javafx.collections.FXCollections;
+import javafx.collections.ObservableList;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.time.LocalDate;
+import java.util.List;
+
+public class RoomDAO {
+
+ public static ObservableList getRooms() throws SQLException, ClassNotFoundException {
+ String query = "SELECT * FROM rooms";
+ ResultSet rs = DBManager.dbExecuteQuery(query);
+
+ ObservableList rooms = getRoomsFromRs(rs);
+ rs.close();
+ return rooms;
+ }
+
+
+ public static Room getRoomFromRs(ResultSet rs) throws SQLException {
+ return new Room(
+ rs.getInt("id"),
+ rs.getString("category")
+ );
+ }
+
+ public static ObservableList getRoomsFromRs(ResultSet rs) throws SQLException {
+ ObservableList rooms = FXCollections.observableArrayList();
+ while (rs.next()) {
+ rooms.add(getRoomFromRs(rs));
+ }
+ return rooms;
+ }
+
+ public static List getAvailableForDate(LocalDate checkIn, LocalDate checkOut, String cat) throws SQLException, ClassNotFoundException {
+
+
+ String query = """
+ SELECT * FROM rooms r
+ WHERE r.category = ?
+ AND r.id NOT IN (
+ SELECT b.room_id FROM books b
+ WHERE (b.check_in <= ? AND b.check_out >= ? )
+ OR (b.check_in <= ? AND b.check_out >= ? )
+ OR (b.check_in >= ? AND b.check_out <= ? )
+ )
+ """;
+
+
+ ResultSet rs = DBManager.dbExecuteQuery(query,
+ cat,
+ checkIn.toString(),
+ checkOut.toString(),
+ checkOut.toString(),
+ checkIn.toString(),
+ checkIn.toString(),
+ checkOut.toString()
+ );
+ List rooms = getRoomsFromRs(rs);
+ rs.close();
+ return rooms;
+
+ }
+
+}
diff --git a/src/main/java/com/github/mariosplen/bookings/models/SettingsDAO.java b/src/main/java/com/github/mariosplen/bookings/models/SettingsDAO.java
new file mode 100644
index 0000000..a9b8751
--- /dev/null
+++ b/src/main/java/com/github/mariosplen/bookings/models/SettingsDAO.java
@@ -0,0 +1,24 @@
+package com.github.mariosplen.bookings.models;
+
+import com.github.mariosplen.bookings.util.DBManager;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+public class SettingsDAO {
+ public static String getHotelKey() throws SQLException, ClassNotFoundException {
+ String query = "SELECT value FROM settings WHERE name = 'hotel_key'";
+ ResultSet rs = DBManager.dbExecuteQuery(query);
+
+ String key = getKeyFromRS(rs);
+ rs.close();
+ return key;
+ }
+
+ private static String getKeyFromRS(ResultSet rs) throws SQLException {
+ if (rs.next()) {
+ return rs.getString("value");
+ }
+ return null;
+ }
+}
diff --git a/src/main/java/com/github/mariosplen/bookings/models/User.java b/src/main/java/com/github/mariosplen/bookings/models/User.java
new file mode 100644
index 0000000..e996888
--- /dev/null
+++ b/src/main/java/com/github/mariosplen/bookings/models/User.java
@@ -0,0 +1,10 @@
+package com.github.mariosplen.bookings.models;
+
+public record User(
+ String username,
+ String password,
+ Boolean canDoBasic,
+ Boolean canManageGuests,
+ Boolean canManageUsers
+) {
+}
\ No newline at end of file
diff --git a/src/main/java/com/github/mariosplen/bookings/models/UserDAO.java b/src/main/java/com/github/mariosplen/bookings/models/UserDAO.java
new file mode 100644
index 0000000..7aba285
--- /dev/null
+++ b/src/main/java/com/github/mariosplen/bookings/models/UserDAO.java
@@ -0,0 +1,91 @@
+package com.github.mariosplen.bookings.models;
+
+import com.github.mariosplen.bookings.util.DBManager;
+import javafx.collections.FXCollections;
+import javafx.collections.ObservableList;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+public class UserDAO {
+
+
+ public static ObservableList getUsers() throws SQLException, ClassNotFoundException {
+ String query = "SELECT * FROM users";
+ ResultSet rs = DBManager.dbExecuteQuery(query);
+
+ ObservableList users = getUsersFromRS(rs);
+ rs.close();
+ return users;
+ }
+
+ public static User login(String username, String password) throws SQLException, ClassNotFoundException {
+ String query = "SELECT * FROM users WHERE username = ? AND password = ?";
+ ResultSet rs = DBManager.dbExecuteQuery(query, username, password);
+
+ if (rs.next()) {
+ User user = getUserFromRs(rs);
+ rs.close();
+ return user;
+ }
+ rs.close();
+ return null;
+
+ }
+
+ public static void changePass(String username, String newPass) throws SQLException, ClassNotFoundException {
+ String query = "UPDATE users SET password = ? WHERE username = ? ";
+ DBManager.dbExecuteUpdate(query, newPass, username);
+ }
+
+ private static User getUserFromRs(ResultSet rs) throws SQLException {
+ return new User(
+ rs.getString("username"),
+ rs.getString("password"),
+ rs.getBoolean("basic_functions"),
+ rs.getBoolean("manage_guests"),
+ rs.getBoolean("manage_users")
+ );
+ }
+
+ private static ObservableList getUsersFromRS(ResultSet rs) throws SQLException {
+ ObservableList users = FXCollections.observableArrayList();
+ while (rs.next()) {
+ users.add(getUserFromRs(rs));
+ }
+ return users;
+ }
+
+ public static void addUser(
+ String username,
+ String password,
+ Boolean canDoBasic,
+ Boolean canManageGuests,
+ Boolean canManageUsers
+ ) throws SQLException, ClassNotFoundException {
+ String query = """
+ INSERT INTO users(username, password, basic_functions, manage_guests, manage_users)
+ VALUES(?,?,?,?,?)
+ """;
+ DBManager.dbExecuteUpdate(query,
+ username,
+ password,
+ canDoBasic,
+ canManageGuests,
+ canManageUsers
+ );
+
+ }
+
+ public static void deleteUser(String username) throws SQLException, ClassNotFoundException {
+ String query = "DELETE FROM users WHERE username = ? ";
+ DBManager.dbExecuteUpdate(query, username);
+ }
+
+ public static void switchPerm(String username, String perm) throws SQLException, ClassNotFoundException {
+
+ String query = "UPDATE `users` SET %s = (( %s | 1) - ( %s & 1)) WHERE username = ? ".formatted(perm, perm, perm);
+
+ DBManager.dbExecuteUpdate(query, username);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/github/mariosplen/bookings/util/DBManager.java b/src/main/java/com/github/mariosplen/bookings/util/DBManager.java
new file mode 100644
index 0000000..3f72331
--- /dev/null
+++ b/src/main/java/com/github/mariosplen/bookings/util/DBManager.java
@@ -0,0 +1,66 @@
+package com.github.mariosplen.bookings.util;
+
+import javax.sql.rowset.CachedRowSet;
+import javax.sql.rowset.RowSetProvider;
+import java.sql.*;
+
+public class DBManager {
+ private static final String JDBC_DRIVER = "org.sqlite.JDBC";
+ private static final String connStr = "jdbc:sqlite:assets/database/bookings.db";
+ private static Connection conn = null;
+
+ private static void dbConnect() throws SQLException, ClassNotFoundException {
+ Class.forName(JDBC_DRIVER);
+ conn = DriverManager.getConnection(connStr);
+ }
+
+ private static void dbDisconnect() throws SQLException {
+ if (conn != null && !conn.isClosed()) {
+ conn.close();
+ }
+ }
+
+ public static ResultSet dbExecuteQuery(
+ String query, Object... varArgs
+ ) throws SQLException, ClassNotFoundException {
+ dbConnect();
+ PreparedStatement ps = conn.prepareStatement(query);
+
+ // Sets the value of every designated parameter
+ for (int i = 0; i < varArgs.length; i++) {
+ ps.setObject(i + 1, varArgs[i]);
+ }
+
+ ResultSet rs = ps.executeQuery();
+
+ CachedRowSet crs = RowSetProvider.newFactory().createCachedRowSet();
+ crs.populate(rs);
+
+ if (rs != null) {
+ rs.close();
+ }
+
+ ps.close();
+ dbDisconnect();
+ return crs;
+ }
+
+
+ public static void dbExecuteUpdate(
+ String query, Object... varArgs
+ ) throws SQLException, ClassNotFoundException {
+ dbConnect();
+ PreparedStatement ps = conn.prepareStatement(query);
+
+ // Sets the value of every designated parameter
+ for (int i = 0; i < varArgs.length; i++) {
+ ps.setObject(i + 1, varArgs[i]);
+ }
+
+ ps.executeUpdate();
+
+ ps.close();
+ dbDisconnect();
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/github/mariosplen/bookings/util/Nav.java b/src/main/java/com/github/mariosplen/bookings/util/Nav.java
new file mode 100644
index 0000000..ef00adb
--- /dev/null
+++ b/src/main/java/com/github/mariosplen/bookings/util/Nav.java
@@ -0,0 +1,146 @@
+package com.github.mariosplen.bookings.util;
+
+
+import com.github.mariosplen.bookings.controllers.MainView;
+import com.github.mariosplen.bookings.controllers.reservation.ReservationDetailsView;
+import com.github.mariosplen.bookings.models.Book;
+import com.github.mariosplen.bookings.models.User;
+import javafx.fxml.FXMLLoader;
+import javafx.scene.Node;
+import javafx.scene.Scene;
+import javafx.scene.control.Button;
+import javafx.scene.image.Image;
+import javafx.scene.layout.BorderPane;
+import javafx.stage.Stage;
+
+import java.io.IOException;
+import java.sql.SQLException;
+import java.util.Objects;
+
+public class Nav {
+ private static Stage stage;
+ public static BorderPane content;
+ public static Button backBtn;
+ public static User user;
+
+ public static void toLoading(Stage stage) throws IOException {
+ Nav.stage = stage;
+ FXMLLoader fxmlLoader = new FXMLLoader(Nav.class.getResource(Views.LOADING));
+ Nav.stage.setScene(new Scene(fxmlLoader.load()));
+ // Set the icon of the stage
+ stage.getIcons().add(new Image(Objects.requireNonNull(Nav.class.getResource("/com/github/mariosplen/bookings/media/icons/icon.png")).toExternalForm()));
+
+ // Set the title of the stage
+ stage.setTitle("Hotel Reservation Management");
+
+ // Make the stage non-resizable, because of intro video
+ stage.setResizable(false);
+
+ // Show the stage
+ stage.show();
+ }
+
+ public static void toLogin() throws IOException {
+ FXMLLoader fxmlLoader = new FXMLLoader(Nav.class.getResource(Views.LOGIN));
+ stage.setScene(new Scene(fxmlLoader.load()));
+
+ // Set the stage to be resizable again
+ stage.setResizable(true);
+
+ // Set the minimum dimensions for the stage
+ stage.setMinHeight(600);
+ stage.setMinWidth(800);
+ }
+
+ public static void toRegister() throws IOException {
+ FXMLLoader contentLoader = new FXMLLoader(Nav.class.getResource(Views.REGISTER));
+ Node content = contentLoader.load();
+
+ FXMLLoader fxmlLoader = new FXMLLoader(Nav.class.getResource(Views.MAIN));
+ fxmlLoader.setControllerFactory(aClass -> new MainView(null, content));
+ stage.setScene(new Scene(fxmlLoader.load()));
+
+
+ }
+
+ public static void toRecovery() throws IOException {
+ FXMLLoader contentLoader = new FXMLLoader(Nav.class.getResource(Views.RECOVERY));
+
+ stage.setScene(new Scene(contentLoader.load()));
+ }
+
+ public static void toHome() throws IOException {
+ FXMLLoader contentLoader = new FXMLLoader(Nav.class.getResource(Views.HOME));
+
+ FXMLLoader loader = new FXMLLoader(Nav.class.getResource(Views.MAIN));
+
+ loader.setControllerFactory(controllerClass -> {
+ try {
+ return new MainView(user, contentLoader.load());
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ });
+
+
+ stage.setScene(new Scene(loader.load()));
+ MainView mainViewController = loader.getController();
+ backBtn = mainViewController.getBackBtn();
+ backBtn.setVisible(false);
+ Nav.content = mainViewController.contentPane;
+ }
+
+ public static void toCalendar() throws IOException {
+ FXMLLoader contentLoader = new FXMLLoader(Nav.class.getResource(Views.CALENDAR));
+ content.setCenter(contentLoader.load());
+ backBtn.setVisible(true);
+ }
+
+
+ public static void toNewGuest() throws IOException {
+ FXMLLoader contentLoader = new FXMLLoader(Nav.class.getResource(Views.NEW_GUEST));
+ content.setCenter(contentLoader.load());
+ backBtn.setVisible(true);
+ }
+
+ public static void toUsers() throws IOException {
+ FXMLLoader contentLoader = new FXMLLoader(Nav.class.getResource(Views.USERS));
+ content.setCenter(contentLoader.load());
+ backBtn.setVisible(true);
+ }
+
+ public static void toGuests() throws IOException {
+ FXMLLoader contentLoader = new FXMLLoader(Nav.class.getResource(Views.GUESTS));
+ content.setCenter(contentLoader.load());
+ backBtn.setVisible(true);
+ }
+
+ public static void toReservation() throws IOException {
+ FXMLLoader contentLoader = new FXMLLoader(Nav.class.getResource(Views.RESERVATION));
+ content.setCenter(contentLoader.load());
+ backBtn.setVisible(true);
+ }
+
+ public static void toResDetails(Book tempBook) throws IOException {
+ FXMLLoader loader = new FXMLLoader(Nav.class.getResource(Views.RESERVATION_DETAILS));
+ loader.setControllerFactory(controllerClass -> {
+ try {
+ return new ReservationDetailsView(tempBook);
+ } catch (SQLException | ClassNotFoundException e) {
+ throw new RuntimeException(e);
+ }
+ });
+ content.setCenter(loader.load());
+ backBtn.setVisible(true);
+ }
+
+
+ public static void toBooks() throws IOException {
+ FXMLLoader loader = new FXMLLoader(Nav.class.getResource(Views.BOOKS));
+ content.setCenter(loader.load());
+ backBtn.setVisible(true);
+ }
+
+
+
+}
diff --git a/src/main/java/com/github/mariosplen/bookings/util/ReceiptGenerator.java b/src/main/java/com/github/mariosplen/bookings/util/ReceiptGenerator.java
new file mode 100644
index 0000000..ac1e99b
--- /dev/null
+++ b/src/main/java/com/github/mariosplen/bookings/util/ReceiptGenerator.java
@@ -0,0 +1,149 @@
+package com.github.mariosplen.bookings.util;
+
+import javafx.stage.FileChooser;
+import org.apache.pdfbox.pdmodel.PDDocument;
+import org.apache.pdfbox.pdmodel.PDPage;
+import org.apache.pdfbox.pdmodel.PDPageContentStream;
+import org.apache.pdfbox.pdmodel.font.PDType1Font;
+
+import java.awt.*;
+import java.io.File;
+import java.io.IOException;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.ZoneOffset;
+import java.time.format.DateTimeFormatter;
+import java.util.Locale;
+
+public class ReceiptGenerator {
+
+
+
+ public void genReceipt(
+ String name, LocalDate dateOfArrivalLD, LocalDate dateOfDepartureLD, int total
+ ) throws IOException {
+
+ String dateOfArrival = dateOfArrivalLD.format(DateTimeFormatter.ofPattern("EEEE, MMM dd yyyy").withLocale(Locale.ENGLISH));
+ String dateOfDeparture = dateOfDepartureLD.format(DateTimeFormatter.ofPattern("EEEE, MMM dd yyyy").withLocale(Locale.ENGLISH));
+ int days = dateOfArrivalLD.until(dateOfDepartureLD).getDays();
+
+
+ PDDocument document = new PDDocument();
+ PDPage page = new PDPage();
+ document.addPage(page);
+
+
+ //first page
+ PDPage page1 = document.getPage(0);
+
+ //initialisation of content stream
+ PDPageContentStream cs = new PDPageContentStream(document, page1);
+
+ cs.beginText();
+ cs.setFont(PDType1Font.HELVETICA_BOLD, 40);
+ cs.setNonStrokingColor(Color.getColor("5100FC"));
+ cs.newLineAtOffset(75, 700);
+ cs.showText("HOTELINO");
+ cs.endText();
+
+ cs.beginText();
+ cs.setFont(PDType1Font.TIMES_ROMAN, 28);
+ cs.setNonStrokingColor(Color.black);
+ cs.newLineAtOffset(100, 675);
+ cs.showText("Invoice");
+ cs.endText();
+
+
+ java.util.Date date = new java.util.Date();
+ cs.beginText();
+ cs.setFont(PDType1Font.TIMES_ROMAN, 14);
+ cs.newLineAtOffset(400, 675);
+ cs.showText("" + date);
+ cs.endText();
+
+
+ // Predetermined text
+ cs.beginText();
+ cs.setFont(PDType1Font.TIMES_ROMAN, 14);
+ cs.newLineAtOffset(100, 590);
+ cs.showText("Name:");
+ cs.endText();
+
+ cs.beginText();
+ cs.setFont(PDType1Font.TIMES_ROMAN, 14);
+ cs.newLineAtOffset(100, 570);
+ cs.showText("Date of arrival:");
+ cs.endText();
+
+ cs.beginText();
+ cs.setFont(PDType1Font.TIMES_ROMAN, 14);
+ cs.newLineAtOffset(100, 550);
+ cs.showText("Date of departure:");
+ cs.endText();
+
+ cs.beginText();
+ cs.setFont(PDType1Font.TIMES_ROMAN, 14);
+ cs.newLineAtOffset(100, 530);
+ cs.showText("Length of stay:");
+ cs.endText();
+
+ cs.beginText();
+ cs.setFont(PDType1Font.TIMES_ROMAN, 20);
+ cs.setNonStrokingColor(Color.getColor("5100FC"));
+ cs.newLineAtOffset(100, 210);
+ cs.showText("Total:");
+ cs.setNonStrokingColor(Color.black);
+ cs.endText();
+
+
+ // Dynamic data
+
+
+ cs.beginText();
+ cs.setFont(PDType1Font.TIMES_ROMAN, 14);
+ cs.newLineAtOffset(250, 590);
+ cs.showText(name);
+ cs.endText();
+
+ cs.beginText();
+ cs.setFont(PDType1Font.TIMES_ROMAN, 14);
+ cs.newLineAtOffset(250, 570);
+ cs.showText(dateOfArrival);
+ cs.endText();
+
+ cs.beginText();
+ cs.setFont(PDType1Font.TIMES_ROMAN, 14);
+ cs.newLineAtOffset(250, 550);
+ cs.showText(dateOfDeparture);
+ cs.endText();
+
+ cs.beginText();
+ cs.setFont(PDType1Font.TIMES_ROMAN, 14);
+ cs.newLineAtOffset(250, 530);
+ cs.showText("" + days);
+ cs.endText();
+
+ cs.beginText();
+ cs.setFont(PDType1Font.TIMES_ROMAN, 21);
+ cs.setNonStrokingColor(Color.getColor("5100FC"));
+ cs.newLineAtOffset(250, 210);
+ cs.showText(total + "€");
+ cs.setNonStrokingColor(Color.black);
+ cs.endText();
+
+
+ cs.close();
+
+
+ // Save the pdf
+ FileChooser fileChooser = new FileChooser();
+ fileChooser.setTitle("Save");
+ fileChooser.getExtensionFilters().addAll(new FileChooser.ExtensionFilter("All Files", "*.*"));
+
+ File dir = fileChooser.showSaveDialog(Nav.content.getScene().getWindow());
+ String directory = dir + String.valueOf(LocalDateTime.now().toEpochSecond(ZoneOffset.UTC)) + ".pdf";
+ document.save(directory);
+
+
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/github/mariosplen/bookings/util/Views.java b/src/main/java/com/github/mariosplen/bookings/util/Views.java
new file mode 100644
index 0000000..a45d6cb
--- /dev/null
+++ b/src/main/java/com/github/mariosplen/bookings/util/Views.java
@@ -0,0 +1,22 @@
+package com.github.mariosplen.bookings.util;
+
+public class Views {
+ public static final String MAIN = "/com/github/mariosplen/bookings/fxml/main-view.fxml";
+
+
+ public static final String BOOKS = "/com/github/mariosplen/bookings/fxml/books/books-view.fxml";
+ public static final String CALENDAR = "/com/github/mariosplen/bookings/fxml/calendar/calendar-view.fxml";
+ public static final String GUESTS = "/com/github/mariosplen/bookings/fxml/guests/guests-view.fxml";
+ public static final String HOME = "/com/github/mariosplen/bookings/fxml/home/home-view.fxml";
+ public static final String LOADING = "/com/github/mariosplen/bookings/fxml/loading/loading-view.fxml";
+ public static final String LOGIN = "/com/github/mariosplen/bookings/fxml/login/login-view.fxml";
+ public static final String REGISTER = "/com/github/mariosplen/bookings/fxml/register/register-view.fxml";
+ public static final String RESERVATION = "/com/github/mariosplen/bookings/fxml/reservation/reservation-view.fxml";
+ public static final String USER_ITEM = "/com/github/mariosplen/bookings/fxml/users/user-item.fxml";
+ public static final String USERS = "/com/github/mariosplen/bookings/fxml/users/users-view.fxml";
+ public static final String RECOVERY = "/com/github/mariosplen/bookings/fxml/recovery/recovery-view.fxml";
+ public static final String NEW_GUEST = "/com/github/mariosplen/bookings/fxml/new-guest/new-guest-view.fxml";
+ public static final String RESERVATION_DETAILS = "/com/github/mariosplen/bookings/fxml/reservation/reservation-details-view.fxml";
+}
+
+
diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java
new file mode 100644
index 0000000..45272bf
--- /dev/null
+++ b/src/main/java/module-info.java
@@ -0,0 +1,42 @@
+module com.github.mariosplen.bookings {
+ requires javafx.controls;
+ requires javafx.fxml;
+ requires java.sql;
+ requires javafx.media;
+ requires java.sql.rowset;
+ requires org.controlsfx.controls;
+ requires java.desktop;
+ requires org.apache.pdfbox;
+ requires org.xerial.sqlitejdbc;
+
+ exports com.github.mariosplen.bookings.controllers;
+ exports com.github.mariosplen.bookings;
+ exports com.github.mariosplen.bookings.models;
+ exports com.github.mariosplen.bookings.util;
+ exports com.github.mariosplen.bookings.controllers.books;
+ exports com.github.mariosplen.bookings.controllers.calendar;
+ exports com.github.mariosplen.bookings.controllers.home;
+ exports com.github.mariosplen.bookings.controllers.register;
+ exports com.github.mariosplen.bookings.controllers.recovery;
+ exports com.github.mariosplen.bookings.controllers.users;
+ exports com.github.mariosplen.bookings.controllers.loading;
+ exports com.github.mariosplen.bookings.controllers.reservation;
+ exports com.github.mariosplen.bookings.controllers.guests;
+ exports com.github.mariosplen.bookings.controllers.new_guest;
+
+ opens com.github.mariosplen.bookings.controllers to javafx.fxml;
+ opens com.github.mariosplen.bookings to javafx.fxml;
+ opens com.github.mariosplen.bookings.models to javafx.fxml;
+ opens com.github.mariosplen.bookings.util to javafx.fxml;
+ opens com.github.mariosplen.bookings.controllers.books to javafx.fxml;
+ opens com.github.mariosplen.bookings.controllers.calendar to javafx.fxml;
+ opens com.github.mariosplen.bookings.controllers.recovery to javafx.fxml;
+ opens com.github.mariosplen.bookings.controllers.home to javafx.fxml;
+ opens com.github.mariosplen.bookings.controllers.new_guest to javafx.fxml;
+ opens com.github.mariosplen.bookings.controllers.login to javafx.fxml;
+ opens com.github.mariosplen.bookings.controllers.register to javafx.fxml;
+ opens com.github.mariosplen.bookings.controllers.users to javafx.fxml;
+ opens com.github.mariosplen.bookings.controllers.loading to javafx.fxml;
+ opens com.github.mariosplen.bookings.controllers.reservation to javafx.fxml;
+ opens com.github.mariosplen.bookings.controllers.guests to javafx.fxml;
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/github/mariosplen/bookings/HelloApplication.kt b/src/main/kotlin/com/github/mariosplen/bookings/HelloApplication.kt
deleted file mode 100644
index 2b680e3..0000000
--- a/src/main/kotlin/com/github/mariosplen/bookings/HelloApplication.kt
+++ /dev/null
@@ -1,20 +0,0 @@
-package com.github.mariosplen.bookings
-
-import javafx.application.Application
-import javafx.fxml.FXMLLoader
-import javafx.scene.Scene
-import javafx.stage.Stage
-
-class HelloApplication : Application() {
- override fun start(stage: Stage) {
- val fxmlLoader = FXMLLoader(HelloApplication::class.java.getResource("hello-view.fxml"))
- val scene = Scene(fxmlLoader.load(), 320.0, 240.0)
- stage.title = "Hello!"
- stage.scene = scene
- stage.show()
- }
-}
-
-fun main() {
- Application.launch(HelloApplication::class.java)
-}
\ No newline at end of file
diff --git a/src/main/kotlin/com/github/mariosplen/bookings/HelloController.kt b/src/main/kotlin/com/github/mariosplen/bookings/HelloController.kt
deleted file mode 100644
index 2a3247b..0000000
--- a/src/main/kotlin/com/github/mariosplen/bookings/HelloController.kt
+++ /dev/null
@@ -1,13 +0,0 @@
-package bookings
-
-import javafx.fxml.FXML
-import javafx.scene.control.Label
-
-class HelloController {
- @FXML
- private lateinit var welcomeText: Label
-
- fun onHelloButtonClick() {
- welcomeText.text = "Welcome to JavaFX Application!"
- }
-}
\ No newline at end of file
diff --git a/src/main/kotlin/module-info.java b/src/main/kotlin/module-info.java
deleted file mode 100644
index 3ccadfe..0000000
--- a/src/main/kotlin/module-info.java
+++ /dev/null
@@ -1,9 +0,0 @@
-module com.github.mariosplen.bookings {
- requires javafx.controls;
- requires javafx.fxml;
- requires kotlin.stdlib;
-
-
- opens com.github.mariosplen.bookings to javafx.fxml;
- exports com.github.mariosplen.bookings;
-}
\ No newline at end of file
diff --git a/src/main/resources/com/github/mariosplen/bookings/bookings.css b/src/main/resources/com/github/mariosplen/bookings/bookings.css
new file mode 100644
index 0000000..2637851
--- /dev/null
+++ b/src/main/resources/com/github/mariosplen/bookings/bookings.css
@@ -0,0 +1,386 @@
+@font-face {
+ src: url("fonts/Solway/Solway-Bold.ttf");
+}
+
+.hotelinoTitle {
+ -fx-font-family: 'Atomic Age';
+ -fx-font-size: 96
+}
+
+.mainViewUsername {
+ -fx-fill: #FFF;
+ -fx-font-family: Solway;
+ -fx-font-size: 30;
+ -fx-font-weight: bold
+}
+
+.header {
+ -fx-font-family: Solway;
+ -fx-font-size: 40;
+ -fx-font-weight: bold
+}
+
+.mediumText {
+ -fx-font-family: Solway;
+ -fx-font-size: 20;
+ -fx-font-weight: bold
+}
+
+.smallText {
+ -fx-font-family: Solway;
+ -fx-font-size: 15;
+ -fx-font-weight: bold
+}
+
+.errorText {
+ -fx-fill: #FF1212;
+ -fx-font-family: Solway;
+ -fx-font-size: 15;
+ -fx-font-weight: bold
+}
+
+.bigBtn {
+ -fx-background-color: #5100FC;
+ -fx-background-radius: 32;
+ -fx-font-family: Solway;
+ -fx-font-size: 40;
+ -fx-font-weight: bold;
+ -fx-padding: 0;
+ -fx-text-fill: #FFF
+}
+
+.mediumBtn {
+ -fx-background-color: #5100FC;
+ -fx-background-radius: 6;
+ -fx-font-family: Solway;
+ -fx-font-size: 32;
+ -fx-font-weight: bold;
+ -fx-padding: 0;
+ -fx-text-fill: #FFF
+}
+
+.smallBtn {
+ -fx-background-color: #5100FC;
+ -fx-background-radius: 6;
+ -fx-font-family: Solway;
+ -fx-font-size: 20;
+ -fx-font-weight: bold;
+ -fx-padding: 14;
+ -fx-text-fill: #FFF
+}
+
+/*noinspection CssUnusedSymbol*/
+.verySmallBtn {
+ -fx-background-color: #5100FC;
+ -fx-background-radius: 3;
+ -fx-font-family: Solway;
+ -fx-font-size: 12;
+ -fx-font-weight: bold;
+ -fx-text-fill: #FFF
+}
+
+.smallBtnRed {
+ -fx-background-color: #ff3636;
+ -fx-background-radius: 6;
+ -fx-font-family: Solway;
+ -fx-font-size: 20;
+ -fx-font-weight: bold;
+ -fx-padding: 14;
+ -fx-text-fill: #FFF
+}
+
+/*noinspection CssUnusedSymbol*/
+.verySmallRedBtn {
+ -fx-background-color: #ff3636;
+ -fx-background-radius: 3;
+ -fx-font-family: Solway;
+ -fx-font-size: 12;
+ -fx-font-weight: bold;
+ -fx-text-fill: #FFF
+}
+
+.mediumBtn:disabled {
+ -fx-background-color: #696969;
+ -fx-opacity: 1
+}
+
+.calendarLeftBtn {
+ -fx-background-radius: 0 0 0 6;
+ -fx-font-size: 24;
+ -fx-font-weight: normal
+}
+
+.calendarRightBtn {
+ -fx-background-radius: 0 0 6 0;
+ -fx-font-size: 24;
+ -fx-font-weight: normal
+}
+
+.basicTF {
+ -fx-background-color: #C6B3EF;
+ -fx-background-radius: 3;
+ -fx-font-size: 24
+}
+
+/*noinspection CssUnusedSymbol*/
+.basicTF:hover, .basicTF:focused, .choice-box .menu-item:focused, .choice-box:hover {
+ -fx-background-color: #D1C2F2
+}
+
+.logoutHBox:hover, .backButton:hover {
+ -fx-background-color: #e9f5f9
+}
+
+.checkBox {
+ -fx-font-size: 24;
+ -fx-text-fill: #000
+}
+
+/*noinspection CssUnusedSymbol*/
+.checkBox .box {
+ -fx-background-color: #D9D9D9;
+ -fx-background-radius: 0;
+ -fx-border-width: 0
+}
+
+/*noinspection CssUnusedSymbol*/
+.checkBox:hover .box {
+ -fx-background-color: #E6E6E6
+}
+
+.designPane {
+ -fx-background-color: #C6B3EF;
+ -fx-background-radius: 3
+}
+
+.choice-box {
+ -fx-background-color: #C6B3EF;
+ -fx-font-size: 24px;
+ -fx-mark-color: #000
+}
+
+/*noinspection CssUnusedSymbol*/
+.choice-box .context-menu {
+ -fx-background-color: #C6B3EF
+}
+
+.choice-box .menu-item > .label {
+ -fx-text-fill: #FFF
+}
+
+.choice-box .menu-item:focused > .label, .choice-box .label {
+ -fx-text-fill: #000
+}
+
+.date-picker {
+ -fx-background-color: #5100FC;
+ -fx-focus-color: -fx-secondary-color;
+ -fx-font-size: 24px;
+ -fx-light-grey-color: #d1d1d1;
+ -fx-primary-color: #5100FC;
+ -fx-secondary-color: #5100FC
+}
+
+/*noinspection CssUnusedSymbol*/
+.date-picker .arrow-button {
+ -fx-background-color: -fx-primary-color;
+ -fx-background-radius: 0
+}
+
+/*noinspection CssUnusedSymbol*/
+.date-picker .arrow-button .arrow, .date-picker .cell {
+ -fx-background-color: #fff
+}
+
+/*noinspection CssUnusedSymbol*/
+.date-picker .arrow-button:hover {
+ -fx-background-color: #784ae3
+}
+
+/*noinspection CssUnusedSymbol*/
+.date-picker .cell:hover, .date-picker .cell:focused, .date-picker-popup .month-year-pane {
+ -fx-background-color: -fx-primary-color
+}
+
+/*noinspection CssUnusedSymbol*/
+.date-picker .selected, .date-picker .selected:focused {
+ -fx-background-color: -fx-primary-color;
+ -fx-text-fill: #fff
+}
+
+/*noinspection CssUnusedSymbol*/
+.date-picker-popup {
+ -fx-border-color: transparent
+}
+
+.date-picker-popup .month-year-pane .label {
+ -fx-text-fill: #fff
+}
+
+/*noinspection CssUnusedSymbol*/
+.date-picker-popup .spinner .button .left-arrow, .date-picker-popup .spinner .button .right-arrow {
+ -fx-background-color: -fx-secondary-color
+}
+
+/*noinspection CssUnusedSymbol*/
+.date-picker-popup .week-number-cell {
+ -fx-text-fill: -fx-secondary-color
+}
+
+.permissionsBoxesBackground {
+ -fx-background-color: #D9D9D9
+}
+
+/*noinspection CssUnusedSymbol*/
+.scroll-bar:horizontal .thumb, .scroll-bar:vertical .thumb {
+ -fx-background-color: #5100FC;
+ -fx-background-radius: 5em
+}
+
+/*noinspection CssUnusedSymbol*/
+.scroll-bar:horizontal .track, .scroll-bar:vertical .track {
+ -fx-background-color: transparent;
+ -fx-background-radius: 0;
+ -fx-border-color: transparent
+}
+
+/*noinspection CssUnusedSymbol*/
+.scroll-pane {
+ -fx-background-color: #B3A5D1;
+ -fx-background-radius: 8
+}
+
+/*noinspection CssUnusedSymbol*/
+.scroll-pane .menu-item {
+ -fx-border-color: transparent;
+ -fx-border-style: solid
+}
+
+/*noinspection CssUnusedSymbol*/
+.scroll-pane .scroll-arrow {
+ -fx-padding: 0 0 0 0
+}
+
+/*noinspection CssUnusedSymbol*/
+.scroll-pane > .corner {
+ -fx-background-color: #B3A5D1
+}
+
+/*noinspection CssUnusedSymbol*/
+.calendarCell {
+ -fx-fill: #C6B3EF
+}
+
+/*noinspection CssUnusedSymbol*/
+.calendarCell:disabled {
+ -fx-border-width: 0;
+ -fx-effect: innershadow(gaussian, #000, 2, 0, 0, 0);
+ -fx-fill: #6100FF;
+ -fx-opacity: 1;
+ -fx-stroke-width: 0
+}
+
+/*noinspection CssUnusedSymbol*/
+.calendarCell:disabled:hover {
+ -fx-fill: #711BFF
+}
+
+/*noinspection CssUnusedSymbol*/
+.calendarCell:hover {
+ -fx-fill: #D3C2F6
+}
+
+/*noinspection CssUnusedSymbol*/
+.calendarCellTagBlack {
+ -fx-background-color: #F7F7F7;
+ -fx-font-size: 22px;
+ -fx-text-fill: #000
+}
+
+/*noinspection CssUnusedSymbol*/
+.calendarCellTagWhite {
+ -fx-background-color: #5100FC;
+ -fx-font-size: 22px;
+ -fx-text-fill: #FFF
+}
+
+/*noinspection CssUnusedSymbol*/
+.table-view .column-header-background {
+ -fx-background-color: linear-gradient(to bottom, rgba(81, 0, 252, 0.27), #C6B3EF44);
+ -fx-background-insets: 0 11px 0 0;
+ -fx-background-radius: 7px 7px 0 0;
+ -fx-padding: 0 0 5px 0
+}
+
+/*noinspection CssUnusedSymbol*/
+.table-view .table-cell {
+ -fx-border-color: transparent;
+ -fx-padding: 2 0 2 10px
+}
+
+/*noinspection CssUnusedSymbol*/
+.table-row-cell:hover {
+ -fx-background-color: #93f9b911;
+ -fx-text-background-color: red
+}
+
+/*noinspection CssUnusedSymbol*/
+.table-row-cell:odd {
+ -fx-background-color: #93f9b911;
+ -fx-background-insets: 0, 0 0 1 0;
+ -fx-padding: 0
+}
+
+/*noinspection CssUnusedSymbol*/
+.table-row-cell:even {
+ -fx-background-color: #1dbbdd11;
+ -fx-background-insets: 0, 0 0 1 0;
+ -fx-padding: 0
+}
+
+/*noinspection CssUnusedSymbol*/
+.table-view .virtual-flow .scroll-bar .increment-button, .table-view .virtual-flow .scroll-bar .decrement-button {
+ -fx-opacity: 0;
+ -fx-padding: 2
+}
+
+/*noinspection CssUnusedSymbol*/
+.table-view .virtual-flow .scroll-bar:vertical .thumb {
+ -fx-background-color: linear-gradient(to bottom, #1dbbdd44, #93f9b944)
+}
+
+/*noinspection CssUnusedSymbol*/
+.table-view .virtual-flow .scroll-bar:horizontal .thumb {
+ -fx-background-color: linear-gradient(to right, #1dbbdd44, #93f9b944)
+}
+
+/*noinspection CssUnusedSymbol*/
+.table-row-cell:selected {
+ -fx-background-color: #81c483;
+ -fx-background-radius: 15px
+}
+
+/*noinspection CssUnusedSymbol*/
+.mainView, .blueBackground, .bigButton:pressed, .mediumBtn:pressed, .smallBtn:pressed, .check-box:selected .mark {
+ -fx-background-color: #5100FC
+}
+
+/*noinspection CssUnusedSymbol*/
+.smallBtnRed:hover, .verySmallRedBtn:hover {
+ -fx-background-color: #ff4c4c
+}
+
+/*noinspection CssUnusedSymbol*/
+.bigButton:hover, .mediumBtn:hover, .smallBtn:hover, .verySmallBtn:hover {
+ -fx-background-color: #7332FC
+}
+
+.contentPane, .backButton {
+ -fx-background-color: #FFF;
+ -fx-background-radius: 16
+}
+
+/*noinspection CssUnusedSymbol*/
+.scroll-bar:horizontal, .scroll-bar:vertical, .table-view, .table-view .column-header-background .filler, .table-view .corner, .table-view .column-header, .table-view .virtual-flow .scroll-bar:vertical, .table-view .virtual-flow .scroll-bar:vertical .track, .table-view .virtual-flow .scroll-bar:vertical .track-background, .table-view .virtual-flow .scroll-bar:horizontal, .table-view .virtual-flow .scroll-bar:horizontal .track, .table-view .virtual-flow .scroll-bar:horizontal .track-background {
+ -fx-background-color: transparent
+}
\ No newline at end of file
diff --git a/src/main/resources/com/github/mariosplen/bookings/fonts/AtomicAge/AtomicAge-Regular.ttf b/src/main/resources/com/github/mariosplen/bookings/fonts/AtomicAge/AtomicAge-Regular.ttf
new file mode 100644
index 0000000..fb8f824
Binary files /dev/null and b/src/main/resources/com/github/mariosplen/bookings/fonts/AtomicAge/AtomicAge-Regular.ttf differ
diff --git a/src/main/resources/com/github/mariosplen/bookings/fonts/AtomicAge/OFL.txt b/src/main/resources/com/github/mariosplen/bookings/fonts/AtomicAge/OFL.txt
new file mode 100644
index 0000000..b0c2f04
--- /dev/null
+++ b/src/main/resources/com/github/mariosplen/bookings/fonts/AtomicAge/OFL.txt
@@ -0,0 +1,93 @@
+Copyright (c) 2013 - 2016, Sorkin Type Co (www.sorkintype.com) with Reserved Font Name 'Atomic Age'.
+
+This Font Software is licensed under the SIL Open Font License, Version 1.1.
+This license is copied below, and is also available with a FAQ at:
+http://scripts.sil.org/OFL
+
+
+-----------------------------------------------------------
+SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+-----------------------------------------------------------
+
+PREAMBLE
+The goals of the Open Font License (OFL) are to stimulate worldwide
+development of collaborative font projects, to support the font creation
+efforts of academic and linguistic communities, and to provide a free and
+open framework in which fonts may be shared and improved in partnership
+with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and
+redistributed freely as long as they are not sold by themselves. The
+fonts, including any derivative works, can be bundled, embedded,
+redistributed and/or sold with any software provided that any reserved
+names are not used by derivative works. The fonts and derivatives,
+however, cannot be released under any other type of license. The
+requirement for fonts to remain under this license does not apply
+to any document created using the fonts or their derivatives.
+
+DEFINITIONS
+"Font Software" refers to the set of files released by the Copyright
+Holder(s) under this license and clearly marked as such. This may
+include source files, build scripts and documentation.
+
+"Reserved Font Name" refers to any names specified as such after the
+copyright statement(s).
+
+"Original Version" refers to the collection of Font Software components as
+distributed by the Copyright Holder(s).
+
+"Modified Version" refers to any derivative made by adding to, deleting,
+or substituting -- in part or in whole -- any of the components of the
+Original Version, by changing formats or by porting the Font Software to a
+new environment.
+
+"Author" refers to any designer, engineer, programmer, technical
+writer or other person who contributed to the Font Software.
+
+PERMISSION & CONDITIONS
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of the Font Software, to use, study, copy, merge, embed, modify,
+redistribute, and sell modified and unmodified copies of the Font
+Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components,
+in Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled,
+redistributed and/or sold with any software, provided that each copy
+contains the above copyright notice and this license. These can be
+included either as stand-alone text files, human-readable headers or
+in the appropriate machine-readable metadata fields within text or
+binary files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font
+Name(s) unless explicit written permission is granted by the corresponding
+Copyright Holder. This restriction only applies to the primary font name as
+presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
+Software shall not be used to promote, endorse or advertise any
+Modified Version, except to acknowledge the contribution(s) of the
+Copyright Holder(s) and the Author(s) or with their explicit written
+permission.
+
+5) The Font Software, modified or unmodified, in part or in whole,
+must be distributed entirely under this license, and must not be
+distributed under any other license. The requirement for fonts to
+remain under this license does not apply to any document created
+using the Font Software.
+
+TERMINATION
+This license becomes null and void if any of the above conditions are
+not met.
+
+DISCLAIMER
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
+DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
+OTHER DEALINGS IN THE FONT SOFTWARE.
diff --git a/src/main/resources/com/github/mariosplen/bookings/fonts/AtomicAge/atomic_age.css b/src/main/resources/com/github/mariosplen/bookings/fonts/AtomicAge/atomic_age.css
new file mode 100644
index 0000000..0dba506
--- /dev/null
+++ b/src/main/resources/com/github/mariosplen/bookings/fonts/AtomicAge/atomic_age.css
@@ -0,0 +1,3 @@
+@font-face {
+ src: url("AtomicAge-Regular.ttf");
+}
\ No newline at end of file
diff --git a/src/main/resources/com/github/mariosplen/bookings/fonts/Solway/OFL.txt b/src/main/resources/com/github/mariosplen/bookings/fonts/Solway/OFL.txt
new file mode 100644
index 0000000..a51be44
--- /dev/null
+++ b/src/main/resources/com/github/mariosplen/bookings/fonts/Solway/OFL.txt
@@ -0,0 +1,93 @@
+Copyright 2018 The Solway Project Authors (https://github.com/mashavp/Solway)
+
+This Font Software is licensed under the SIL Open Font License, Version 1.1.
+This license is copied below, and is also available with a FAQ at:
+http://scripts.sil.org/OFL
+
+
+-----------------------------------------------------------
+SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+-----------------------------------------------------------
+
+PREAMBLE
+The goals of the Open Font License (OFL) are to stimulate worldwide
+development of collaborative font projects, to support the font creation
+efforts of academic and linguistic communities, and to provide a free and
+open framework in which fonts may be shared and improved in partnership
+with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and
+redistributed freely as long as they are not sold by themselves. The
+fonts, including any derivative works, can be bundled, embedded,
+redistributed and/or sold with any software provided that any reserved
+names are not used by derivative works. The fonts and derivatives,
+however, cannot be released under any other type of license. The
+requirement for fonts to remain under this license does not apply
+to any document created using the fonts or their derivatives.
+
+DEFINITIONS
+"Font Software" refers to the set of files released by the Copyright
+Holder(s) under this license and clearly marked as such. This may
+include source files, build scripts and documentation.
+
+"Reserved Font Name" refers to any names specified as such after the
+copyright statement(s).
+
+"Original Version" refers to the collection of Font Software components as
+distributed by the Copyright Holder(s).
+
+"Modified Version" refers to any derivative made by adding to, deleting,
+or substituting -- in part or in whole -- any of the components of the
+Original Version, by changing formats or by porting the Font Software to a
+new environment.
+
+"Author" refers to any designer, engineer, programmer, technical
+writer or other person who contributed to the Font Software.
+
+PERMISSION & CONDITIONS
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of the Font Software, to use, study, copy, merge, embed, modify,
+redistribute, and sell modified and unmodified copies of the Font
+Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components,
+in Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled,
+redistributed and/or sold with any software, provided that each copy
+contains the above copyright notice and this license. These can be
+included either as stand-alone text files, human-readable headers or
+in the appropriate machine-readable metadata fields within text or
+binary files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font
+Name(s) unless explicit written permission is granted by the corresponding
+Copyright Holder. This restriction only applies to the primary font name as
+presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
+Software shall not be used to promote, endorse or advertise any
+Modified Version, except to acknowledge the contribution(s) of the
+Copyright Holder(s) and the Author(s) or with their explicit written
+permission.
+
+5) The Font Software, modified or unmodified, in part or in whole,
+must be distributed entirely under this license, and must not be
+distributed under any other license. The requirement for fonts to
+remain under this license does not apply to any document created
+using the Font Software.
+
+TERMINATION
+This license becomes null and void if any of the above conditions are
+not met.
+
+DISCLAIMER
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
+DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
+OTHER DEALINGS IN THE FONT SOFTWARE.
diff --git a/src/main/resources/com/github/mariosplen/bookings/fonts/Solway/Solway-Bold.ttf b/src/main/resources/com/github/mariosplen/bookings/fonts/Solway/Solway-Bold.ttf
new file mode 100644
index 0000000..283ab55
Binary files /dev/null and b/src/main/resources/com/github/mariosplen/bookings/fonts/Solway/Solway-Bold.ttf differ
diff --git a/src/main/resources/com/github/mariosplen/bookings/fonts/Solway/Solway-ExtraBold.ttf b/src/main/resources/com/github/mariosplen/bookings/fonts/Solway/Solway-ExtraBold.ttf
new file mode 100644
index 0000000..e6c86e5
Binary files /dev/null and b/src/main/resources/com/github/mariosplen/bookings/fonts/Solway/Solway-ExtraBold.ttf differ
diff --git a/src/main/resources/com/github/mariosplen/bookings/fonts/Solway/Solway-Light.ttf b/src/main/resources/com/github/mariosplen/bookings/fonts/Solway/Solway-Light.ttf
new file mode 100644
index 0000000..a1e7bc8
Binary files /dev/null and b/src/main/resources/com/github/mariosplen/bookings/fonts/Solway/Solway-Light.ttf differ
diff --git a/src/main/resources/com/github/mariosplen/bookings/fonts/Solway/Solway-Medium.ttf b/src/main/resources/com/github/mariosplen/bookings/fonts/Solway/Solway-Medium.ttf
new file mode 100644
index 0000000..7ab6d00
Binary files /dev/null and b/src/main/resources/com/github/mariosplen/bookings/fonts/Solway/Solway-Medium.ttf differ
diff --git a/src/main/resources/com/github/mariosplen/bookings/fonts/Solway/Solway-Regular.ttf b/src/main/resources/com/github/mariosplen/bookings/fonts/Solway/Solway-Regular.ttf
new file mode 100644
index 0000000..3ef963c
Binary files /dev/null and b/src/main/resources/com/github/mariosplen/bookings/fonts/Solway/Solway-Regular.ttf differ
diff --git a/src/main/resources/com/github/mariosplen/bookings/fxml/books/books-view.fxml b/src/main/resources/com/github/mariosplen/bookings/fxml/books/books-view.fxml
new file mode 100644
index 0000000..40b31be
--- /dev/null
+++ b/src/main/resources/com/github/mariosplen/bookings/fxml/books/books-view.fxml
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/com/github/mariosplen/bookings/fxml/calendar/calendar-view.fxml b/src/main/resources/com/github/mariosplen/bookings/fxml/calendar/calendar-view.fxml
new file mode 100644
index 0000000..4e01fb2
--- /dev/null
+++ b/src/main/resources/com/github/mariosplen/bookings/fxml/calendar/calendar-view.fxml
@@ -0,0 +1,54 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/com/github/mariosplen/bookings/fxml/guests/guests-view.fxml b/src/main/resources/com/github/mariosplen/bookings/fxml/guests/guests-view.fxml
new file mode 100644
index 0000000..2061457
--- /dev/null
+++ b/src/main/resources/com/github/mariosplen/bookings/fxml/guests/guests-view.fxml
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/com/github/mariosplen/bookings/fxml/home/home-view.fxml b/src/main/resources/com/github/mariosplen/bookings/fxml/home/home-view.fxml
new file mode 100644
index 0000000..058b047
--- /dev/null
+++ b/src/main/resources/com/github/mariosplen/bookings/fxml/home/home-view.fxml
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/com/github/mariosplen/bookings/fxml/loading/loading-view.fxml b/src/main/resources/com/github/mariosplen/bookings/fxml/loading/loading-view.fxml
new file mode 100644
index 0000000..884df32
--- /dev/null
+++ b/src/main/resources/com/github/mariosplen/bookings/fxml/loading/loading-view.fxml
@@ -0,0 +1,54 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/com/github/mariosplen/bookings/fxml/login/login-view.fxml b/src/main/resources/com/github/mariosplen/bookings/fxml/login/login-view.fxml
new file mode 100644
index 0000000..4c35b26
--- /dev/null
+++ b/src/main/resources/com/github/mariosplen/bookings/fxml/login/login-view.fxml
@@ -0,0 +1,81 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/com/github/mariosplen/bookings/fxml/main-view.fxml b/src/main/resources/com/github/mariosplen/bookings/fxml/main-view.fxml
new file mode 100644
index 0000000..e268634
--- /dev/null
+++ b/src/main/resources/com/github/mariosplen/bookings/fxml/main-view.fxml
@@ -0,0 +1,47 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/com/github/mariosplen/bookings/fxml/new-guest/new-guest-view.fxml b/src/main/resources/com/github/mariosplen/bookings/fxml/new-guest/new-guest-view.fxml
new file mode 100644
index 0000000..febce68
--- /dev/null
+++ b/src/main/resources/com/github/mariosplen/bookings/fxml/new-guest/new-guest-view.fxml
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/com/github/mariosplen/bookings/fxml/recovery/recovery-view.fxml b/src/main/resources/com/github/mariosplen/bookings/fxml/recovery/recovery-view.fxml
new file mode 100644
index 0000000..4be58d3
--- /dev/null
+++ b/src/main/resources/com/github/mariosplen/bookings/fxml/recovery/recovery-view.fxml
@@ -0,0 +1,87 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/com/github/mariosplen/bookings/fxml/register/register-view.fxml b/src/main/resources/com/github/mariosplen/bookings/fxml/register/register-view.fxml
new file mode 100644
index 0000000..8ee97de
--- /dev/null
+++ b/src/main/resources/com/github/mariosplen/bookings/fxml/register/register-view.fxml
@@ -0,0 +1,58 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/com/github/mariosplen/bookings/fxml/reservation/reservation-details-view.fxml b/src/main/resources/com/github/mariosplen/bookings/fxml/reservation/reservation-details-view.fxml
new file mode 100644
index 0000000..6440d0a
--- /dev/null
+++ b/src/main/resources/com/github/mariosplen/bookings/fxml/reservation/reservation-details-view.fxml
@@ -0,0 +1,64 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/com/github/mariosplen/bookings/fxml/reservation/reservation-view.fxml b/src/main/resources/com/github/mariosplen/bookings/fxml/reservation/reservation-view.fxml
new file mode 100644
index 0000000..1860dd5
--- /dev/null
+++ b/src/main/resources/com/github/mariosplen/bookings/fxml/reservation/reservation-view.fxml
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/com/github/mariosplen/bookings/fxml/users/user-item.fxml b/src/main/resources/com/github/mariosplen/bookings/fxml/users/user-item.fxml
new file mode 100644
index 0000000..577c1ab
--- /dev/null
+++ b/src/main/resources/com/github/mariosplen/bookings/fxml/users/user-item.fxml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/com/github/mariosplen/bookings/fxml/users/users-view.fxml b/src/main/resources/com/github/mariosplen/bookings/fxml/users/users-view.fxml
new file mode 100644
index 0000000..c2a4794
--- /dev/null
+++ b/src/main/resources/com/github/mariosplen/bookings/fxml/users/users-view.fxml
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/com/github/mariosplen/bookings/hello-view.fxml b/src/main/resources/com/github/mariosplen/bookings/hello-view.fxml
deleted file mode 100644
index 1b96e06..0000000
--- a/src/main/resources/com/github/mariosplen/bookings/hello-view.fxml
+++ /dev/null
@@ -1,15 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/main/resources/com/github/mariosplen/bookings/media/icons/add-user.png b/src/main/resources/com/github/mariosplen/bookings/media/icons/add-user.png
new file mode 100644
index 0000000..947fbb6
Binary files /dev/null and b/src/main/resources/com/github/mariosplen/bookings/media/icons/add-user.png differ
diff --git a/src/main/resources/com/github/mariosplen/bookings/media/icons/arrow.png b/src/main/resources/com/github/mariosplen/bookings/media/icons/arrow.png
new file mode 100644
index 0000000..eb919a7
Binary files /dev/null and b/src/main/resources/com/github/mariosplen/bookings/media/icons/arrow.png differ
diff --git a/src/main/resources/com/github/mariosplen/bookings/media/icons/back.png b/src/main/resources/com/github/mariosplen/bookings/media/icons/back.png
new file mode 100644
index 0000000..fc6e86c
Binary files /dev/null and b/src/main/resources/com/github/mariosplen/bookings/media/icons/back.png differ
diff --git a/src/main/resources/com/github/mariosplen/bookings/media/icons/gear.png b/src/main/resources/com/github/mariosplen/bookings/media/icons/gear.png
new file mode 100644
index 0000000..e5c899b
Binary files /dev/null and b/src/main/resources/com/github/mariosplen/bookings/media/icons/gear.png differ
diff --git a/src/main/resources/com/github/mariosplen/bookings/media/icons/icon.png b/src/main/resources/com/github/mariosplen/bookings/media/icons/icon.png
new file mode 100644
index 0000000..2798cf3
Binary files /dev/null and b/src/main/resources/com/github/mariosplen/bookings/media/icons/icon.png differ
diff --git a/src/main/resources/com/github/mariosplen/bookings/media/icons/logout.png b/src/main/resources/com/github/mariosplen/bookings/media/icons/logout.png
new file mode 100644
index 0000000..440f377
Binary files /dev/null and b/src/main/resources/com/github/mariosplen/bookings/media/icons/logout.png differ
diff --git a/src/main/resources/com/github/mariosplen/bookings/media/icons/profile-circle.png b/src/main/resources/com/github/mariosplen/bookings/media/icons/profile-circle.png
new file mode 100644
index 0000000..e141e06
Binary files /dev/null and b/src/main/resources/com/github/mariosplen/bookings/media/icons/profile-circle.png differ
diff --git a/src/main/resources/com/github/mariosplen/bookings/media/intro/intro.mp4 b/src/main/resources/com/github/mariosplen/bookings/media/intro/intro.mp4
new file mode 100644
index 0000000..1758cb1
Binary files /dev/null and b/src/main/resources/com/github/mariosplen/bookings/media/intro/intro.mp4 differ