Skip to content

Commit

Permalink
Update&feat[]: Connect backend to frontend by adding login, registrat…
Browse files Browse the repository at this point in the history
…ion, donation flow, and user page functionality, however per now it only stores data in runtime
  • Loading branch information
Fredrik Marjoni committed Mar 19, 2026
1 parent 04080ed commit 6901cd0
Show file tree
Hide file tree
Showing 21 changed files with 703 additions and 86 deletions.
52 changes: 50 additions & 2 deletions src/main/java/edu/group5/app/App.java
Original file line number Diff line number Diff line change
@@ -1,18 +1,62 @@
package edu.group5.app;

import edu.group5.app.control.MainController;
import edu.group5.app.control.wrapper.DbWrapper;
import edu.group5.app.control.wrapper.OrgApiWrapper;
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.UserRepository;
import edu.group5.app.model.user.UserService;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.stage.Stage;

import java.util.List;

/**
* Hello world!
* Main entry point for the Help-Me-Help charity donation application.
* Handles database connection, data loading, and application setup.
*/
public class App extends Application {
@Override
public void start(Stage stage) {
MainController controller = new MainController();
DbWrapper dbWrapper = new DbWrapper(true);
OrgApiWrapper orgApiWrapper = new OrgApiWrapper("https://app.innsamlingskontrollen.no/api/public/v1/all");

if (!dbWrapper.connect()) {
System.err.println("Failed to connect to database");
return;
}

// Load data from database
List<Object[]> userData = dbWrapper.importUsers();
List<Object[]> donationData = dbWrapper.fetchAllDonations();
dbWrapper.disconnect();

// Load organizations from API
Object[] organizationData = new Object[0];
try {
if (orgApiWrapper.importData()) {
organizationData = orgApiWrapper.getData();
}
} catch (InterruptedException e) {
System.err.println("Failed to load organization data: " + e.getMessage());
}

// Create repositories with fetched data
UserRepository userRepository = new UserRepository(userData);
DonationRepository donationRepository = new DonationRepository(donationData);
OrganizationRepository organizationRepository = new OrganizationRepository(organizationData);

// Create services (backend wiring)
UserService userService = new UserService(userRepository);
DonationService donationService = new DonationService(donationRepository, organizationRepository);
OrganizationService organizationService = new OrganizationService(organizationRepository);

MainController controller = new MainController(userService, donationService, organizationService);

Scene scene = controller.getMainView().getScene();
controller.showLoginPage();
Expand All @@ -22,4 +66,8 @@ public void start(Stage stage) {
stage.setScene(scene);
stage.show();
}

public static void main(String[] args) {
launch(args);
}
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
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() {
System.out.println("Browse Card Clicked");
public void handleCardClick(Organization organization) {
controller.setCurrentOrganization(organization);
controller.showOrganizationPage();
}
}
33 changes: 32 additions & 1 deletion src/main/java/edu/group5/app/control/LoginPageController.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,42 @@
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) {
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();
Expand Down
50 changes: 48 additions & 2 deletions src/main/java/edu/group5/app/control/MainController.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
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;
Expand All @@ -13,10 +19,20 @@ public class MainController {
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;

public MainController() {
this.view = new MainView(this);
this.view = new MainView(this, userService);
this.headerController = new HeaderController(this);
this.homePageController = new HomePageController(this);
this.browsePageController = new BrowsePageController(this);
Expand All @@ -25,6 +41,18 @@ public MainController() {
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;
}
Expand All @@ -33,8 +61,26 @@ 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();
}

Expand Down
47 changes: 44 additions & 3 deletions src/main/java/edu/group5/app/control/SignInPageController.java
Original file line number Diff line number Diff line change
@@ -1,15 +1,56 @@
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) {
public SignInPageController(MainController controller, UserService userService) {
this.controller = controller;
this.userService = userService;
}

public void setView(SignInPageView view) {
this.view = view;
}

public void handleSignInBtn() {
System.out.println("Sign in button pressed");
controller.showHomePage();
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();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
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;
Expand All @@ -9,7 +14,46 @@ public DonationPageController(MainController controller) {
this.controller = controller;
}
public void handleDonationBtn() {
System.out.println("Donating");
// 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();
}

Expand Down
6 changes: 3 additions & 3 deletions src/main/java/edu/group5/app/control/wrapper/DbWrapper.java
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ public int exportUsers(List<Object[]> data) {
return rowsAffected;
}

private List<Object[]> importDonations() {
public List<Object[]> fetchAllDonations() {
return this.importDonations(0, true);
}

Expand Down Expand Up @@ -182,8 +182,8 @@ private List<Object[]> importDonations(int user_id, boolean all) {
return this.donations;
}

public int exportDonations(List<Object[]> data) {
this.importDonations();
public int exportDonations(List<Object[]> data) {
this.fetchAllDonations();

if (data == null) {
throw new IllegalArgumentException("data can't be null");
Expand Down
Loading

0 comments on commit 6901cd0

Please sign in to comment.