Compare commits

...

4 Commits

Author SHA1 Message Date
bryce
e4189b454b Random as - not sure what's in this submit 2024-12-02 12:19:14 +13:00
bryce
49a34e77ab Aperance Modifycation of the Client
sorting out the 'Dashboard' and SettingsWindow
creation of Kitset & MoC pages and BuildView model
2024-12-01 15:41:56 +13:00
bryce
484b60e31e some tweaks - not sure what as this commit
should havve been done ages ago
2024-11-26 23:36:16 +13:00
bryce
6d8795a851 fix docker-compose.yml 2024-11-16 18:25:48 +13:00
29 changed files with 246 additions and 196 deletions

View File

@@ -0,0 +1,45 @@
package com.example.bricklog.model;
public class Build {
private String name;
private String imageUrl;
private String type; // "Kitset" or "MoC"
// Constructor
public Build(String name, String imageUrl, String type) {
this.name = name;
this.imageUrl = imageUrl;
this.type = type;
}
// Getters and setters
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getImageUrl() {
return imageUrl;
}
public void setImageUrl(String imageUrl) {
this.imageUrl = imageUrl;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
// Override toString for display purposes
@Override
public String toString() {
return String.format("Build{name='%s', type='%s', imageUrl='%s'}", name, type, imageUrl);
}
}

View File

@@ -1,5 +1,6 @@
package com.example.bricklog.view; package com.example.bricklog.view;
import com.example.bricklog.model.Build;
import javafx.geometry.Insets; import javafx.geometry.Insets;
import javafx.scene.control.Label; import javafx.scene.control.Label;
import javafx.scene.control.ListView; import javafx.scene.control.ListView;
@@ -12,23 +13,23 @@ import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox; import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox; import javafx.scene.layout.VBox;
import java.util.ArrayList;
import java.util.List;
public class GalleryLayout extends BorderPane { public class GalleryLayout extends BorderPane {
private final GridPane gridView; private final GridPane gridView;
private final ListView<String> listView; private final ListView<String> listView;
private boolean isGridView; private boolean isGridView;
public GalleryLayout() { public GalleryLayout() {
// Create a ToggleGroup for the layout options
ToggleGroup toggleGroup = new ToggleGroup(); ToggleGroup toggleGroup = new ToggleGroup();
// Create toggle buttons for layout options
ToggleButton gridButton = new ToggleButton("Grid"); ToggleButton gridButton = new ToggleButton("Grid");
ToggleButton listButton = new ToggleButton("List"); ToggleButton listButton = new ToggleButton("List");
gridButton.setToggleGroup(toggleGroup); gridButton.setToggleGroup(toggleGroup);
listButton.setToggleGroup(toggleGroup); listButton.setToggleGroup(toggleGroup);
// Set the default selected button
gridButton.setSelected(true); gridButton.setSelected(true);
isGridView = true; isGridView = true;
@@ -37,24 +38,18 @@ public class GalleryLayout extends BorderPane {
toggleBox.setPadding(new Insets(10)); toggleBox.setPadding(new Insets(10));
this.setTop(toggleBox); this.setTop(toggleBox);
// Create both views
gridView = createGridView(); gridView = createGridView();
listView = createListView(); listView = createListView();
// Start with the grid view
isGridView = true; isGridView = true;
this.setCenter(gridView); this.setCenter(gridView);
// Add listener to the toggle group to switch layouts toggleGroup.selectedToggleProperty().addListener((observable, oldValue, newValue) -> {
toggleGroup.selectedToggleProperty().addListener((observable, oldValue, newValue) -> { isGridView = newValue == gridButton;
if (newValue == gridButton) { toggleLayout(isGridView);
isGridView = true; // Update the variable });
toggleLayout(isGridView); // Use the variable
} else if (newValue == listButton) { this.getStylesheets().add(getClass().getResource("/css/gallery.css").toExternalForm());
isGridView = false; // Update the variable
toggleLayout(isGridView); // Use the variable
}
});
} }
private GridPane createGridView() { private GridPane createGridView() {
@@ -63,51 +58,50 @@ public class GalleryLayout extends BorderPane {
grid.setHgap(10); grid.setHgap(10);
grid.setVgap(10); grid.setVgap(10);
// Example data - replace with your actual data retrieval logic List<Build> builds = loadData();
String[] buildTypes = {"Kitset", "MoC", "Kitset", "MoC"};
String[] imageUrls = { for (int i = 0; i < builds.size(); i++) {
"path/to/image1.jpg", Build build = builds.get(i);
"path/to/image2.jpg",
"path/to/image3.jpg",
"path/to/image4.jpg"
};
for (int i = 0; i < buildTypes.length; i++) {
VBox vbox = new VBox(); VBox vbox = new VBox();
ImageView imageView = new ImageView(new Image(imageUrls[i])); ImageView imageView = new ImageView();
try {
imageView.setImage(new Image(build.getImageUrl()));
} catch (Exception e) {
imageView.setImage(new Image("path/to/placeholder.jpg"));
}
imageView.setFitWidth(150); imageView.setFitWidth(150);
imageView.setFitHeight(150); imageView.setFitHeight(150);
imageView.setPreserveRatio(true); imageView.setPreserveRatio(true);
vbox.getChildren().addAll(imageView, new Label(buildTypes[i])); vbox.getChildren().addAll(imageView, new Label(build.getType()));
grid.add(vbox, i % 3, i / 3); // Adjust to layout items in a grid grid.add(vbox, i % 3, i / 3);
} }
return grid; return grid;
} }
private ListView<String> createListView() { private ListView<String> createListView() {
ListView<String> list = new ListView<>(); ListView<String> list = new ListView<>();
List<Build> builds = loadData();
// Example data - replace with your actual data retrieval logic for (Build build : builds) {
String[] details = { list.getItems().add(String.format(
"Build 1: Builder Name, 100 Pieces, 20x30x10 cm, Kitset", "Name: %s, Type: %s, Image: %s",
"Build 2: Builder Name, 150 Pieces, 25x35x15 cm, MoC", build.getName(), build.getType(), build.getImageUrl()
// Add more entries as needed... ));
}; }
list.getItems().addAll(details);
return list; return list;
} }
// Method to toggle layout and print the current state private List<Build> loadData() {
private void toggleLayout(boolean isGrid) { List<Build> builds = new ArrayList<>();
if (isGrid) { builds.add(new Build("Build 1", "path/to/image1.jpg", "Kitset"));
System.out.println("Current layout: Grid View"); builds.add(new Build("Build 2", "path/to/image2.jpg", "MoC"));
this.setCenter(gridView); return builds;
} else { }
System.out.println("Current layout: List View");
this.setCenter(listView); private void toggleLayout(boolean isGrid) {
this.setCenter(isGrid ? gridView : listView);
} }
} }
}

View File

@@ -0,0 +1,14 @@
package com.example.bricklog.view;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.layout.VBox;
public class KitsetPage extends VBox {
public KitsetPage() {
TableView<String> table = new TableView<>();
TableColumn<String, String> column = new TableColumn<>("Kitset Name");
table.getColumns().add(column);
getChildren().add(table);
}
}

View File

@@ -1,137 +1,32 @@
package com.example.bricklog.view; package com.example.bricklog.view;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.control.Button; import javafx.scene.control.Button;
import javafx.scene.control.ButtonType;
import javafx.scene.control.Dialog;
import javafx.scene.control.Label; import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.BorderPane; import javafx.scene.layout.BorderPane;
import javafx.scene.layout.GridPane; import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox; import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
// import javafx.scene.layout.StackPane;
public class MainLayout extends BorderPane { public class MainLayout extends BorderPane {
private VBox menu; // makes menu accessible for updates
public MainLayout() { public MainLayout() {
setTop(createMenuBar());
// Title & Coppyright setCenter(createDashboard());
Label title = new Label("BRICK LOG Client");
title.setStyle("-fx-font-size: 24px; -fx-font-weight: bold;");
Label copyright = new Label("built by Bryce © 2024");
copyright.setStyle("-fx-font-size: 14px;");
VBox titleBox = new VBox(title, copyright);
titleBox.setAlignment(Pos.CENTER);
titleBox.setPadding(new Insets(10));
// Set title at the top
VBox topContainer = new VBox(titleBox);
this.setTop(topContainer);
menu = new VBox();
menu.setSpacing(10);
menu.setPadding(new Insets(10));
menu.setStyle("-fx-background-color: #f0f0f0;"); // Optional: Background color for the menu
// Search Bar
TextField searchField = new TextField();
searchField.setPromptText("Search...");
// Set up the menu
menu = new VBox();
menu.setSpacing(10);
menu.setPadding(new Insets(10));
menu.setStyle("-fx-background-color: #f0f0f0;"); // Optional: Background color for the menu
// Add the Gallery menu item
Label galleryLabel = new Label("Gallery");
galleryLabel.setStyle("-fx-font-weight: bold; cursor: hand;"); // Make it look interactive
galleryLabel.setOnMouseClicked(event -> switchToGalleryLayout()); // Switch layout on click
Label settingsLabel = new Label("Settings");
settingsLabel.setStyle("-fx-font-weight: bold; cursor: hand;");
settingsLabel.setOnMouseClicked(event -> switchToSettingsLayout());
// Add menu items
menu.getChildren().addAll(new Label("Menu"), galleryLabel, settingsLabel);
this.setLeft(menu); // Set the menu on the left side
// Set up the '+' button
Button addButton = new Button("+");
addButton.setStyle("-fx-font-size: 24px; -fx-background-color: lightblue;");
// Set up the action for the '+' button to show the add dialog
addButton.setOnAction(e -> showAddDialog());
// Create an HBox to hold the button and align it to the bottom right
HBox buttonContainer = new HBox(addButton);
buttonContainer.setAlignment(Pos.BOTTOM_RIGHT);
buttonContainer.setPadding(new Insets(10)); // Optional padding
// Add the buttonContainer to the bottom of the layout
this.setBottom(buttonContainer);
// Optionally, set the center to another pane or leave it empty
// this.setCenter(someOtherPane);
} }
private void showAddDialog() { private HBox createMenuBar() {
Dialog<ButtonType> dialog = new Dialog<>(); HBox menuBar = new HBox();
dialog.setTitle("Add Build"); Button dashboardButton = new Button("Dashboard");
dashboardButton.setOnAction(e -> setCenter(createDashboard()));
// Create the dialog layout menuBar.getChildren().add(dashboardButton);
GridPane grid = new GridPane(); return menuBar;
grid.setHgap(10);
grid.setVgap(10);
grid.setPadding(new Insets(20));
TextField nameField = new TextField();
nameField.setPromptText("Build Name");
TextField builderField = new TextField();
builderField.setPromptText("Builder Name");
// Add more fields as needed...
grid.add(new Label("Name:"), 0, 0);
grid.add(nameField, 1, 0);
grid.add(new Label("Builder:"), 0, 1);
grid.add(builderField, 1, 1);
// Add more fields to the grid as needed...
dialog.getDialogPane().setContent(grid);
// Add buttons for adding and canceling
dialog.getDialogPane().getButtonTypes().addAll(ButtonType.OK, ButtonType.CANCEL);
// Show dialog and handle button events
dialog.setResultConverter(button -> {
if (button == ButtonType.OK) {
// Insert data into the database and handle image upload
String name = nameField.getText();
String builder = builderField.getText();
// Handle database insert...
System.out.println("Name: " + name + ", Builder: " + builder); // Debugging line
}
return null;
});
dialog.showAndWait();
} }
// This method is essential for switching to the GalleryLayout
private void switchToGalleryLayout() {
// Create an instance of GalleryLayout
GalleryLayout galleryLayout = new GalleryLayout();
// Set the center of the MainLayout to the GalleryLayout private GridPane createDashboard() {
this.setCenter(galleryLayout); GridPane dashboard = new GridPane();
} dashboard.add(new Label("Number of Kitsets:"), 0, 0);
private void switchToSettingsLayout() { dashboard.add(new Label("..."), 1, 0); // Placeholder for data
SettingsWindow settingsLayout = new SettingsWindow(); dashboard.add(new Label("Number of MoCs:"), 0, 1);
this.setCenter(settingsLayout); dashboard.add(new Label("..."), 1, 1); // Placeholder for data
return dashboard;
} }
} }

View File

@@ -0,0 +1,14 @@
package com.example.bricklog.view;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.layout.VBox;
public class MocPage extends VBox {
public MocPage() {
TableView<String> table = new TableView<>();
TableColumn<String, String> column = new TableColumn<>("MoC Name");
table.getColumns().add(column);
getChildren().add(table);
}
}

View File

@@ -2,6 +2,7 @@ package com.example.bricklog.view;
import javafx.geometry.Insets; import javafx.geometry.Insets;
import javafx.geometry.Pos; import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button; import javafx.scene.control.Button;
import javafx.scene.control.CheckBox; import javafx.scene.control.CheckBox;
import javafx.scene.control.Label; import javafx.scene.control.Label;
@@ -9,17 +10,22 @@ import javafx.scene.control.TextField;
import javafx.scene.layout.BorderPane; import javafx.scene.layout.BorderPane;
import javafx.scene.layout.StackPane; import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox; import javafx.scene.layout.VBox;
import static javafx.scene.paint.Color.WHITE; import javafx.scene.paint.Color;
import javafx.scene.text.Font; import javafx.scene.text.Font;
import java.util.Objects;
public class SettingsWindow extends BorderPane { public class SettingsWindow extends BorderPane {
private final StackPane contentPane; private final StackPane contentPane;
private final VBox generalSettings; private final VBox generalSettings;
private final VBox serverSettings; private final VBox serverSettings;
private final Label connectionStatus; private final Label connectionStatus;
private final Scene currentScene; // Reference to the main scene for applying styles dynamically
public SettingsWindow(Scene scene) {
this.currentScene = scene; // Pass the main scene
public SettingsWindow() {
// Menu on the left side for navigation // Menu on the left side for navigation
VBox menu = new VBox(); VBox menu = new VBox();
menu.setSpacing(10); menu.setSpacing(10);
@@ -48,6 +54,7 @@ public class SettingsWindow extends BorderPane {
generalSettings.setAlignment(Pos.TOP_LEFT); generalSettings.setAlignment(Pos.TOP_LEFT);
Label themeLabel = new Label("Theme:"); Label themeLabel = new Label("Theme:");
CheckBox darkTheme = new CheckBox("Dark Theme"); CheckBox darkTheme = new CheckBox("Dark Theme");
darkTheme.setOnAction(event -> toggleTheme(darkTheme.isSelected()));
Label layoutLabel = new Label("Layout:"); Label layoutLabel = new Label("Layout:");
CheckBox compactLayout = new CheckBox("Compact Layout"); CheckBox compactLayout = new CheckBox("Compact Layout");
@@ -62,7 +69,7 @@ public class SettingsWindow extends BorderPane {
// Connection Status Label // Connection Status Label
connectionStatus = new Label("Server Status: Not Connected"); connectionStatus = new Label("Server Status: Not Connected");
connectionStatus.setFont(new Font("Arial", 14)); connectionStatus.setFont(new Font("Arial", 14));
connectionStatus.setTextFill(WHITE); connectionStatus.setTextFill(Color.WHITE);
connectionStatus.setStyle("-fx-background-color: lightpink; -fx-padding: 5;"); connectionStatus.setStyle("-fx-background-color: lightpink; -fx-padding: 5;");
connectionStatus.setAlignment(Pos.CENTER); connectionStatus.setAlignment(Pos.CENTER);
connectionStatus.setMaxWidth(Double.MAX_VALUE); connectionStatus.setMaxWidth(Double.MAX_VALUE);
@@ -77,7 +84,6 @@ public class SettingsWindow extends BorderPane {
serverSettings.getChildren().addAll(connectionStatus, ipLabel, ipField, connectButton); serverSettings.getChildren().addAll(connectionStatus, ipLabel, ipField, connectButton);
// Add panels to contentPane and show the default panel // Add panels to contentPane and show the default panel
contentPane.getChildren().addAll(generalSettings, serverSettings); contentPane.getChildren().addAll(generalSettings, serverSettings);
showGeneralSettings(); // Default to showing the general settings showGeneralSettings(); // Default to showing the general settings
@@ -97,22 +103,41 @@ public class SettingsWindow extends BorderPane {
generalSettings.setVisible(false); generalSettings.setVisible(false);
} }
// Method to connect to the server // Method to toggle themes
private void connectToServer(String ipAddress) { private void toggleTheme(boolean isDarkTheme) {
boolean isConnected = simulateServerConnection(ipAddress); // Replace with real connection logic String theme = isDarkTheme ? "/css/dark-theme.css" : "/css/light-theme.css";
currentScene.getStylesheets().clear(); // Clear existing stylesheets
currentScene.getStylesheets().add(Objects.requireNonNull(getClass().getResource(theme)).toExternalForm());
}
if (isConnected) { // Method to connect to the server
connectionStatus.setText("Connected"); private void connectToServer(String ipAddress) {
connectionStatus.setStyle("-fx-background-color: lightgreen; -fx-padding: 5;"); if (!isValidIPAddress(ipAddress)) {
} else { connectionStatus.setText("Invalid IP Address");
connectionStatus.setText("Not Connected"); connectionStatus.setStyle("-fx-background-color: orange; -fx-padding: 5;");
connectionStatus.setStyle("-fx-background-color: lightpink; -fx-padding: 5;"); return;
}
} }
// Simulated connection logic for demonstration purposes boolean isConnected = simulateServerConnection(ipAddress);
private boolean simulateServerConnection(String ipAddress) {
// Here, add logic for real server connection. For now, a simple placeholder: if (isConnected) {
return !ipAddress.isEmpty() && ipAddress.equals("127.0.0.1"); connectionStatus.setText("Connected");
connectionStatus.setStyle("-fx-background-color: lightgreen; -fx-padding: 5;");
} else {
connectionStatus.setText("Not Connected");
connectionStatus.setStyle("-fx-background-color: lightpink; -fx-padding: 5;");
} }
}
// Utility method to validate IP addresses
private boolean isValidIPAddress(String ipAddress) {
return ipAddress.matches(
"^((25[0-5]|2[0-4][0-9]|[0-1]?[0-9][0-9]?)\\.){3}(25[0-5]|2[0-4][0-9]|[0-1]?[0-9][0-9]?)$"
);
}
// Simulated connection logic for demonstration purposes
private boolean simulateServerConnection(String ipAddress) {
return ipAddress.equals("127.0.0.1") || ipAddress.startsWith("192.168.");
}
} }

View File

@@ -0,0 +1,19 @@
.root {
-fx-background-color: #161616;
background-color: #161616; /* Compatibility fix */
}
.label.title {
-fx-text-fill: #B22222;
-fx-effect: dropshadow(gaussian, white, 2, 0, 0, 0);
}
.table-view {
-fx-font-size: 14px;
font-size: 14px;/* Compatibility fix */
-fx-text-fill: #E0FFFF;
}
.caption {
-fx-text-fill: #C0C0C0;
}

View File

@@ -0,0 +1,22 @@
.toggle-button {
-fx-background-color: #444;
-fx-text-fill: white;
-fx-padding: 5 10;
-fx-border-radius: 5;
-fx-background-radius: 5;
}
.toggle-button:selected {
-fx-background-color: #666;
}
.grid-pane {
-fx-background-color: #f0f0f0;
-fx-padding: 10;
-fx-hgap: 15;
-fx-vgap: 15;
}
.list-view {
-fx-background-color: #f9f9f9;
}

View File

@@ -1,4 +1,7 @@
com\example\bricklog\model\Build.class
com\example\bricklog\BrickLogClientApplication.class com\example\bricklog\BrickLogClientApplication.class
com\example\bricklog\view\MainLayout.class com\example\bricklog\view\MainLayout.class
com\example\bricklog\view\MocPage.class
com\example\bricklog\view\SettingsWindow.class com\example\bricklog\view\SettingsWindow.class
com\example\bricklog\view\KitsetPage.class
com\example\bricklog\view\GalleryLayout.class com\example\bricklog\view\GalleryLayout.class

View File

@@ -2,4 +2,7 @@ C:\Users\bryce\Documents\Git\BrickLog\BrickLog-Client\src\main\java\com\example\
C:\Users\bryce\Documents\Git\BrickLog\BrickLog-Client\src\main\java\com\example\bricklog\controller\SettingsController.java C:\Users\bryce\Documents\Git\BrickLog\BrickLog-Client\src\main\java\com\example\bricklog\controller\SettingsController.java
C:\Users\bryce\Documents\Git\BrickLog\BrickLog-Client\src\main\java\com\example\bricklog\view\MainLayout.java C:\Users\bryce\Documents\Git\BrickLog\BrickLog-Client\src\main\java\com\example\bricklog\view\MainLayout.java
C:\Users\bryce\Documents\Git\BrickLog\BrickLog-Client\src\main\java\com\example\bricklog\view\SettingsWindow.java C:\Users\bryce\Documents\Git\BrickLog\BrickLog-Client\src\main\java\com\example\bricklog\view\SettingsWindow.java
C:\Users\bryce\Documents\Git\BrickLog\BrickLog-Client\src\main\java\com\example\bricklog\view\KitsetPage.java
C:\Users\bryce\Documents\Git\BrickLog\BrickLog-Client\src\main\java\com\example\bricklog\view\GalleryLayout.java C:\Users\bryce\Documents\Git\BrickLog\BrickLog-Client\src\main\java\com\example\bricklog\view\GalleryLayout.java
C:\Users\bryce\Documents\Git\BrickLog\BrickLog-Client\src\main\java\com\example\bricklog\view\MocPage.java
C:\Users\bryce\Documents\Git\BrickLog\BrickLog-Client\src\main\java\com\example\bricklog\model\Build.java

View File

@@ -11,11 +11,11 @@ services:
extra_hosts: extra_hosts:
- "host.docker.internal:host-gateway" # Enables access to the host's MariaDB instance - "host.docker.internal:host-gateway" # Enables access to the host's MariaDB instance
watchtower: watchtower:
image: v2tec/watchtower image: v2tec/watchtower
container_name: watchtower container_name: watchtower
environment: environment:
- WATCHTOWER_TRACE=true # Optional for debug output - WATCHTOWER_TRACE=true # Optional for debug output
volumes: volumes:
- /var/run/docker.sock:/var/run/docker.sock # This allows Watchtower to interact with Docker - /var/run/docker.sock:/var/run/docker.sock # This allows Watchtower to interact with Docker
restart: always # Ensures Watchtower restarts if it stops restart: always # Ensures Watchtower restarts if it stops

View File

@@ -72,6 +72,12 @@
<configuration> <configuration>
<source>${java.version}</source> <source>${java.version}</source>
<target>${java.version}</target> <target>${java.version}</target>
<archive>
<manifest>
<mainClass>com.example.bricklog</mainClass>
</manifest>
</archive>
</configuration> </configuration>
</plugin> </plugin>
</plugins> </plugins>

View File

@@ -0,0 +1,10 @@
# Database configuration
spring.datasource.url=jdbc:mariadb://host.docker.internal:3306/bricklog
spring.datasource.username=bricklog
spring.datasource.password=sl0gg1ngBricks4llD4y
# JPA settings
spring.jpa.hibernate.ddl-auto=update # Creates tables automatically; set to 'none' in production if not needed
spring.jpa.show-sql=true # Shows SQL queries in the console, useful for debugging
spring.jpa.database-platform=org.hibernate.dialect.MariaDBDialect