Skip to content

Feat/donation page #60

Merged
merged 6 commits into from
Apr 7, 2026
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
9 changes: 7 additions & 2 deletions src/main/java/edu/group5/app/control/DonationController.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ public void handleDonate() {
User currentUser = appState.getCurrentUser();
Organization currentOrg = appState.getCurrentOrganization();
BigDecimal amount = appState.getCurrentDonationAmount();
String paymentMethod = appState.getCurrentPaymentMethod();

if (currentUser == null) {
System.err.println("Error: No user logged in");
Expand All @@ -60,17 +61,21 @@ public void handleDonate() {
System.err.println("Error: Invalid donation amount");
return;
}
if (paymentMethod == null) {
System.out.println("Error: Invalid payment method");
return;
}

// Create donation via service
boolean success = service.donate(
customer,
currentOrg.orgNumber(),
amount,
"Online"
paymentMethod
);

if (success) {
System.out.println("Donation created: " + amount + " kr to " + currentOrg.name());
System.out.println("Donation created: " + amount + " kr to " + currentOrg.name() + ", with payment method: " + paymentMethod);
} else {
System.err.println("Failed to create donation");
}
Expand Down
9 changes: 9 additions & 0 deletions src/main/java/edu/group5/app/model/AppState.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ public class AppState {
private User currentUser;
private BigDecimal currentDonationAmount;
private Organization currentOrganization;
private String currentDonation;

public User getCurrentUser() {
return this.currentUser;
Expand All @@ -33,4 +34,12 @@ public BigDecimal getCurrentDonationAmount() {
public void setCurrentDonationAmount(BigDecimal amount) {
this.currentDonationAmount = amount;
}

public String getCurrentPaymentMethod() {
return this.currentDonation;
}

public void setCurrentPaymentMethod(String paymentMethod){
this.currentDonation = paymentMethod;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,31 +16,43 @@
import javafx.scene.Node;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;

public class DonationPageView extends BorderPane {
private final AppState appState;
private final NavigationController nav;
private final DonationController donationController;

private final List<Node> allDonationElements = new ArrayList<>();
private final List<Node> allPaymentElements = new ArrayList<>();
private final Map<Object, BigDecimal> elementAmounts = new HashMap<>();
private final Map<Object, String> elementPaymentMethods = new HashMap<>();

private BigDecimal selectedAmount = null;
private String selectedPaymentMethod = null;
private Button donateBtn;

public DonationPageView(AppState appState, NavigationController nav, DonationController donationController) {
this.appState = appState;
this.nav = nav;
this.donationController = donationController;

getStylesheets().add(getClass().getResource("/donationpage/donation.css").toExternalForm());
getStylesheets().add(Objects.requireNonNull(getClass().getResource("/donationpage/donation.css")).toExternalForm());

VBox content = new VBox();
content.getChildren().addAll(createDonationGrid(), createDonateSection());
content.getChildren().addAll(createBackButton(), createDonationGrid(), createPaymentMethodSection(), createDonateSection());
setCenter(content);

}
private HBox createBackButton() {
Button backBtn = new Button("←");
backBtn.getStyleClass().add("back-button");
backBtn.setOnAction(e -> nav.showOrganizationPage());

HBox container = new HBox(backBtn);
container.setPadding(new Insets(10, 0, 0, 10));
return container;
}
private TilePane createDonationGrid(){
TilePane body = new TilePane();
body.setAlignment(Pos.CENTER);
Expand Down Expand Up @@ -104,7 +116,12 @@ private VBox createCustomButton() {

box.setOnMouseClicked(e -> {
try {
BigDecimal amount = new BigDecimal(amountField.getText().trim());
String text = amountField.getText().trim();
if (text.isEmpty()) {
return;
}
BigDecimal amount = new BigDecimal(text);

elementAmounts.put(box, amount);
selectDonationElement(box);
} catch (NumberFormatException exception) {
Expand All @@ -115,14 +132,40 @@ private VBox createCustomButton() {
allDonationElements.add(box);
return box;
}

public HBox createPaymentMethodSection() {
Button appleBtn = new Button("Apple Pay");
Button vippsBtn = new Button("Vipps");
Button visaBtn = new Button("Visa");

for (Button btn : new Button[]{appleBtn, vippsBtn, visaBtn}) {
btn.getStyleClass().add("payment-method-button");

btn.setOnAction(e -> {selectPaymentMethod(btn);});
allPaymentElements.add(btn);
}

elementPaymentMethods.put(appleBtn, "Apple Pay");
elementPaymentMethods.put(vippsBtn, "Vipps");
elementPaymentMethods.put(visaBtn, "Visa");

HBox sectionPm = new HBox(appleBtn, vippsBtn, visaBtn);
sectionPm.setAlignment(Pos.CENTER);
sectionPm.setSpacing(20);
sectionPm.setPadding(new Insets(20, 20, 20, 20));
return sectionPm;
}

private HBox createDonateSection() {
Button donateBtn = new Button("Donate");
donateBtn = new Button("Donate");
donateBtn.getStyleClass().add("donate-button");

donateBtn.setDisable(true);

donateBtn.setOnAction(e -> donationController.handleDonate());

HBox section = new HBox(donateBtn);
section.setAlignment(Pos.CENTER);
section.setPadding(new Insets(20, 0, 30, 0));
return section;
}

Expand All @@ -137,13 +180,30 @@ private void selectDonationElement(Node element) {
// Extract and store the amount
extractAndStoreAmount(element);
}
private void selectPaymentMethod(Node element) {
for (Node node : allPaymentElements) {
node.getStyleClass().remove("payment-method-selected");
}
element.getStyleClass().add("payment-method-selected");

extractAndStorePaymentMethod(element);
}

private void extractAndStoreAmount(Node element) {
BigDecimal amount = elementAmounts.get(element);
if (amount != null) {
selectedAmount = amount;
appState.setCurrentDonationAmount(amount);
} else {
System.err.println("Error: No amount found for selected element");
updateDonationButtonState();
}
}

private void extractAndStorePaymentMethod(Node element) {
String paymentMethod = elementPaymentMethods.get(element);
if (paymentMethod != null) {
selectedPaymentMethod = paymentMethod;
appState.setCurrentPaymentMethod(paymentMethod);
updateDonationButtonState();
}
}

Expand All @@ -154,5 +214,8 @@ private BigDecimal parseAmount(String amountStr) {
return BigDecimal.ZERO;
}
}
private void updateDonationButtonState() {
donateBtn.setDisable(selectedAmount == null || selectedPaymentMethod == null);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import edu.group5.app.control.NavigationController;
import edu.group5.app.model.AppState;
import edu.group5.app.model.organization.Organization;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
Expand All @@ -16,6 +17,8 @@
import javafx.scene.layout.VBox;
import javafx.scene.text.Text;

import java.util.Objects;

public class OrganizationPageView extends BorderPane {
private final AppState appState;
private final NavigationController nav;
Expand All @@ -26,24 +29,34 @@ public OrganizationPageView(AppState appState, NavigationController nav, Donatio
this.nav = nav;
this.donationController = donationController;

getStylesheets().add(getClass().getResource("/organizationpage/organizationpage.css").toExternalForm());
setCenter(createBody());
getStylesheets().add(Objects.requireNonNull(getClass().getResource("/organizationpage/organizationpage.css")).toExternalForm());

VBox content = new VBox();
content.getChildren().addAll(createBackButton(), createBody());
setCenter(content);
}

private ScrollPane createBody() {
ScrollPane body = new ScrollPane();
body.setFitToWidth(true);
body.setFitToHeight(true)
;
body.setFitToHeight(true);

VBox vBox = new VBox();
vBox.setId("main-container");

vBox.getChildren().addAll(
createOrgSection()
);
vBox.getChildren().addAll(createOrgSection());
body.setContent(vBox);
return body;
}
private HBox createBackButton() {
Button backBtn = new Button("←");
backBtn.getStyleClass().add("back-button");
backBtn.setOnAction(e -> nav.showCausesPage());

HBox container = new HBox(backBtn);
container.setPadding(new Insets(10, 0, 0, 10));
return container;
}

private HBox createOrgSection() {
HBox orgSection = new HBox();
Expand Down
16 changes: 12 additions & 4 deletions src/main/java/edu/group5/app/view/userpage/UserPageView.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,15 @@
import javafx.geometry.Pos;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ScrollPane;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.scene.text.Text;

import java.math.RoundingMode;
import java.util.*;


Expand Down Expand Up @@ -73,7 +75,6 @@ private HBox createProfileSection() {
profile.setAlignment(Pos.CENTER_LEFT);
return profile;
}

private VBox createCausesSection() {
Text title = new Text("YOUR SUPPORTED CAUSES");
title.getStyleClass().add("section-title");
Expand All @@ -99,8 +100,11 @@ private VBox createCausesSection() {
}
}
}
ScrollPane scrollPane = new ScrollPane(causesBox);
scrollPane.setFitToWidth(true);
scrollPane.setPrefHeight(150);

return new VBox(10, title, causesBox);
return new VBox(10, title, scrollPane);
}

private VBox createDonationsSection() {
Expand All @@ -125,13 +129,17 @@ private VBox createDonationsSection() {
String orgName = (org != null) ? org.name() : "Unknown Organization";

Label donationLabel = new Label(
orgName + " • " + donation.amount() + " kr" + " • " + donation.date()
orgName + " • " + donation.amount().setScale(2, RoundingMode.HALF_UP) + " kr" + " • " +
donation.date() + " • " + donation.paymentMethod()
);
donationsBox.getChildren().add(donationLabel);
}
}
ScrollPane scrollPane = new ScrollPane(donationsBox);
scrollPane.setFitToWidth(true);
scrollPane.setPrefHeight(200);

return new VBox(10, title, donationsBox);
return new VBox(10, title, scrollPane);
}

}
55 changes: 51 additions & 4 deletions src/main/resources/donationpage/donation.css
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,24 @@
-fx-text-fill: white;
-fx-border-color: #111;
}
.donation-button-selected:hover {
-fx-background-color: #222;
-fx-border-color: #222;
}

.donation-button-selected Text,
.donation-button-selected .donation-input {
-fx-fill: white;
-fx-border-color: transparent transparent white transparent;
-fx-text-fill: white;
-fx-prompt-text-fill: #ccc;
}

.donation-title {
-fx-font-size: 18px;
-fx-font-weight: bold;
-fx-fill: #111;
}
.donation-amount {
-fx-font-size: 18px;
-fx-fill: #111;
}
.donation-input {
-fx-font-size:16px;
-fx-pref-width: 140px;
Expand All @@ -51,3 +60,41 @@
-fx-background-color: #c02020;
}

.payment-method-button {
-fx-background-color: #111;
-fx-text-fill: white;
-fx-font-size: 16px;
-fx-font-weight: bold;
-fx-pref-width: 180px;
-fx-pref-height: 45px;
-fx-background-radius: 6;
-fx-border-radius: 6;
-fx-cursor: hand;
}
.payment-method-button:hover {
-fx-background-color: #222;
}
.payment-method-selected,
.payment-method-selected:hover {
-fx-background-color: #e03030;
}
.donation-button-selected .donation-title,
.donation-button-selected .donation-amount {
-fx-fill: white;
}
.back-button {
-fx-background-color: white;
-fx-text-fill: black;
-fx-font-weight: bold;
-fx-font-size: 20px;
-fx-background-radius: 50;
-fx-padding: 4px 10px;
-fx-cursor: hand;
-fx-border-radius: 50;
-fx-border-color: black;
-fx-border-width: 2px;
}
.back-button:hover {
-fx-background-color: #333;
-fx-border-color:#333;
}
Loading