Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion src/main/java/no/ntnu/idatt1005/group03/App.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package no.ntnu.idatt1005.group03;

import javafx.application.Application;
import javafx.scene.text.Font;
import javafx.stage.Stage;
import no.ntnu.idatt1005.group03.DAO.DatabaseConnection;
import no.ntnu.idatt1005.group03.UI.LoginScreen;
Expand Down Expand Up @@ -29,6 +30,7 @@ public class App extends Application {
public void start(Stage primaryStage) {
// 1. Initialize the database so it is ready for the rest of the app
DatabaseConnection.initializeDatabase();
loadFonts();

// 2. Create and launch the LoginScreen
LoginScreen loginScreen = new LoginScreen();
Expand All @@ -47,4 +49,12 @@ public void start(Stage primaryStage) {
public static void main(String[] args) {
launch(args);
}
}

/**
* Loads bundled fonts so they are available to the shared stylesheet.
*/
private void loadFonts() {
Font.loadFont(getClass().getResource("/fonts/Inter-Regular.ttf").toExternalForm(), 14);
Font.loadFont(getClass().getResource("/fonts/Inter-SemiBold.ttf").toExternalForm(), 14);
}
}
10 changes: 0 additions & 10 deletions src/main/java/no/ntnu/idatt1005/group03/UI/AboutUsScreen.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@
import javafx.scene.layout.Region;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import no.ntnu.idatt1005.group03.Model.User;


/**
* Displays the "About Us" screen in the application.
Expand All @@ -25,14 +23,6 @@
*/
public class AboutUsScreen {

/**
* Constructs a new {@code AboutUsScreen} instance.
*
* @param user the current user context for the screen
*/
public AboutUsScreen(User user) {
}

/**
* Builds and displays the About Us screen on the provided stage.
*
Expand Down
44 changes: 18 additions & 26 deletions src/main/java/no/ntnu/idatt1005/group03/UI/AccountScreen.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,11 @@
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
import javafx.scene.layout.VBox;
import javafx.scene.layout.Priority;
import javafx.geometry.Insets;
import javafx.scene.control.Label;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import no.ntnu.idatt1005.group03.Model.User;
import javafx.scene.layout.Region;
import no.ntnu.idatt1005.group03.Model.Donation;

/**
Expand Down Expand Up @@ -49,9 +47,9 @@ public void start(Stage stage) {
BorderPane accountLayout = new BorderPane();
accountLayout.setTop(new TopMenu("Account"));

VBox mainContent = new VBox(20);
VBox mainContent = new VBox(28);
mainContent.setAlignment(Pos.CENTER);
mainContent.setPadding(new Insets(15));
mainContent.setPadding(new Insets(24));

mainContent.getChildren().addAll(
createProfileSection(),
Expand All @@ -70,47 +68,44 @@ public void start(Stage stage) {
}

private VBox createProfileSection() {
VBox profileBox = new VBox(10);
profileBox.setPadding(new Insets(20));
VBox profileBox = new VBox(14);
profileBox.setPadding(new Insets(28));
profileBox.getStyleClass().add("profile-box");
profileBox.setPrefSize(300, 150);
profileBox.setMaxSize(300, 150);
profileBox.setPrefSize(380, 220);
profileBox.setMaxSize(380, 220);
profileBox.setAlignment(Pos.CENTER);

Image profile = new Image(getClass().getResourceAsStream("/images/profile.png"));
ImageView profileView = new ImageView(profile);
profileView.setFitWidth(60);
profileView.setFitHeight(60);
profileView.setFitWidth(84);
profileView.setFitHeight(84);
profileView.setPreserveRatio(true);

Label usernameLabel = new Label(user.getUsername());
// CSS: Large title text
usernameLabel.getStyleClass().add("title-text");
usernameLabel.getStyleClass().add("account-name");

Label emailLabel = new Label(user.getEmail());
// CSS: Muted/grey text
emailLabel.getStyleClass().add("muted-text");
emailLabel.getStyleClass().add("account-email");

Button editProfileButton = new Button("Edit Profile");
// CSS: Outline button
editProfileButton.getStyleClass().addAll("btn", "btn-outline");
editProfileButton.getStyleClass().addAll("btn", "btn-outline", "btn-large");

profileBox.getChildren().addAll(profileView, usernameLabel, emailLabel, editProfileButton);
return profileBox;
}

private VBox createDonationLog() {
VBox donationsBox = new VBox();
VBox donationsBox = new VBox(8);
donationsBox.setAlignment(Pos.CENTER);

Label recentTitle = new Label("Donations");
recentTitle.getStyleClass().add("bold-text");
recentTitle.getStyleClass().add("account-section-title");
donationsBox.getChildren().add(recentTitle);


if (user.getDonations() == null || user.getDonations().isEmpty()) {
Label noDonations = new Label("No donations yet.");
noDonations.getStyleClass().add("muted-text");
noDonations.getStyleClass().add("account-email");
donationsBox.getChildren().add(noDonations);
} else {
for (Donation donation : user.getDonations()) {
Expand All @@ -119,6 +114,7 @@ private VBox createDonationLog() {
" - " + donation.getAmount() + " kr" +
" (" + donation.getDate() + ")"
);
donationLabel.getStyleClass().add("account-donation-text");

donationsBox.getChildren().add(donationLabel);
}
Expand All @@ -130,17 +126,13 @@ private VBox createDonationLog() {
private VBox createLogoutSection() {
VBox logoutBox = new VBox();
logoutBox.setAlignment(Pos.CENTER);

// The Region acts like an invisible spring, pushing the logout button to the bottom!
Region spacer = new Region();
VBox.setVgrow(spacer, Priority.ALWAYS);
logoutBox.setPadding(new Insets(14, 0, 0, 0));

Button logoutButton = new Button("Log out");
logoutButton.getStyleClass().addAll("btn", "btn-primary");
logoutButton.getStyleClass().addAll("btn", "btn-primary", "btn-large");
logoutButton.setOnAction(e -> ScreenManager.logout());

logoutBox.getChildren().addAll(spacer, logoutButton);
VBox.setVgrow(logoutBox, Priority.ALWAYS);
logoutBox.getChildren().add(logoutButton);
return logoutBox;
}
}
26 changes: 20 additions & 6 deletions src/main/java/no/ntnu/idatt1005/group03/UI/DonationScreen.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
package no.ntnu.idatt1005.group03.UI;

import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.HBox;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
Expand Down Expand Up @@ -57,14 +59,19 @@ public DonationScreen(Organization organization, User user) {
public void start(Stage stage) {

VBox layout = new VBox(15);
layout.setPadding(new Insets(20));
layout.setPadding(new Insets(30));
layout.setPrefWidth(920);
layout.setMaxWidth(920);
layout.setFillWidth(true);
layout.setAlignment(Pos.TOP_CENTER);

Label orgName = createOrgNameLabel();
Label websiteFeedbackLabel = new Label();
Button websiteButton = createWebsiteButton(websiteFeedbackLabel);
Button favoriteButton = createFavoriteButton();

HBox actionButtons = new HBox(10);
actionButtons.setAlignment(Pos.CENTER);
actionButtons.getChildren().addAll(
favoriteButton,
websiteButton
Expand All @@ -73,6 +80,10 @@ public void start(Stage stage) {
Label amountLabel = new Label("Amount");
TextField amountInput = new TextField();
amountInput.setPromptText("Enter amount");
amountInput.setPrefWidth(420);
amountInput.setMaxWidth(420);
VBox amountSection = new VBox(8, amountLabel, amountInput);
amountSection.setAlignment(Pos.CENTER);

Label feedbackLabel = new Label();
feedbackLabel.setWrapText(true);
Expand All @@ -84,23 +95,26 @@ public void start(Stage stage) {
orgName,
actionButtons,
websiteFeedbackLabel,
amountLabel,
amountInput,
amountSection,
feedbackLabel,
donateButton,
backButton);

StackPane centeredLayout = new StackPane(layout);
centeredLayout.setAlignment(Pos.CENTER);
StackPane.setMargin(layout, new Insets(100, 0, 0, 0));

ScreenManager.showRoot(
stage,
layout,
centeredLayout,
"Donation",
getClass().getResource("/styles/app.css").toExternalForm()
);
}

private Label createOrgNameLabel() {
Label orgName = new Label("Donate to: " + organization.getName());
orgName.getStyleClass().add("title-text");
Label orgName = new Label(organization.getName());
orgName.getStyleClass().add("donation-title");
return orgName;
}

Expand Down
44 changes: 27 additions & 17 deletions src/main/java/no/ntnu/idatt1005/group03/UI/LoginScreen.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import javafx.scene.control.*;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.Parent;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;
import javafx.scene.text.Text;
Expand All @@ -24,9 +25,10 @@
* Displays the login and sign-up screen for the application.
*
* <p>This class is part of the <b>UI layer</b> in the MVC architecture and serves as the
* entry point for user authentication. It provides two scenes: one for user registration
* and one for user login. The class coordinates user input with the authentication
* controller and handles navigation to the home screen after successful authentication.</p>
* entry point for user authentication. It provides both user registration and user login
* flows, reusing a single JavaFX scene while swapping between different root layouts.
* The class coordinates user input with the authentication controller and handles
* navigation to the home screen after successful authentication.</p>
*
* <p>The class extends {@link Application} and is responsible for initializing the
* primary stage used for login and registration.</p>
Expand All @@ -44,8 +46,8 @@ public class LoginScreen extends Application { // homepage
* Initializes and displays the login screen on the provided primary stage.
*
* <p>This method creates the authentication controller and favorite controller,
* initializes feedback labels, builds both the sign-up and login scenes,
* and displays the initial scene.</p>
* initializes feedback labels, prepares the shared authentication scene,
* and displays the initial sign-up view.</p>
*
* @param primaryStage the primary JavaFX stage for the application
*/
Expand Down Expand Up @@ -84,7 +86,7 @@ public void start(Stage primaryStage) {
}

// -------- SCENE 1 (Sign Up) --------
private GridPane createSignUpRoot() {
private Parent createSignUpRoot() {
GridPane root1 = createBaseGrid();

Label nameLabel = new Label("Email address");
Expand Down Expand Up @@ -127,11 +129,11 @@ private GridPane createSignUpRoot() {
accountBox.setAlignment(Pos.CENTER);
root1.add(accountBox, 1, 9, 3, 1);

return root1;
return wrapCentered(root1);
}

// -------- SCENE 2 (Log In) --------
private GridPane createLoginRoot() {
private Parent createLoginRoot() {
GridPane root2 = createBaseGrid();

Label usernameLabel2 = new Label("Email address or username");
Expand Down Expand Up @@ -170,30 +172,38 @@ private GridPane createLoginRoot() {

GridPane.setHalignment(forgot, HPos.CENTER);

return root2;
return wrapCentered(root2);
}

// -------- REUSABLE COMPONENTS --------

private GridPane createBaseGrid() {
GridPane grid = new GridPane();
grid.setPadding(new Insets(10));
grid.setHgap(10);
grid.setVgap(10);
grid.setPadding(new Insets(12));
grid.setHgap(12);
grid.setVgap(12);

ColumnConstraints col0 = new ColumnConstraints(50);
ColumnConstraints col1 = new ColumnConstraints(150);
ColumnConstraints col2 = new ColumnConstraints(150);
ColumnConstraints col0 = new ColumnConstraints(58);
ColumnConstraints col1 = new ColumnConstraints(175);
ColumnConstraints col2 = new ColumnConstraints(175);
grid.getColumnConstraints().addAll(col0, col1, col2);

return grid;
}

private StackPane wrapCentered(GridPane content) {
content.setMaxSize(Region.USE_PREF_SIZE, Region.USE_PREF_SIZE);
StackPane wrapper = new StackPane(content);
wrapper.setAlignment(Pos.TOP_CENTER);
StackPane.setMargin(content, new Insets(100, 0, 0, 0));
return wrapper;
}

private void addHeader(GridPane grid, boolean isScene2) {
Image image = new Image(getClass().getResourceAsStream("/images/donate2.png"));
ImageView imageView = new ImageView(image);
imageView.setFitWidth(40);
imageView.setFitHeight(40);
imageView.setFitWidth(48);
imageView.setFitHeight(48);
imageView.setPreserveRatio(true);

Button signloginButton = new Button("Sign In");
Expand Down
Loading
Loading