diff --git a/src/main/java/edu/group5/app/App.java b/src/main/java/edu/group5/app/App.java index d657fb8..22b3baa 100644 --- a/src/main/java/edu/group5/app/App.java +++ b/src/main/java/edu/group5/app/App.java @@ -1,19 +1,19 @@ package edu.group5.app; -import edu.group5.app.control.MainController; +import edu.group5.app.control.NavigationController; import edu.group5.app.control.wrapper.DbWrapper; import edu.group5.app.control.wrapper.OrgApiWrapper; -import edu.group5.app.model.donation.Donation; +import edu.group5.app.model.AppState; import edu.group5.app.model.donation.DonationRepository; import edu.group5.app.model.donation.DonationService; import edu.group5.app.model.organization.OrganizationRepository; import edu.group5.app.model.organization.OrganizationService; -import edu.group5.app.model.user.User; import edu.group5.app.model.user.UserRepository; import edu.group5.app.model.user.UserService; import javafx.application.Application; import javafx.scene.Scene; import javafx.scene.image.Image; +import javafx.scene.layout.BorderPane; import javafx.stage.Stage; import java.util.List; @@ -28,9 +28,12 @@ public class App extends Application { DbWrapper dbWrapper; UserRepository userRepository; DonationRepository donationRepository; + + BorderPane root; + AppState appState; + NavigationController nav; + private Logger logger; - private MainController controller; - private Scene scene; @Override public void init() { @@ -69,18 +72,19 @@ public void init() { DonationService donationService = new DonationService(this.donationRepository, organizationRepository); OrganizationService organizationService = new OrganizationService(organizationRepository); - this.controller = new MainController(userService, donationService, organizationService); - - this.scene = controller.getMainView().getScene(); + this.root = new BorderPane(); + this.appState = new AppState(); + this.nav = new NavigationController(root, appState, userService, donationService, organizationService); } @Override public void start(Stage stage) { - this.controller.showLoginPage(); + this.nav.showLoginPage(); + Scene scene = new Scene(root, 1280, 720); stage.getIcons().add(new Image(getClass().getResource("/header/images/hmh-logo.png").toExternalForm())); stage.setTitle("Help-Me-Help"); - stage.setScene(this.scene); + stage.setScene(scene); stage.show(); } diff --git a/src/main/java/edu/group5/app/control/BrowseCardController.java b/src/main/java/edu/group5/app/control/BrowseCardController.java deleted file mode 100644 index 9f86271..0000000 --- a/src/main/java/edu/group5/app/control/BrowseCardController.java +++ /dev/null @@ -1,16 +0,0 @@ -package edu.group5.app.control; - -import edu.group5.app.model.organization.Organization; - -public class BrowseCardController { - private final MainController controller; - - public BrowseCardController(MainController mainController) { - this.controller = mainController; - } - - public void handleCardClick(Organization organization) { - controller.setCurrentOrganization(organization); - controller.showOrganizationPage(); - } -} diff --git a/src/main/java/edu/group5/app/control/BrowsePageController.java b/src/main/java/edu/group5/app/control/BrowsePageController.java deleted file mode 100644 index 0922e68..0000000 --- a/src/main/java/edu/group5/app/control/BrowsePageController.java +++ /dev/null @@ -1,9 +0,0 @@ -package edu.group5.app.control; - -public class BrowsePageController { - private final MainController controller; - - public BrowsePageController(MainController mainController) { - this.controller = mainController; - } -} diff --git a/src/main/java/edu/group5/app/control/DonationController.java b/src/main/java/edu/group5/app/control/DonationController.java new file mode 100644 index 0000000..97a1c9d --- /dev/null +++ b/src/main/java/edu/group5/app/control/DonationController.java @@ -0,0 +1,84 @@ +package edu.group5.app.control; + +import edu.group5.app.model.AppState; +import edu.group5.app.model.donation.Donation; +import edu.group5.app.model.donation.DonationService; +import edu.group5.app.model.organization.Organization; +import edu.group5.app.model.user.Customer; +import edu.group5.app.model.user.User; + +import java.math.BigDecimal; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +public class DonationController { + private final AppState appState; + private final NavigationController nav; + private final DonationService service; + + public DonationController(AppState appState, NavigationController nav, DonationService service) { + this.appState = appState; + this.nav = nav; + this.service = service; + } + + public Map getUserDonations(int userId) { + return service.getDonationRepository().filterByUser(userId); + } + + public Set getUniqueOrgs() { + Map userDonations = getUserDonations(appState.getCurrentUser().getUserId()); + + Set uniqueOrgs = new HashSet<>(); + for (Donation donation : userDonations.values()) { + uniqueOrgs.add(donation.organizationId()); + } + + return uniqueOrgs; + } + + public void handleDonate() { + // Get session data from MainController + User currentUser = appState.getCurrentUser(); + Organization currentOrg = appState.getCurrentOrganization(); + BigDecimal amount = appState.getCurrentDonationAmount(); + + if (currentUser == null) { + System.err.println("Error: No user logged in"); + return; + } + if (!(currentUser instanceof Customer customer)) { + System.err.println("Error: Only customers can donate"); + return; + } + if (currentOrg == null) { + System.err.println("Error: No organization selected"); + return; + } + if (amount == null || amount.compareTo(BigDecimal.ZERO) <= 0) { + System.err.println("Error: Invalid donation amount"); + return; + } + + // Create donation via service + boolean success = service.donate( + customer, + currentOrg.orgNumber(), + amount, + "Online" + ); + + if (success) { + System.out.println("Donation created: " + amount + " kr to " + currentOrg.name()); + } else { + System.err.println("Failed to create donation"); + } + + // Clear donation session state + appState.setCurrentDonationAmount(null); + + // Navigate to payment complete + nav.showPaymentCompletePage(); + } +} diff --git a/src/main/java/edu/group5/app/control/HeaderController.java b/src/main/java/edu/group5/app/control/HeaderController.java deleted file mode 100644 index 0a1e424..0000000 --- a/src/main/java/edu/group5/app/control/HeaderController.java +++ /dev/null @@ -1,28 +0,0 @@ -package edu.group5.app.control; - -public class HeaderController { - private final MainController controller; - - public HeaderController(MainController controller) { - this.controller = controller; - } - - public void handleHomeBtn() { - System.out.println("Home button pressed"); - controller.showHomePage(); - } - - public void handleCausesBtn() { - System.out.println("Causes button pressed"); - controller.showBrowsePage(); - } - - public void handleAboutBtn() { - System.out.println("About button pressed"); - } - - public void handleProfileBtn() { - System.out.println("profileSection"); - controller.showUserPage(); - } -} diff --git a/src/main/java/edu/group5/app/control/HomePageController.java b/src/main/java/edu/group5/app/control/HomePageController.java deleted file mode 100644 index 10d3fbf..0000000 --- a/src/main/java/edu/group5/app/control/HomePageController.java +++ /dev/null @@ -1,19 +0,0 @@ -package edu.group5.app.control; - -public class HomePageController { - private final MainController controller; - - public HomePageController(MainController controller) { - this.controller = controller; - } - - public void handleDonateToACauseBtn() { - System.out.println("Donate to a cause button pressed"); - controller.showBrowsePage(); - } - - public void handleAboutUsBtn() { - System.out.println("About us button pressed"); - controller.showAboutUsPage(); - } -} diff --git a/src/main/java/edu/group5/app/control/LoginController.java b/src/main/java/edu/group5/app/control/LoginController.java new file mode 100644 index 0000000..cdd5b5f --- /dev/null +++ b/src/main/java/edu/group5/app/control/LoginController.java @@ -0,0 +1,69 @@ +package edu.group5.app.control; + +import edu.group5.app.model.AppState; +import edu.group5.app.model.user.User; +import edu.group5.app.model.user.UserService; +import edu.group5.app.view.loginpage.LoginPageView; +import edu.group5.app.view.loginpage.SignInPageView; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; + +public class LoginController { + private final AppState appState; + private final NavigationController nav; + private final UserService userService; + + public LoginController(AppState appState, NavigationController nav, UserService userService) { + this.appState = appState; + this.nav = nav; + this.userService = userService; + } + + public void handleSignIn(SignInPageView view, String firstName, String lastName, String email, char[] passwordChars) { + if (firstName == null || firstName.trim().isEmpty() || + lastName == null || lastName.trim().isEmpty() || + email == null || email.trim().isEmpty() || + passwordChars == null || passwordChars.length == 0) { + view.showError("All fields are required"); + return; + } + + String password = new String(passwordChars); + BCryptPasswordEncoder encoder = new BCryptPasswordEncoder(); + String hashedPassword = encoder.encode(password); + + boolean success = userService.registerUser( + "Customer", firstName, lastName, email, hashedPassword); + + if (success) { + User user = userService.getUserByEmail(email); + + appState.setCurrentUser(user); + nav.showHomePage(); + } else { + view.showError("Registration failed. Email may already be in use."); + } + } + + public void handleLogin(LoginPageView view, String email, char[] passwordChars) { + if (email == null || email.trim().isEmpty() || passwordChars == null || passwordChars.length == 0) { + view.showError("Email and password are required"); + return; + } + + User user = userService.login(email, passwordChars); + + if (user != null) { + appState.setCurrentUser(user); + nav.showHomePage(); + } else { + view.showError("Invalid email or password"); + } + } + + public void handleLogout() { + appState.setCurrentUser(null); + appState.setCurrentOrganization(null); + appState.setCurrentDonationAmount(null); + nav.showLoginPage(); + } +} diff --git a/src/main/java/edu/group5/app/control/LoginPageController.java b/src/main/java/edu/group5/app/control/LoginPageController.java deleted file mode 100644 index b28f191..0000000 --- a/src/main/java/edu/group5/app/control/LoginPageController.java +++ /dev/null @@ -1,44 +0,0 @@ -package edu.group5.app.control; - -import edu.group5.app.model.user.User; -import edu.group5.app.model.user.UserService; -import edu.group5.app.view.loginpage.LoginPageView; - -public class LoginPageController { - private final MainController controller; - private final UserService userService; - private LoginPageView view; - - public LoginPageController(MainController controller, UserService userService) { - this.controller = controller; - this.userService = userService; - } - - public void setView(LoginPageView view) { - this.view = view; - } - - public void handleLoginBtn() { - String email = view.getEmail(); - char[] passwordChars = view.getPassword(); - - if (email == null || email.trim().isEmpty() || passwordChars == null || passwordChars.length == 0) { - view.showError("Email and password are required"); - return; - } - - User user = userService.login(email, passwordChars); - - if (user != null) { - controller.setCurrentUser(user); - controller.showHomePage(); - } else { - view.showError("Invalid email or password"); - } - } - - public void handleRegisterBtn() { - System.out.println("Sign in button pressed"); - controller.showSignInPage(); - } -} diff --git a/src/main/java/edu/group5/app/control/MainController.java b/src/main/java/edu/group5/app/control/MainController.java deleted file mode 100644 index 2b75487..0000000 --- a/src/main/java/edu/group5/app/control/MainController.java +++ /dev/null @@ -1,121 +0,0 @@ -package edu.group5.app.control; - -import edu.group5.app.control.donationpage.DonationPageController; -import edu.group5.app.model.donation.DonationService; -import edu.group5.app.model.organization.Organization; -import edu.group5.app.model.organization.OrganizationService; -import edu.group5.app.model.user.User; -import edu.group5.app.model.user.UserService; -import edu.group5.app.view.MainView; -import edu.group5.app.view.donationpage.DonationPageView; - -import java.math.BigDecimal; - -public class MainController { - private final MainView view; - private final HeaderController headerController; - private final HomePageController homePageController; - private final BrowsePageController browsePageController; - private final BrowseCardController browseCardController; - private final OrganizationPageController organizationPageController; - private final DonationPageController donationPageController; - private final UserService userService; - private final DonationService donationService; - private final OrganizationService organizationService; - private User currentUser; - private Organization currentOrganization; - private BigDecimal currentDonationAmount; - - public MainController(UserService userService, DonationService donationService, - OrganizationService organizationService) { - this.userService = userService; - this.donationService = donationService; - this.organizationService = organizationService; - - this.view = new MainView(this, userService); - this.headerController = new HeaderController(this); - this.homePageController = new HomePageController(this); - this.browsePageController = new BrowsePageController(this); - this.browseCardController = new BrowseCardController(this); - this.organizationPageController = new OrganizationPageController(this); - this.donationPageController = new DonationPageController(this); - } - - public UserService getUserService() { - return userService; - } - - public DonationService getDonationService() { - return donationService; - } - - public OrganizationService getOrganizationService() { - return organizationService; - } - - public void setCurrentUser(User user) { - this.currentUser = user; - } - - public User getCurrentUser() { - return this.currentUser; - } - - public void setCurrentOrganization(Organization organization) { - this.currentOrganization = organization; - } - - public Organization getCurrentOrganization() { - return this.currentOrganization; - } - - public void setCurrentDonationAmount(BigDecimal amount) { - this.currentDonationAmount = amount; - } - - public BigDecimal getCurrentDonationAmount() { - return this.currentDonationAmount; - } - - public void logout() { - currentUser = null; - currentOrganization = null; - currentDonationAmount = null; - showLoginPage(); - } - - public MainView getMainView() { - return view; - } - - public void showHomePage() { - view.showHomePage(homePageController, headerController); - } - - public void showLoginPage() { - view.showLoginPage(); - } - public void showSignInPage() { - view.showSignInPage(); - } - public void showPaymentCompletePage() { - view.showPaymentCompletePage(); - } - public void showBrowsePage() { - view.showBrowsePage(browsePageController, browseCardController, headerController); - } - - public void showOrganizationPage() { - view.showOrganizationPage(organizationPageController, headerController); - } - - public void showDonationPage() { - view.showDonationPage(); - } - - public void showAboutUsPage() {} - - public void showUserPage() { - view.showUserPage(); - } -} diff --git a/src/main/java/edu/group5/app/control/NavigationController.java b/src/main/java/edu/group5/app/control/NavigationController.java new file mode 100644 index 0000000..ddab7e2 --- /dev/null +++ b/src/main/java/edu/group5/app/control/NavigationController.java @@ -0,0 +1,85 @@ +package edu.group5.app.control; + +import edu.group5.app.model.AppState; +import edu.group5.app.model.donation.DonationService; +import edu.group5.app.model.organization.OrganizationService; +import edu.group5.app.model.user.UserService; +import edu.group5.app.view.Header; +import edu.group5.app.view.causespage.CausesPageView; +import edu.group5.app.view.donationpage.DonationPageView; +import edu.group5.app.view.donationpage.PaymentCompletePageView; +import edu.group5.app.view.homepage.HomePageView; +import edu.group5.app.view.loginpage.LoginHeader; +import edu.group5.app.view.loginpage.LoginPageView; +import edu.group5.app.view.loginpage.SignInPageView; +import edu.group5.app.view.organizationpage.OrganizationPageView; +import edu.group5.app.view.userpage.UserPageView; +import javafx.scene.layout.BorderPane; + +public class NavigationController { + private final BorderPane root; + private final Header header; + private final LoginHeader loginHeader; + + private final AppState appState; + + private final LoginController loginController; + private final DonationController donationController; + private final OrganizationController organizationController; + + public NavigationController(BorderPane root, AppState appState, UserService userService, DonationService donationService, OrganizationService organizationService) { + this.root = root; + this.header = new Header(this); + this.loginHeader = new LoginHeader(); + + this.appState = appState; + + this.loginController = new LoginController(appState, this, userService); + this.donationController = new DonationController(appState, this, donationService); + this.organizationController = new OrganizationController(appState, this, organizationService); + } + + public void showHomePage() { + root.setTop(header); + root.setCenter(new HomePageView(appState, this)); + } + + public void showLoginPage() { + root.setTop(loginHeader); + root.setCenter(new LoginPageView(appState, this, loginController)); + } + + public void showSignInPage() { + root.setTop(loginHeader); + root.setCenter(new SignInPageView(appState, this, loginController)); + } + + public void showPaymentCompletePage() { + root.setTop(header); + root.setCenter(new PaymentCompletePageView(this)); + } + + public void showCausesPage() { + root.setTop(header); + root.setCenter(new CausesPageView(appState, this, organizationController)); + } + + public void showOrganizationPage() { + root.setTop(header); + root.setCenter(new OrganizationPageView(appState, this, donationController)); + } + + public void showDonationPage() { + root.setTop(header); + root.setCenter(new DonationPageView(appState, this, donationController)); + } + + public void showAboutUsPage() { + root.setTop(header); + } + + public void showUserPage() { + root.setTop(header); + root.setCenter(new UserPageView(appState, this, loginController, donationController, organizationController)); + } +} diff --git a/src/main/java/edu/group5/app/control/OrganizationController.java b/src/main/java/edu/group5/app/control/OrganizationController.java new file mode 100644 index 0000000..499b7c9 --- /dev/null +++ b/src/main/java/edu/group5/app/control/OrganizationController.java @@ -0,0 +1,32 @@ +package edu.group5.app.control; + +import edu.group5.app.model.AppState; +import edu.group5.app.model.organization.Organization; +import edu.group5.app.model.organization.OrganizationService; + +import java.util.Map; +import java.util.concurrent.CompletableFuture; + +public class OrganizationController { + private final AppState appState; + private final NavigationController nav; + private final OrganizationService service; + + public OrganizationController(AppState appState, NavigationController nav, OrganizationService service) { + this.appState = appState; + this.nav = nav; + this.service = service; + } + + public Organization getOrgById(int orgId) { + return service.findByOrgNumber(orgId); + } + + public Map getTrustedOrgs() { + return service.getTrustedOrganizations(); + } + + public CompletableFuture> getOrganizationsWithLogosAsync() { + return service.getTrustedOrganizationsWithLogosAsync(); + } +} diff --git a/src/main/java/edu/group5/app/control/OrganizationPageController.java b/src/main/java/edu/group5/app/control/OrganizationPageController.java deleted file mode 100644 index dd8f1bf..0000000 --- a/src/main/java/edu/group5/app/control/OrganizationPageController.java +++ /dev/null @@ -1,13 +0,0 @@ -package edu.group5.app.control; - -public class OrganizationPageController { - private final MainController controller; - - public OrganizationPageController(MainController controller) { - this.controller = controller; - } - - public void handleDonateClick() { - controller.showDonationPage(); - } -} diff --git a/src/main/java/edu/group5/app/control/SignInPageController.java b/src/main/java/edu/group5/app/control/SignInPageController.java deleted file mode 100644 index 2d8d874..0000000 --- a/src/main/java/edu/group5/app/control/SignInPageController.java +++ /dev/null @@ -1,58 +0,0 @@ -package edu.group5.app.control; -import edu.group5.app.model.user.UserService; -import edu.group5.app.view.loginpage.SignInPageView; - -import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; - -import edu.group5.app.model.user.User; - -public class SignInPageController { - private final MainController controller; - private final UserService userService; - private SignInPageView view; - - public SignInPageController(MainController controller, UserService userService) { - this.controller = controller; - this.userService = userService; - } - - public void setView(SignInPageView view) { - this.view = view; - } - - public void handleSignInBtn() { - String firstName = view.getFirstName(); - String lastName = view.getLastName(); - String email = view.getEmail(); - char[] passwordChars = view.getPassword(); - - if (firstName == null || firstName.trim().isEmpty() || - lastName == null || lastName.trim().isEmpty() || - email == null || email.trim().isEmpty() || - passwordChars == null || passwordChars.length == 0) { - view.showError("All fields are required"); - return; - } - - String password = new String(passwordChars); - BCryptPasswordEncoder encoder = new BCryptPasswordEncoder(); - String hashedPassword = encoder.encode(password); - - boolean success = userService.registerUser( - "Customer", firstName, lastName, email, hashedPassword); - - if (success) { - User user = userService.getUserByEmail(email); - - controller.setCurrentUser(user); - controller.showHomePage(); - } else { - view.showError("Registration failed. Email may already be in use."); - } - } - - public void handleLoginBtn() { - System.out.println("Back to login button pressed"); - controller.showLoginPage(); - } -} diff --git a/src/main/java/edu/group5/app/control/donationpage/DonationPageController.java b/src/main/java/edu/group5/app/control/donationpage/DonationPageController.java deleted file mode 100644 index 5fed3e2..0000000 --- a/src/main/java/edu/group5/app/control/donationpage/DonationPageController.java +++ /dev/null @@ -1,60 +0,0 @@ -package edu.group5.app.control.donationpage; - -import edu.group5.app.control.MainController; -import edu.group5.app.model.organization.Organization; -import edu.group5.app.model.user.Customer; -import edu.group5.app.model.user.User; - -import java.math.BigDecimal; - -public class DonationPageController { - private final MainController controller; - - public DonationPageController(MainController controller) { - this.controller = controller; - } - public void handleDonationBtn() { - // Get session data from MainController - User currentUser = controller.getCurrentUser(); - Organization currentOrg = controller.getCurrentOrganization(); - BigDecimal amount = controller.getCurrentDonationAmount(); - - if (currentUser == null) { - System.err.println("Error: No user logged in"); - return; - } - if (!(currentUser instanceof Customer customer)) { - System.err.println("Error: Only customers can donate"); - return; - } - if (currentOrg == null) { - System.err.println("Error: No organization selected"); - return; - } - if (amount == null || amount.compareTo(BigDecimal.ZERO) <= 0) { - System.err.println("Error: Invalid donation amount"); - return; - } - - // Create donation via service - boolean success = controller.getDonationService().donate( - customer, - currentOrg.orgNumber(), - amount, - "Online" - ); - - if (success) { - System.out.println("Donation created: " + amount + " kr to " + currentOrg.name()); - } else { - System.err.println("Failed to create donation"); - } - - // Clear donation session state - controller.setCurrentDonationAmount(null); - - // Navigate to payment complete - controller.showPaymentCompletePage(); - } - -} diff --git a/src/main/java/edu/group5/app/control/donationpage/PaymentCompleteController.java b/src/main/java/edu/group5/app/control/donationpage/PaymentCompleteController.java deleted file mode 100644 index d1bc3a5..0000000 --- a/src/main/java/edu/group5/app/control/donationpage/PaymentCompleteController.java +++ /dev/null @@ -1,15 +0,0 @@ -package edu.group5.app.control.donationpage; - -import edu.group5.app.control.MainController; - -public class PaymentCompleteController { - private final MainController controller; - - public PaymentCompleteController(MainController controller) { - this.controller = controller; - } - public void handleHomeBtn() { - System.out.println("Home button pressed"); - controller.showHomePage(); - } -} diff --git a/src/main/java/edu/group5/app/model/AppState.java b/src/main/java/edu/group5/app/model/AppState.java new file mode 100644 index 0000000..d8dd03a --- /dev/null +++ b/src/main/java/edu/group5/app/model/AppState.java @@ -0,0 +1,36 @@ +package edu.group5.app.model; + +import edu.group5.app.model.organization.Organization; +import edu.group5.app.model.user.User; + +import java.math.BigDecimal; + +public class AppState { + private User currentUser; + private BigDecimal currentDonationAmount; + private Organization currentOrganization; + + public User getCurrentUser() { + return this.currentUser; + } + + public void setCurrentUser(User user) { + this.currentUser = user; + } + + public Organization getCurrentOrganization() { + return this.currentOrganization; + } + + public void setCurrentOrganization(Organization organization) { + this.currentOrganization = organization; + } + + public BigDecimal getCurrentDonationAmount() { + return this.currentDonationAmount; + } + + public void setCurrentDonationAmount(BigDecimal amount) { + this.currentDonationAmount = amount; + } +} diff --git a/src/main/java/edu/group5/app/view/Header.java b/src/main/java/edu/group5/app/view/Header.java index 1edc5e4..35472e1 100644 --- a/src/main/java/edu/group5/app/view/Header.java +++ b/src/main/java/edu/group5/app/view/Header.java @@ -1,6 +1,6 @@ package edu.group5.app.view; -import edu.group5.app.control.HeaderController; +import edu.group5.app.control.NavigationController; import javafx.geometry.Pos; import javafx.scene.control.Button; import javafx.scene.image.Image; @@ -8,9 +8,9 @@ import javafx.scene.layout.*; public class Header extends BorderPane { - private final HeaderController controller; + private final NavigationController controller; - public Header(HeaderController controller) { + public Header(NavigationController controller) { this.controller = controller; getStylesheets().add(getClass().getResource("/header/header.css").toExternalForm()); setId("header"); @@ -24,7 +24,7 @@ private StackPane getLogoSection() { StackPane logoSection = new StackPane(); logoSection.setId("logo-section"); logoSection.setAlignment(Pos.CENTER); - logoSection.setOnMouseClicked(e -> controller.handleHomeBtn()); + logoSection.setOnMouseClicked(e -> controller.showHomePage()); logoSection.setStyle("-fx-cursor: hand;"); ImageView logo = new ImageView( @@ -44,15 +44,15 @@ private HBox getNavBar() { navbar.setSpacing(10); Button home = new Button("Home"); - home.setOnAction(e -> controller.handleHomeBtn()); + home.setOnAction(e -> controller.showHomePage()); home.setStyle("-fx-cursor: hand;"); Button causes = new Button("Causes"); - causes.setOnAction(e -> controller.handleCausesBtn()); + causes.setOnAction(e -> controller.showCausesPage()); causes.setStyle("-fx-cursor: hand;"); Button about = new Button("About us"); - about.setOnAction(e -> controller.handleAboutBtn()); + about.setOnAction(e -> controller.showAboutUsPage()); about.setStyle("-fx-cursor: hand;"); navbar.getChildren().addAll(home, causes, about); @@ -63,7 +63,7 @@ private StackPane getProfileSection() { StackPane profileSection = new StackPane(); profileSection.setId("profile-section"); profileSection.setAlignment(Pos.CENTER); - profileSection.setOnMouseClicked(e -> controller.handleProfileBtn()); + profileSection.setOnMouseClicked(e -> controller.showUserPage()); profileSection.setStyle("-fx-cursor: hand;"); ImageView avatar = new ImageView( diff --git a/src/main/java/edu/group5/app/view/MainView.java b/src/main/java/edu/group5/app/view/MainView.java deleted file mode 100644 index e35935f..0000000 --- a/src/main/java/edu/group5/app/view/MainView.java +++ /dev/null @@ -1,86 +0,0 @@ -package edu.group5.app.view; - -import edu.group5.app.control.*; -import edu.group5.app.view.browsepage.BrowsePageView; -import edu.group5.app.control.*; -import edu.group5.app.control.donationpage.DonationPageController; -import edu.group5.app.control.donationpage.PaymentCompleteController; -import edu.group5.app.model.user.User; -import edu.group5.app.model.user.UserService; -import edu.group5.app.view.donationpage.DonationPageView; -import edu.group5.app.view.donationpage.PaymentCompletePageView; -import edu.group5.app.view.homepage.HomePageView; -import edu.group5.app.view.loginpage.LoginPageView; -import edu.group5.app.view.loginpage.SignInPageView; -import edu.group5.app.view.userpage.UserPageView; -import edu.group5.app.view.organizationpage.OrganizationPageView; -import javafx.scene.Scene; -import javafx.scene.layout.BorderPane; - -public class MainView { - private final MainController mainController; - private final HeaderController headerController; - private final HomePageController homePageController; - private final LoginPageController loginPageController; - private final SignInPageController signInPageController; - private final DonationPageController donationPageController; - private final PaymentCompleteController paymentCompleteController; - private final Scene scene; - private final BorderPane root; - - public MainView(MainController mainController, UserService userService) { - this.mainController = mainController; - this.headerController = new HeaderController(mainController); - this.homePageController = new HomePageController(mainController); - this.loginPageController = new LoginPageController(mainController, userService); - this.signInPageController = new SignInPageController(mainController, userService); - this.donationPageController = new DonationPageController(mainController); - this.paymentCompleteController = new PaymentCompleteController(mainController); - this.root = new BorderPane(); - this.scene = new Scene(root, 1280, 720); - } - - public Scene getScene() { - return this.scene; - } - - public Scene createView() { - root.setCenter(new LoginPageView(loginPageController)); - return new Scene(root, 1280, 720); - } - - public void showHomePage(HomePageController homePageController, HeaderController headerController) { - root.setCenter(new HomePageView(homePageController, headerController)); - } - - public void showLoginPage() { - root.setCenter(new LoginPageView(loginPageController)); - } - - public void showBrowsePage(BrowsePageController browsePageController, BrowseCardController browseCardController, HeaderController headerController) { - root.setCenter(new BrowsePageView(getScene(), browsePageController, browseCardController, headerController, mainController)); - } - - public void showOrganizationPage(OrganizationPageController organizationController, HeaderController headerController) { - root.setCenter(new OrganizationPageView(organizationController, headerController, mainController)); - } - - public void showSignInPage() { - root.setCenter(new SignInPageView(signInPageController)); - } - public void showDonationPage() { - root.setCenter(new DonationPageView(donationPageController, headerController, mainController)); - } - public void showPaymentCompletePage() { - root.setCenter(new PaymentCompletePageView(paymentCompleteController)); - } - - public void showAboutUsPage() {} - - public void showUserPage() { - User currentUser = mainController.getCurrentUser(); - if (currentUser != null) { - root.setCenter(new UserPageView(headerController, mainController)); - } - } -} diff --git a/src/main/java/edu/group5/app/view/browsepage/BrowsePageView.java b/src/main/java/edu/group5/app/view/causespage/CausesPageView.java similarity index 75% rename from src/main/java/edu/group5/app/view/browsepage/BrowsePageView.java rename to src/main/java/edu/group5/app/view/causespage/CausesPageView.java index b27b011..1cd6e83 100644 --- a/src/main/java/edu/group5/app/view/browsepage/BrowsePageView.java +++ b/src/main/java/edu/group5/app/view/causespage/CausesPageView.java @@ -1,37 +1,32 @@ -package edu.group5.app.view.browsepage; +package edu.group5.app.view.causespage; -import edu.group5.app.control.BrowseCardController; -import edu.group5.app.control.BrowsePageController; -import edu.group5.app.control.HeaderController; -import edu.group5.app.control.MainController; import edu.group5.app.model.organization.Organization; -import edu.group5.app.view.Header; +import edu.group5.app.control.NavigationController; +import edu.group5.app.control.OrganizationController; +import edu.group5.app.model.AppState; import javafx.application.Platform; -import javafx.geometry.Pos; -import javafx.scene.Scene; import javafx.scene.control.ScrollPane; import javafx.scene.control.TextField; import javafx.scene.layout.*; +import java.util.HashMap; import java.util.Map; import java.util.stream.Collectors; -public class BrowsePageView extends BorderPane { - private final Scene scene; - private final BrowsePageController controller; - private final BrowseCardController orgController; - private final MainController mainController; +public class CausesPageView extends BorderPane { + private final AppState appState; + private final NavigationController nav; + private final OrganizationController orgController; + private GridPane organizationGrid; private Map allOrganizations; - public BrowsePageView(Scene mainScene, BrowsePageController browsePageController, BrowseCardController browseCardController, HeaderController headerController, MainController mainController) { - this.scene = mainScene; - this.controller = browsePageController; - this.orgController = browseCardController; - this.mainController = mainController; + public CausesPageView(AppState appState, NavigationController nav, OrganizationController orgController) { + this.appState = appState; + this.nav = nav; + this.orgController = orgController; + getStylesheets().add(getClass().getResource("/browsepage/browsepage.css").toExternalForm()); - Header headerView = new Header(headerController); - setTop(headerView); setCenter(createBody()); } @@ -82,13 +77,13 @@ private GridPane createOrganizationSection(String searchTerm) { } if (allOrganizations == null) { + allOrganizations = orgController.getTrustedOrgs(); //Show loading text while organizations and logos are fetched grid.add(new javafx.scene.control.Label("Loading..."), 0, 0); //Fetch trusted organizations with logos asynchronously (runs in background) - mainController.getOrganizationService() - .getTrustedOrganizationsWithLogosAsync() + orgController.getOrganizationsWithLogosAsync() .thenAccept(orgs -> { this.allOrganizations = orgs; @@ -98,8 +93,13 @@ private GridPane createOrganizationSection(String searchTerm) { return grid; } - // Filter organizations by search term - Map organizations = filterOrganizations(searchTerm); + Map organizations = new HashMap<>(); + if (searchTerm != null) { + // Filter organizations by search term + organizations = filterOrganizations(searchTerm); + } else { + organizations = allOrganizations; + } int column = 0; int row = 0; @@ -110,11 +110,12 @@ private GridPane createOrganizationSection(String searchTerm) { ? org.logoUrl() : null; - BrowseCard card = new BrowseCard(orgController, org, img); + OrganizationCard card = new OrganizationCard(appState, nav, org, img); grid.add(card, column, row); column++; + if (column == 4) { column = 0; row++; @@ -127,6 +128,11 @@ private GridPane createOrganizationSection(String searchTerm) { grid.getColumnConstraints().add(col); } + // Store reference for later updates + if (organizationGrid == null) { + organizationGrid = grid; + } + return grid; } diff --git a/src/main/java/edu/group5/app/view/browsepage/BrowseCard.java b/src/main/java/edu/group5/app/view/causespage/OrganizationCard.java similarity index 82% rename from src/main/java/edu/group5/app/view/browsepage/BrowseCard.java rename to src/main/java/edu/group5/app/view/causespage/OrganizationCard.java index b529e89..31b25ce 100644 --- a/src/main/java/edu/group5/app/view/browsepage/BrowseCard.java +++ b/src/main/java/edu/group5/app/view/causespage/OrganizationCard.java @@ -1,6 +1,7 @@ -package edu.group5.app.view.browsepage; +package edu.group5.app.view.causespage; -import edu.group5.app.control.BrowseCardController; +import edu.group5.app.control.NavigationController; +import edu.group5.app.model.AppState; import edu.group5.app.model.organization.Organization; import javafx.geometry.Pos; import javafx.scene.image.Image; @@ -9,12 +10,14 @@ import javafx.scene.layout.VBox; import javafx.scene.text.Text; -public class BrowseCard extends VBox { - private final BrowseCardController controller; +public class OrganizationCard extends VBox { + private final AppState appState; private final Organization organization; + private final NavigationController nav; - public BrowseCard(BrowseCardController browseCardController, Organization org, String img) { - this.controller = browseCardController; + public OrganizationCard(AppState appstate, NavigationController nav, Organization org, String img) { + this.appState = appstate; + this.nav = nav; this.organization = org; setId("mainContainer"); getStylesheets().add(getClass().getResource("/browsepage/browse_org.css").toExternalForm()); @@ -26,7 +29,8 @@ public BrowseCard(BrowseCardController browseCardController, Organization org, S ); setOnMouseClicked(e -> { - controller.handleCardClick(organization); + appstate.setCurrentOrganization(organization); + nav.showOrganizationPage(); }); setSpacing(10); diff --git a/src/main/java/edu/group5/app/view/donationpage/DonationPageView.java b/src/main/java/edu/group5/app/view/donationpage/DonationPageView.java index 6c5e5e6..5087267 100644 --- a/src/main/java/edu/group5/app/view/donationpage/DonationPageView.java +++ b/src/main/java/edu/group5/app/view/donationpage/DonationPageView.java @@ -1,9 +1,8 @@ package edu.group5.app.view.donationpage; -import edu.group5.app.control.HeaderController; -import edu.group5.app.control.MainController; -import edu.group5.app.control.donationpage.DonationPageController; -import edu.group5.app.view.Header; +import edu.group5.app.control.DonationController; +import edu.group5.app.control.NavigationController; +import edu.group5.app.model.AppState; import javafx.geometry.Insets; import javafx.geometry.Pos; import javafx.scene.control.Button; @@ -23,18 +22,19 @@ import java.util.Map; public class DonationPageView extends BorderPane { - private final DonationPageController controller; - private final MainController mainController; + private final AppState appState; + private final NavigationController nav; + private final DonationController donationController; + private final List allDonationElements = new ArrayList<>(); - private final Map elementAmounts = new HashMap<>(); + private final Map elementAmounts = new HashMap<>(); - public DonationPageView(DonationPageController donationPageController, HeaderController headerController, MainController mainController) { - this.controller = donationPageController; - this.mainController = mainController; - getStylesheets().add(getClass().getResource("/donationpage/donation.css").toExternalForm()); + public DonationPageView(AppState appState, NavigationController nav, DonationController donationController) { + this.appState = appState; + this.nav = nav; + this.donationController = donationController; - Header headerView = new Header(headerController); - setTop(headerView); + getStylesheets().add(getClass().getResource("/donationpage/donation.css").toExternalForm()); VBox content = new VBox(); content.getChildren().addAll(createDonationGrid(), createDonateSection()); @@ -102,7 +102,6 @@ private VBox createCustomButton() { box.setAlignment(Pos.CENTER); box.getStyleClass().add("donation-button"); - box.setOnMouseClicked(e -> { try { BigDecimal amount = new BigDecimal(amountField.getText().trim()); @@ -111,7 +110,6 @@ private VBox createCustomButton() { } catch (NumberFormatException exception) { System.err.println("Invalid custom donation amount: " + amountField.getText()); } - }); allDonationElements.add(box); @@ -120,7 +118,7 @@ private VBox createCustomButton() { private HBox createDonateSection() { Button donateBtn = new Button("Donate"); donateBtn.getStyleClass().add("donate-button"); - donateBtn.setOnAction(e -> controller.handleDonationBtn()); + donateBtn.setOnAction(e -> donationController.handleDonate()); HBox section = new HBox(donateBtn); section.setAlignment(Pos.CENTER); @@ -143,7 +141,7 @@ private void selectDonationElement(Node element) { private void extractAndStoreAmount(Node element) { BigDecimal amount = elementAmounts.get(element); if (amount != null) { - mainController.setCurrentDonationAmount(amount); + appState.setCurrentDonationAmount(amount); } else { System.err.println("Error: No amount found for selected element"); } diff --git a/src/main/java/edu/group5/app/view/donationpage/PaymentCompletePageView.java b/src/main/java/edu/group5/app/view/donationpage/PaymentCompletePageView.java index d563fef..fcefe97 100644 --- a/src/main/java/edu/group5/app/view/donationpage/PaymentCompletePageView.java +++ b/src/main/java/edu/group5/app/view/donationpage/PaymentCompletePageView.java @@ -1,6 +1,6 @@ package edu.group5.app.view.donationpage; -import edu.group5.app.control.donationpage.PaymentCompleteController; +import edu.group5.app.control.NavigationController; import javafx.geometry.Insets; import javafx.geometry.Pos; import javafx.scene.control.Button; @@ -9,14 +9,13 @@ import javafx.scene.layout.BorderPane; import javafx.scene.layout.VBox; -import java.awt.*; import java.util.Objects; public class PaymentCompletePageView extends BorderPane { - private final PaymentCompleteController controller; + private final NavigationController nav; - public PaymentCompletePageView(PaymentCompleteController paymentCompleteController) { - this.controller = paymentCompleteController; + public PaymentCompletePageView(NavigationController nav) { + this.nav = nav; getStylesheets().add(getClass().getResource("/donationpage/paymentcomplete.css").toExternalForm()); VBox content = new VBox(20); @@ -40,7 +39,7 @@ public VBox getImageSection() { public Button getHomeBtn() { Button home = new Button("Home"); - home.setOnAction(e -> controller.handleHomeBtn()); + home.setOnAction(e -> nav.showHomePage()); home.setId("home-button"); return home; } diff --git a/src/main/java/edu/group5/app/view/homepage/HomePageView.java b/src/main/java/edu/group5/app/view/homepage/HomePageView.java index 5510daa..b40299a 100644 --- a/src/main/java/edu/group5/app/view/homepage/HomePageView.java +++ b/src/main/java/edu/group5/app/view/homepage/HomePageView.java @@ -1,8 +1,7 @@ package edu.group5.app.view.homepage; -import edu.group5.app.control.HeaderController; -import edu.group5.app.control.HomePageController; -import edu.group5.app.view.Header; +import edu.group5.app.control.NavigationController; +import edu.group5.app.model.AppState; import javafx.geometry.Pos; import javafx.scene.control.Button; import javafx.scene.control.ScrollPane; @@ -12,13 +11,14 @@ import javafx.scene.text.Text; public class HomePageView extends BorderPane { - private final HomePageController controller; + private final AppState appState; + private final NavigationController nav; + + public HomePageView(AppState appState, NavigationController nav) { + this.appState = appState; + this.nav = nav; - public HomePageView(HomePageController homePageController, HeaderController headerController) { - this.controller = homePageController; getStylesheets().add(getClass().getResource("/homepage/homepage.css").toExternalForm()); - Header headerView = new Header(headerController); - setTop(headerView); setCenter(createBody()); } @@ -46,10 +46,12 @@ private VBox createIntroductionSection() { h2.setId("h2"); Button donateToACauseBtn = new Button("Donate to a cause"); - donateToACauseBtn.setOnAction(e -> controller.handleDonateToACauseBtn()); + donateToACauseBtn.setId("donate-to-cause-btn"); + donateToACauseBtn.setOnAction(e -> nav.showCausesPage()); Button aboutUsBtn = new Button("About us"); - aboutUsBtn.setOnAction(e -> controller.handleAboutUsBtn()); + aboutUsBtn.setId("about-us-btn"); + aboutUsBtn.setOnAction(e -> nav.showAboutUsPage()); introductionSection.getChildren().addAll(h1, h2, donateToACauseBtn, aboutUsBtn); return introductionSection; diff --git a/src/main/java/edu/group5/app/view/loginpage/LoginHeader.java b/src/main/java/edu/group5/app/view/loginpage/LoginHeader.java index decd5a1..ad6a412 100644 --- a/src/main/java/edu/group5/app/view/loginpage/LoginHeader.java +++ b/src/main/java/edu/group5/app/view/loginpage/LoginHeader.java @@ -1,6 +1,5 @@ package edu.group5.app.view.loginpage; -import edu.group5.app.control.HeaderController; import javafx.geometry.Pos; import javafx.scene.image.Image; import javafx.scene.image.ImageView; @@ -19,7 +18,6 @@ private StackPane getLogoSection() { StackPane logoSection = new StackPane(); logoSection.setId("logo-section"); logoSection.setAlignment(Pos.CENTER); - logoSection.setStyle("-fx-cursor: hand;"); ImageView logo = new ImageView( new Image(getClass().getResource("/header/images/hmh-logo.png").toExternalForm()) diff --git a/src/main/java/edu/group5/app/view/loginpage/LoginPageView.java b/src/main/java/edu/group5/app/view/loginpage/LoginPageView.java index 96d83d7..af972e0 100644 --- a/src/main/java/edu/group5/app/view/loginpage/LoginPageView.java +++ b/src/main/java/edu/group5/app/view/loginpage/LoginPageView.java @@ -1,9 +1,8 @@ package edu.group5.app.view.loginpage; - -import edu.group5.app.control.HeaderController; -import edu.group5.app.control.LoginPageController; -import javafx.geometry.Insets; +import edu.group5.app.control.NavigationController; +import edu.group5.app.control.LoginController; +import edu.group5.app.model.AppState; import javafx.geometry.Pos; import javafx.scene.control.Button; import javafx.scene.control.Label; @@ -14,16 +13,18 @@ import java.util.Objects; public class LoginPageView extends BorderPane { - private final LoginPageController controller; + private final AppState appState; + private final NavigationController nav; + private final LoginController loginController; + private TextField emailField; private PasswordField passwordField; private Label errorLabel; - public LoginPageView(LoginPageController loginPageController) { - this.controller = loginPageController; - this.controller.setView(this); - LoginHeader loginHeaderView = new LoginHeader(); - setTop(loginHeaderView); + public LoginPageView(AppState appState, NavigationController nav, LoginController loginController) { + this.appState = appState; + this.nav = nav; + this.loginController = loginController; HBox content = new HBox(); content.setFillHeight(true); @@ -58,6 +59,7 @@ private VBox getOuterSection() { outerSection.getChildren().addAll(getLoginBox(), getRegisterBtn()); return outerSection; } + private VBox getLoginBox() { VBox loginSection = new VBox(12); loginSection.setAlignment(Pos.CENTER); @@ -81,6 +83,7 @@ private VBox getEmailBox() { emailBox.getChildren().addAll(new Label("Email"), emailField); return emailBox; } + private VBox getPasswordBox() { VBox passwordBox = new VBox(); passwordBox.setMaxWidth(300); @@ -89,20 +92,27 @@ private VBox getPasswordBox() { passwordBox.getChildren().addAll(new Label("Password"), passwordField); return passwordBox; } + private Button getLoginBtn() { Button loginBtn = new Button("Log In"); loginBtn.setMaxWidth(300); loginBtn.setId("login-btn"); - loginBtn.setOnMouseClicked(e -> controller.handleLoginBtn()); + loginBtn.setOnMouseClicked(e -> loginController.handleLogin( + this, + getEmail(), + getPassword() + )); return loginBtn; } + public Button getRegisterBtn() { Button registerBtn = new Button("Don't have an account? Sign In"); registerBtn.setMaxWidth(300); - registerBtn.setOnMouseClicked(e -> controller.handleRegisterBtn()); + registerBtn.setOnMouseClicked(e -> nav.showSignInPage()); registerBtn.setId("register-btn"); return registerBtn; } + private StackPane getImageSection() { StackPane imageSection = new StackPane(); imageSection.setId("image-section"); diff --git a/src/main/java/edu/group5/app/view/loginpage/SignInPageView.java b/src/main/java/edu/group5/app/view/loginpage/SignInPageView.java index 6ee0e9b..946dae4 100644 --- a/src/main/java/edu/group5/app/view/loginpage/SignInPageView.java +++ b/src/main/java/edu/group5/app/view/loginpage/SignInPageView.java @@ -1,7 +1,8 @@ package edu.group5.app.view.loginpage; -import edu.group5.app.control.HeaderController; -import edu.group5.app.control.SignInPageController; +import edu.group5.app.control.NavigationController; +import edu.group5.app.control.LoginController; +import edu.group5.app.model.AppState; import javafx.geometry.Pos; import javafx.scene.control.Button; import javafx.scene.control.Label; @@ -13,17 +14,20 @@ public class SignInPageView extends BorderPane { - private final SignInPageController controller; + private final AppState appState; + private final NavigationController nav; + private final LoginController loginController; + private TextField nameField; private TextField surnameField; private TextField emailField; private PasswordField passwordField; private Label errorLabel; - public SignInPageView(SignInPageController signInPageController) { - this.controller = signInPageController; - this.controller.setView(this); - setTop(new LoginHeader()); + public SignInPageView(AppState appState, NavigationController nav, LoginController loginController) { + this.appState = appState; + this.nav = nav; + this.loginController = loginController; HBox content = new HBox(); content.setFillHeight(true); @@ -39,7 +43,6 @@ public SignInPageView(SignInPageController signInPageController) { } - public String getFirstName() { return nameField.getText(); } @@ -68,6 +71,7 @@ private VBox getOuterSection() { outerSection.getChildren().addAll(getSignInBox(), getBackToLoginBtn()); return outerSection; } + private VBox getSignInBox() { VBox signInSection = new VBox(12); signInSection.setAlignment(Pos.CENTER); @@ -102,6 +106,7 @@ private HBox getNameRow() { return nameRow; } + private VBox getEmailBox() { VBox emailBox = new VBox(); emailBox.setMaxWidth(300); @@ -111,6 +116,7 @@ private VBox getEmailBox() { emailBox.getChildren().addAll(new Label("Email"), emailField); return emailBox; } + private VBox getPasswordBox() { VBox passwordBox = new VBox(); passwordBox.setMaxWidth(300); @@ -119,20 +125,29 @@ private VBox getPasswordBox() { passwordBox.getChildren().addAll(new Label("Password"), passwordField); return passwordBox; } + private Button getSignInBtn() { Button signInBtn = new Button("Sign In"); signInBtn.setMaxWidth(300); signInBtn.setId("login-btn"); - signInBtn.setOnMouseClicked(e -> controller.handleSignInBtn()); + signInBtn.setOnMouseClicked(e -> loginController.handleSignIn( + this, + getFirstName(), + getLastName(), + getEmail(), + getPassword() + )); return signInBtn; } + public Button getBackToLoginBtn() { Button backBtn = new Button("Already have an account? Log in"); backBtn.setMaxWidth(300); - backBtn.setOnMouseClicked(e -> controller.handleLoginBtn()); + backBtn.setOnMouseClicked(e -> nav.showLoginPage()); backBtn.setId("register-btn"); return backBtn; } + private StackPane getImageSection() { StackPane imageSection = new StackPane(); imageSection.setId("image-section"); diff --git a/src/main/java/edu/group5/app/view/organizationpage/OrganizationPageView.java b/src/main/java/edu/group5/app/view/organizationpage/OrganizationPageView.java index b0afa27..da8d1df 100644 --- a/src/main/java/edu/group5/app/view/organizationpage/OrganizationPageView.java +++ b/src/main/java/edu/group5/app/view/organizationpage/OrganizationPageView.java @@ -1,10 +1,9 @@ package edu.group5.app.view.organizationpage; -import edu.group5.app.control.HeaderController; -import edu.group5.app.control.MainController; -import edu.group5.app.control.OrganizationPageController; +import edu.group5.app.control.DonationController; +import edu.group5.app.control.NavigationController; +import edu.group5.app.model.AppState; import edu.group5.app.model.organization.Organization; -import edu.group5.app.view.Header; import javafx.geometry.Pos; import javafx.scene.control.Button; import javafx.scene.control.Label; @@ -18,15 +17,16 @@ import javafx.scene.text.Text; public class OrganizationPageView extends BorderPane { - private final OrganizationPageController controller; - private final MainController mainController; + private final AppState appState; + private final NavigationController nav; + private final DonationController donationController; + + public OrganizationPageView(AppState appState, NavigationController nav, DonationController donationController) { + this.appState = appState; + this.nav = nav; + this.donationController = donationController; - public OrganizationPageView(OrganizationPageController controller, HeaderController headerController, MainController mainController) { - this.controller = controller; - this.mainController = mainController; getStylesheets().add(getClass().getResource("/organizationpage/organizationpage.css").toExternalForm()); - Header headerView = new Header(headerController); - setTop(headerView); setCenter(createBody()); } @@ -62,7 +62,7 @@ private StackPane createImageContainer() { imageContainer.setPrefWidth(120); imageContainer.setMaxWidth(Double.MAX_VALUE); - Organization org = mainController.getCurrentOrganization(); + Organization org = appState.getCurrentOrganization(); if (org != null && org.logoUrl() != null && !org.logoUrl().isBlank()) { ImageView logo = new ImageView(new Image(org.logoUrl(), true)); logo.setId("logo"); @@ -82,7 +82,7 @@ private StackPane createImageContainer() { } private VBox createOrgInfoSection() { - Organization org = mainController.getCurrentOrganization(); + Organization org = appState.getCurrentOrganization(); VBox orgInfoSection = new VBox(); orgInfoSection.setSpacing(50); @@ -99,7 +99,7 @@ private VBox createOrgInfoSection() { Button donateBtn = new Button("Donate"); donateBtn.setId("donate-button"); - donateBtn.setOnAction(e -> controller.handleDonateClick()); + donateBtn.setOnAction(e -> nav.showDonationPage()); orgInfoSection.getChildren().addAll(orgNameAndDescription, donateBtn); return orgInfoSection; diff --git a/src/main/java/edu/group5/app/view/userpage/UserPageView.java b/src/main/java/edu/group5/app/view/userpage/UserPageView.java index 9ab73ee..c5d886d 100644 --- a/src/main/java/edu/group5/app/view/userpage/UserPageView.java +++ b/src/main/java/edu/group5/app/view/userpage/UserPageView.java @@ -1,11 +1,13 @@ package edu.group5.app.view.userpage; -import edu.group5.app.control.HeaderController; -import edu.group5.app.control.MainController; +import edu.group5.app.control.DonationController; +import edu.group5.app.control.NavigationController; +import edu.group5.app.control.OrganizationController; +import edu.group5.app.control.LoginController; +import edu.group5.app.model.AppState; import edu.group5.app.model.donation.Donation; import edu.group5.app.model.organization.Organization; import edu.group5.app.model.user.User; -import edu.group5.app.view.Header; import javafx.geometry.Insets; import javafx.geometry.Pos; import javafx.scene.control.Button; @@ -17,24 +19,25 @@ import javafx.scene.layout.VBox; import javafx.scene.text.Text; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Set; +import java.util.*; public class UserPageView extends BorderPane { - private final User currentUser; - private final MainController mainController; - - public UserPageView(HeaderController headerController, MainController mainController) { - this.mainController = mainController; - this.currentUser = mainController.getCurrentUser(); + private final AppState appState; + private final NavigationController nav; + private final LoginController loginController; + private final DonationController donationController; + private final OrganizationController organizationController; + + public UserPageView(AppState appState, NavigationController nav, LoginController loginController, DonationController donationController, OrganizationController organizationController) { + this.appState = appState; + this.nav = nav; + this.loginController = loginController; + this.donationController = donationController; + this.organizationController = organizationController; getStylesheets().add(getClass().getResource("/userpage/userpage.css").toExternalForm()); - Header headerView = new Header(headerController); - setTop(headerView); - VBox content = new VBox(30); content.setPadding(new Insets(40)); content.getChildren().addAll(createProfileSection(), createCausesSection(), createDonationsSection()); @@ -42,12 +45,14 @@ public UserPageView(HeaderController headerController, MainController mainContro } private HBox createProfileSection() { - ImageView avatar = new ImageView(new Image(getClass().getResourceAsStream("/userpage/account_circle.png"))); + ImageView avatar = new ImageView(new Image(Objects.requireNonNull(getClass().getResourceAsStream("/userpage/account_circle.png")))); avatar.setFitWidth(150); avatar.setFitHeight(150); avatar.setPreserveRatio(true); avatar.setId("avatar"); + User currentUser = appState.getCurrentUser(); + Text name = new Text(currentUser.getFirstName() + " " + currentUser.getLastName()); name.setId("profile-name"); @@ -59,7 +64,7 @@ private HBox createProfileSection() { Button logoutBtn = new Button("Logout"); logoutBtn.getStyleClass().add("logout-button"); - logoutBtn.setOnAction(e -> mainController.logout()); + logoutBtn.setOnAction(e -> loginController.handleLogout()); VBox info = new VBox(10, name, email, location, logoutBtn); info.setAlignment(Pos.CENTER_LEFT); @@ -77,13 +82,9 @@ private VBox createCausesSection() { causesBox.getStyleClass().add("section-box"); causesBox.setPadding(new Insets(10)); - HashMap userDonations = mainController.getDonationService() - .getDonationRepository().filterByUser(currentUser.getUserId()); + User currentUser = appState.getCurrentUser(); - Set uniqueOrgs = new HashSet<>(); - for (Donation donation : userDonations.values()) { - uniqueOrgs.add(donation.organizationId()); - } + Set uniqueOrgs = donationController.getUniqueOrgs(); if (uniqueOrgs.isEmpty()) { Label noCauses = new Label("No causes supported yet"); @@ -91,7 +92,7 @@ private VBox createCausesSection() { causesBox.getChildren().add(noCauses); } else { for (int orgId : uniqueOrgs) { - Organization org = mainController.getOrganizationService().findByOrgNumber(orgId); + Organization org = organizationController.getOrgById(orgId); if (org != null) { Label causeLabel = new Label("• " + org.name()); causesBox.getChildren().add(causeLabel); @@ -110,8 +111,9 @@ private VBox createDonationsSection() { donationsBox.getStyleClass().add("section-box"); donationsBox.setPadding(new Insets(10)); - HashMap userDonations = mainController.getDonationService() - .getDonationRepository().filterByUser(currentUser.getUserId()); + User currentUser = appState.getCurrentUser(); + + Map userDonations = donationController.getUserDonations(currentUser.getUserId()); if (userDonations.isEmpty()) { Label noDonations = new Label("No donations yet"); @@ -119,8 +121,7 @@ private VBox createDonationsSection() { donationsBox.getChildren().add(noDonations); } else { for (Donation donation : userDonations.values()) { - Organization org = mainController.getOrganizationService() - .findByOrgNumber(donation.organizationId()); + Organization org = organizationController.getOrgById(donation.organizationId()); String orgName = (org != null) ? org.name() : "Unknown Organization"; Label donationLabel = new Label( diff --git a/src/main/resources/header/header.css b/src/main/resources/header/header.css index 28fcc59..23115eb 100644 --- a/src/main/resources/header/header.css +++ b/src/main/resources/header/header.css @@ -4,16 +4,10 @@ } #logo-section { - -fx-border-color: black; - -fx-border-width: 2px; } #navbar { - -fx-border-color: black; - -fx-border-width: 2px; } #profile-section { - -fx-border-color: black; - -fx-border-width: 2px; } \ No newline at end of file diff --git a/src/main/resources/homepage/homepage.css b/src/main/resources/homepage/homepage.css index 90b090c..2579557 100644 --- a/src/main/resources/homepage/homepage.css +++ b/src/main/resources/homepage/homepage.css @@ -1,6 +1,4 @@ #introduction-section { - -fx-border-color: black; - -fx-border-width: 2px; -fx-padding: 20px 0; } @@ -16,7 +14,6 @@ } #charity-image-section { - -fx-border-color: black; } #charity-image { @@ -24,4 +21,12 @@ -fx-background-position: center 55%; -fx-background-size: 100% auto; -fx-background-repeat: no-repeat; +} + +#donate-to-cause-btn { + -fx-cursor: hand; +} + +#about-us-btn { + -fx-cursor: hand; } \ No newline at end of file